LibreOffice Module sw (master)  1
flddinf.cxx
Go to the documentation of this file.
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 <sfx2/frame.hxx>
21 #include <sfx2/sfxsids.hrc>
22 #include <svl/numformat.hxx>
23 #include <svl/zforlist.hxx>
24 #include <svl/zformat.hxx>
25 
26 #include <swtypes.hxx>
27 #include <flddinf.hrc>
28 #include <strings.hrc>
29 #include <fldbas.hxx>
30 #include <docufld.hxx>
31 #include <wrtsh.hxx>
32 
33 #include "flddinf.hxx"
34 #include <com/sun/star/beans/XPropertySet.hpp>
35 #include <com/sun/star/beans/XPropertySetInfo.hpp>
36 #include <com/sun/star/util/Time.hpp>
37 #include <com/sun/star/util/DateTime.hpp>
38 #include <com/sun/star/util/Date.hpp>
39 
40 #define USER_DATA_VERSION_1 "1"
41 #define USER_DATA_VERSION USER_DATA_VERSION_1
42 
43 using namespace nsSwDocInfoSubType;
44 using namespace com::sun::star;
45 
47 {
48  for (size_t i = 0; i < SAL_N_ELEMENTS(FLD_SELECT); ++i)
49  rListBox.append_text(SwResId(FLD_SELECT[i]));
50 }
51 
53  : SwFieldPage(pPage, pController, "modules/swriter/ui/flddocinfopage.ui", "FieldDocInfoPage", pCoreSet)
54  , nOldSel(0)
55  , nOldFormat(0)
56  , m_xTypeTLB(m_xBuilder->weld_tree_view("type"))
57  , m_xSelection(m_xBuilder->weld_widget("selectframe"))
58  , m_xSelectionLB(m_xBuilder->weld_tree_view("select"))
59  , m_xFormat(m_xBuilder->weld_widget("formatframe"))
60  , m_xFormatLB(new SwNumFormatTreeView(m_xBuilder->weld_tree_view("format")))
61  , m_xFixedCB(m_xBuilder->weld_check_button("fixed"))
62 {
63  m_xTypeTLB->make_sorted();
65 
66  auto nWidth = m_xTypeTLB->get_approximate_digit_width() * FIELD_COLUMN_WIDTH;
67  auto nHeight = m_xTypeTLB->get_height_rows(10);
68  m_xTypeTLB->set_size_request(nWidth, nHeight);
69  m_xFormatLB->get_widget().set_size_request(nWidth * 2, nHeight);
70  m_xSelectionLB->set_size_request(nWidth, nHeight);
71 
72  //enable 'active' language selection
73  m_xFormatLB->SetShowLanguageControl(true);
74 
75  const SfxUnoAnyItem* pItem = pCoreSet
76  ? pCoreSet->GetItem<SfxUnoAnyItem>(SID_DOCINFO, false)
77  : nullptr;
78  if ( pItem )
79  pItem->GetValue() >>= xCustomPropertySet;
80 }
81 
83 {
84 }
85 
87 {
88  Init(); // general initialisation
89 
90  // initialise TypeListBox
91  m_xTypeTLB->freeze();
92  m_xTypeTLB->clear();
93  m_xSelEntry.reset();
94 
95  // display SubTypes in TypeLB
96  sal_uInt16 nSubType = USHRT_MAX;
97  if (IsFieldEdit())
98  {
99  const SwField* pCurField = GetCurField();
100  nSubType = static_cast<const SwDocInfoField*>(pCurField)->GetSubType() & 0xff;
101  if( nSubType == DI_CUSTOM )
102  {
103  m_sOldCustomFieldName = static_cast<const SwDocInfoField*>(pCurField)->GetName();
104  }
105  m_xFormatLB->SetAutomaticLanguage(pCurField->IsAutomaticLanguage());
106  SwWrtShell *pSh = GetWrtShell();
107  if(pSh)
108  {
109  const SvNumberformat* pFormat = pSh->GetNumberFormatter()->GetEntry(pCurField->GetFormat());
110  if(pFormat)
111  m_xFormatLB->SetLanguage(pFormat->GetLanguage());
112  }
113  }
114 
115  sal_Int32 nSelEntryData = -1;
116  const OUString sUserData = GetUserData();
117  sal_Int32 nIdx{ 0 };
118  if (sUserData.getToken(0, ';', nIdx).equalsIgnoreAsciiCase(USER_DATA_VERSION_1))
119  {
120  nSelEntryData = sUserData.getToken(0, ';', nIdx).toInt32();
121  }
122 
123  std::vector<OUString> aLst;
125  std::unique_ptr<weld::TreeIter> xEntry(m_xTypeTLB->make_iterator());
126  std::unique_ptr<weld::TreeIter> xExpandEntry;
127  for(size_t i = 0; i < aLst.size(); ++i)
128  {
129  if (!IsFieldEdit() || nSubType == i)
130  {
131  const OUString sId(OUString::number(i));
132  if (DI_CUSTOM == i)
133  {
134  if(xCustomPropertySet.is() )
135  {
136  uno::Reference< beans::XPropertySetInfo > xSetInfo = xCustomPropertySet->getPropertySetInfo();
137  const uno::Sequence< beans::Property > rProperties = xSetInfo->getProperties();
138 
139  if( rProperties.hasElements() )
140  {
141  std::unique_ptr<weld::TreeIter> xInfo(m_xTypeTLB->make_iterator());
142 
143  OUString sText(SwResId(STR_CUSTOM_FIELD));
144  OUString sEntryId(OUString::number(USHRT_MAX));
145  m_xTypeTLB->insert(nullptr, -1, &sText, &sEntryId, nullptr,
146  nullptr, false, xInfo.get());
147  for (const auto& rProperty : rProperties)
148  {
149  const OUString sEntry = rProperty.Name;
150 
151  m_xTypeTLB->insert(xInfo.get(), -1, &sEntry, &sId,
152  nullptr, nullptr, false, xEntry.get());
153  if (m_sOldCustomFieldName == sEntry)
154  {
155  m_xSelEntry = m_xTypeTLB->make_iterator(xEntry.get());
156  xExpandEntry = m_xTypeTLB->make_iterator(xInfo.get());
157  }
158  }
159  }
160  }
161  }
162  else
163  {
164  if (!(IsFieldDlgHtmlMode() && (i == DI_EDIT || i == DI_SUBJECT || i == DI_PRINT)))
165  {
166  m_xTypeTLB->insert(nullptr, -1, &aLst[i], &sId,
167  nullptr, nullptr, false, xEntry.get());
168  }
169  }
170  if (static_cast<size_t>(nSelEntryData) == i)
171  m_xSelEntry = std::move(xEntry);
172  }
173  }
174 
175  m_xTypeTLB->thaw();
176 
177  if (xExpandEntry)
178  m_xTypeTLB->expand_row(*xExpandEntry);
179 
180  // select old Pos
181  if (m_xSelEntry)
182  {
183  m_xTypeTLB->select(*m_xSelEntry);
184  nSubType = m_xTypeTLB->get_id(*m_xSelEntry).toUInt32();
185  }
186  else
187  {
188  m_xSelEntry = m_xTypeTLB->make_iterator();
189  if (m_xTypeTLB->get_iter_first(*m_xSelEntry))
190  nSubType = m_xTypeTLB->get_id(*m_xSelEntry).toUInt32();
191  else
192  m_xSelEntry.reset();
193  }
194 
195  FillSelectionLB(nSubType);
196  if (m_xSelEntry)
197  TypeHdl(*m_xTypeTLB);
198 
199  m_xTypeTLB->connect_changed(LINK(this, SwFieldDokInfPage, TypeHdl));
200  m_xTypeTLB->connect_row_activated(LINK(this, SwFieldDokInfPage, TreeViewInsertHdl));
201  m_xSelectionLB->connect_changed(LINK(this, SwFieldDokInfPage, SubTypeHdl));
202  m_xSelectionLB->connect_row_activated(LINK(this, SwFieldDokInfPage, TreeViewInsertHdl));
203  m_xFormatLB->connect_row_activated(LINK(this, SwFieldDokInfPage, TreeViewInsertHdl));
204 
205  if (IsFieldEdit())
206  {
207  nOldSel = m_xSelectionLB->get_selected_index();
209  m_xFixedCB->save_state();
210  }
211 }
212 
214 {
215  // current ListBoxPos
216  if (!m_xTypeTLB->get_selected(m_xSelEntry.get()) &&
217  m_xTypeTLB->get_iter_first(*m_xSelEntry))
218  {
219  m_xTypeTLB->select(*m_xSelEntry);
220  }
221  FillSelectionLB(m_xTypeTLB->get_id(*m_xSelEntry).toUInt32());
222  SubTypeHdl(*m_xSelectionLB);
223 }
224 
226 {
227  sal_uInt16 nSubType = m_xTypeTLB->get_id(*m_xSelEntry).toUInt32();
228  sal_Int32 nPos = m_xSelectionLB->get_selected_index();
229  sal_uInt16 nExtSubType;
230  SvNumFormatType nNewType = SvNumFormatType::ALL;
231 
232  if (nSubType != DI_EDIT)
233  {
234  if (nPos == -1)
235  {
236  if (!m_xSelectionLB->n_children())
237  {
238  m_xFormatLB->clear();
239  m_xFormat->set_sensitive(false);
240  if( nSubType == DI_CUSTOM )
241  {
242  //find out which type the custom field has - for a start set to DATE format
243  const OUString sName = m_xTypeTLB->get_text(*m_xSelEntry);
244  try
245  {
246  uno::Any aVal = xCustomPropertySet->getPropertyValue( sName );
247  const uno::Type& rValueType = aVal.getValueType();
248  if( rValueType == ::cppu::UnoType<util::DateTime>::get())
249  {
250  nNewType = SvNumFormatType::DATETIME;
251  }
252  else if( rValueType == ::cppu::UnoType<util::Date>::get())
253  {
254  nNewType = SvNumFormatType::DATE;
255  }
256  else if( rValueType == ::cppu::UnoType<util::Time>::get())
257  {
258  nNewType = SvNumFormatType::TIME;
259  }
260  }
261  catch( const uno::Exception& )
262  {
263  }
264  }
265  else
266  return;
267  }
268  nPos = 0;
269  }
270 
271  nExtSubType = m_xSelectionLB->get_id(nPos).toUInt32();
272  }
273  else
274  nExtSubType = DI_SUB_TIME;
275 
276  SvNumFormatType nOldType = SvNumFormatType::ALL;
277  bool bEnable = false;
278  bool bOneArea = false;
279 
280  if (m_xFormatLB->get_active())
281  nOldType = m_xFormatLB->GetFormatType();
282 
283  switch (nExtSubType)
284  {
285  case DI_SUB_AUTHOR:
286  break;
287 
288  case DI_SUB_DATE:
289  nNewType = SvNumFormatType::DATE;
290  bOneArea = true;
291  break;
292 
293  case DI_SUB_TIME:
294  nNewType = SvNumFormatType::TIME;
295  bOneArea = true;
296  break;
297  }
298  if (nNewType == SvNumFormatType::ALL)
299  {
300  m_xFormatLB->clear();
301  }
302  else
303  {
304  if (nOldType != nNewType)
305  {
306  m_xFormatLB->SetFormatType(nNewType);
307  m_xFormatLB->SetOneArea(bOneArea);
308  }
309  bEnable = true;
310  }
311 
312  sal_uInt32 nFormat = IsFieldEdit() ? static_cast<SwDocInfoField*>(GetCurField())->GetFormat() : 0;
313 
314  sal_uInt16 nOldSubType = IsFieldEdit() ? (static_cast<SwDocInfoField*>(GetCurField())->GetSubType() & 0xff00) : 0;
315 
316  if (IsFieldEdit())
317  {
318  nPos = m_xSelectionLB->get_selected_index();
319  if (nPos != -1)
320  {
321  nSubType = m_xSelectionLB->get_id(nPos).toUInt32();
322 
323  nOldSubType &= ~DI_SUB_FIXED;
324  if (nOldSubType == nSubType)
325  {
326  if (!nFormat && (nNewType == SvNumFormatType::DATE || nNewType == SvNumFormatType::TIME))
327  {
328  SwWrtShell *pSh = GetWrtShell();
329  if(pSh)
330  {
331  SvNumberFormatter* pFormatter = pSh->GetNumberFormatter();
332  LanguageType eLang = m_xFormatLB->GetCurLanguage();
333  if (nNewType == SvNumFormatType::DATE)
334  nFormat = pFormatter->GetFormatIndex( NF_DATE_SYSTEM_SHORT, eLang);
335  else if (nNewType == SvNumFormatType::TIME)
336  nFormat = pFormatter->GetFormatIndex( NF_TIME_HHMM, eLang);
337  }
338  }
339  m_xFormatLB->SetDefFormat(nFormat);
340  }
341  }
342  else if( (nSubType == DI_CUSTOM) && (nNewType != SvNumFormatType::ALL) )
343  {
344  m_xFormatLB->SetDefFormat(nFormat);
345  }
346  }
347 
348  m_xFormat->set_sensitive(bEnable);
349 
350  if (bEnable && m_xFormatLB->get_selected_index() == -1)
351  m_xFormatLB->select(0);
352 }
353 
354 sal_Int32 SwFieldDokInfPage::FillSelectionLB(sal_uInt16 nSubType)
355 {
356  // fill Format-Listbox
358 
359  EnableInsert(nSubType != USHRT_MAX);
360 
361  if (nSubType == USHRT_MAX) // Info-Text
362  nSubType = DI_SUBTYPE_BEGIN;
363 
364  m_xSelectionLB->clear();
365 
366  sal_uInt16 nSize = 0;
367  sal_Int32 nSelPos = -1;
368  sal_uInt16 nExtSubType = IsFieldEdit() ? (static_cast<SwDocInfoField*>(GetCurField())->GetSubType() & 0xff00) : 0;
369 
370  if (IsFieldEdit())
371  {
372  m_xFixedCB->set_active((nExtSubType & DI_SUB_FIXED) != 0);
373  nExtSubType = ((nExtSubType & ~DI_SUB_FIXED) >> 8) - 1;
374  }
375 
376  if (nSubType < DI_CREATE || nSubType == DI_DOCNO || nSubType == DI_EDIT|| nSubType == DI_CUSTOM )
377  {
378  // Format Box is empty for Title and Time
379  }
380  else
381  {
382  nSize = GetFieldMgr().GetFormatCount(nTypeId, IsFieldDlgHtmlMode());
383  for (sal_uInt16 i = 0; i < nSize; ++i)
384  {
385  OUString sId(OUString::number(GetFieldMgr().GetFormatId(nTypeId, i)));
386  m_xSelectionLB->append(sId, GetFieldMgr().GetFormatStr(nTypeId, i));
387  if (IsFieldEdit() && i == nExtSubType)
388  nSelPos = i;
389  }
390  }
391 
392  bool bEnable = nSize != 0;
393 
394  if (nSize)
395  {
396  if (m_xSelectionLB->get_selected_index() == -1)
397  m_xSelectionLB->select(nSelPos == USHRT_MAX ? 0 : nSelPos);
398  bEnable = true;
399  }
400 
401  m_xSelection->set_sensitive(bEnable);
402 
403  return nSize;
404 }
405 
407 {
408  if (!m_xSelEntry)
409  return false;
410 
411  sal_uInt16 nSubType = m_xTypeTLB->get_id(*m_xSelEntry).toUInt32();
412  if (nSubType == USHRT_MAX)
413  return false;
414 
415  sal_uInt32 nFormat = 0;
416 
417  sal_Int32 nPos = m_xSelectionLB->get_selected_index();
418 
419  OUString aName;
420  if (DI_CUSTOM == nSubType)
421  aName = m_xTypeTLB->get_text(*m_xSelEntry);
422 
423  if (nPos != -1)
424  nSubType |= m_xSelectionLB->get_id(nPos).toUInt32();
425 
426  if (m_xFixedCB->get_active())
427  nSubType |= DI_SUB_FIXED;
428 
429  nPos = m_xFormatLB->get_selected_index();
430  if(nPos != -1)
431  nFormat = m_xFormatLB->GetFormat();
432 
433  if (!IsFieldEdit() || nOldSel != m_xSelectionLB->get_selected_index() ||
434  nOldFormat != nFormat || m_xFixedCB->get_state_changed_from_saved()
435  || (DI_CUSTOM == nSubType && aName != m_sOldCustomFieldName ))
436  {
437  InsertField(SwFieldTypesEnum::DocumentInfo, nSubType, aName, OUString(), nFormat,
438  ' ', m_xFormatLB->IsAutomaticLanguage());
439  }
440 
441  return false;
442 }
443 
444 std::unique_ptr<SfxTabPage> SwFieldDokInfPage::Create( weld::Container* pPage, weld::DialogController* pController,
445  const SfxItemSet *const pAttrSet)
446 {
447  return std::make_unique<SwFieldDokInfPage>(pPage, pController, pAttrSet);
448 }
449 
451 {
452  return GRP_REG;
453 }
454 
456 {
457  int nEntry = m_xTypeTLB->get_selected_index();
458  sal_uInt16 nTypeSel = nEntry != -1 ? m_xTypeTLB->get_id(nEntry).toUInt32() : USHRT_MAX;
459  SetUserData(USER_DATA_VERSION ";" + OUString::number( nTypeSel ));
460 }
461 
462 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const SwDocInfoSubType DI_SUB_TIME
Definition: docufld.hxx:84
SwFieldDokInfPage(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet *pSet)
Definition: flddinf.cxx:52
virtual bool FillItemSet(SfxItemSet *rSet) override
Definition: flddinf.cxx:406
#define USER_DATA_VERSION_1
Definition: flddinf.cxx:40
void SetUserData(const OUString &rString)
sal_uInt32 GetFormat() const
Query parameters for dialog and for BASIC.
Definition: fldbas.hxx:397
sal_uInt32 GetFormatIndex(NfIndexTableOffset, LanguageType eLnge=LANGUAGE_DONTKNOW)
virtual ~SwFieldDokInfPage() override
Definition: flddinf.cxx:82
Base class of all fields.
Definition: fldbas.hxx:289
virtual void Reset(const SfxItemSet *rSet) override
Definition: flddinf.cxx:86
virtual sal_uInt16 GetGroup() override
Definition: flddinf.cxx:450
std::unique_ptr< SwNumFormatTreeView > m_xFormatLB
Definition: flddinf.hxx:41
NF_TIME_HHMM
const SwDocInfoSubType DI_EDIT
Definition: docufld.hxx:79
sal_Int32 FillSelectionLB(sal_uInt16 nSubTypeId)
Definition: flddinf.cxx:354
Used by the UI to modify the document model.
Definition: wrtsh.hxx:93
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:165
SwFieldMgr & GetFieldMgr()
Definition: fldpage.hxx:81
void append_text(const OUString &rStr)
sal_Int32 nOldSel
Definition: flddinf.hxx:33
IMPL_LINK_NOARG(SwFieldDokInfPage, TypeHdl, weld::TreeView &, void)
Definition: flddinf.cxx:213
const SwDocInfoSubType DI_SUBJECT
Definition: docufld.hxx:72
const OUString & GetUserData() const
sal_uInt16 GetFormatCount(SwFieldTypesEnum nTypeId, bool bHtmlMode) const
Definition: fldmgr.cxx:674
std::unique_ptr< weld::CheckButton > m_xFixedCB
Definition: flddinf.hxx:42
bool IsFieldDlgHtmlMode() const
Definition: fldpage.hxx:49
const css::uno::Any & GetValue() const
css::uno::Reference< css::beans::XPropertySet > xCustomPropertySet
Definition: flddinf.hxx:31
const char * sName
#define SAL_N_ELEMENTS(arr)
const SwDocInfoSubType DI_CUSTOM
Definition: docufld.hxx:80
void FillFieldSelect(weld::TreeView &rListBox)
Definition: flddinf.cxx:46
const SwDocInfoSubType DI_PRINT
Definition: docufld.hxx:77
void EnableInsert(bool bEnable)
Definition: fldpage.cxx:316
int i
const SwDocInfoSubType DI_CREATE
Definition: docufld.hxx:75
SwFieldTypesEnum
List of FieldTypes at UI.
Definition: fldbas.hxx:93
void Init()
Definition: fldpage.cxx:63
std::unique_ptr< weld::Widget > m_xSelection
Definition: flddinf.hxx:38
std::unique_ptr< weld::TreeView > m_xSelectionLB
Definition: flddinf.hxx:39
SvNumFormatType
void InsertField(SwFieldTypesEnum nTypeId, sal_uInt16 nSubType, const OUString &rPar1, const OUString &rPar2, sal_uInt32 nFormatId, sal_Unicode cDelim= ' ', bool bIsAutomaticLanguage=true)
Definition: fldpage.cxx:115
const SwDocInfoSubType DI_SUB_DATE
Definition: docufld.hxx:85
SwField * GetCurField()
Definition: fldpage.hxx:51
bool IsAutomaticLanguage() const
Definition: fldbas.hxx:379
#define FIELD_COLUMN_WIDTH
Definition: fldpage.hxx:25
const SwDocInfoSubType DI_SUB_AUTHOR
Definition: docufld.hxx:83
SwWrtShell * GetWrtShell()
Definition: fldpage.hxx:52
const SwDocInfoSubType DI_SUBTYPE_BEGIN
NB: these must denote consecutive integers! NB2: these are extended by 4 DI_INFO values for backward ...
Definition: docufld.hxx:70
const SwDocInfoSubType DI_DOCNO
Definition: docufld.hxx:78
const SvNumberformat * GetEntry(sal_uInt32 nKey) const
static std::unique_ptr< SfxTabPage > Create(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet *rAttrSet)
Definition: flddinf.cxx:444
OUString aName
std::unique_ptr< weld::TreeIter > m_xSelEntry
Definition: flddinf.hxx:30
NF_DATE_SYSTEM_SHORT
std::unique_ptr< weld::TreeView > m_xTypeTLB
Definition: flddinf.hxx:37
virtual void FillUserData() override
Definition: flddinf.cxx:455
OUString m_sOldCustomFieldName
Definition: flddinf.hxx:35
bool IsFieldEdit() const
Definition: fldpage.hxx:62
const SwDocInfoSubType DI_SUB_FIXED
Definition: docufld.hxx:86
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
#define USER_DATA_VERSION
Definition: flddinf.cxx:41
SvNumberFormatter * GetNumberFormatter()
Query NumberFormatter from document.
Definition: editsh.cxx:745
sal_uLong nOldFormat
Definition: flddinf.hxx:34
LanguageType GetLanguage() const
sal_uInt16 nPos
void GetSubTypes(SwFieldTypesEnum nId, std::vector< OUString > &rToFill)
Definition: fldmgr.cxx:571
OUString sId