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