Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / ui / fldui / fldedt.cxx
blob306d864fab0265d3776fb1c941c290bb76ab4c61
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 <sfx2/basedlgs.hxx>
24 #include <sfx2/viewfrm.hxx>
25 #include <svx/optgenrl.hxx>
26 #include <docufld.hxx>
27 #include <expfld.hxx>
28 #include <view.hxx>
29 #include <wrtsh.hxx>
30 #include "flddb.hxx"
31 #include "flddinf.hxx"
32 #include "fldvar.hxx"
33 #include "flddok.hxx"
34 #include "fldfunc.hxx"
35 #include "fldref.hxx"
36 #include <fldedt.hxx>
38 #include <cmdid.h>
39 #include <swabstdlg.hxx>
41 #include <com/sun/star/beans/XPropertySet.hpp>
42 #include <com/sun/star/document/XDocumentProperties.hpp>
43 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
44 #include <com/sun/star/frame/XModel.hpp>
45 #include <memory>
46 #include <swuiexp.hxx>
48 void SwFieldEditDlg::EnsureSelection(SwField *pCurField, SwFieldMgr &rMgr)
50 if (m_pSh->CursorInsideInputField())
52 // move cursor to start of Input Field
53 SwInputField* pInputField = dynamic_cast<SwInputField*>(pCurField);
54 if (pInputField && pInputField->GetFormatField())
56 m_pSh->GotoField( *(pInputField->GetFormatField()) );
58 else
60 SwSetExpField *const pSetField(dynamic_cast<SwSetExpField*>(pCurField));
61 if (pSetField)
63 assert(pSetField->GetFormatField());
64 m_pSh->GotoField( *(pSetField->GetFormatField()) );
66 else
68 assert(!"what input field is this");
73 /* Only create selection if there is none already.
74 Normalize PaM instead of swapping. */
75 if (!m_pSh->HasSelection())
77 SwShellCursor* pCursor = m_pSh->getShellCursor(true);
78 SwPosition aOrigPos(*pCursor->GetPoint());
80 //After this attempt it is possible that rMgr.GetCurField() != pCurField if
81 //the field was in e.g. a zero height portion and so invisible in which
82 //case it will be skipped over
83 m_pSh->Right(SwCursorSkipMode::Chars, true, 1, false );
84 //So (fdo#50640) if it didn't work then reposition back to the original
85 //location where the field was
86 SwField *pRealCurField = rMgr.GetCurField();
87 bool bSelectionFailed = pCurField != pRealCurField;
88 if (bSelectionFailed)
90 pCursor->DeleteMark();
91 *pCursor->GetPoint() = aOrigPos;
95 m_pSh->NormalizePam();
97 assert(pCurField == rMgr.GetCurField());
100 SwFieldEditDlg::SwFieldEditDlg(SwView const & rVw)
101 : SfxSingleTabDialogController(rVw.GetViewFrame().GetFrameWeld(), nullptr,
102 "modules/swriter/ui/editfielddialog.ui", "EditFieldDialog")
103 , m_pSh(rVw.GetWrtShellPtr())
104 , m_xPrevBT(m_xBuilder->weld_button("prev"))
105 , m_xNextBT(m_xBuilder->weld_button("next"))
106 , m_xAddressBT(m_xBuilder->weld_button("edit"))
108 SwFieldMgr aMgr(m_pSh);
110 SwField *pCurField = aMgr.GetCurField();
111 if (!pCurField)
112 return;
114 SwViewShell::SetCareDialog(m_xDialog);
116 EnsureSelection(pCurField, aMgr);
118 sal_uInt16 nGroup = SwFieldMgr::GetGroup(pCurField->GetTypeId(), pCurField->GetSubType());
120 CreatePage(nGroup);
122 GetOKButton().connect_clicked(LINK(this, SwFieldEditDlg, OKHdl));
124 m_xPrevBT->connect_clicked(LINK(this, SwFieldEditDlg, NextPrevHdl));
125 m_xNextBT->connect_clicked(LINK(this, SwFieldEditDlg, NextPrevHdl));
127 m_xAddressBT->connect_clicked(LINK(this, SwFieldEditDlg, AddressHdl));
129 Init();
132 // initialise controls
133 void SwFieldEditDlg::Init()
135 SwFieldPage* pTabPage = static_cast<SwFieldPage*>(GetTabPage());
136 if (pTabPage)
138 SwFieldMgr& rMgr = pTabPage->GetFieldMgr();
140 SwField *pCurField = rMgr.GetCurField();
142 if(!pCurField)
143 return;
145 // Traveling only when more than one field
146 m_pSh->StartAction();
147 m_pSh->ClearMark();
148 m_pSh->CreateCursor();
150 bool bMove = rMgr.GoNext();
151 if( bMove )
152 rMgr.GoPrev();
153 m_xNextBT->set_sensitive(bMove);
155 bMove = rMgr.GoPrev();
156 if( bMove )
157 rMgr.GoNext();
158 m_xPrevBT->set_sensitive( bMove );
160 if (pCurField->GetTypeId() == SwFieldTypesEnum::ExtendedUser)
161 m_xAddressBT->set_sensitive(true);
162 else
163 m_xAddressBT->set_sensitive(false);
165 m_pSh->DestroyCursor();
166 m_pSh->EndAction();
169 GetOKButton().set_sensitive(!m_pSh->IsReadOnlyAvailable() ||
170 !m_pSh->HasReadonlySel());
173 SfxTabPage* SwFieldEditDlg::CreatePage(sal_uInt16 nGroup)
175 // create TabPage
176 std::unique_ptr<SfxTabPage> xTabPage;
178 switch (nGroup)
180 case GRP_DOC:
181 xTabPage = SwFieldDokPage::Create(get_content_area(), this, nullptr);
182 break;
183 case GRP_FKT:
184 xTabPage = SwFieldFuncPage::Create(get_content_area(), this, nullptr);
185 break;
186 case GRP_REF:
187 xTabPage = SwFieldRefPage::Create(get_content_area(), this, nullptr);
188 break;
189 case GRP_REG:
190 if (SfxObjectShell* pDocSh = SfxObjectShell::Current())
192 auto pSet = new SfxItemSetFixed<FN_FIELD_DIALOG_DOC_PROPS, FN_FIELD_DIALOG_DOC_PROPS>( pDocSh->GetPool() );
193 using namespace ::com::sun::star;
194 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
195 pDocSh->GetModel(), uno::UNO_QUERY_THROW);
196 uno::Reference<document::XDocumentProperties> xDocProps
197 = xDPS->getDocumentProperties();
198 uno::Reference< beans::XPropertySet > xUDProps(
199 xDocProps->getUserDefinedProperties(),
200 uno::UNO_QUERY_THROW);
201 pSet->Put( SfxUnoAnyItem( FN_FIELD_DIALOG_DOC_PROPS, uno::Any(xUDProps) ) );
202 xTabPage = SwFieldDokInfPage::Create(get_content_area(), this, pSet);
204 break;
205 #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
206 case GRP_DB:
207 xTabPage = SwFieldDBPage::Create(get_content_area(), this, nullptr);
208 static_cast<SwFieldDBPage*>(xTabPage.get())->SetWrtShell(*m_pSh);
209 break;
210 #endif
211 case GRP_VAR:
212 xTabPage = SwFieldVarPage::Create(get_content_area(), this, nullptr);
213 break;
217 assert(xTabPage);
219 static_cast<SwFieldPage*>(xTabPage.get())->SetWrtShell(m_pSh);
220 SetTabPage(std::move(xTabPage));
222 return GetTabPage();
225 SwFieldEditDlg::~SwFieldEditDlg()
227 SwViewShell::SetCareDialog(nullptr);
228 m_pSh->EnterStdMode();
231 void SwFieldEditDlg::EnableInsert(bool bEnable)
233 if( bEnable && m_pSh->IsReadOnlyAvailable() && m_pSh->HasReadonlySel() )
234 bEnable = false;
235 GetOKButton().set_sensitive(bEnable);
238 void SwFieldEditDlg::InsertHdl()
240 GetOKButton().clicked();
243 // kick off changing of the field
244 IMPL_LINK_NOARG(SwFieldEditDlg, OKHdl, weld::Button&, void)
246 if (GetOKButton().get_sensitive())
248 SfxTabPage* pTabPage = GetTabPage();
249 if (pTabPage)
250 pTabPage->FillItemSet(nullptr);
251 m_xDialog->response(RET_OK);
255 short SwFieldEditDlg::run()
257 // without TabPage no dialog
258 return GetTabPage() ? SfxSingleTabDialogController::run() : static_cast<short>(RET_CANCEL);
261 // Traveling between fields of the same type
262 IMPL_LINK(SwFieldEditDlg, NextPrevHdl, weld::Button&, rButton, void)
264 bool bNext = &rButton == m_xNextBT.get();
266 m_pSh->EnterStdMode();
268 SwFieldType *pOldTyp = nullptr;
269 SwFieldPage* pTabPage = static_cast<SwFieldPage*>(GetTabPage());
271 //#112462# FillItemSet may delete the current field
272 //that's why it has to be called before accessing the current field
273 if (GetOKButton().get_sensitive())
274 pTabPage->FillItemSet(nullptr);
276 SwFieldMgr& rMgr = pTabPage->GetFieldMgr();
277 SwField *pCurField = rMgr.GetCurField();
278 if (pCurField->GetTypeId() == SwFieldTypesEnum::Database)
279 pOldTyp = pCurField->GetTyp();
281 rMgr.GoNextPrev( bNext, pOldTyp );
282 pCurField = rMgr.GetCurField();
284 sal_uInt16 nGroup = SwFieldMgr::GetGroup(pCurField->GetTypeId(), pCurField->GetSubType());
286 if (nGroup != pTabPage->GetGroup())
287 pTabPage = static_cast<SwFieldPage*>(CreatePage(nGroup));
289 pTabPage->EditNewField();
291 Init();
292 EnsureSelection(pCurField, rMgr);
295 IMPL_LINK_NOARG(SwFieldEditDlg, AddressHdl, weld::Button&, void)
297 SwFieldPage* pTabPage = static_cast<SwFieldPage*>(GetTabPage());
298 SwFieldMgr& rMgr = pTabPage->GetFieldMgr();
299 SwField *pCurField = rMgr.GetCurField();
301 SfxItemSetFixed<SID_FIELD_GRABFOCUS, SID_FIELD_GRABFOCUS> aSet( m_pSh->GetAttrPool() );
303 EditPosition nEditPos = EditPosition::UNKNOWN;
305 switch(pCurField->GetSubType())
307 case EU_FIRSTNAME: nEditPos = EditPosition::FIRSTNAME; break;
308 case EU_NAME: nEditPos = EditPosition::LASTNAME; break;
309 case EU_SHORTCUT: nEditPos = EditPosition::SHORTNAME; break;
310 case EU_COMPANY: nEditPos = EditPosition::COMPANY; break;
311 case EU_STREET: nEditPos = EditPosition::STREET; break;
312 case EU_TITLE: nEditPos = EditPosition::TITLE; break;
313 case EU_POSITION: nEditPos = EditPosition::POSITION; break;
314 case EU_PHONE_PRIVATE:nEditPos = EditPosition::TELPRIV; break;
315 case EU_PHONE_COMPANY:nEditPos = EditPosition::TELCOMPANY; break;
316 case EU_FAX: nEditPos = EditPosition::FAX; break;
317 case EU_EMAIL: nEditPos = EditPosition::EMAIL; break;
318 case EU_COUNTRY: nEditPos = EditPosition::COUNTRY; break;
319 case EU_ZIP: nEditPos = EditPosition::PLZ; break;
320 case EU_CITY: nEditPos = EditPosition::CITY; break;
321 case EU_STATE: nEditPos = EditPosition::STATE; break;
323 default: nEditPos = EditPosition::UNKNOWN; break;
326 aSet.Put(SfxUInt16Item(SID_FIELD_GRABFOCUS, static_cast<sal_uInt16>(nEditPos)));
327 SwAbstractDialogFactory& rFact = swui::GetFactory();
329 ScopedVclPtr<SfxAbstractDialog> pDlg(rFact.CreateSwAddressAbstractDlg(m_xDialog.get(), aSet));
330 if (RET_OK == pDlg->Execute())
332 m_pSh->UpdateOneField(*pCurField);
336 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */