LibreOffice Module sw (master)  1
fldedt.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 <config_features.h>
21 #include <config_fuzzers.h>
22 
23 #include <sfx2/basedlgs.hxx>
24 #include <sfx2/viewfrm.hxx>
25 #include <svx/optgenrl.hxx>
26 #include <docufld.hxx>
27 #include <expfld.hxx>
28 #include <view.hxx>
29 #include <wrtsh.hxx>
30 #include "flddb.hxx"
31 #include "flddinf.hxx"
32 #include "fldvar.hxx"
33 #include "flddok.hxx"
34 #include "fldfunc.hxx"
35 #include "fldref.hxx"
36 #include <fldedt.hxx>
37 
38 #include <cmdid.h>
39 #include <swabstdlg.hxx>
40 
41 #include <com/sun/star/beans/XPropertySet.hpp>
42 #include <com/sun/star/document/XDocumentProperties.hpp>
43 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
44 #include <com/sun/star/frame/XModel.hpp>
45 #include <memory>
46 #include <swuiexp.hxx>
47 
49 {
51  {
52  // move cursor to start of Input Field
53  SwInputField* pInputField = dynamic_cast<SwInputField*>(pCurField);
54  if (pInputField && pInputField->GetFormatField())
55  {
56  pSh->GotoField( *(pInputField->GetFormatField()) );
57  }
58  else
59  {
60  SwSetExpField *const pSetField(dynamic_cast<SwSetExpField*>(pCurField));
61  if (pSetField)
62  {
63  assert(pSetField->GetFormatField());
64  pSh->GotoField( *(pSetField->GetFormatField()) );
65  }
66  else
67  {
68  assert(!"what input field is this");
69  }
70  }
71  }
72 
73  /* Only create selection if there is none already.
74  Normalize PaM instead of swapping. */
75  if (!pSh->HasSelection())
76  {
77  SwShellCursor* pCursor = pSh->getShellCursor(true);
78  SwPosition aOrigPos(*pCursor->GetPoint());
79 
80  //After this attempt it is possible that rMgr.GetCurField() != pCurField if
81  //the field was in e.g. a zero height portion and so invisible in which
82  //case it will be skipped over
83  pSh->Right(CRSR_SKIP_CHARS, true, 1, false );
84  //So (fdo#50640) if it didn't work then reposition back to the original
85  //location where the field was
86  SwField *pRealCurField = rMgr.GetCurField();
87  bool bSelectionFailed = pCurField != pRealCurField;
88  if (bSelectionFailed)
89  {
90  pCursor->DeleteMark();
91  *pCursor->GetPoint() = aOrigPos;
92  }
93  }
94 
95  pSh->NormalizePam();
96 
97  assert(pCurField == rMgr.GetCurField());
98 }
99 
101  : SfxSingleTabDialogController(rVw.GetViewFrame()->GetFrameWeld(), nullptr,
102  "modules/swriter/ui/editfielddialog.ui", "EditFieldDialog")
103  , pSh(rVw.GetWrtShellPtr())
104  , m_xPrevBT(m_xBuilder->weld_button("prev"))
105  , m_xNextBT(m_xBuilder->weld_button("next"))
106  , m_xAddressBT(m_xBuilder->weld_button("edit"))
107 {
108  SwFieldMgr aMgr(pSh);
109 
110  SwField *pCurField = aMgr.GetCurField();
111  if (!pCurField)
112  return;
113 
115 
116  EnsureSelection(pCurField, aMgr);
117 
118  sal_uInt16 nGroup = SwFieldMgr::GetGroup(pCurField->GetTypeId(), pCurField->GetSubType());
119 
120  CreatePage(nGroup);
121 
123 
124  m_xPrevBT->connect_clicked(LINK(this, SwFieldEditDlg, NextPrevHdl));
125  m_xNextBT->connect_clicked(LINK(this, SwFieldEditDlg, NextPrevHdl));
126 
127  m_xAddressBT->connect_clicked(LINK(this, SwFieldEditDlg, AddressHdl));
128 
129  Init();
130 }
131 
132 // initialise controls
134 {
135  SwFieldPage* pTabPage = static_cast<SwFieldPage*>(GetTabPage());
136  if (pTabPage)
137  {
138  SwFieldMgr& rMgr = pTabPage->GetFieldMgr();
139 
140  SwField *pCurField = rMgr.GetCurField();
141 
142  if(!pCurField)
143  return;
144 
145  // Traveling only when more than one field
146  pSh->StartAction();
147  pSh->ClearMark();
148  pSh->CreateCursor();
149 
150  bool bMove = rMgr.GoNext();
151  if( bMove )
152  rMgr.GoPrev();
153  m_xNextBT->set_sensitive(bMove);
154 
155  bMove = rMgr.GoPrev();
156  if( bMove )
157  rMgr.GoNext();
158  m_xPrevBT->set_sensitive( bMove );
159 
160  if (pCurField->GetTypeId() == SwFieldTypesEnum::ExtendedUser)
161  m_xAddressBT->set_sensitive(true);
162  else
163  m_xAddressBT->set_sensitive(false);
164 
165  pSh->DestroyCursor();
166  pSh->EndAction();
167  }
168 
170  !pSh->HasReadonlySel());
171 }
172 
174 {
175  // create TabPage
176  std::unique_ptr<SfxTabPage> xTabPage;
177 
178  switch (nGroup)
179  {
180  case GRP_DOC:
181  xTabPage = SwFieldDokPage::Create(get_content_area(), this, nullptr);
182  break;
183  case GRP_FKT:
184  xTabPage = SwFieldFuncPage::Create(get_content_area(), this, nullptr);
185  break;
186  case GRP_REF:
187  xTabPage = SwFieldRefPage::Create(get_content_area(), this, nullptr);
188  break;
189  case GRP_REG:
190  {
193  using namespace ::com::sun::star;
194  uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
195  pDocSh->GetModel(), uno::UNO_QUERY_THROW);
196  uno::Reference<document::XDocumentProperties> xDocProps
197  = xDPS->getDocumentProperties();
198  uno::Reference< beans::XPropertySet > xUDProps(
199  xDocProps->getUserDefinedProperties(),
200  uno::UNO_QUERY_THROW);
201  pSet->Put( SfxUnoAnyItem( FN_FIELD_DIALOG_DOC_PROPS, uno::Any(xUDProps) ) );
202  xTabPage = SwFieldDokInfPage::Create(get_content_area(), this, pSet);
203  break;
204  }
205 #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
206  case GRP_DB:
207  xTabPage = SwFieldDBPage::Create(get_content_area(), this, nullptr);
208  static_cast<SwFieldDBPage*>(xTabPage.get())->SetWrtShell(*pSh);
209  break;
210 #endif
211  case GRP_VAR:
212  xTabPage = SwFieldVarPage::Create(get_content_area(), this, nullptr);
213  break;
214 
215  }
216 
217  assert(xTabPage);
218 
219  static_cast<SwFieldPage*>(xTabPage.get())->SetWrtShell(pSh);
220  SetTabPage(std::move(xTabPage));
221 
222  return GetTabPage();
223 }
224 
226 {
228  pSh->EnterStdMode();
229 }
230 
232 {
233  if( bEnable && pSh->IsReadOnlyAvailable() && pSh->HasReadonlySel() )
234  bEnable = false;
235  GetOKButton().set_sensitive(bEnable);
236 }
237 
239 {
240  GetOKButton().clicked();
241 }
242 
243 // kick off changing of the field
245 {
246  if (GetOKButton().get_sensitive())
247  {
248  SfxTabPage* pTabPage = GetTabPage();
249  if (pTabPage)
250  pTabPage->FillItemSet(nullptr);
251  m_xDialog->response(RET_OK);
252  }
253 }
254 
256 {
257  // without TabPage no dialog
258  return GetTabPage() ? SfxSingleTabDialogController::run() : static_cast<short>(RET_CANCEL);
259 }
260 
261 // Traveling between fields of the same type
262 IMPL_LINK(SwFieldEditDlg, NextPrevHdl, weld::Button&, rButton, void)
263 {
264  bool bNext = &rButton == m_xNextBT.get();
265 
266  pSh->EnterStdMode();
267 
268  SwFieldType *pOldTyp = nullptr;
269  SwFieldPage* pTabPage = static_cast<SwFieldPage*>(GetTabPage());
270 
271  //#112462# FillItemSet may delete the current field
272  //that's why it has to be called before accessing the current field
273  if (GetOKButton().get_sensitive())
274  pTabPage->FillItemSet(nullptr);
275 
276  SwFieldMgr& rMgr = pTabPage->GetFieldMgr();
277  SwField *pCurField = rMgr.GetCurField();
278  if (pCurField->GetTypeId() == SwFieldTypesEnum::Database)
279  pOldTyp = pCurField->GetTyp();
280 
281  rMgr.GoNextPrev( bNext, pOldTyp );
282  pCurField = rMgr.GetCurField();
283 
284  sal_uInt16 nGroup = SwFieldMgr::GetGroup(pCurField->GetTypeId(), pCurField->GetSubType());
285 
286  if (nGroup != pTabPage->GetGroup())
287  pTabPage = static_cast<SwFieldPage*>(CreatePage(nGroup));
288 
289  pTabPage->EditNewField();
290 
291  Init();
292  EnsureSelection(pCurField, rMgr);
293 }
294 
296 {
297  SwFieldPage* pTabPage = static_cast<SwFieldPage*>(GetTabPage());
298  SwFieldMgr& rMgr = pTabPage->GetFieldMgr();
299  SwField *pCurField = rMgr.GetCurField();
300 
302 
303  EditPosition nEditPos = EditPosition::UNKNOWN;
304 
305  switch(pCurField->GetSubType())
306  {
307  case EU_FIRSTNAME: nEditPos = EditPosition::FIRSTNAME; break;
308  case EU_NAME: nEditPos = EditPosition::LASTNAME; break;
309  case EU_SHORTCUT: nEditPos = EditPosition::SHORTNAME; break;
310  case EU_COMPANY: nEditPos = EditPosition::COMPANY; break;
311  case EU_STREET: nEditPos = EditPosition::STREET; break;
312  case EU_TITLE: nEditPos = EditPosition::TITLE; break;
313  case EU_POSITION: nEditPos = EditPosition::POSITION; break;
314  case EU_PHONE_PRIVATE:nEditPos = EditPosition::TELPRIV; break;
315  case EU_PHONE_COMPANY:nEditPos = EditPosition::TELCOMPANY; break;
316  case EU_FAX: nEditPos = EditPosition::FAX; break;
317  case EU_EMAIL: nEditPos = EditPosition::EMAIL; break;
318  case EU_COUNTRY: nEditPos = EditPosition::COUNTRY; break;
319  case EU_ZIP: nEditPos = EditPosition::PLZ; break;
320  case EU_CITY: nEditPos = EditPosition::CITY; break;
321  case EU_STATE: nEditPos = EditPosition::STATE; break;
322 
323  default: nEditPos = EditPosition::UNKNOWN; break;
324 
325  }
326  aSet.Put(SfxUInt16Item(SID_FIELD_GRABFOCUS, static_cast<sal_uInt16>(nEditPos)));
328 
330  if (RET_OK == pDlg->Execute())
331  {
332  pSh->UpdateOneField(*pCurField);
333  }
334 }
335 
336 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:241
void DeleteMark()
Definition: pam.hxx:178
bool Right(sal_uInt16 nMode, bool bSelect, sal_uInt16 nCount, bool bBasicCall, bool bVisual=false)
Definition: move.cxx:127
Marks a position in the document model.
Definition: pam.hxx:36
void Init()
static std::unique_ptr< SfxTabPage > Create(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet *rAttrSet)
Definition: flddok.cxx:622
SwShellCursor * getShellCursor(bool bBlock)
Delivers the current shell cursor.
Definition: crsrsh.cxx:3048
Base class of all fields.
Definition: fldbas.hxx:291
css::uno::Reference< css::frame::XModel3 > GetModel() const
std::unique_ptr< IconChoicePage >(* CreatePage)(weld::Container *pParent, SvxHpLinkDlg *pDlg, const SfxItemSet *pAttrSet)
weld::Container * get_content_area()
bool GoPrev()
Definition: fldmgr.hxx:150
void EnterStdMode()
Definition: select.cxx:551
void DestroyCursor()
transform TableCursor to normal cursor, nullify Tablemode
Definition: crsrsh.cxx:152
static SfxObjectShell * Current()
virtual sal_uInt16 GetGroup()=0
void EnableInsert(bool bEnable)
Definition: fldedt.cxx:231
RET_CANCEL
virtual bool FillItemSet(SfxItemSet *)
SwFieldMgr & GetFieldMgr()
Definition: fldpage.hxx:81
static std::unique_ptr< SfxTabPage > Create(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet *rAttrSet)
Definition: fldvar.cxx:1227
void NormalizePam(bool bPointFirst=true)
Ensure point and mark of the current PaM are in a specific order.
Definition: crsrsh.cxx:970
IMPL_LINK(SwFieldEditDlg, NextPrevHdl, weld::Button &, rButton, void)
Definition: fldedt.cxx:262
void InsertHdl()
Definition: fldedt.cxx:238
SfxItemPool & GetPool() const
std::unique_ptr< weld::Button > m_xAddressBT
Definition: fldedt.hxx:35
weld::Window * GetFrameWeld(const SfxFrame *pFrame)
Definition: dialoghelp.cxx:19
void connect_clicked(const Link< Button &, void > &rLink)
bool HasSelection() const
Definition: wrtsh.hxx:147
SwPaM * CreateCursor()
delete the current cursor and make the following into the current
Definition: crsrsh.cxx:124
virtual ~SwFieldEditDlg() override
Definition: fldedt.cxx:225
const SwPosition * GetPoint() const
Definition: pam.hxx:208
SwAbstractDialogFactory & GetFactory()
Definition: swuiexp.cxx:26
IMPL_LINK_NOARG(SwFieldEditDlg, OKHdl, weld::Button &, void)
Definition: fldedt.cxx:244
std::unique_ptr< weld::Button > m_xNextBT
Definition: fldedt.hxx:34
static std::unique_ptr< SfxTabPage > Create(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet *rAttrSet)
Definition: fldfunc.cxx:580
virtual VclPtr< SfxAbstractDialog > CreateSwAddressAbstractDlg(weld::Window *pParent, const SfxItemSet &rSet)=0
SwField * GetCurField()
Definition: fldmgr.cxx:430
void Init()
Definition: fldedt.cxx:133
SwWrtShell * pSh
Definition: fldedt.hxx:32
void SetTabPage(std::unique_ptr< SfxTabPage > xTabPage)
static std::unique_ptr< SfxTabPage > Create(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet *rAttrSet)
Definition: flddb.cxx:262
SwFieldEditDlg(SwView const &rVw)
Definition: fldedt.cxx:100
bool HasReadonlySel() const
Definition: crsrsh.cxx:3355
bool GoNextPrev(bool bNext=true, SwFieldType *pTyp=nullptr)
Definition: fldmgr.cxx:855
virtual sal_uInt16 GetSubType() const
Definition: fldbas.cxx:342
SwFieldType * GetTyp() const
Definition: fldbas.hxx:398
void StartAction()
Definition: crsrsh.cxx:227
void EnsureSelection(SwField *pCurField, SwFieldMgr &rMgr)
Definition: fldedt.cxx:48
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
void EditNewField(bool bOnlyActivate=false)
Definition: fldpage.cxx:105
SwFieldTypesEnum GetTypeId() const
Definition: fldbas.cxx:257
SwFormatField * GetFormatField()
Definition: expfld.hxx:223
bool IsReadOnlyAvailable() const
Definition: crsrsh.hxx:479
bool GotoField(const SwFormatField &rField)
Definition: wrtsh3.cxx:71
SfxTabPage * CreatePage(sal_uInt16 nGroup)
Definition: fldedt.cxx:173
bool GoNext()
Definition: fldmgr.hxx:149
std::unique_ptr< weld::Button > m_xPrevBT
Definition: fldedt.hxx:33
static void SetCareDialog(const std::shared_ptr< weld::Window > &rNew)
Definition: viewsh.cxx:2667
static std::unique_ptr< SfxTabPage > Create(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet *rAttrSet)
Definition: flddinf.cxx:465
void clicked()
static sal_uInt16 GetGroup(SwFieldTypesEnum nTypeId, sal_uInt16 nSubType)
Definition: fldmgr.cxx:498
SwFormatField * GetFormatField()
Definition: expfld.hxx:315
RET_OK
Reference< XExecutableDialog > m_xDialog
virtual short run() override
Definition: fldedt.cxx:255
void ClearMark()
Definition: crsrsh.cxx:939
const sal_uInt16 CRSR_SKIP_CHARS
Definition: swcrsr.hxx:65
SfxTabPage * GetTabPage() const
static std::unique_ptr< SfxTabPage > Create(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet *rAttrSet)
Definition: fldref.cxx:1127
virtual weld::Button & GetOKButton() const override
Definition: view.hxx:144
virtual void set_sensitive(bool sensitive)=0
void EndAction(const bool bIdleEnd=false)
Definition: crsrsh.cxx:244
#define FN_FIELD_DIALOG_DOC_PROPS
Definition: cmdid.h:639
bool CursorInsideInputField() const
Definition: crstrvl.cxx:995