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