LibreOffice Module sw (master)  1
edfld.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 
22 #include <osl/diagnose.h>
23 #include <unotools/charclass.hxx>
24 #include <editsh.hxx>
25 #include <fldbas.hxx>
26 #include <doc.hxx>
28 #include <IDocumentState.hxx>
29 #include <docary.hxx>
30 #include <fmtfld.hxx>
31 #include <txtfld.hxx>
32 #include <pamtyp.hxx>
33 #include <expfld.hxx>
34 #include <swundo.hxx>
35 #include <dbmgr.hxx>
36 #include <hints.hxx>
37 #include <calbck.hxx>
38 #include <fieldhint.hxx>
41 
44 {
45  const SwFieldTypes* pFieldTypes = GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
46 
47  if(nResId == SwFieldIds::Unknown)
48  {
49  return o3tl::narrowing<sal_uInt16>(pFieldTypes->size());
50  }
51 
52  // all types with the same ResId
53  size_t nIdx = 0;
54  for(const auto & pFieldType : *pFieldTypes)
55  {
56  // same ResId -> increment index
57  if(pFieldType->Which() == nResId)
58  nIdx++;
59  }
60  return nIdx;
61 }
62 
64 SwFieldType* SwEditShell::GetFieldType(size_t nField, SwFieldIds nResId ) const
65 {
66  const SwFieldTypes* pFieldTypes = GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
67 
68  if(nResId == SwFieldIds::Unknown && nField < pFieldTypes->size())
69  {
70  return (*pFieldTypes)[nField].get();
71  }
72 
73  size_t nIdx = 0;
74  for(const auto & pFieldType : *pFieldTypes)
75  {
76  // same ResId -> increment index
77  if(pFieldType->Which() == nResId)
78  {
79  if(nIdx == nField)
80  return pFieldType.get();
81  nIdx++;
82  }
83  }
84  return nullptr;
85 }
86 
88 SwFieldType* SwEditShell::GetFieldType(SwFieldIds nResId, const OUString& rName) const
89 {
90  return GetDoc()->getIDocumentFieldsAccess().GetFieldType( nResId, rName, false );
91 }
92 
94 void SwEditShell::RemoveFieldType(size_t nField)
95 {
97 }
98 
100 void SwEditShell::RemoveFieldType(SwFieldIds nResId, const OUString& rStr)
101 {
102  const SwFieldTypes* pFieldTypes = GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
103  const SwFieldTypes::size_type nSize = pFieldTypes->size();
104  const CharClass& rCC = GetAppCharClass();
105 
106  OUString aTmp( rCC.lowercase( rStr ));
107 
108  for(SwFieldTypes::size_type i = 0; i < nSize; ++i)
109  {
110  // same ResId -> increment index
111  SwFieldType* pFieldType = (*pFieldTypes)[i].get();
112  if( pFieldType->Which() == nResId )
113  {
114  if( aTmp == rCC.lowercase( pFieldType->GetName() ) )
115  {
117  return;
118  }
119  }
120  }
121 }
122 
124 {
125  if( !pType->HasWriterListeners() )
126  return;
127 
128  CurrShell aCurr( this );
129  StartAllAction();
131  Push();
132  SwPaM* pPaM = GetCursor();
133  const SwFieldHint aHint(pPaM, GetLayout());
134  CallSwClientNotify(aHint);
135 
137  EndAllAction();
139 }
140 
142 void SwEditShell::Insert2(SwField const & rField, const bool bForceExpandHints)
143 {
144  CurrShell aCurr( this );
145  StartAllAction();
146  SwFormatField aField( rField );
147 
148  const SetAttrMode nInsertFlags = bForceExpandHints
151 
152  for(const SwPaM& rPaM : GetCursor()->GetRingContainer()) // for each PaM
153  {
154  const bool bSuccess(GetDoc()->getIDocumentContentOperations().InsertPoolItem(rPaM, aField, nInsertFlags));
155  OSL_ENSURE( bSuccess, "Doc->Insert(Field) failed");
156  }
157 
158  EndAllAction();
159 }
160 
162 static SwTextField* lcl_FindInputField( SwDoc* pDoc, SwField& rField )
163 {
164  // Search field via its address. For input fields this needs to be done in protected fields.
165  SwTextField* pTField = nullptr;
166  if (SwFieldIds::Input == rField.Which()
167  || (SwFieldIds::SetExp == rField.Which()
168  && static_cast<SwSetExpField&>(rField).GetInputFlag()
169  && (static_cast<SwSetExpFieldType*>(rField.GetTyp())->GetType()
171  {
172  for (const SfxPoolItem* pItem : pDoc->GetAttrPool().GetItemSurrogates(RES_TXTATR_INPUTFIELD))
173  {
174  auto pFormatField = dynamic_cast<const SwFormatField*>(pItem);
175  if( pFormatField && pFormatField->GetField() == &rField )
176  {
177  pTField = const_cast<SwFormatField*>(pFormatField)->GetTextField();
178  break;
179  }
180  }
181  }
182  else if( SwFieldIds::SetExp == rField.Which()
183  && static_cast<SwSetExpField&>(rField).GetInputFlag() )
184  {
185  for (const SfxPoolItem* pItem : pDoc->GetAttrPool().GetItemSurrogates(RES_TXTATR_FIELD))
186  {
187  auto pFormatField = dynamic_cast<const SwFormatField*>(pItem);
188  if( pFormatField && pFormatField->GetField() == &rField )
189  {
190  pTField = const_cast<SwFormatField*>(pFormatField)->GetTextField();
191  break;
192  }
193  }
194  }
195  return pTField;
196 }
197 
199 {
200  CurrShell aCurr( this );
201  StartAllAction();
202  {
203  // If there are no selections so take the value of the current cursor position.
204  SwMsgPoolItem* pMsgHint = nullptr;
205  SwRefMarkFieldUpdate aRefMkHt( GetOut() );
206  SwFieldIds nFieldWhich = rField.GetTyp()->Which();
207  if( SwFieldIds::GetRef == nFieldWhich )
208  pMsgHint = &aRefMkHt;
209 
210  SwPaM* pCursor = GetCursor();
211  SwTextField *pTextField;
212  SwFormatField *pFormatField;
213 
214  if ( !pCursor->IsMultiSelection() && !pCursor->HasMark())
215  {
216  pTextField = GetTextFieldAtPos( pCursor->Start(), true );
217 
218  if (!pTextField) // #i30221#
219  pTextField = lcl_FindInputField( GetDoc(), rField);
220 
221  if (pTextField != nullptr)
222  GetDoc()->getIDocumentFieldsAccess().UpdateField(pTextField, rField, pMsgHint, true);
223  }
224 
225  // bOkay (instead of return because of EndAllAction) becomes false,
226  // 1) if only one PaM has more than one field or
227  // 2) if there are mixed field types
228  bool bOkay = true;
229  bool bTableSelBreak = false;
230 
231  SwMsgPoolItem aFieldHint( RES_TXTATR_FIELD ); // Search-Hint
232  SwMsgPoolItem aAnnotationFieldHint( RES_TXTATR_ANNOTATION );
233  SwMsgPoolItem aInputFieldHint( RES_TXTATR_INPUTFIELD );
234  for(SwPaM& rPaM : GetCursor()->GetRingContainer()) // for each PaM
235  {
236  if( rPaM.HasMark() && bOkay ) // ... with selection
237  {
238  // copy of the PaM
239  SwPaM aCurPam( *rPaM.GetMark(), *rPaM.GetPoint() );
240  SwPaM aPam( *rPaM.GetPoint() );
241 
242  SwPosition *pCurStt = aCurPam.Start(), *pCurEnd =
243  aCurPam.End();
244  /*
245  * In case that there are two contiguous fields in a PaM, the aPam goes step by step
246  * to the end. aCurPam is reduced in each loop. If aCurPam was searched completely,
247  * the loop terminates because Start = End.
248  */
249 
250  // Search for SwTextField ...
251  while( bOkay
252  && pCurStt->nContent != pCurEnd->nContent
253  && (sw::FindAttrImpl(aPam, aFieldHint, fnMoveForward, aCurPam, true, GetLayout())
254  || sw::FindAttrImpl(aPam, aAnnotationFieldHint, fnMoveForward, aCurPam, false, GetLayout())
255  || sw::FindAttrImpl(aPam, aInputFieldHint, fnMoveForward, aCurPam, false, GetLayout())))
256  {
257  // if only one PaM has more than one field ...
258  if( aPam.Start()->nContent != pCurStt->nContent )
259  bOkay = false;
260 
261  pTextField = GetTextFieldAtPos( pCurStt, true );
262  if( nullptr != pTextField )
263  {
264  pFormatField = const_cast<SwFormatField*>(&pTextField->GetFormatField());
265  SwField *pCurField = pFormatField->GetField();
266 
267  // if there are mixed field types
268  if( pCurField->GetTyp()->Which() !=
269  rField.GetTyp()->Which() )
270  bOkay = false;
271 
272  bTableSelBreak = GetDoc()->getIDocumentFieldsAccess().UpdateField(pTextField, rField,
273  pMsgHint, false);
274  }
275  // The search area is reduced by the found area:
276  ++pCurStt->nContent;
277  }
278  }
279 
280  if( bTableSelBreak ) // If table section and table formula are updated -> finish
281  break;
282 
283  }
284  }
286  EndAllAction();
287 }
288 
290 {
291  return GetDoc()->GetDBData();
292 }
293 
294 void SwEditShell::ChgDBData(const SwDBData& rNewData)
295 {
296  GetDoc()->ChgDBData(rNewData);
297 }
298 
299 void SwEditShell::GetAllUsedDB( std::vector<OUString>& rDBNameList,
300  std::vector<OUString> const * pAllDBNames )
301 {
302  GetDoc()->GetAllUsedDB( rDBNameList, pAllDBNames );
303 }
304 
305 void SwEditShell::ChangeDBFields( const std::vector<OUString>& rOldNames,
306  const OUString& rNewName )
307 {
308  GetDoc()->ChangeDBFields( rOldNames, rNewName );
309 }
310 
312 void SwEditShell::UpdateExpFields(bool bCloseDB)
313 {
314  CurrShell aCurr( this );
315  StartAllAction();
316  GetDoc()->getIDocumentFieldsAccess().UpdateExpFields(nullptr, true);
317  if (bCloseDB)
318  {
319 #if HAVE_FEATURE_DBCONNECTIVITY
320  GetDoc()->GetDBManager()->CloseAll(); // close all database connections
321 #endif
322  }
323  EndAllAction();
324 }
325 
327 {
328 #if HAVE_FEATURE_DBCONNECTIVITY
329  return GetDoc()->GetDBManager();
330 #else
331  return NULL;
332 #endif
333 }
334 
337 {
338  return GetDoc()->getIDocumentFieldsAccess().InsertFieldType(rFieldType);
339 }
340 
342 {
344 }
345 
347 {
349 }
350 
352 {
354 }
355 
357 {
359 }
360 
362 {
364 }
365 
366 void SwEditShell::SetLabelDoc( bool bFlag )
367 {
369 }
370 
372 {
374 }
375 
377 {
378  GetDoc()->ChangeAuthorityData(pNewData);
379 }
380 
382 {
383  // Similar to: SwDoc::GetDBDesc
384  const SwFieldTypes * pFieldTypes = GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
385  for(const auto & pFieldType : *pFieldTypes)
386  {
387  if(IsUsed(*pFieldType))
388  {
389  switch(pFieldType->Which())
390  {
395  {
396  std::vector<SwFormatField*> vFields;
397  pFieldType->GatherFields(vFields);
398  return vFields.size();
399  }
400  break;
401  default: break;
402  }
403  }
404  }
405  return false;
406 }
407 
408 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SwFieldType * GetFieldType(size_t nField, SwFieldIds nResId=SwFieldIds::Unknown) const
get field types with a ResId, if 0 get all
Definition: edfld.cxx:64
SwRefMarkFieldUpdate is sent when the referencemarks should be updated.
Definition: hints.hxx:229
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:338
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:240
void ChgDBData(const SwDBData &SwDBData)
Definition: edfld.cxx:294
void ChgDBData(const SwDBData &rNewData)
Definition: doc.cxx:453
Marks a position in the document model.
Definition: pam.hxx:35
const SwField * GetField() const
Definition: fmtfld.hxx:110
bool IsMultiSelection() const
Definition: pam.hxx:272
SwPaM * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:195
SwFieldUpdateFlags
Definition: fldupde.hxx:22
virtual SwFieldType * GetFieldType(SwFieldIds nResId, const OUString &rName, bool bDbFieldMatching) const =0
virtual void SetModified()=0
Must be called manually at changes of format.
Base class of all fields.
Definition: fldbas.hxx:289
Definition: doc.hxx:188
virtual void set(DocumentSettingId id, bool value) override
Set the specified document setting.
virtual void setFieldUpdateFlags(SwFieldUpdateFlags nMode)=0
Set the current field update mode.
SwUndoId EndUndo(SwUndoId eUndoId=SwUndoId::EMPTY, const SwRewriter *pRewriter=nullptr)
Closes parenthesis of nUndoId, not used by UI.
Definition: edws.cxx:234
const IDocumentSettingAccess & getIDocumentSettingAccess() const
Provides access to the document setting interface.
Definition: viewsh.cxx:2668
static SwTextField * lcl_FindInputField(SwDoc *pDoc, SwField &rField)
Are the PaMs positioned on fields?
Definition: edfld.cxx:162
void SetLabelDoc(bool bFlag)
Labels: Synchronize ranges.
Definition: edfld.cxx:366
bool HasWriterListeners() const
Definition: calbck.hxx:203
constexpr TypedWhichId< SwFormatField > RES_TXTATR_ANNOTATION(59)
void EndAllAction()
Definition: edws.cxx:97
For old documents the Field-Which IDs must be preserved !!!
virtual bool UpdateField(SwTextField *rDstFormatField, SwField &rSrcField, SwMsgPoolItem *pMsgHint, bool bUpdateTableFields)=0
Updates a field.
void ChangeAuthorityData(const SwAuthEntry *pNewData)
Definition: edfld.cxx:376
SwFieldUpdateFlags GetFieldUpdateFlags() const
Definition: edfld.cxx:361
virtual void LockExpFields()=0
virtual void UpdateExpFields(SwTextField *pField, bool bUpdateRefFields)=0
IDocumentContentOperations & getIDocumentContentOperations()
Provides access to the content operations interface.
Definition: viewsh.cxx:2680
IDocumentFieldsAccess const & getIDocumentFieldsAccess() const
Definition: doc.cxx:357
return NULL
bool IsUsed(const sw::BroadcastingModify &) const
Query if the paragraph-/character-/frame-/page-style is used.
Definition: edfmt.cxx:139
virtual bool IsExpFieldsLocked() const =0
SwDoc * GetDoc() const
Definition: viewsh.hxx:281
const SwFormatField & GetFormatField() const
Definition: txatbase.hxx:195
bool IsLabelDoc() const
Definition: edfld.cxx:371
virtual SwFieldUpdateFlags getFieldUpdateFlags(bool bGlobalSettings) const =0
Get the current field update mode.
bool FindAttrImpl(SwPaM &rSearchPam, const SfxPoolItem &rAttr, SwMoveFnCollection const &fnMove, const SwPaM &rRegion, bool bInReadOnly, SwRootFrame const *const pLayout)
Definition: findattr.cxx:911
SwDBManager * GetDBManager() const
For evaluation of DB fields (new DB-manager).
Definition: edfld.cxx:326
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
constexpr TypedWhichId< SwFormatField > RES_TXTATR_FIELD(RES_TXTATR_NOEND_BEGIN)
void GetAllUsedDB(std::vector< OUString > &rDBNameList, std::vector< OUString > const *pAllDBNames)
Definition: edfld.cxx:299
SwDBData const & GetDBData()
Definition: docfld.cxx:370
int i
void Insert2(const OUString &, const bool bForceExpandHints=false)
Definition: editsh.cxx:80
SwFieldType * InsertFieldType(const SwFieldType &)
insert field type
Definition: edfld.cxx:336
void Push()
store a copy of the current cursor on the cursor stack
Definition: crsrsh.cxx:2240
SetAttrMode
Definition: swtypes.hxx:133
void GetAllUsedDB(std::vector< OUString > &rDBNameList, const std::vector< OUString > *pAllDBNames=nullptr)
Definition: docfld.cxx:431
SwFieldIds
Definition: fldbas.hxx:44
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:205
size_t GetFieldTypeCount(SwFieldIds nResId=SwFieldIds::Unknown) const
count field types with a ResId, if SwFieldIds::Unknown count all
Definition: edfld.cxx:43
SwUndoId StartUndo(SwUndoId eUndoId=SwUndoId::EMPTY, const SwRewriter *pRewriter=nullptr)
Undo: set up Undo parenthesis, return nUndoId of this parenthesis.
Definition: edws.cxx:223
Force hint expand (only matters for hints with CH_TXTATR).
void CloseAll(bool bIncludingMerge=true)
close all data sources - after fields were updated
Definition: dbmgr.cxx:2398
SwDBData const & GetDBData() const
Database information.
Definition: edfld.cxx:289
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:394
size
virtual const SwFieldTypes * GetFieldTypes() const =0
ring_container GetRingContainer()
OUString lowercase(const OUString &rStr, sal_Int32 nPos, sal_Int32 nCount) const
void UpdateOneField(SwField &)
One single field.
Definition: edfld.cxx:198
void UnlockExpFields()
Definition: edfld.cxx:346
const SwPosition * Start() const
Definition: pam.hxx:212
SwFieldType * GetTyp() const
Definition: fldbas.hxx:392
void FieldToText(SwFieldType const *pType)
Definition: edfld.cxx:123
void UpdateExpFields(bool bCloseDB=false)
only every expression fields update
Definition: edfld.cxx:312
bool IsAnyDatabaseFieldInDoc() const
Definition: edfld.cxx:381
SwFieldIds Which() const
ResId.
Definition: fldbas.cxx:245
virtual OUString GetName() const
Only in derived classes.
Definition: fldbas.cxx:137
virtual SwFieldType * InsertFieldType(const SwFieldType &)=0
SwMoveFnCollection const & fnMoveForward
SwPam::Move()/Find() default argument.
Definition: paminit.cxx:59
void ChangeDBFields(const std::vector< OUString > &rOldNames, const OUString &rNewName)
Definition: docfld.cxx:592
void RemoveFieldType(size_t nField)
delete field type
Definition: edfld.cxx:94
Item2Range GetItemSurrogates(sal_uInt16 nWhich) const
::sw::DocumentSettingManager & GetDocumentSettingManager()
Definition: doc.cxx:186
void SetFieldUpdateFlags(SwFieldUpdateFlags eFlags)
Definition: edfld.cxx:356
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
constexpr TypedWhichId< SwFormatField > RES_TXTATR_INPUTFIELD(55)
virtual void CallSwClientNotify(const SfxHint &rHint) const override
Definition: calbck.cxx:326
const SwGetSetExpType GSE_STRING
String.
Definition: fldbas.hxx:202
bool Pop(PopMode)
delete cursor
Definition: crsrsh.cxx:2262
virtual void UnlockExpFields()=0
void ChangeDBFields(const std::vector< OUString > &rOldNames, const OUString &rNewName)
Definition: edfld.cxx:305
void ChangeAuthorityData(const SwAuthEntry *pNewData)
Definition: docfld.cxx:753
void StartAllAction()
For all views of this document.
Definition: edws.cxx:86
bool IsExpFieldsLocked() const
Definition: edfld.cxx:351
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2074
CharClass & GetAppCharClass()
Definition: init.cxx:703
SwFieldIds Which() const
Definition: fldbas.hxx:272
SwDBManager * GetDBManager() const
Definition: doc.hxx:670
void LockExpFields()
Definition: edfld.cxx:341
virtual void RemoveFieldType(size_t nField)=0
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1319
static SwTextField * GetTextFieldAtPos(const SwPosition *pPos, const bool bIncludeInputFieldAtStart)
Definition: crstrvl.cxx:860