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
210 if ( !pCursor->IsMultiSelection() && !pCursor->HasMark())
211 {
213
214 if (!pTextField) // #i30221#
215 pTextField = lcl_FindInputField( GetDoc(), rField);
216
217 if (pTextField != nullptr)
218 {
220 pTextField,
221 rField,
222 true);
223 }
224 }
225
226 // bOkay (instead of return because of EndAllAction) becomes false,
227 // 1) if only one PaM has more than one field or
228 // 2) if there are mixed field types
229 bool bOkay = true;
230 bool bTableSelBreak = false;
231
232 SwMsgPoolItem aFieldHint( RES_TXTATR_FIELD ); // Search-Hint
233 SwMsgPoolItem aAnnotationFieldHint( RES_TXTATR_ANNOTATION );
234 SwMsgPoolItem aInputFieldHint( RES_TXTATR_INPUTFIELD );
235 for(SwPaM& rPaM : GetCursor()->GetRingContainer()) // for each PaM
236 {
237 if( rPaM.HasMark() && bOkay ) // ... with selection
238 {
239 // copy of the PaM
240 SwPaM aCurPam( *rPaM.GetMark(), *rPaM.GetPoint() );
241 SwPaM aPam( *rPaM.GetPoint() );
242
243 SwPosition *pCurStt = aCurPam.Start(), *pCurEnd =
244 aCurPam.End();
245 /*
246 * In case that there are two contiguous fields in a PaM, the aPam goes step by step
247 * to the end. aCurPam is reduced in each loop. If aCurPam was searched completely,
248 * the loop terminates because Start = End.
249 */
250
251 // Search for SwTextField ...
252 while( bOkay
253 && pCurStt->GetContentIndex() != pCurEnd->GetContentIndex()
254 && (sw::FindAttrImpl(aPam, aFieldHint, fnMoveForward, aCurPam, true, GetLayout())
255 || sw::FindAttrImpl(aPam, aAnnotationFieldHint, fnMoveForward, aCurPam, false, GetLayout())
256 || sw::FindAttrImpl(aPam, aInputFieldHint, fnMoveForward, aCurPam, false, GetLayout())))
257 {
258 // if only one PaM has more than one field ...
259 if( aPam.Start()->GetContentIndex() != pCurStt->GetContentIndex() )
260 bOkay = false;
261
263 if( nullptr != pTextField )
264 {
265 pFormatField = const_cast<SwFormatField*>(&pTextField->GetFormatField());
266 SwField *pCurField = pFormatField->GetField();
267
268 // if there are mixed field types
269 if( pCurField->GetTyp()->Which() !=
270 rField.GetTyp()->Which() )
271 bOkay = false;
272
273 bTableSelBreak = GetDoc()->getIDocumentFieldsAccess().UpdateField(
274 pTextField,
275 rField,
276 false);
277 }
278 // The search area is reduced by the found area:
279 pCurStt->AdjustContent(+1);
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
297void SwEditShell::ChgDBData(const SwDBData& rNewData)
298{
299 GetDoc()->ChgDBData(rNewData);
300}
301
302void SwEditShell::GetAllUsedDB( std::vector<OUString>& rDBNameList,
303 std::vector<OUString> const * pAllDBNames )
304{
305 GetDoc()->GetAllUsedDB( rDBNameList, pAllDBNames );
306}
307
308void SwEditShell::ChangeDBFields( const std::vector<OUString>& rOldNames,
309 const OUString& rNewName )
310{
311 GetDoc()->ChangeDBFields( rOldNames, rNewName );
312}
313
316{
317 CurrShell aCurr( this );
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
369void 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: */
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 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 bool UpdateField(SwTextField *rDstFormatField, SwField &rSrcField, bool bUpdateTableFields)=0
Updates a field.
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:1025
void Push()
store a copy of the current cursor on the cursor stack
Definition: crsrsh.cxx:2550
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:2423
Definition: doc.hxx:197
SwDBData const & GetDBData()
Definition: docfld.cxx:386
void ChangeAuthorityData(const SwAuthEntry *pNewData)
Definition: docfld.cxx:769
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:408
SwDBManager * GetDBManager() const
Definition: doc.hxx:685
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:329
IDocumentFieldsAccess const & getIDocumentFieldsAccess() const
Definition: doc.cxx:371
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1337
void ChgDBData(const SwDBData &rNewData)
Definition: doc.cxx:467
void GetAllUsedDB(std::vector< OUString > &rDBNameList, const std::vector< OUString > *pAllDBNames=nullptr)
Definition: docfld.cxx:447
::sw::DocumentSettingManager & GetDocumentSettingManager()
Definition: doc.cxx:200
void ChangeDBFields(const std::vector< OUString > &rOldNames, const OUString &rNewName)
Definition: docfld.cxx:608
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:297
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:329
void RemoveFieldType(size_t nField)
delete field type
Definition: edfld.cxx:94
void ChangeAuthorityData(const SwAuthEntry *pNewData)
Definition: edfld.cxx:379
void SetFieldUpdateFlags(SwFieldUpdateFlags eFlags)
Definition: edfld.cxx:359
void FieldToText(SwFieldType const *pType)
Definition: edfld.cxx:123
bool IsExpFieldsLocked() const
Definition: edfld.cxx:354
void ChangeDBFields(const std::vector< OUString > &rOldNames, const OUString &rNewName)
Definition: edfld.cxx:308
SwFieldUpdateFlags GetFieldUpdateFlags() const
Definition: edfld.cxx:364
bool IsAnyDatabaseFieldInDoc() const
Definition: edfld.cxx:384
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:344
void UpdateOneField(SwField &)
One single field.
Definition: edfld.cxx:200
SwDBData const & GetDBData() const
Database information.
Definition: edfld.cxx:292
void GetAllUsedDB(std::vector< OUString > &rDBNameList, std::vector< OUString > const *pAllDBNames)
Definition: edfld.cxx:302
bool IsLabelDoc() const
Definition: edfld.cxx:374
SwFieldType * InsertFieldType(const SwFieldType &)
insert field type
Definition: edfld.cxx:339
void UnlockExpFields()
Definition: edfld.cxx:349
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:369
void UpdateExpFields(bool bCloseDB=false)
only every expression fields update
Definition: edfld.cxx:315
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:247
virtual OUString GetName() const
Only in derived classes.
Definition: fldbas.cxx:139
SwFieldIds Which() const
Definition: fldbas.hxx:276
Base class of all fields.
Definition: fldbas.hxx:296
SwFieldType * GetTyp() const
Definition: fldbas.hxx:402
SwFieldIds Which() const
ResId.
Definition: fldbas.cxx:263
const SwField * GetField() const
Definition: fmtfld.hxx:131
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:188
bool IsMultiSelection() const
Definition: pam.hxx:322
const SwPosition * End() const
Definition: pam.hxx:263
const SwPosition * Start() const
Definition: pam.hxx:258
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:251
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:2817
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2163
SwDoc * GetDoc() const
Definition: viewsh.hxx:308
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:49
@ Database
For old documents the Field-Which IDs must be preserved !!!
SwFieldUpdateFlags
Definition: fldupde.hxx:23
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:721
return NULL
size
int i
const SwGetSetExpType GSE_STRING
String.
Definition: fldbas.hxx:207
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:38
sal_Int32 GetContentIndex() const
Definition: pam.hxx:85
void AdjustContent(sal_Int32 nDelta)
Adjust content index, only valid to call this if the position points to a SwContentNode subclass.
Definition: pam.cxx:262
SetAttrMode
Definition: swtypes.hxx:133
@ FORCEHINTEXPAND
Force hint expand (only matters for hints with CH_TXTATR).