/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include #include #include #include #include "cuioptgenrl.hxx" #include #include #include namespace { // rows enum RowType { Row_Company, Row_Name, Row_Street, Row_Street_Russian, Row_City, Row_City_US, Row_Country, Row_TitlePos, Row_Phone, Row_FaxMail, nRowCount }; // language flags namespace Lang { unsigned const Others = 1; unsigned const Russian = 2; unsigned const US = 8; unsigned const All = static_cast(-1); } // vRowInfo[] -- rows (text + one or more edit boxes) // The order is the same as in RowType above, which is up to down. struct { // id of the text const char *pTextId; // language flags (see Lang above): // which language is this row for? unsigned nLangFlags; } const vRowInfo[] = { { "companyft", Lang::All }, { "nameft", Lang::All }, { "streetft", Lang::All & ~Lang::Russian }, { "russtreetft", Lang::Russian }, { "icityft", Lang::All & ~Lang::US }, { "cityft", Lang::US }, { "countryft", Lang::All }, { "titleft", Lang::All }, { "phoneft", Lang::All }, { "faxft", Lang::All }, }; // vFieldInfo[] -- edit boxes // The order is up to down, and then left to right. struct { // in which row? RowType eRow; // id of the edit box const char *pEditId; // id for SvtUserOptions in unotools/useroptions.hxx UserOptToken nUserOptionsId; // id for settings the focus (defined in svx/optgenrl.hxx) EditPosition nGrabFocusId; } const vFieldInfo[] = { // Company { Row_Company, "company", UserOptToken::Company, EditPosition::COMPANY }, // Name { Row_Name, "lastname", UserOptToken::LastName, EditPosition::LASTNAME }, { Row_Name, "shortname", UserOptToken::ID, EditPosition::SHORTNAME }, // Street { Row_Street, "street", UserOptToken::Street, EditPosition::STREET }, // Street (russian) { Row_Street_Russian, "russtreet", UserOptToken::Street, EditPosition::STREET }, { Row_Street_Russian, "apartnum", UserOptToken::Apartment, EditPosition::UNKNOWN }, // City { Row_City, "izip", UserOptToken::Zip, EditPosition::PLZ }, { Row_City, "icity", UserOptToken::City, EditPosition::CITY }, // City (US) { Row_City_US, "city", UserOptToken::City, EditPosition::CITY }, { Row_City_US, "state", UserOptToken::State, EditPosition::STATE }, { Row_City_US, "zip", UserOptToken::Zip, EditPosition::PLZ }, // Country { Row_Country, "country", UserOptToken::Country, EditPosition::COUNTRY }, // Title/Position { Row_TitlePos, "title", UserOptToken::Title, EditPosition::TITLE }, { Row_TitlePos, "position", UserOptToken::Position, EditPosition::POSITION }, // Phone { Row_Phone, "home", UserOptToken::TelephoneHome, EditPosition::TELPRIV }, { Row_Phone, "work", UserOptToken::TelephoneWork, EditPosition::TELCOMPANY }, // Fax/Mail { Row_FaxMail, "fax", UserOptToken::Fax, EditPosition::FAX }, { Row_FaxMail, "email", UserOptToken::Email, EditPosition::EMAIL }, }; } // namespace // Row struct SvxGeneralTabPage::Row { // row label VclPtr pLabel; // first and last field in the row (last is exclusive) unsigned nFirstField, nLastField; public: explicit Row (FixedText *pLabel_) : pLabel(pLabel_) , nFirstField(0) , nLastField(0) { pLabel->Show(); } }; // Field struct SvxGeneralTabPage::Field { // which field is this? (in vFieldInfo[] above) unsigned iField; // edit box VclPtr pEdit; public: Field (Edit *pEdit_, unsigned iField_) : iField(iField_) , pEdit(pEdit_) { //We want all widgets inside a container, so each row of the toplevel //grid has another container in it. To avoid adding spacing to these //empty grids they all default to invisible, so show them if their //children are visible pEdit->GetParent()->Show(); pEdit->Show(); } }; SvxGeneralTabPage::SvxGeneralTabPage(vcl::Window* pParent, const SfxItemSet& rCoreSet) : SfxTabPage(pParent, "OptUserPage", "cui/ui/optuserpage.ui", &rCoreSet) { get(m_pUseDataCB, "usefordocprop"); InitControls(); SetExchangeSupport(); // this page needs ExchangeSupport SetLinks(); } SvxGeneralTabPage::~SvxGeneralTabPage() { disposeOnce(); } void SvxGeneralTabPage::dispose() { m_pUseDataCB.clear(); SfxTabPage::dispose(); } // Initializes the titles and the edit boxes, // according to vRowInfo[] and vFieldInfo[] above. void SvxGeneralTabPage::InitControls () { // which language bit do we use? (see Lang and vRowInfo[] above) unsigned LangBit; switch (Application::GetSettings().GetUILanguageTag().getLanguageType()) { case LANGUAGE_ENGLISH_US: LangBit = Lang::US; break; case LANGUAGE_RUSSIAN: LangBit = Lang::Russian; break; default: LangBit = Lang::Others; break; } // creating rows unsigned iField = 0; for (unsigned iRow = 0; iRow != nRowCount; ++iRow) { RowType const eRow = static_cast(iRow); // is the row visible? if (!(vRowInfo[iRow].nLangFlags & LangBit)) continue; // creating row vRows.push_back(std::make_shared( get(vRowInfo[iRow].pTextId))); Row& rRow = *vRows.back(); // fields in the row static unsigned const nFieldCount = SAL_N_ELEMENTS(vFieldInfo); // skipping other (invisible) rows while (iField != nFieldCount && vFieldInfo[iField].eRow != eRow) ++iField; // fields in the row rRow.nFirstField = vFields.size(); for ( ; iField != nFieldCount && vFieldInfo[iField].eRow == eRow; ++iField) { // creating edit field vFields.push_back(std::make_shared( get(vFieldInfo[iField].pEditId), iField)); // "short name" field? if (vFieldInfo[iField].nUserOptionsId == UserOptToken::ID) { nShortNameField = vFields.size() - 1; } } rRow.nLastField = vFields.size(); } } void SvxGeneralTabPage::SetLinks () { // link for updating the initials Link aLink = LINK( this, SvxGeneralTabPage, ModifyHdl_Impl ); Row& rNameRow = *vRows[Row_Name]; for (unsigned i = rNameRow.nFirstField; i != rNameRow.nLastField - 1; ++i) vFields[i]->pEdit->SetModifyHdl(aLink); } VclPtr SvxGeneralTabPage::Create( vcl::Window* pParent, const SfxItemSet* rAttrSet ) { return VclPtr::Create( pParent, *rAttrSet ); } bool SvxGeneralTabPage::FillItemSet( SfxItemSet* ) { // remove leading and trailing whitespaces for (auto const & i: vFields) i->pEdit->SetText(comphelper::string::strip(i->pEdit->GetText(), ' ')); bool bModified = false; bModified |= GetData_Impl(); SvtSaveOptions aSaveOpt; if ( m_pUseDataCB->IsChecked() != aSaveOpt.IsUseUserData() ) { aSaveOpt.SetUseUserData( m_pUseDataCB->IsChecked() ); bModified = true; } return bModified; } void SvxGeneralTabPage::Reset( const SfxItemSet* rSet ) { SetData_Impl(); sal_uInt16 const nWhich = GetWhich(SID_FIELD_GRABFOCUS); if (rSet->GetItemState(nWhich) == SfxItemState::SET) { EditPosition nField = static_cast(static_cast(rSet->Get(nWhich)).GetValue()); if (nField != EditPosition::UNKNOWN) { for (auto const & i: vFields) if (nField == vFieldInfo[i->iField].nGrabFocusId) i->pEdit->GrabFocus(); } else vFields.front()->pEdit->GrabFocus(); } m_pUseDataCB->Check( SvtSaveOptions().IsUseUserData() ); } // ModifyHdl_Impl() // This handler updates the initials (short name) // when the name field was updated. IMPL_LINK( SvxGeneralTabPage, ModifyHdl_Impl, Edit&, rEdit, void ) { // short name field and row Field& rShortName = *vFields[nShortNameField]; if (rShortName.pEdit->IsEnabled()) { sal_Int32 nIndex = 0; OUString sName = rEdit.GetText(); OUString sShortName; do { OUString sToken = sName.getToken(0, ' ', nIndex); if (!sToken.isEmpty()) sShortName += sToken.copy(0, 1); } while (nIndex != -1); rShortName.pEdit->SetText(sShortName); } } bool SvxGeneralTabPage::GetData_Impl() { // updating SvtUserOptions aUserOpt; for (auto const & i: vFields) { aUserOpt.SetToken( vFieldInfo[i->iField].nUserOptionsId, i->pEdit->GetText() ); // Blank out first name and father's name which aren't kept separately any longer if (vFieldInfo[i->iField].nUserOptionsId == UserOptToken::LastName) { aUserOpt.SetToken(UserOptToken::FirstName, ""); aUserOpt.SetToken(UserOptToken::FathersName, ""); } } // modified? for (auto const & i: vFields) if (i->pEdit->IsValueChangedFromSaved()) return true; return false; } void SvxGeneralTabPage::SetData_Impl() { // updating and disabling edit boxes SvtUserOptions aUserOpt; for (auto const & i: vRows) { Row& rRow = *i; // the label is enabled if any of its edit fields are enabled bool bEnableLabel = false; for (unsigned iField = rRow.nFirstField; iField != rRow.nLastField; ++iField) { Field& rField = *vFields[iField]; // updating content UserOptToken const nToken = vFieldInfo[rField.iField].nUserOptionsId; if (nToken == UserOptToken::LastName) { // When using old-style data (with separated name), if // "family name" comes first in the locale, use that // order. If Russian, use also father's name if // present. OUString sName; if (MsLangId::isFamilyNameFirst(Application::GetSettings().GetUILanguageTag().getLanguageType())) { sName += aUserOpt.GetToken(UserOptToken::LastName); OUString sFirstName = aUserOpt.GetToken(UserOptToken::FirstName); if (!sName.isEmpty() && !sFirstName.isEmpty()) sName += " "; sName += sFirstName; } else { sName += aUserOpt.GetToken(UserOptToken::FirstName); OUString sFathersName; if (Application::GetSettings().GetUILanguageTag().getLanguageType() == LANGUAGE_RUSSIAN) sFathersName = aUserOpt.GetToken(UserOptToken::FathersName); if (!sName.isEmpty() && !sFathersName.isEmpty()) sName += " "; sName += sFathersName; OUString sLastName = aUserOpt.GetToken(UserOptToken::LastName); if (!sName.isEmpty() && !sLastName.isEmpty()) sName += " "; sName += sLastName; } rField.pEdit->SetText(sName); } else rField.pEdit->SetText(aUserOpt.GetToken(nToken)); // is enabled? bool const bEnableEdit = !aUserOpt.IsTokenReadonly(nToken); rField.pEdit->Enable(bEnableEdit); bEnableLabel = bEnableLabel || bEnableEdit; } rRow.pLabel->Enable(bEnableLabel); } // saving for (auto const & i: vFields) i->pEdit->SaveValue(); } DeactivateRC SvxGeneralTabPage::DeactivatePage( SfxItemSet* pSet_ ) { if ( pSet_ ) FillItemSet( pSet_ ); return DeactivateRC::LeavePage; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */