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 <edimp.hxx>
34 #include <dbfld.hxx>
35 #include <expfld.hxx>
36 #include <flddat.hxx>
37 #include <swundo.hxx>
38 #include <dbmgr.hxx>
39 #include <swddetbl.hxx>
40 #include <hints.hxx>
41 #include <calbck.hxx>
42 #include <fieldhint.hxx>
45 
48 {
49  const SwFieldTypes* pFieldTypes = GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
50 
51  if(nResId == SwFieldIds::Unknown)
52  {
53  return static_cast<sal_uInt16>(pFieldTypes->size());
54  }
55 
56  // all types with the same ResId
57  size_t nIdx = 0;
58  for(const auto & pFieldType : *pFieldTypes)
59  {
60  // same ResId -> increment index
61  if(pFieldType->Which() == nResId)
62  nIdx++;
63  }
64  return nIdx;
65 }
66 
68 SwFieldType* SwEditShell::GetFieldType(size_t nField, SwFieldIds nResId ) const
69 {
70  const SwFieldTypes* pFieldTypes = GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
71 
72  if(nResId == SwFieldIds::Unknown && nField < pFieldTypes->size())
73  {
74  return (*pFieldTypes)[nField].get();
75  }
76 
77  size_t nIdx = 0;
78  for(const auto & pFieldType : *pFieldTypes)
79  {
80  // same ResId -> increment index
81  if(pFieldType->Which() == nResId)
82  {
83  if(nIdx == nField)
84  return pFieldType.get();
85  nIdx++;
86  }
87  }
88  return nullptr;
89 }
90 
92 SwFieldType* SwEditShell::GetFieldType(SwFieldIds nResId, const OUString& rName) const
93 {
94  return GetDoc()->getIDocumentFieldsAccess().GetFieldType( nResId, rName, false );
95 }
96 
98 void SwEditShell::RemoveFieldType(size_t nField)
99 {
101 }
102 
104 void SwEditShell::RemoveFieldType(SwFieldIds nResId, const OUString& rStr)
105 {
106  const SwFieldTypes* pFieldTypes = GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
107  const SwFieldTypes::size_type nSize = pFieldTypes->size();
108  const CharClass& rCC = GetAppCharClass();
109 
110  OUString aTmp( rCC.lowercase( rStr ));
111 
112  for(SwFieldTypes::size_type i = 0; i < nSize; ++i)
113  {
114  // same ResId -> increment index
115  SwFieldType* pFieldType = (*pFieldTypes)[i].get();
116  if( pFieldType->Which() == nResId )
117  {
118  if( aTmp == rCC.lowercase( pFieldType->GetName() ) )
119  {
121  return;
122  }
123  }
124  }
125 }
126 
128 {
129  if( !pType->HasWriterListeners() )
130  return;
131 
132  SET_CURR_SHELL( this );
133  StartAllAction();
135  Push();
136  SwPaM* pPaM = GetCursor();
137  // TODO: this is really hackish
138  SwFieldHint aHint(pPaM, GetLayout());
139  SwIterator<SwClient,SwFieldType> aIter(*pType);
140  for( SwClient* pClient = aIter.First(); pClient; pClient = aIter.Next() )
141  {
142  pPaM->DeleteMark();
143  pClient->SwClientNotifyCall( *pType, aHint );
144  }
145 
147  EndAllAction();
149 }
150 
152 void SwEditShell::Insert2(SwField const & rField, const bool bForceExpandHints)
153 {
154  SET_CURR_SHELL( this );
155  StartAllAction();
156  SwFormatField aField( rField );
157 
158  const SetAttrMode nInsertFlags = bForceExpandHints
161 
162  for(const SwPaM& rPaM : GetCursor()->GetRingContainer()) // for each PaM
163  {
164  const bool bSuccess(GetDoc()->getIDocumentContentOperations().InsertPoolItem(rPaM, aField, nInsertFlags));
165  OSL_ENSURE( bSuccess, "Doc->Insert(Field) failed");
166  }
167 
168  EndAllAction();
169 }
170 
172 static SwTextField* lcl_FindInputField( SwDoc* pDoc, SwField& rField )
173 {
174  // Search field via its address. For input fields this needs to be done in protected fields.
175  SwTextField* pTField = nullptr;
176  if (SwFieldIds::Input == rField.Which()
177  || (SwFieldIds::SetExp == rField.Which()
178  && static_cast<SwSetExpField&>(rField).GetInputFlag()
179  && (static_cast<SwSetExpFieldType*>(rField.GetTyp())->GetType()
181  {
182  for (const SfxPoolItem* pItem : pDoc->GetAttrPool().GetItemSurrogates(RES_TXTATR_INPUTFIELD))
183  {
184  auto pFormatField = dynamic_cast<const SwFormatField*>(pItem);
185  if( pFormatField && pFormatField->GetField() == &rField )
186  {
187  pTField = const_cast<SwFormatField*>(pFormatField)->GetTextField();
188  break;
189  }
190  }
191  }
192  else if( SwFieldIds::SetExp == rField.Which()
193  && static_cast<SwSetExpField&>(rField).GetInputFlag() )
194  {
195  for (const SfxPoolItem* pItem : pDoc->GetAttrPool().GetItemSurrogates(RES_TXTATR_FIELD))
196  {
197  auto pFormatField = dynamic_cast<const SwFormatField*>(pItem);
198  if( pFormatField && pFormatField->GetField() == &rField )
199  {
200  pTField = const_cast<SwFormatField*>(pFormatField)->GetTextField();
201  break;
202  }
203  }
204  }
205  return pTField;
206 }
207 
209 {
210  SET_CURR_SHELL( this );
211  StartAllAction();
212  {
213  // If there are no selections so take the value of the current cursor position.
214  SwMsgPoolItem* pMsgHint = nullptr;
215  SwRefMarkFieldUpdate aRefMkHt( GetOut() );
216  SwFieldIds nFieldWhich = rField.GetTyp()->Which();
217  if( SwFieldIds::GetRef == nFieldWhich )
218  pMsgHint = &aRefMkHt;
219 
220  SwPaM* pCursor = GetCursor();
221  SwTextField *pTextField;
222  SwFormatField *pFormatField;
223 
224  if ( !pCursor->IsMultiSelection() && !pCursor->HasMark())
225  {
226  pTextField = GetTextFieldAtPos( pCursor->Start(), true );
227 
228  if (!pTextField) // #i30221#
229  pTextField = lcl_FindInputField( GetDoc(), rField);
230 
231  if (pTextField != nullptr)
232  GetDoc()->getIDocumentFieldsAccess().UpdateField(pTextField, rField, pMsgHint, true);
233  }
234 
235  // bOkay (instead of return because of EndAllAction) becomes false,
236  // 1) if only one PaM has more than one field or
237  // 2) if there are mixed field types
238  bool bOkay = true;
239  bool bTableSelBreak = false;
240 
241  SwMsgPoolItem aFieldHint( RES_TXTATR_FIELD ); // Search-Hint
242  SwMsgPoolItem aAnnotationFieldHint( RES_TXTATR_ANNOTATION );
243  SwMsgPoolItem aInputFieldHint( RES_TXTATR_INPUTFIELD );
244  for(SwPaM& rPaM : GetCursor()->GetRingContainer()) // for each PaM
245  {
246  if( rPaM.HasMark() && bOkay ) // ... with selection
247  {
248  // copy of the PaM
249  SwPaM aCurPam( *rPaM.GetMark(), *rPaM.GetPoint() );
250  SwPaM aPam( *rPaM.GetPoint() );
251 
252  SwPosition *pCurStt = aCurPam.Start(), *pCurEnd =
253  aCurPam.End();
254  /*
255  * In case that there are two contiguous fields in a PaM, the aPam goes step by step
256  * to the end. aCurPam is reduced in each loop. If aCurPam was searched completely,
257  * the loop terminates because Start = End.
258  */
259 
260  // Search for SwTextField ...
261  while( bOkay
262  && pCurStt->nContent != pCurEnd->nContent
263  && (sw::FindAttrImpl(aPam, aFieldHint, fnMoveForward, aCurPam, true, GetLayout())
264  || sw::FindAttrImpl(aPam, aAnnotationFieldHint, fnMoveForward, aCurPam, false, GetLayout())
265  || sw::FindAttrImpl(aPam, aInputFieldHint, fnMoveForward, aCurPam, false, GetLayout())))
266  {
267  // if only one PaM has more than one field ...
268  if( aPam.Start()->nContent != pCurStt->nContent )
269  bOkay = false;
270 
271  if( nullptr != (pTextField = GetTextFieldAtPos( pCurStt, true )) )
272  {
273  pFormatField = const_cast<SwFormatField*>(&pTextField->GetFormatField());
274  SwField *pCurField = pFormatField->GetField();
275 
276  // if there are mixed field types
277  if( pCurField->GetTyp()->Which() !=
278  rField.GetTyp()->Which() )
279  bOkay = false;
280 
281  bTableSelBreak = GetDoc()->getIDocumentFieldsAccess().UpdateField(pTextField, rField,
282  pMsgHint, false);
283  }
284  // The search area is reduced by the found area:
285  ++pCurStt->nContent;
286  }
287  }
288 
289  if( bTableSelBreak ) // If table section and table formula are updated -> finish
290  break;
291 
292  }
293  }
295  EndAllAction();
296 }
297 
299 {
300  return GetDoc()->GetDBData();
301 }
302 
304 {
305  return GetDoc()->GetDBDesc();
306 }
307 
308 void SwEditShell::ChgDBData(const SwDBData& rNewData)
309 {
310  GetDoc()->ChgDBData(rNewData);
311 }
312 
313 void SwEditShell::GetAllUsedDB( std::vector<OUString>& rDBNameList,
314  std::vector<OUString> const * pAllDBNames )
315 {
316  GetDoc()->GetAllUsedDB( rDBNameList, pAllDBNames );
317 }
318 
319 void SwEditShell::ChangeDBFields( const std::vector<OUString>& rOldNames,
320  const OUString& rNewName )
321 {
322  GetDoc()->ChangeDBFields( rOldNames, rNewName );
323 }
324 
326 void SwEditShell::UpdateExpFields(bool bCloseDB)
327 {
328  SET_CURR_SHELL( this );
329  StartAllAction();
330  GetDoc()->getIDocumentFieldsAccess().UpdateExpFields(nullptr, true);
331  if (bCloseDB)
332  {
333 #if HAVE_FEATURE_DBCONNECTIVITY
334  GetDoc()->GetDBManager()->CloseAll(); // close all database connections
335 #endif
336  }
337  EndAllAction();
338 }
339 
341 {
342 #if HAVE_FEATURE_DBCONNECTIVITY
343  return GetDoc()->GetDBManager();
344 #else
345  return NULL;
346 #endif
347 }
348 
351 {
352  return GetDoc()->getIDocumentFieldsAccess().InsertFieldType(rFieldType);
353 }
354 
356 {
358 }
359 
361 {
363 }
364 
366 {
368 }
369 
371 {
373 }
374 
376 {
378 }
379 
380 void SwEditShell::SetLabelDoc( bool bFlag )
381 {
383 }
384 
386 {
388 }
389 
391 {
392  GetDoc()->ChangeAuthorityData(pNewData);
393 }
394 
396 {
397  const SwFieldTypes * pFieldTypes = GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
398  for(const auto & pFieldType : *pFieldTypes)
399  {
400  if(IsUsed(*pFieldType))
401  {
402  switch(pFieldType->Which())
403  {
408  {
409  SwIterator<SwFormatField,SwFieldType> aIter( *pFieldType );
410  SwFormatField* pField = aIter.First();
411  while(pField)
412  {
413  if(pField->IsFieldInDoc())
414  return true;
415  pField = aIter.Next();
416  }
417  }
418  break;
419  default: break;
420  }
421  }
422  }
423  return false;
424 }
425 
426 /* 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:68
SwRefMarkFieldUpdate is sent when the referencemarks should be updated.
Definition: hints.hxx:169
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:341
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:233
void DeleteMark()
Definition: pam.hxx:177
void ChgDBData(const SwDBData &SwDBData)
Definition: edfld.cxx:308
void ChgDBData(const SwDBData &rNewData)
Definition: doc.cxx:485
Marks a position in the document model.
Definition: pam.hxx:35
const SwField * GetField() const
Definition: fmtfld.hxx:71
bool IsMultiSelection() const
Definition: pam.hxx:272
SwPaM * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:184
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:279
Definition: doc.hxx:185
TElementType * Next()
Definition: calbck.hxx:376
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:233
const IDocumentSettingAccess & getIDocumentSettingAccess() const
Provides access to the document setting interface.
Definition: viewsh.cxx:2587
static SwTextField * lcl_FindInputField(SwDoc *pDoc, SwField &rField)
Are the PaMs positioned on fields?
Definition: edfld.cxx:172
void SetLabelDoc(bool bFlag)
Labels: Synchronize ranges.
Definition: edfld.cxx:380
bool HasWriterListeners() const
Definition: calbck.hxx:211
void EndAllAction()
Definition: edws.cxx:96
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:390
SwFieldUpdateFlags GetFieldUpdateFlags() const
Definition: edfld.cxx:375
virtual void LockExpFields()=0
virtual void UpdateExpFields(SwTextField *pField, bool bUpdateRefFields)=0
IDocumentContentOperations & getIDocumentContentOperations()
Provides access to the content operations interface.
Definition: viewsh.cxx:2599
IDocumentFieldsAccess const & getIDocumentFieldsAccess() const
Definition: doc.cxx:389
return NULL
virtual bool IsExpFieldsLocked() const =0
SwDoc * GetDoc() const
Definition: viewsh.hxx:284
const SwFormatField & GetFormatField() const
Definition: txatbase.hxx:191
bool IsLabelDoc() const
Definition: edfld.cxx:385
virtual SwFieldUpdateFlags getFieldUpdateFlags(bool bGlobalSettings) const =0
Get the current field update mode.
const SwDBData & GetDBDesc()
Definition: docfld.cxx:359
bool FindAttrImpl(SwPaM &rSearchPam, const SfxPoolItem &rAttr, SwMoveFnCollection const &fnMove, const SwPaM &rRegion, bool bInReadOnly, SwRootFrame const *const pLayout)
Definition: findattr.cxx:889
SwDBManager * GetDBManager() const
For evaluation of DB fields (new DB-manager).
Definition: edfld.cxx:340
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
void GetAllUsedDB(std::vector< OUString > &rDBNameList, std::vector< OUString > const *pAllDBNames)
Definition: edfld.cxx:313
SwDBData const & GetDBData()
Definition: docfld.cxx:354
void Insert2(const OUString &, const bool bForceExpandHints=false)
Definition: editsh.cxx:85
SwFieldType * InsertFieldType(const SwFieldType &)
insert field type
Definition: edfld.cxx:350
void Push()
store a copy of the current cursor on the cursor stack
Definition: crsrsh.cxx:2221
SetAttrMode
Definition: swtypes.hxx:143
TElementType * First()
Definition: calbck.hxx:345
int i
void GetAllUsedDB(std::vector< OUString > &rDBNameList, const std::vector< OUString > *pAllDBNames=nullptr)
Definition: docfld.cxx:424
SwFieldIds
Definition: fldbas.hxx:38
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:47
SwUndoId StartUndo(SwUndoId eUndoId=SwUndoId::EMPTY, const SwRewriter *pRewriter=nullptr)
Undo: set up Undo parenthesis, return nUndoId of this parenthesis.
Definition: edws.cxx:222
Force hint expand (only matters for hints with CH_TXTATR).
bool IsUsed(const SwModify &) const
Query if the paragraph-/character-/frame-/page-style is used.
Definition: edfmt.cxx:141
void CloseAll(bool bIncludingMerge=true)
close all data sources - after fields were updated
Definition: dbmgr.cxx:2493
SwDBData const & GetDBData() const
Database information.
Definition: edfld.cxx:298
const SwDBData & GetDBDesc() const
Definition: edfld.cxx:303
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:426
size
#define SET_CURR_SHELL(shell)
Definition: swtypes.hxx:101
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:208
void UnlockExpFields()
Definition: edfld.cxx:360
const SwPosition * Start() const
Definition: pam.hxx:212
SwFieldType * GetTyp() const
Definition: fldbas.hxx:382
bool IsFieldInDoc() const
Definition: atrfld.cxx:329
void FieldToText(SwFieldType const *pType)
Definition: edfld.cxx:127
void UpdateExpFields(bool bCloseDB=false)
only every expression fields update
Definition: edfld.cxx:326
bool IsAnyDatabaseFieldInDoc() const
Definition: edfld.cxx:395
#define RES_TXTATR_FIELD
Definition: hintids.hxx:150
SwFieldIds Which() const
ResId.
Definition: fldbas.cxx:202
virtual OUString GetName() const
Only in derived classes.
Definition: fldbas.cxx:145
virtual SwFieldType * InsertFieldType(const SwFieldType &)=0
SwMoveFnCollection const & fnMoveForward
SwPam::Move()/Find() default argument.
Definition: paminit.cxx:59
#define RES_TXTATR_ANNOTATION
Definition: hintids.hxx:153
void ChangeDBFields(const std::vector< OUString > &rOldNames, const OUString &rNewName)
Definition: docfld.cxx:585
void RemoveFieldType(size_t nField)
delete field type
Definition: edfld.cxx:98
Item2Range GetItemSurrogates(sal_uInt16 nWhich) const
::sw::DocumentSettingManager & GetDocumentSettingManager()
Definition: doc.cxx:218
void SetFieldUpdateFlags(SwFieldUpdateFlags eFlags)
Definition: edfld.cxx:370
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
const SwGetSetExpType GSE_STRING
String.
Definition: fldbas.hxx:195
bool Pop(PopMode)
delete cursor
Definition: crsrsh.cxx:2243
virtual void UnlockExpFields()=0
void ChangeDBFields(const std::vector< OUString > &rOldNames, const OUString &rNewName)
Definition: edfld.cxx:319
void ChangeAuthorityData(const SwAuthEntry *pNewData)
Definition: docfld.cxx:746
void StartAllAction()
For all views of this document.
Definition: edws.cxx:85
bool IsExpFieldsLocked() const
Definition: edfld.cxx:365
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2071
CharClass & GetAppCharClass()
Definition: init.cxx:745
#define RES_TXTATR_INPUTFIELD
Definition: hintids.hxx:145
SwFieldIds Which() const
Definition: fldbas.hxx:265
SwDBManager * GetDBManager() const
Definition: doc.hxx:663
void LockExpFields()
Definition: edfld.cxx:355
virtual void RemoveFieldType(size_t nField)=0
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1308
static SwTextField * GetTextFieldAtPos(const SwPosition *pPos, const bool bIncludeInputFieldAtStart)
Definition: crstrvl.cxx:879