Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <comphelper/string.hxx>
21 : #include <i18nlangtag/mslangid.hxx>
22 : #include <vcl/svapp.hxx>
23 : #include <vcl/msgbox.hxx>
24 : #include <unotools/saveopt.hxx>
25 : #include <svl/intitem.hxx>
26 : #include <vcl/edit.hxx>
27 : #include <vcl/settings.hxx>
28 :
29 : #include <cuires.hrc>
30 : #include <unotools/useroptions.hxx>
31 : #include "cuioptgenrl.hxx"
32 : #include <dialmgr.hxx>
33 : #include <svx/dlgutil.hxx>
34 : #include <svx/svxids.hrc>
35 :
36 : #include <boost/ref.hpp>
37 : #include <boost/make_shared.hpp>
38 :
39 : namespace
40 : {
41 :
42 : // rows
43 : enum RowType
44 : {
45 : Row_Company,
46 : Row_Name,
47 : Row_Name_Russian,
48 : Row_Name_Eastern,
49 : Row_Street,
50 : Row_Street_Russian,
51 : Row_City,
52 : Row_City_US,
53 : Row_Country,
54 : Row_TitlePos,
55 : Row_Phone,
56 : Row_FaxMail,
57 :
58 : nRowCount
59 : };
60 :
61 : // language flags
62 : namespace Lang
63 : {
64 : unsigned const Others = 1;
65 : unsigned const Russian = 2;
66 : unsigned const Eastern = 4;
67 : unsigned const US = 8;
68 : unsigned const All = static_cast<unsigned>(-1);
69 : }
70 :
71 :
72 : // vRowInfo[] -- rows (text + one or more edit boxes)
73 : // The order is the same as in RowType above, which is up to down.
74 :
75 : struct
76 : {
77 : // id of the text
78 : const char *pTextId;
79 : // language flags (see Lang above):
80 : // which language is this row for?
81 : unsigned nLangFlags;
82 : }
83 : const vRowInfo[] =
84 : {
85 : { "companyft", Lang::All },
86 : { "nameft", Lang::All & ~Lang::Russian & ~Lang::Eastern },
87 : { "rusnameft", Lang::Russian },
88 : { "eastnameft", Lang::Eastern },
89 : { "streetft", Lang::All & ~Lang::Russian },
90 : { "russtreetft", Lang::Russian },
91 : { "icityft", Lang::All & ~Lang::US },
92 : { "cityft", Lang::US },
93 : { "countryft", Lang::All },
94 : { "titleft", Lang::All },
95 : { "phoneft", Lang::All },
96 : { "faxft", Lang::All },
97 : };
98 :
99 :
100 : // vFieldInfo[] -- edit boxes
101 : // The order is up to down, and then left to right.
102 :
103 : struct
104 : {
105 : // in which row?
106 : RowType eRow;
107 : // id of the edit box
108 : const char *pEditId;
109 : // id for SvtUserOptions in unotools/useroptions.hxx
110 : UserOptToken nUserOptionsId;
111 : // id for settings the focus (defined in svx/optgenrl.hxx)
112 : EditPosition nGrabFocusId;
113 : }
114 : const vFieldInfo[] =
115 : {
116 : // Company
117 : { Row_Company, "company", UserOptToken::Company, EditPosition::COMPANY },
118 : // Name
119 : { Row_Name, "firstname", UserOptToken::FirstName, EditPosition::FIRSTNAME },
120 : { Row_Name, "lastname", UserOptToken::LastName, EditPosition::LASTNAME },
121 : { Row_Name, "shortname", UserOptToken::ID, EditPosition::SHORTNAME },
122 : // Name (russian)
123 : { Row_Name_Russian, "ruslastname", UserOptToken::LastName, EditPosition::LASTNAME },
124 : { Row_Name_Russian, "rusfirstname", UserOptToken::FirstName, EditPosition::FIRSTNAME },
125 : { Row_Name_Russian, "rusfathersname", UserOptToken::FathersName, EditPosition::UNKNOWN },
126 : { Row_Name_Russian, "russhortname", UserOptToken::ID, EditPosition::SHORTNAME },
127 : // Name (eastern: reversed name ord
128 : { Row_Name_Eastern, "eastlastname", UserOptToken::LastName, EditPosition::LASTNAME },
129 : { Row_Name_Eastern, "eastfirstname", UserOptToken::FirstName, EditPosition::FIRSTNAME },
130 : { Row_Name_Eastern, "eastshortname", UserOptToken::ID, EditPosition::SHORTNAME },
131 : // Street
132 : { Row_Street, "street", UserOptToken::Street, EditPosition::STREET },
133 : // Street (russian)
134 : { Row_Street_Russian, "russtreet", UserOptToken::Street, EditPosition::STREET },
135 : { Row_Street_Russian, "apartnum", UserOptToken::Apartment, EditPosition::UNKNOWN },
136 : // City
137 : { Row_City, "izip", UserOptToken::Zip, EditPosition::PLZ },
138 : { Row_City, "icity", UserOptToken::City, EditPosition::CITY },
139 : // City (US)
140 : { Row_City_US, "city", UserOptToken::City, EditPosition::CITY },
141 : { Row_City_US, "state", UserOptToken::State, EditPosition::STATE },
142 : { Row_City_US, "zip", UserOptToken::Zip, EditPosition::PLZ },
143 : // Country
144 : { Row_Country, "country", UserOptToken::Country, EditPosition::COUNTRY },
145 : // Title/Position
146 : { Row_TitlePos, "title", UserOptToken::Title, EditPosition::TITLE },
147 : { Row_TitlePos, "position", UserOptToken::Position, EditPosition::POSITION },
148 : // Phone
149 : { Row_Phone, "home", UserOptToken::TelephoneHome, EditPosition::TELPRIV },
150 : { Row_Phone, "work", UserOptToken::TelephoneWork, EditPosition::TELCOMPANY },
151 : // Fax/Mail
152 : { Row_FaxMail, "fax", UserOptToken::Fax, EditPosition::FAX },
153 : { Row_FaxMail, "email", UserOptToken::Email, EditPosition::EMAIL },
154 : };
155 :
156 :
157 : } // namespace
158 :
159 :
160 :
161 :
162 : // Row
163 :
164 0 : struct SvxGeneralTabPage::Row
165 : {
166 : // which row is it?
167 : RowType eRow;
168 : // row label
169 : VclPtr<FixedText> pLabel;
170 : // first and last field in the row (last is exclusive)
171 : unsigned nFirstField, nLastField;
172 :
173 : public:
174 0 : Row (FixedText *pLabel_, RowType eRow_)
175 : : eRow(eRow_)
176 : , pLabel(pLabel_)
177 : , nFirstField(0)
178 0 : , nLastField(0)
179 : {
180 0 : pLabel->Show();
181 0 : }
182 : };
183 :
184 :
185 :
186 :
187 : // Field
188 :
189 0 : struct SvxGeneralTabPage::Field
190 : {
191 : // which field is this? (in vFieldInfo[] above)
192 : unsigned iField;
193 : // edit box
194 : VclPtr<Edit> pEdit;
195 :
196 : public:
197 0 : Field (Edit *pEdit_, unsigned iField_)
198 : : iField(iField_)
199 0 : , pEdit(pEdit_)
200 : {
201 : //We want all widgets inside a container, so each row of the toplevel
202 : //grid has another container in it. To avoid adding spacing to these
203 : //empty grids they all default to invisible, so show them if their
204 : //children are visibles
205 0 : pEdit->GetParent()->Show();
206 0 : pEdit->Show();
207 0 : }
208 : };
209 :
210 :
211 :
212 0 : SvxGeneralTabPage::SvxGeneralTabPage(vcl::Window* pParent, const SfxItemSet& rCoreSet)
213 :
214 0 : : SfxTabPage(pParent, "OptUserPage", "cui/ui/optuserpage.ui", &rCoreSet)
215 : {
216 0 : get(m_pUseDataCB, "usefordocprop");
217 0 : InitControls();
218 0 : SetExchangeSupport(); // this page needs ExchangeSupport
219 0 : SetLinks();
220 0 : }
221 :
222 0 : SvxGeneralTabPage::~SvxGeneralTabPage()
223 : {
224 0 : disposeOnce();
225 0 : }
226 :
227 0 : void SvxGeneralTabPage::dispose()
228 : {
229 0 : m_pUseDataCB.clear();
230 0 : SfxTabPage::dispose();
231 0 : }
232 :
233 :
234 : // Initializes the titles and the edit boxes,
235 : // according to vRowInfo[] and vFieldInfo[] above.
236 0 : void SvxGeneralTabPage::InitControls ()
237 : {
238 : // which language bit do we use? (see Lang and vRowInfo[] above)
239 : unsigned LangBit;
240 0 : switch (LanguageType const eLang = Application::GetSettings().GetUILanguageTag().getLanguageType())
241 : {
242 : case LANGUAGE_ENGLISH_US:
243 0 : LangBit = Lang::US;
244 0 : break;
245 : case LANGUAGE_RUSSIAN:
246 0 : LangBit = Lang::Russian;
247 0 : break;
248 : default:
249 0 : if (MsLangId::isFamilyNameFirst(eLang))
250 0 : LangBit = Lang::Eastern;
251 : else
252 0 : LangBit = Lang::Others;
253 0 : break;
254 : }
255 :
256 : // creating rows
257 0 : unsigned iField = 0;
258 0 : for (unsigned iRow = 0; iRow != nRowCount; ++iRow)
259 : {
260 0 : RowType const eRow = static_cast<RowType>(iRow);
261 : // is the row visible?
262 0 : if (!(vRowInfo[iRow].nLangFlags & LangBit))
263 0 : continue;
264 : // creating row
265 : vRows.push_back(boost::make_shared<Row>(
266 0 : get<FixedText>(vRowInfo[iRow].pTextId), eRow));
267 0 : Row& rRow = *vRows.back();
268 : // fields in the row
269 : static unsigned const nFieldCount = SAL_N_ELEMENTS(vFieldInfo);
270 : // skipping other (invisible) rows
271 0 : while (iField != nFieldCount && vFieldInfo[iField].eRow != eRow)
272 0 : ++iField;
273 : // fields in the row
274 0 : rRow.nFirstField = vFields.size();
275 0 : for ( ; iField != nFieldCount && vFieldInfo[iField].eRow == eRow; ++iField)
276 : {
277 : // creating edit field
278 : vFields.push_back(boost::make_shared<Field>(
279 0 : get<Edit>(vFieldInfo[iField].pEditId), iField));
280 : // "short name" field?
281 0 : if (vFieldInfo[iField].nUserOptionsId == UserOptToken::ID)
282 : {
283 0 : nNameRow = vRows.size() - 1;
284 0 : nShortNameField = vFields.size() - 1;
285 : }
286 : }
287 0 : rRow.nLastField = vFields.size();
288 : }
289 0 : }
290 :
291 :
292 :
293 0 : void SvxGeneralTabPage::SetLinks ()
294 : {
295 : // link for updating the initials
296 0 : Link<> aLink = LINK( this, SvxGeneralTabPage, ModifyHdl_Impl );
297 0 : Row& rNameRow = *vRows[nNameRow];
298 0 : for (unsigned i = rNameRow.nFirstField; i != rNameRow.nLastField - 1; ++i)
299 0 : vFields[i]->pEdit->SetModifyHdl(aLink);
300 0 : }
301 :
302 :
303 :
304 0 : VclPtr<SfxTabPage> SvxGeneralTabPage::Create( vcl::Window* pParent, const SfxItemSet* rAttrSet )
305 : {
306 0 : return VclPtr<SvxGeneralTabPage>::Create( pParent, *rAttrSet );
307 : }
308 :
309 :
310 :
311 0 : bool SvxGeneralTabPage::FillItemSet( SfxItemSet* )
312 : {
313 : // remove leading and trailing whitespaces
314 0 : for (unsigned i = 0; i != vFields.size(); ++i)
315 0 : vFields[i]->pEdit->SetText(comphelper::string::strip(vFields[i]->pEdit->GetText(), ' '));
316 :
317 0 : bool bModified = false;
318 0 : bModified |= GetAddress_Impl();
319 0 : SvtSaveOptions aSaveOpt;
320 0 : if ( m_pUseDataCB->IsChecked() != aSaveOpt.IsUseUserData() )
321 : {
322 0 : aSaveOpt.SetUseUserData( m_pUseDataCB->IsChecked() );
323 0 : bModified |= true;
324 : }
325 0 : return bModified;
326 : }
327 :
328 :
329 :
330 0 : void SvxGeneralTabPage::Reset( const SfxItemSet* rSet )
331 : {
332 0 : SetAddress_Impl();
333 :
334 0 : sal_uInt16 const nWhich = GetWhich(SID_FIELD_GRABFOCUS);
335 :
336 0 : if (rSet->GetItemState(nWhich) == SfxItemState::SET)
337 : {
338 0 : EditPosition nField = static_cast<EditPosition>(static_cast<const SfxUInt16Item&>(rSet->Get(nWhich)).GetValue());
339 0 : if (nField != EditPosition::UNKNOWN)
340 : {
341 0 : for (unsigned i = 0; i != vFields.size(); ++i)
342 0 : if (nField == vFieldInfo[vFields[i]->iField].nGrabFocusId)
343 0 : vFields[i]->pEdit->GrabFocus();
344 : }
345 : else
346 0 : vFields.front()->pEdit->GrabFocus();
347 : }
348 :
349 0 : m_pUseDataCB->Check( SvtSaveOptions().IsUseUserData() );
350 0 : }
351 :
352 :
353 :
354 : // ModifyHdl_Impl()
355 : // This handler updates the initials (short name)
356 : // when one of the name fields was updated.
357 0 : IMPL_LINK( SvxGeneralTabPage, ModifyHdl_Impl, Edit *, pEdit )
358 : {
359 : // short name field and row
360 0 : Field& rShortName = *vFields[nShortNameField];
361 0 : Row& rNameRow = *vRows[nNameRow];
362 : // number of initials
363 0 : unsigned const nInits = rNameRow.nLastField - rNameRow.nFirstField - 1;
364 : // which field was updated? (in rNameRow)
365 0 : unsigned nField = nInits;
366 0 : for (unsigned i = 0; i != nInits; ++i)
367 : {
368 0 : if (vFields[rNameRow.nFirstField + i]->pEdit == pEdit)
369 0 : nField = i;
370 : }
371 : // updating the initial
372 0 : if (nField < nInits && rShortName.pEdit->IsEnabled())
373 : {
374 0 : OUString sShortName = rShortName.pEdit->GetText();
375 : // clear short name if it contains more characters than the number of initials
376 0 : if ((unsigned)sShortName.getLength() > nInits)
377 : {
378 0 : rShortName.pEdit->SetText(OUString());
379 : }
380 0 : while ((unsigned)sShortName.getLength() < nInits)
381 0 : sShortName += OUString(' ');
382 0 : OUString sName = pEdit->GetText();
383 0 : OUString sLetter = OUString(sName.getLength() ? sName.toChar() : ' ');
384 0 : rShortName.pEdit->SetText(sShortName.replaceAt(nField, 1, sLetter).trim());
385 : }
386 0 : return 0;
387 : }
388 :
389 :
390 :
391 0 : bool SvxGeneralTabPage::GetAddress_Impl()
392 : {
393 : // updating
394 0 : SvtUserOptions aUserOpt;
395 0 : for (unsigned i = 0; i != vFields.size(); ++i)
396 : aUserOpt.SetToken(
397 0 : vFieldInfo[vFields[i]->iField].nUserOptionsId,
398 0 : vFields[i]->pEdit->GetText()
399 0 : );
400 :
401 : // modified?
402 0 : for (unsigned i = 0; i != vFields.size(); ++i)
403 0 : if (vFields[i]->pEdit->IsValueChangedFromSaved())
404 0 : return true;
405 0 : return false;
406 : }
407 :
408 :
409 :
410 0 : void SvxGeneralTabPage::SetAddress_Impl()
411 : {
412 : // updating and disabling edit boxes
413 0 : SvtUserOptions aUserOpt;
414 0 : for (unsigned iRow = 0; iRow != vRows.size(); ++iRow)
415 : {
416 0 : Row& rRow = *vRows[iRow];
417 : // the label is enabled if any of its edit fields are enabled
418 0 : bool bEnableLabel = false;
419 0 : for (unsigned iField = rRow.nFirstField; iField != rRow.nLastField; ++iField)
420 : {
421 0 : Field& rField = *vFields[iField];
422 : // updating content
423 0 : UserOptToken const nToken = vFieldInfo[rField.iField].nUserOptionsId;
424 0 : rField.pEdit->SetText(aUserOpt.GetToken(nToken));
425 : // is enabled?
426 0 : bool const bEnableEdit = !aUserOpt.IsTokenReadonly(nToken);
427 0 : rField.pEdit->Enable(bEnableEdit);
428 0 : bEnableLabel = bEnableLabel || bEnableEdit;
429 : }
430 0 : rRow.pLabel->Enable(bEnableLabel);
431 : }
432 :
433 : // saving
434 0 : for (unsigned i = 0; i != vFields.size(); ++i)
435 0 : vFields[i]->pEdit->SaveValue();
436 0 : }
437 :
438 :
439 :
440 0 : SvxGeneralTabPage::sfxpg SvxGeneralTabPage::DeactivatePage( SfxItemSet* pSet_ )
441 : {
442 0 : if ( pSet_ )
443 0 : FillItemSet( pSet_ );
444 0 : return LEAVE_PAGE;
445 0 : }
446 :
447 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|