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 SwMsgPoolItem* pMsgHint = nullptr;
207 SwRefMarkFieldUpdate aRefMkHt( GetOut() );
208 SwFieldIds nFieldWhich = rField.GetTyp()->Which();
209 if( SwFieldIds::GetRef == nFieldWhich )
210 pMsgHint = &aRefMkHt;
211
212 SwPaM* pCursor = GetCursor();
213 SwTextField *pTextField;
214 SwFormatField *pFormatField;
215
216 if ( !pCursor->IsMultiSelection() && !pCursor->HasMark())
217 {
218 pTextField = GetTextFieldAtPos( pCursor->Start(), true );
219
220 if (!pTextField) // #i30221#
221 pTextField = lcl_FindInputField( GetDoc(), rField);
222
223 if (pTextField != nullptr)
224 GetDoc()->getIDocumentFieldsAccess().UpdateField(pTextField, rField, pMsgHint, true);
225 }
226
227 // bOkay (instead of return because of EndAllAction) becomes false,
228 // 1) if only one PaM has more than one field or
229 // 2) if there are mixed field types
230 bool bOkay = true;
231 bool bTableSelBreak = false;
232
233 SwMsgPoolItem aFieldHint( RES_TXTATR_FIELD ); // Search-Hint
234 SwMsgPoolItem aAnnotationFieldHint( RES_TXTATR_ANNOTATION );
235 SwMsgPoolItem aInputFieldHint( RES_TXTATR_INPUTFIELD );
236 for(SwPaM& rPaM : GetCursor()->GetRingContainer()) // for each PaM
237 {
238 if( rPaM.HasMark() && bOkay ) // ... with selection
239 {
240 // copy of the PaM
241 SwPaM aCurPam( *rPaM.GetMark(), *rPaM.GetPoint() );
242 SwPaM aPam( *rPaM.GetPoint() );
243
244 SwPosition *pCurStt = aCurPam.Start(), *pCurEnd =
245 aCurPam.End();
246 /*
247 * In case that there are two contiguous fields in a PaM, the aPam goes step by step
248 * to the end. aCurPam is reduced in each loop. If aCurPam was searched completely,
249 * the loop terminates because Start = End.
250 */
251
252 // Search for SwTextField ...
253 while( bOkay
254 && pCurStt->nContent != pCurEnd->nContent
255 && (sw::FindAttrImpl(aPam, aFieldHint, fnMoveForward, aCurPam, true, GetLayout())
256 || sw::FindAttrImpl(aPam, aAnnotationFieldHint, fnMoveForward, aCurPam, false, GetLayout())
257 || sw::FindAttrImpl(aPam, aInputFieldHint, fnMoveForward, aCurPam, false, GetLayout())))
258 {
259 // if only one PaM has more than one field ...
260 if( aPam.Start()->nContent != pCurStt->nContent )
261 bOkay = false;
262
263 pTextField = GetTextFieldAtPos( pCurStt, true );
264 if( nullptr != pTextField )
265 {
266 pFormatField = const_cast<SwFormatField*>(&pTextField->GetFormatField());
267 SwField *pCurField = pFormatField->GetField();
268
269 // if there are mixed field types
270 if( pCurField->GetTyp()->Which() !=
271 rField.GetTyp()->Which() )
272 bOkay = false;
273
274 bTableSelBreak = GetDoc()->getIDocumentFieldsAccess().UpdateField(pTextField, rField,
275 pMsgHint, false);
276 }
277 // The search area is reduced by the found area:
278 ++pCurStt->nContent;
279 }
280 }
281
282 if( bTableSelBreak ) // If table section and table formula are updated -> finish
283 break;
284
285 }
286 }
288 EndAllAction();
289}
290
292{
293 return GetDoc()->GetDBData();
294}
295
296void SwEditShell::ChgDBData(const SwDBData& rNewData)
297{
298 GetDoc()->ChgDBData(rNewData);
299}
300
301void SwEditShell::GetAllUsedDB( std::vector<OUString>& rDBNameList,
302 std::vector<OUString> const * pAllDBNames )
303{
304 GetDoc()->GetAllUsedDB( rDBNameList, pAllDBNames );
305}
306
307void SwEditShell::ChangeDBFields( const std::vector<OUString>& rOldNames,
308 const OUString& rNewName )
309{
310 GetDoc()->ChangeDBFields( rOldNames, rNewName );
311}
312
315{
316 CurrShell aCurr( this );
319 if (bCloseDB)
320 {
321#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
322 GetDoc()->GetDBManager()->CloseAll(); // close all database connections
323#endif
324 }
325 EndAllAction();
326}
327
329{
330#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
331 return GetDoc()->GetDBManager();
332#else
333 return NULL;
334#endif
335}
336
339{
340 return GetDoc()->getIDocumentFieldsAccess().InsertFieldType(rFieldType);
341}
342
344{
346}
347
349{
351}
352
354{
356}
357
359{
361}
362
364{
366}
367
368void SwEditShell::SetLabelDoc( bool bFlag )
369{
371}
372
374{
376}
377
379{
380 GetDoc()->ChangeAuthorityData(pNewData);
381}
382
384{
385 // Similar to: SwDoc::GetDBDesc
386 const SwFieldTypes * pFieldTypes = GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
387 for(const auto & pFieldType : *pFieldTypes)
388 {
389 if(IsUsed(*pFieldType))
390 {
391 switch(pFieldType->Which())
392 {
397 {
398 std::vector<SwFormatField*> vFields;
399 pFieldType->GatherFields(vFields);
400 return vFields.size();
401 }
402 break;
403 default: break;
404 }
405 }
406 }
407 return false;
408}
409
410/* 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, 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
void Push()
store a copy of the current cursor on the cursor stack
Definition: crsrsh.cxx:2248
static SwTextField * GetTextFieldAtPos(const SwPosition *pPos, const bool bIncludeInputFieldAtStart)
Definition: crstrvl.cxx:926
SwCursor * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:195
bool Pop(PopMode)
delete cursor
Definition: crsrsh.cxx:2270
void CloseAll(bool bIncludingMerge=true)
close all data sources - after fields were updated
Definition: dbmgr.cxx:2397
Definition: doc.hxx:188
SwDBData const & GetDBData()
Definition: docfld.cxx:384
void ChangeAuthorityData(const SwAuthEntry *pNewData)
Definition: docfld.cxx:767
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:394
SwDBManager * GetDBManager() const
Definition: doc.hxx:669
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:315
IDocumentFieldsAccess const & getIDocumentFieldsAccess() const
Definition: doc.cxx:357
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1318
void ChgDBData(const SwDBData &rNewData)
Definition: doc.cxx:453
void GetAllUsedDB(std::vector< OUString > &rDBNameList, const std::vector< OUString > *pAllDBNames=nullptr)
Definition: docfld.cxx:445
::sw::DocumentSettingManager & GetDocumentSettingManager()
Definition: doc.cxx:186
void ChangeDBFields(const std::vector< OUString > &rOldNames, const OUString &rNewName)
Definition: docfld.cxx:606
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:296
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:328
void RemoveFieldType(size_t nField)
delete field type
Definition: edfld.cxx:94
void ChangeAuthorityData(const SwAuthEntry *pNewData)
Definition: edfld.cxx:378
void SetFieldUpdateFlags(SwFieldUpdateFlags eFlags)
Definition: edfld.cxx:358
void FieldToText(SwFieldType const *pType)
Definition: edfld.cxx:123
bool IsExpFieldsLocked() const
Definition: edfld.cxx:353
void ChangeDBFields(const std::vector< OUString > &rOldNames, const OUString &rNewName)
Definition: edfld.cxx:307
SwFieldUpdateFlags GetFieldUpdateFlags() const
Definition: edfld.cxx:363
bool IsAnyDatabaseFieldInDoc() const
Definition: edfld.cxx:383
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:343
void UpdateOneField(SwField &)
One single field.
Definition: edfld.cxx:200
SwDBData const & GetDBData() const
Database information.
Definition: edfld.cxx:291
void GetAllUsedDB(std::vector< OUString > &rDBNameList, std::vector< OUString > const *pAllDBNames)
Definition: edfld.cxx:301
bool IsLabelDoc() const
Definition: edfld.cxx:373
SwFieldType * InsertFieldType(const SwFieldType &)
insert field type
Definition: edfld.cxx:338
void UnlockExpFields()
Definition: edfld.cxx:348
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:368
void UpdateExpFields(bool bCloseDB=false)
only every expression fields update
Definition: edfld.cxx:314
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:242
virtual OUString GetName() const
Only in derived classes.
Definition: fldbas.cxx:137
SwFieldIds Which() const
Definition: fldbas.hxx:273
Base class of all fields.
Definition: fldbas.hxx:292
SwFieldType * GetTyp() const
Definition: fldbas.hxx:398
SwFieldIds Which() const
ResId.
Definition: fldbas.cxx:250
const SwField * GetField() const
Definition: fmtfld.hxx:116
bool HasWriterListeners() const
Definition: calbck.hxx:202
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:138
bool IsMultiSelection() const
Definition: pam.hxx:273
const SwPosition * End() const
Definition: pam.hxx:218
const SwPosition * Start() const
Definition: pam.hxx:213
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:206
SwRefMarkFieldUpdate is sent when the referencemarks should be updated.
Definition: hints.hxx:232
sal_uInt16 GetType() const
Definition: expfld.hxx:197
bool GetInputFlag() const
Definition: expfld.hxx:268
const SwFormatField & GetFormatField() const
Definition: txatbase.hxx:199
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:339
const IDocumentSettingAccess & getIDocumentSettingAccess() const
Provides access to the document setting interface.
Definition: viewsh.cxx:2777
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2172
SwDoc * GetDoc() const
Definition: viewsh.hxx:282
virtual void CallSwClientNotify(const SfxHint &rHint) const override
Definition: calbck.cxx:325
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:45
@ 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:705
return NULL
size
int i
const SwGetSetExpType GSE_STRING
String.
Definition: fldbas.hxx:203
bool FindAttrImpl(SwPaM &rSearchPam, const SfxPoolItem &rAttr, SwMoveFnCollection const &fnMove, const SwPaM &rRegion, bool bInReadOnly, SwRootFrame const *const pLayout)
Definition: findattr.cxx:911
SwMoveFnCollection const & fnMoveForward
SwPam::Move()/Find() default argument.
Definition: paminit.cxx:59
Marks a position in the document model.
Definition: pam.hxx:37
SwIndex nContent
Definition: pam.hxx:39
SetAttrMode
Definition: swtypes.hxx:133
@ FORCEHINTEXPAND
Force hint expand (only matters for hints with CH_TXTATR).