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>
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 <fieldhint.hxx>
41
44{
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
64SwFieldType* SwEditShell::GetFieldType(size_t nField, SwFieldIds nResId ) const
65{
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
88SwFieldType* SwEditShell::GetFieldType(SwFieldIds nResId, const OUString& rName) const
89{
90 return GetDoc()->getIDocumentFieldsAccess().GetFieldType( nResId, rName, false );
91}
92
95{
97}
98
100void 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 );
131 Push();
132 SwPaM* pPaM = GetCursor();
133 const SwFieldHint aHint(pPaM, GetLayout());
134 pType->CallSwClientNotify(aHint);
135
137 EndAllAction();
139}
140
142bool SwEditShell::InsertField(SwField const & rField, const bool bForceExpandHints)
143{
144 CurrShell aCurr( this );
146 SwFormatField aField( rField );
147
148 const SetAttrMode nInsertFlags = bForceExpandHints
151
152 bool bSuccess(false);
153 for(const SwPaM& rPaM : GetCursor()->GetRingContainer()) // for each PaM
154 {
155 bSuccess |= GetDoc()->getIDocumentContentOperations().InsertPoolItem(rPaM, aField, nInsertFlags);
156 OSL_ENSURE( bSuccess, "Doc->Insert(Field) failed");
157 }
158
159 EndAllAction();
160 return bSuccess;
161}
162
164static SwTextField* lcl_FindInputField( SwDoc* pDoc, const SwField& rField )
165{
166 // Search field via its address. For input fields this needs to be done in protected fields.
167 SwTextField* pTField = nullptr;
168 if (SwFieldIds::Input == rField.Which()
169 || (SwFieldIds::SetExp == rField.Which()
170 && static_cast<const SwSetExpField&>(rField).GetInputFlag()
171 && (static_cast<SwSetExpFieldType*>(rField.GetTyp())->GetType()
173 {
175 {
176 auto pFormatField = dynamic_cast<const SwFormatField*>(pItem);
177 if( pFormatField && pFormatField->GetField() == &rField )
178 {
179 pTField = const_cast<SwFormatField*>(pFormatField)->GetTextField();
180 break;
181 }
182 }
183 }
184 else if( SwFieldIds::SetExp == rField.Which()
185 && static_cast<const SwSetExpField&>(rField).GetInputFlag() )
186 {
187 for (const SfxPoolItem* pItem : pDoc->GetAttrPool().GetItemSurrogates(RES_TXTATR_FIELD))
188 {
189 auto pFormatField = dynamic_cast<const SwFormatField*>(pItem);
190 if( pFormatField && pFormatField->GetField() == &rField )
191 {
192 pTField = const_cast<SwFormatField*>(pFormatField)->GetTextField();
193 break;
194 }
195 }
196 }
197 return pTField;
198}
199
201{
202 CurrShell aCurr( this );
204 {
205 // If there are no selections so take the value of the current cursor position.
206 SwPaM* pCursor = GetCursor();
207 SwTextField *pTextField;
208 SwFormatField *pFormatField;
209 static const SwMsgPoolItem aRefMarkHint(RES_REFMARKFLD_UPDATE);
210 const SwMsgPoolItem* pRefMarkHint = SwFieldIds::GetRef == rField.GetTyp()->Which() // is this conditional even needed?
211 ? &aRefMarkHint
212 : nullptr;
213
214 if ( !pCursor->IsMultiSelection() && !pCursor->HasMark())
215 {
217
218 if (!pTextField) // #i30221#
219 pTextField = lcl_FindInputField( GetDoc(), rField);
220
221 if (pTextField != nullptr)
222 {
224 pTextField,
225 rField,
226 pRefMarkHint,
227 true);
228 }
229 }
230
231 // bOkay (instead of return because of EndAllAction) becomes false,
232 // 1) if only one PaM has more than one field or
233 // 2) if there are mixed field types
234 bool bOkay = true;
235 bool bTableSelBreak = false;
236
237 SwMsgPoolItem aFieldHint( RES_TXTATR_FIELD ); // Search-Hint
238 SwMsgPoolItem aAnnotationFieldHint( RES_TXTATR_ANNOTATION );
239 SwMsgPoolItem aInputFieldHint( RES_TXTATR_INPUTFIELD );
240 for(SwPaM& rPaM : GetCursor()->GetRingContainer()) // for each PaM
241 {
242 if( rPaM.HasMark() && bOkay ) // ... with selection
243 {
244 // copy of the PaM
245 SwPaM aCurPam( *rPaM.GetMark(), *rPaM.GetPoint() );
246 SwPaM aPam( *rPaM.GetPoint() );
247
248 SwPosition *pCurStt = aCurPam.Start(), *pCurEnd =
249 aCurPam.End();
250 /*
251 * In case that there are two contiguous fields in a PaM, the aPam goes step by step
252 * to the end. aCurPam is reduced in each loop. If aCurPam was searched completely,
253 * the loop terminates because Start = End.
254 */
255
256 // Search for SwTextField ...
257 while( bOkay
258 && pCurStt->GetContentIndex() != pCurEnd->GetContentIndex()
259 && (sw::FindAttrImpl(aPam, aFieldHint, fnMoveForward, aCurPam, true, GetLayout())
260 || sw::FindAttrImpl(aPam, aAnnotationFieldHint, fnMoveForward, aCurPam, false, GetLayout())
261 || sw::FindAttrImpl(aPam, aInputFieldHint, fnMoveForward, aCurPam, false, GetLayout())))
262 {
263 // if only one PaM has more than one field ...
264 if( aPam.Start()->GetContentIndex() != pCurStt->GetContentIndex() )
265 bOkay = false;
266
268 if( nullptr != pTextField )
269 {
270 pFormatField = const_cast<SwFormatField*>(&pTextField->GetFormatField());
271 SwField *pCurField = pFormatField->GetField();
272
273 // if there are mixed field types
274 if( pCurField->GetTyp()->Which() !=
275 rField.GetTyp()->Which() )
276 bOkay = false;
277
278 bTableSelBreak = GetDoc()->getIDocumentFieldsAccess().UpdateField(
279 pTextField,
280 rField,
281 pRefMarkHint,
282 false);
283 }
284 // The search area is reduced by the found area:
285 pCurStt->AdjustContent(+1);
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
303void SwEditShell::ChgDBData(const SwDBData& rNewData)
304{
305 GetDoc()->ChgDBData(rNewData);
306}
307
308void SwEditShell::GetAllUsedDB( std::vector<OUString>& rDBNameList,
309 std::vector<OUString> const * pAllDBNames )
310{
311 GetDoc()->GetAllUsedDB( rDBNameList, pAllDBNames );
312}
313
314void SwEditShell::ChangeDBFields( const std::vector<OUString>& rOldNames,
315 const OUString& rNewName )
316{
317 GetDoc()->ChangeDBFields( rOldNames, rNewName );
318}
319
322{
323 CurrShell aCurr( this );
326 if (bCloseDB)
327 {
328#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
329 GetDoc()->GetDBManager()->CloseAll(); // close all database connections
330#endif
331 }
332 EndAllAction();
333}
334
336{
337#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
338 return GetDoc()->GetDBManager();
339#else
340 return NULL;
341#endif
342}
343
346{
347 return GetDoc()->getIDocumentFieldsAccess().InsertFieldType(rFieldType);
348}
349
351{
353}
354
356{
358}
359
361{
363}
364
366{
368}
369
371{
373}
374
375void SwEditShell::SetLabelDoc( bool bFlag )
376{
378}
379
381{
383}
384
386{
387 GetDoc()->ChangeAuthorityData(pNewData);
388}
389
391{
392 // Similar to: SwDoc::GetDBDesc
393 const SwFieldTypes * pFieldTypes = GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
394 for(const auto & pFieldType : *pFieldTypes)
395 {
396 if(IsUsed(*pFieldType))
397 {
398 switch(pFieldType->Which())
399 {
404 {
405 std::vector<SwFormatField*> vFields;
406 pFieldType->GatherFields(vFields);
407 return vFields.size();
408 }
409 break;
410 default: break;
411 }
412 }
413 }
414 return false;
415}
416
417/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OUString lowercase(const OUString &rStr, sal_Int32 nPos, sal_Int32 nCount) const
virtual bool InsertPoolItem(const SwPaM &rRg, const SfxPoolItem &, const SetAttrMode nFlags=SetAttrMode::DEFAULT, SwRootFrame const *pLayout=nullptr, SwTextAttr **ppNewTextAttr=nullptr)=0
Insert an attribute.
virtual bool UpdateField(SwTextField *rDstFormatField, SwField &rSrcField, const SwMsgPoolItem *pMsgHint, bool bUpdateTableFields)=0
Updates a field.
virtual SwFieldType * GetFieldType(SwFieldIds nResId, const OUString &rName, bool bDbFieldMatching) const =0
virtual SwFieldType * InsertFieldType(const SwFieldType &)=0
virtual const SwFieldTypes * GetFieldTypes() const =0
virtual void LockExpFields()=0
virtual void RemoveFieldType(size_t nField)=0
virtual bool IsExpFieldsLocked() const =0
virtual void UpdateExpFields(SwTextField *pField, bool bUpdateRefFields)=0
virtual void UnlockExpFields()=0
virtual void setFieldUpdateFlags(SwFieldUpdateFlags nMode)=0
Set the current field update mode.
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
virtual SwFieldUpdateFlags getFieldUpdateFlags(bool bGlobalSettings) const =0
Get the current field update mode.
virtual void SetModified()=0
Must be called manually at changes of format.
Item2Range GetItemSurrogates(sal_uInt16 nWhich) const
bool Pop(PopMode, ::std::optional< SwCallLink > &roLink)
static SwTextField * GetTextFieldAtPos(const SwPosition *pPos, ::sw::GetTextAttrMode eMode)
Definition: crstrvl.cxx:1020
void Push()
store a copy of the current cursor on the cursor stack
Definition: crsrsh.cxx:2265
SwCursor * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:194
void CloseAll(bool bIncludingMerge=true)
close all data sources - after fields were updated
Definition: dbmgr.cxx:2427
Definition: doc.hxx:195
SwDBData const & GetDBData()
Definition: docfld.cxx:383
void ChangeAuthorityData(const SwAuthEntry *pNewData)
Definition: docfld.cxx:766
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:402
SwDBManager * GetDBManager() const
Definition: doc.hxx:681
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:323
IDocumentFieldsAccess const & getIDocumentFieldsAccess() const
Definition: doc.cxx:365
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1331
void ChgDBData(const SwDBData &rNewData)
Definition: doc.cxx:461
void GetAllUsedDB(std::vector< OUString > &rDBNameList, const std::vector< OUString > *pAllDBNames=nullptr)
Definition: docfld.cxx:444
::sw::DocumentSettingManager & GetDocumentSettingManager()
Definition: doc.cxx:194
void ChangeDBFields(const std::vector< OUString > &rOldNames, const OUString &rNewName)
Definition: docfld.cxx:605
bool InsertField(SwField const &, const bool bForceExpandHints)
add a field at the cursor position
Definition: edfld.cxx:142
void StartAllAction()
For all views of this document.
Definition: edws.cxx:86
size_t GetFieldTypeCount(SwFieldIds nResId=SwFieldIds::Unknown) const
count field types with a ResId, if SwFieldIds::Unknown count all
Definition: edfld.cxx:43
void ChgDBData(const SwDBData &SwDBData)
Definition: edfld.cxx:303
SwUndoId StartUndo(SwUndoId eUndoId=SwUndoId::EMPTY, const SwRewriter *pRewriter=nullptr)
Undo: set up Undo parenthesis, return nUndoId of this parenthesis.
Definition: edws.cxx:223
SwDBManager * GetDBManager() const
For evaluation of DB fields (new DB-manager).
Definition: edfld.cxx:335
void RemoveFieldType(size_t nField)
delete field type
Definition: edfld.cxx:94
void ChangeAuthorityData(const SwAuthEntry *pNewData)
Definition: edfld.cxx:385
void SetFieldUpdateFlags(SwFieldUpdateFlags eFlags)
Definition: edfld.cxx:365
void FieldToText(SwFieldType const *pType)
Definition: edfld.cxx:123
bool IsExpFieldsLocked() const
Definition: edfld.cxx:360
void ChangeDBFields(const std::vector< OUString > &rOldNames, const OUString &rNewName)
Definition: edfld.cxx:314
SwFieldUpdateFlags GetFieldUpdateFlags() const
Definition: edfld.cxx:370
bool IsAnyDatabaseFieldInDoc() const
Definition: edfld.cxx:390
SwFieldType * GetFieldType(size_t nField, SwFieldIds nResId=SwFieldIds::Unknown) const
get field types with a ResId, if 0 get all
Definition: edfld.cxx:64
void LockExpFields()
Definition: edfld.cxx:350
void UpdateOneField(SwField &)
One single field.
Definition: edfld.cxx:200
SwDBData const & GetDBData() const
Database information.
Definition: edfld.cxx:298
void GetAllUsedDB(std::vector< OUString > &rDBNameList, std::vector< OUString > const *pAllDBNames)
Definition: edfld.cxx:308
bool IsLabelDoc() const
Definition: edfld.cxx:380
SwFieldType * InsertFieldType(const SwFieldType &)
insert field type
Definition: edfld.cxx:345
void UnlockExpFields()
Definition: edfld.cxx:355
SwUndoId EndUndo(SwUndoId eUndoId=SwUndoId::EMPTY, const SwRewriter *pRewriter=nullptr)
Closes parenthesis of nUndoId, not used by UI.
Definition: edws.cxx:234
void SetLabelDoc(bool bFlag)
Labels: Synchronize ranges.
Definition: edfld.cxx:375
void UpdateExpFields(bool bCloseDB=false)
only every expression fields update
Definition: edfld.cxx:321
void EndAllAction()
Definition: edws.cxx:97
bool IsUsed(const sw::BroadcastingModify &) const
Query if the paragraph-/character-/frame-/page-style is used.
Definition: edfmt.cxx:137
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:244
virtual OUString GetName() const
Only in derived classes.
Definition: fldbas.cxx:137
SwFieldIds Which() const
Definition: fldbas.hxx:275
Base class of all fields.
Definition: fldbas.hxx:295
SwFieldType * GetTyp() const
Definition: fldbas.hxx:401
SwFieldIds Which() const
ResId.
Definition: fldbas.cxx:254
const SwField * GetField() const
Definition: fmtfld.hxx:131
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:187
bool IsMultiSelection() const
Definition: pam.hxx:328
const SwPosition * End() const
Definition: pam.hxx:271
const SwPosition * Start() const
Definition: pam.hxx:266
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:259
sal_uInt16 GetType() const
Definition: expfld.hxx:198
bool GetInputFlag() const
Definition: expfld.hxx:269
const SwFormatField & GetFormatField() const
Definition: txatbase.hxx:199
const IDocumentSettingAccess & getIDocumentSettingAccess() const
Provides access to the document setting interface.
Definition: viewsh.cxx:2809
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2159
SwDoc * GetDoc() const
Definition: viewsh.hxx:290
virtual void set(DocumentSettingId id, bool value) override
Set the specified document setting.
ring_container GetRingContainer()
Definition: ring.hxx:240
static SwTextField * lcl_FindInputField(SwDoc *pDoc, const SwField &rField)
Are the PaMs positioned on fields?
Definition: edfld.cxx:164
SwFieldIds
Definition: fldbas.hxx:46
@ Database
For old documents the Field-Which IDs must be preserved !!!
SwFieldUpdateFlags
Definition: fldupde.hxx:23
constexpr TypedWhichId< SwPtrMsgPoolItem > RES_REFMARKFLD_UPDATE(171)
constexpr TypedWhichId< SwFormatField > RES_TXTATR_ANNOTATION(60)
constexpr TypedWhichId< SwFormatField > RES_TXTATR_FIELD(RES_TXTATR_NOEND_BEGIN)
constexpr TypedWhichId< SwFormatField > RES_TXTATR_INPUTFIELD(55)
CharClass & GetAppCharClass()
Definition: init.cxx:719
return NULL
size
int i
const SwGetSetExpType GSE_STRING
String.
Definition: fldbas.hxx:204
bool FindAttrImpl(SwPaM &rSearchPam, const SfxPoolItem &rAttr, SwMoveFnCollection const &fnMove, const SwPaM &rRegion, bool bInReadOnly, SwRootFrame const *const pLayout)
Definition: findattr.cxx:910
SwMoveFnCollection const & fnMoveForward
SwPam::Move()/Find() default argument.
Definition: paminit.cxx:61
Marks a position in the document model.
Definition: pam.hxx:37
sal_Int32 GetContentIndex() const
Definition: pam.hxx:84
void AdjustContent(sal_Int32 nDelta)
Adjust content index, only valid to call this if the position points to a SwContentNode subclass.
Definition: pam.cxx:261
SetAttrMode
Definition: swtypes.hxx:133
@ FORCEHINTEXPAND
Force hint expand (only matters for hints with CH_TXTATR).