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 #include <config_fuzzers.h>
22 
23 #include <osl/diagnose.h>
24 #include <unotools/charclass.hxx>
25 #include <editsh.hxx>
26 #include <fldbas.hxx>
27 #include <doc.hxx>
29 #include <IDocumentState.hxx>
30 #include <docary.hxx>
31 #include <fmtfld.hxx>
32 #include <txtfld.hxx>
33 #include <pamtyp.hxx>
34 #include <expfld.hxx>
35 #include <swundo.hxx>
36 #include <dbmgr.hxx>
37 #include <hints.hxx>
38 #include <calbck.hxx>
39 #include <fieldhint.hxx>
42 
45 {
46  const SwFieldTypes* pFieldTypes = GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
47 
48  if(nResId == SwFieldIds::Unknown)
49  {
50  return o3tl::narrowing<sal_uInt16>(pFieldTypes->size());
51  }
52 
53  // all types with the same ResId
54  size_t nIdx = 0;
55  for(const auto & pFieldType : *pFieldTypes)
56  {
57  // same ResId -> increment index
58  if(pFieldType->Which() == nResId)
59  nIdx++;
60  }
61  return nIdx;
62 }
63 
65 SwFieldType* SwEditShell::GetFieldType(size_t nField, SwFieldIds nResId ) const
66 {
67  const SwFieldTypes* pFieldTypes = GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
68 
69  if(nResId == SwFieldIds::Unknown && nField < pFieldTypes->size())
70  {
71  return (*pFieldTypes)[nField].get();
72  }
73 
74  size_t nIdx = 0;
75  for(const auto & pFieldType : *pFieldTypes)
76  {
77  // same ResId -> increment index
78  if(pFieldType->Which() == nResId)
79  {
80  if(nIdx == nField)
81  return pFieldType.get();
82  nIdx++;
83  }
84  }
85  return nullptr;
86 }
87 
89 SwFieldType* SwEditShell::GetFieldType(SwFieldIds nResId, const OUString& rName) const
90 {
91  return GetDoc()->getIDocumentFieldsAccess().GetFieldType( nResId, rName, false );
92 }
93 
95 void SwEditShell::RemoveFieldType(size_t nField)
96 {
98 }
99 
101 void SwEditShell::RemoveFieldType(SwFieldIds nResId, const OUString& rStr)
102 {
103  const SwFieldTypes* pFieldTypes = GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
104  const SwFieldTypes::size_type nSize = pFieldTypes->size();
105  const CharClass& rCC = GetAppCharClass();
106 
107  OUString aTmp( rCC.lowercase( rStr ));
108 
109  for(SwFieldTypes::size_type i = 0; i < nSize; ++i)
110  {
111  // same ResId -> increment index
112  SwFieldType* pFieldType = (*pFieldTypes)[i].get();
113  if( pFieldType->Which() == nResId )
114  {
115  if( aTmp == rCC.lowercase( pFieldType->GetName() ) )
116  {
118  return;
119  }
120  }
121  }
122 }
123 
125 {
126  if( !pType->HasWriterListeners() )
127  return;
128 
129  CurrShell aCurr( this );
130  StartAllAction();
132  Push();
133  SwPaM* pPaM = GetCursor();
134  const SwFieldHint aHint(pPaM, GetLayout());
135  pType->CallSwClientNotify(aHint);
136 
138  EndAllAction();
140 }
141 
143 bool SwEditShell::InsertField(SwField const & rField, const bool bForceExpandHints)
144 {
145  CurrShell aCurr( this );
146  StartAllAction();
147  SwFormatField aField( rField );
148 
149  const SetAttrMode nInsertFlags = bForceExpandHints
152 
153  bool bSuccess(false);
154  for(const SwPaM& rPaM : GetCursor()->GetRingContainer()) // for each PaM
155  {
156  bSuccess |= GetDoc()->getIDocumentContentOperations().InsertPoolItem(rPaM, aField, nInsertFlags);
157  OSL_ENSURE( bSuccess, "Doc->Insert(Field) failed");
158  }
159 
160  EndAllAction();
161  return bSuccess;
162 }
163 
165 static SwTextField* lcl_FindInputField( SwDoc* pDoc, const SwField& rField )
166 {
167  // Search field via its address. For input fields this needs to be done in protected fields.
168  SwTextField* pTField = nullptr;
169  if (SwFieldIds::Input == rField.Which()
170  || (SwFieldIds::SetExp == rField.Which()
171  && static_cast<const SwSetExpField&>(rField).GetInputFlag()
172  && (static_cast<SwSetExpFieldType*>(rField.GetTyp())->GetType()
174  {
175  for (const SfxPoolItem* pItem : pDoc->GetAttrPool().GetItemSurrogates(RES_TXTATR_INPUTFIELD))
176  {
177  auto pFormatField = dynamic_cast<const SwFormatField*>(pItem);
178  if( pFormatField && pFormatField->GetField() == &rField )
179  {
180  pTField = const_cast<SwFormatField*>(pFormatField)->GetTextField();
181  break;
182  }
183  }
184  }
185  else if( SwFieldIds::SetExp == rField.Which()
186  && static_cast<const SwSetExpField&>(rField).GetInputFlag() )
187  {
188  for (const SfxPoolItem* pItem : pDoc->GetAttrPool().GetItemSurrogates(RES_TXTATR_FIELD))
189  {
190  auto pFormatField = dynamic_cast<const SwFormatField*>(pItem);
191  if( pFormatField && pFormatField->GetField() == &rField )
192  {
193  pTField = const_cast<SwFormatField*>(pFormatField)->GetTextField();
194  break;
195  }
196  }
197  }
198  return pTField;
199 }
200 
202 {
203  CurrShell aCurr( this );
204  StartAllAction();
205  {
206  // If there are no selections so take the value of the current cursor position.
207  SwMsgPoolItem* pMsgHint = nullptr;
208  SwRefMarkFieldUpdate aRefMkHt( GetOut() );
209  SwFieldIds nFieldWhich = rField.GetTyp()->Which();
210  if( SwFieldIds::GetRef == nFieldWhich )
211  pMsgHint = &aRefMkHt;
212 
213  SwPaM* pCursor = GetCursor();
214  SwTextField *pTextField;
215  SwFormatField *pFormatField;
216 
217  if ( !pCursor->IsMultiSelection() && !pCursor->HasMark())
218  {
219  pTextField = GetTextFieldAtPos( pCursor->Start(), true );
220 
221  if (!pTextField) // #i30221#
222  pTextField = lcl_FindInputField( GetDoc(), rField);
223 
224  if (pTextField != nullptr)
225  GetDoc()->getIDocumentFieldsAccess().UpdateField(pTextField, rField, pMsgHint, true);
226  }
227 
228  // bOkay (instead of return because of EndAllAction) becomes false,
229  // 1) if only one PaM has more than one field or
230  // 2) if there are mixed field types
231  bool bOkay = true;
232  bool bTableSelBreak = false;
233 
234  SwMsgPoolItem aFieldHint( RES_TXTATR_FIELD ); // Search-Hint
235  SwMsgPoolItem aAnnotationFieldHint( RES_TXTATR_ANNOTATION );
236  SwMsgPoolItem aInputFieldHint( RES_TXTATR_INPUTFIELD );
237  for(SwPaM& rPaM : GetCursor()->GetRingContainer()) // for each PaM
238  {
239  if( rPaM.HasMark() && bOkay ) // ... with selection
240  {
241  // copy of the PaM
242  SwPaM aCurPam( *rPaM.GetMark(), *rPaM.GetPoint() );
243  SwPaM aPam( *rPaM.GetPoint() );
244 
245  SwPosition *pCurStt = aCurPam.Start(), *pCurEnd =
246  aCurPam.End();
247  /*
248  * In case that there are two contiguous fields in a PaM, the aPam goes step by step
249  * to the end. aCurPam is reduced in each loop. If aCurPam was searched completely,
250  * the loop terminates because Start = End.
251  */
252 
253  // Search for SwTextField ...
254  while( bOkay
255  && pCurStt->nContent != pCurEnd->nContent
256  && (sw::FindAttrImpl(aPam, aFieldHint, fnMoveForward, aCurPam, true, GetLayout())
257  || sw::FindAttrImpl(aPam, aAnnotationFieldHint, fnMoveForward, aCurPam, false, GetLayout())
258  || sw::FindAttrImpl(aPam, aInputFieldHint, fnMoveForward, aCurPam, false, GetLayout())))
259  {
260  // if only one PaM has more than one field ...
261  if( aPam.Start()->nContent != pCurStt->nContent )
262  bOkay = false;
263 
264  pTextField = GetTextFieldAtPos( pCurStt, true );
265  if( nullptr != pTextField )
266  {
267  pFormatField = const_cast<SwFormatField*>(&pTextField->GetFormatField());
268  SwField *pCurField = pFormatField->GetField();
269 
270  // if there are mixed field types
271  if( pCurField->GetTyp()->Which() !=
272  rField.GetTyp()->Which() )
273  bOkay = false;
274 
275  bTableSelBreak = GetDoc()->getIDocumentFieldsAccess().UpdateField(pTextField, rField,
276  pMsgHint, false);
277  }
278  // The search area is reduced by the found area:
279  ++pCurStt->nContent;
280  }
281  }
282 
283  if( bTableSelBreak ) // If table section and table formula are updated -> finish
284  break;
285 
286  }
287  }
289  EndAllAction();
290 }
291 
293 {
294  return GetDoc()->GetDBData();
295 }
296 
297 void SwEditShell::ChgDBData(const SwDBData& rNewData)
298 {
299  GetDoc()->ChgDBData(rNewData);
300 }
301 
302 void SwEditShell::GetAllUsedDB( std::vector<OUString>& rDBNameList,
303  std::vector<OUString> const * pAllDBNames )
304 {
305  GetDoc()->GetAllUsedDB( rDBNameList, pAllDBNames );
306 }
307 
308 void SwEditShell::ChangeDBFields( const std::vector<OUString>& rOldNames,
309  const OUString& rNewName )
310 {
311  GetDoc()->ChangeDBFields( rOldNames, rNewName );
312 }
313 
315 void SwEditShell::UpdateExpFields(bool bCloseDB)
316 {
317  CurrShell aCurr( this );
318  StartAllAction();
319  GetDoc()->getIDocumentFieldsAccess().UpdateExpFields(nullptr, true);
320  if (bCloseDB)
321  {
322 #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
323  GetDoc()->GetDBManager()->CloseAll(); // close all database connections
324 #endif
325  }
326  EndAllAction();
327 }
328 
330 {
331 #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
332  return GetDoc()->GetDBManager();
333 #else
334  return NULL;
335 #endif
336 }
337 
340 {
341  return GetDoc()->getIDocumentFieldsAccess().InsertFieldType(rFieldType);
342 }
343 
345 {
347 }
348 
350 {
352 }
353 
355 {
357 }
358 
360 {
362 }
363 
365 {
367 }
368 
369 void SwEditShell::SetLabelDoc( bool bFlag )
370 {
372 }
373 
375 {
377 }
378 
380 {
381  GetDoc()->ChangeAuthorityData(pNewData);
382 }
383 
385 {
386  // Similar to: SwDoc::GetDBDesc
387  const SwFieldTypes * pFieldTypes = GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
388  for(const auto & pFieldType : *pFieldTypes)
389  {
390  if(IsUsed(*pFieldType))
391  {
392  switch(pFieldType->Which())
393  {
398  {
399  std::vector<SwFormatField*> vFields;
400  pFieldType->GatherFields(vFields);
401  return vFields.size();
402  }
403  break;
404  default: break;
405  }
406  }
407  }
408  return false;
409 }
410 
411 /* 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:65
SwRefMarkFieldUpdate is sent when the referencemarks should be updated.
Definition: hints.hxx:229
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:339
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:242
void ChgDBData(const SwDBData &SwDBData)
Definition: edfld.cxx:297
void ChgDBData(const SwDBData &rNewData)
Definition: doc.cxx:453
Marks a position in the document model.
Definition: pam.hxx:36
static SwTextField * lcl_FindInputField(SwDoc *pDoc, const SwField &rField)
Are the PaMs positioned on fields?
Definition: edfld.cxx:165
const SwField * GetField() const
Definition: fmtfld.hxx:116
bool IsMultiSelection() const
Definition: pam.hxx:273
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:292
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:2767
virtual bool InsertPoolItem(const SwPaM &rRg, const SfxPoolItem &, const SetAttrMode nFlags=SetAttrMode::DEFAULT, SwRootFrame const *pLayout=nullptr, SwTextAttr **ppNewTextAttr=nullptr)=0
Insert an attribute.
void SetLabelDoc(bool bFlag)
Labels: Synchronize ranges.
Definition: edfld.cxx:369
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:315
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:379
SwFieldUpdateFlags GetFieldUpdateFlags() const
Definition: edfld.cxx:364
virtual void LockExpFields()=0
virtual void UpdateExpFields(SwTextField *pField, bool bUpdateRefFields)=0
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:138
virtual bool IsExpFieldsLocked() const =0
SwDoc * GetDoc() const
Definition: viewsh.hxx:282
const SwFormatField & GetFormatField() const
Definition: txatbase.hxx:195
bool IsLabelDoc() const
Definition: edfld.cxx:374
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:329
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:137
constexpr TypedWhichId< SwFormatField > RES_TXTATR_FIELD(RES_TXTATR_NOEND_BEGIN)
void GetAllUsedDB(std::vector< OUString > &rDBNameList, std::vector< OUString > const *pAllDBNames)
Definition: edfld.cxx:302
SwDBData const & GetDBData()
Definition: docfld.cxx:371
int i
SwFieldType * InsertFieldType(const SwFieldType &)
insert field type
Definition: edfld.cxx:339
void Push()
store a copy of the current cursor on the cursor stack
Definition: crsrsh.cxx:2239
SetAttrMode
Definition: swtypes.hxx:133
void GetAllUsedDB(std::vector< OUString > &rDBNameList, const std::vector< OUString > *pAllDBNames=nullptr)
Definition: docfld.cxx:432
SwFieldIds
Definition: fldbas.hxx:46
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:206
size_t GetFieldTypeCount(SwFieldIds nResId=SwFieldIds::Unknown) const
count field types with a ResId, if SwFieldIds::Unknown count all
Definition: edfld.cxx:44
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:292
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:201
void UnlockExpFields()
Definition: edfld.cxx:349
const SwPosition * Start() const
Definition: pam.hxx:213
SwFieldType * GetTyp() const
Definition: fldbas.hxx:395
void FieldToText(SwFieldType const *pType)
Definition: edfld.cxx:124
void UpdateExpFields(bool bCloseDB=false)
only every expression fields update
Definition: edfld.cxx:315
bool IsAnyDatabaseFieldInDoc() const
Definition: edfld.cxx:384
SwCursor * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:194
SwFieldIds Which() const
ResId.
Definition: fldbas.cxx:250
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:593
void RemoveFieldType(size_t nField)
delete field type
Definition: edfld.cxx:95
Item2Range GetItemSurrogates(sal_uInt16 nWhich) const
::sw::DocumentSettingManager & GetDocumentSettingManager()
Definition: doc.cxx:186
bool InsertField(SwField const &, const bool bForceExpandHints)
add a field at the cursor position
Definition: edfld.cxx:143
void SetFieldUpdateFlags(SwFieldUpdateFlags eFlags)
Definition: edfld.cxx:359
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:204
bool Pop(PopMode)
delete cursor
Definition: crsrsh.cxx:2261
virtual void UnlockExpFields()=0
void ChangeDBFields(const std::vector< OUString > &rOldNames, const OUString &rNewName)
Definition: edfld.cxx:308
void ChangeAuthorityData(const SwAuthEntry *pNewData)
Definition: docfld.cxx:754
void StartAllAction()
For all views of this document.
Definition: edws.cxx:86
bool IsExpFieldsLocked() const
Definition: edfld.cxx:354
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2166
CharClass & GetAppCharClass()
Definition: init.cxx:703
SwFieldIds Which() const
Definition: fldbas.hxx:274
SwDBManager * GetDBManager() const
Definition: doc.hxx:670
void LockExpFields()
Definition: edfld.cxx:344
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:881