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