Revert "tdf#158280 Replace usage of InputDialog with SvxNameDialog"
[LibreOffice.git] / sw / source / core / edit / edfld.cxx
blobe9be8f003abdf8d3157bf3038f4470c02d884e2c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_features.h>
21 #include <config_fuzzers.h>
23 #include <osl/diagnose.h>
24 #include <unotools/charclass.hxx>
25 #include <editsh.hxx>
26 #include <fldbas.hxx>
27 #include <doc.hxx>
28 #include <IDocumentFieldsAccess.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>
39 #include <DocumentSettingManager.hxx>
40 #include <IDocumentContentOperations.hxx>
42 /// count field types with a ResId, if SwFieldIds::Unknown count all
43 size_t SwEditShell::GetFieldTypeCount(SwFieldIds nResId ) const
45 const SwFieldTypes* pFieldTypes = GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
47 if(nResId == SwFieldIds::Unknown)
49 return o3tl::narrowing<sal_uInt16>(pFieldTypes->size());
52 // all types with the same ResId
53 size_t nIdx = 0;
54 for(const auto & pFieldType : *pFieldTypes)
56 // same ResId -> increment index
57 if(pFieldType->Which() == nResId)
58 nIdx++;
60 return nIdx;
63 /// get field types with a ResId, if 0 get all
64 SwFieldType* SwEditShell::GetFieldType(size_t nField, SwFieldIds nResId ) const
66 const SwFieldTypes* pFieldTypes = GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
68 if(nResId == SwFieldIds::Unknown && nField < pFieldTypes->size())
70 return (*pFieldTypes)[nField].get();
73 size_t nIdx = 0;
74 for(const auto & pFieldType : *pFieldTypes)
76 // same ResId -> increment index
77 if(pFieldType->Which() == nResId)
79 if(nIdx == nField)
80 return pFieldType.get();
81 nIdx++;
84 return nullptr;
87 /// get first type with given ResId and name
88 SwFieldType* SwEditShell::GetFieldType(SwFieldIds nResId, const OUString& rName) const
90 return GetDoc()->getIDocumentFieldsAccess().GetFieldType( nResId, rName, false );
93 /// delete field type
94 void SwEditShell::RemoveFieldType(size_t nField)
96 GetDoc()->getIDocumentFieldsAccess().RemoveFieldType(nField);
99 /// delete field type based on its name
100 void SwEditShell::RemoveFieldType(SwFieldIds nResId, const OUString& rStr)
102 const SwFieldTypes* pFieldTypes = GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
103 const SwFieldTypes::size_type nSize = pFieldTypes->size();
104 const CharClass& rCC = GetAppCharClass();
106 OUString aTmp( rCC.lowercase( rStr ));
108 for(SwFieldTypes::size_type i = 0; i < nSize; ++i)
110 // same ResId -> increment index
111 SwFieldType* pFieldType = (*pFieldTypes)[i].get();
112 if( pFieldType->Which() == nResId )
114 if( aTmp == rCC.lowercase( pFieldType->GetName() ) )
116 GetDoc()->getIDocumentFieldsAccess().RemoveFieldType(i);
117 return;
123 void SwEditShell::FieldToText( SwFieldType const * pType )
125 if( !pType->HasWriterListeners() )
126 return;
128 CurrShell aCurr( this );
129 StartAllAction();
130 StartUndo( SwUndoId::DELETE );
131 Push();
132 SwPaM* pPaM = GetCursor();
133 const SwFieldHint aHint(pPaM, GetLayout());
134 pType->CallSwClientNotify(aHint);
136 Pop(PopMode::DeleteCurrent);
137 EndAllAction();
138 EndUndo( SwUndoId::DELETE );
141 /// add a field at the cursor position
142 bool SwEditShell::InsertField(SwField const & rField, const bool bForceExpandHints)
144 CurrShell aCurr( this );
145 StartAllAction();
146 SwFormatField aField( rField );
148 const SetAttrMode nInsertFlags = bForceExpandHints
149 ? SetAttrMode::FORCEHINTEXPAND
150 : SetAttrMode::DEFAULT;
152 bool bSuccess(false);
153 for(const SwPaM& rPaM : GetCursor()->GetRingContainer()) // for each PaM
155 bSuccess |= GetDoc()->getIDocumentContentOperations().InsertPoolItem(rPaM, aField, nInsertFlags);
156 OSL_ENSURE( bSuccess, "Doc->Insert(Field) failed");
159 EndAllAction();
160 return bSuccess;
163 /// Are the PaMs positioned on fields?
164 static SwTextField* lcl_FindInputField( SwDoc* pDoc, const SwField& rField )
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()
172 & nsSwGetSetExpType::GSE_STRING)))
174 pDoc->ForEachFormatField(RES_TXTATR_INPUTFIELD,
175 [&rField, &pTField] (const SwFormatField& rFormatField) -> bool
177 if( rFormatField.GetField() == &rField )
179 pTField = const_cast<SwFormatField&>(rFormatField).GetTextField();
180 return false;
182 return true;
185 else if( SwFieldIds::SetExp == rField.Which()
186 && static_cast<const SwSetExpField&>(rField).GetInputFlag() )
188 pDoc->ForEachFormatField(RES_TXTATR_FIELD,
189 [&rField, &pTField] (const SwFormatField& rFormatField) -> bool
191 if( rFormatField.GetField() == &rField )
193 pTField = const_cast<SwFormatField&>(rFormatField).GetTextField();
194 return false;
196 return true;
199 return pTField;
202 void SwEditShell::UpdateOneField(SwField &rField)
204 CurrShell aCurr( this );
205 StartAllAction();
207 // If there are no selections so take the value of the current cursor position.
208 SwPaM* pCursor = GetCursor();
209 SwTextField *pTextField;
210 SwFormatField *pFormatField;
212 if ( !pCursor->IsMultiSelection() && !pCursor->HasMark())
214 pTextField = GetTextFieldAtPos(pCursor->Start(), ::sw::GetTextAttrMode::Default);
216 if (!pTextField) // #i30221#
217 pTextField = lcl_FindInputField( GetDoc(), rField);
219 if (pTextField != nullptr)
221 GetDoc()->getIDocumentFieldsAccess().UpdateField(
222 pTextField,
223 rField,
224 true);
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;
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
239 if( rPaM.HasMark() && bOkay ) // ... with selection
241 // copy of the PaM
242 SwPaM aCurPam( *rPaM.GetMark(), *rPaM.GetPoint() );
243 SwPaM aPam( *rPaM.GetPoint() );
245 SwPosition *pCurStt = aCurPam.Start(), *pCurEnd =
246 aCurPam.End();
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.
253 // Search for SwTextField ...
254 while( bOkay
255 && pCurStt->GetContentIndex() != pCurEnd->GetContentIndex()
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())))
260 // if only one PaM has more than one field ...
261 if( aPam.Start()->GetContentIndex() != pCurStt->GetContentIndex() )
262 bOkay = false;
264 pTextField = GetTextFieldAtPos(pCurStt, ::sw::GetTextAttrMode::Default);
265 if( nullptr != pTextField )
267 pFormatField = const_cast<SwFormatField*>(&pTextField->GetFormatField());
268 SwField *pCurField = pFormatField->GetField();
270 // if there are mixed field types
271 if( pCurField->GetTyp()->Which() !=
272 rField.GetTyp()->Which() )
273 bOkay = false;
275 bTableSelBreak = GetDoc()->getIDocumentFieldsAccess().UpdateField(
276 pTextField,
277 rField,
278 false);
280 // The search area is reduced by the found area:
281 pCurStt->AdjustContent(+1);
285 if( bTableSelBreak ) // If table section and table formula are updated -> finish
286 break;
290 GetDoc()->getIDocumentState().SetModified();
291 EndAllAction();
294 SwDBData const & SwEditShell::GetDBData() const
296 return GetDoc()->GetDBData();
299 void SwEditShell::ChgDBData(const SwDBData& rNewData)
301 GetDoc()->ChgDBData(rNewData);
304 void SwEditShell::GetAllUsedDB( std::vector<OUString>& rDBNameList,
305 std::vector<OUString> const * pAllDBNames )
307 GetDoc()->GetAllUsedDB( rDBNameList, pAllDBNames );
310 void SwEditShell::ChangeDBFields( const std::vector<OUString>& rOldNames,
311 const OUString& rNewName )
313 GetDoc()->ChangeDBFields( rOldNames, rNewName );
316 /// Update all expression fields
317 void SwEditShell::UpdateExpFields(bool bCloseDB)
319 CurrShell aCurr( this );
320 StartAllAction();
321 GetDoc()->getIDocumentFieldsAccess().UpdateExpFields(nullptr, true);
322 if (bCloseDB)
324 #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
325 GetDoc()->GetDBManager()->CloseAll(); // close all database connections
326 #endif
328 EndAllAction();
331 SwDBManager* SwEditShell::GetDBManager() const
333 #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
334 return GetDoc()->GetDBManager();
335 #else
336 return NULL;
337 #endif
340 /// insert field type
341 SwFieldType* SwEditShell::InsertFieldType(const SwFieldType& rFieldType)
343 return GetDoc()->getIDocumentFieldsAccess().InsertFieldType(rFieldType);
346 void SwEditShell::LockExpFields()
348 GetDoc()->getIDocumentFieldsAccess().LockExpFields();
351 void SwEditShell::UnlockExpFields()
353 GetDoc()->getIDocumentFieldsAccess().UnlockExpFields();
356 bool SwEditShell::IsExpFieldsLocked() const
358 return GetDoc()->getIDocumentFieldsAccess().IsExpFieldsLocked();
361 void SwEditShell::SetFieldUpdateFlags( SwFieldUpdateFlags eFlags )
363 getIDocumentSettingAccess().setFieldUpdateFlags( eFlags );
366 SwFieldUpdateFlags SwEditShell::GetFieldUpdateFlags() const
368 return getIDocumentSettingAccess().getFieldUpdateFlags( false );
371 void SwEditShell::SetLabelDoc( bool bFlag )
373 GetDoc()->GetDocumentSettingManager().set(DocumentSettingId::LABEL_DOCUMENT, bFlag );
376 bool SwEditShell::IsLabelDoc() const
378 return getIDocumentSettingAccess().get(DocumentSettingId::LABEL_DOCUMENT);
381 void SwEditShell::ChangeAuthorityData(const SwAuthEntry* pNewData)
383 GetDoc()->ChangeAuthorityData(pNewData);
386 bool SwEditShell::IsAnyDatabaseFieldInDoc()const
388 // Similar to: SwDoc::GetDBDesc
389 const SwFieldTypes * pFieldTypes = GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
390 for(const auto & pFieldType : *pFieldTypes)
392 if(IsUsed(*pFieldType))
394 switch(pFieldType->Which())
396 case SwFieldIds::Database:
397 case SwFieldIds::DbNextSet:
398 case SwFieldIds::DbNumSet:
399 case SwFieldIds::DbSetNumber:
401 std::vector<SwFormatField*> vFields;
402 pFieldType->GatherFields(vFields);
403 return vFields.size();
405 break;
406 default: break;
410 return false;
413 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */