1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
31 #include "flddinf.hxx"
34 #include "fldfunc.hxx"
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>
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()) );
60 SwSetExpField
*const pSetField(dynamic_cast<SwSetExpField
*>(pCurField
));
63 assert(pSetField
->GetFormatField());
64 m_pSh
->GotoField( *(pSetField
->GetFormatField()) );
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
;
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();
114 SwViewShell::SetCareDialog(m_xDialog
);
116 EnsureSelection(pCurField
, aMgr
);
118 sal_uInt16 nGroup
= SwFieldMgr::GetGroup(pCurField
->GetTypeId(), pCurField
->GetSubType());
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
));
132 // initialise controls
133 void SwFieldEditDlg::Init()
135 SwFieldPage
* pTabPage
= static_cast<SwFieldPage
*>(GetTabPage());
138 SwFieldMgr
& rMgr
= pTabPage
->GetFieldMgr();
140 SwField
*pCurField
= rMgr
.GetCurField();
145 // Traveling only when more than one field
146 m_pSh
->StartAction();
148 m_pSh
->CreateCursor();
150 bool bMove
= rMgr
.GoNext();
153 m_xNextBT
->set_sensitive(bMove
);
155 bMove
= rMgr
.GoPrev();
158 m_xPrevBT
->set_sensitive( bMove
);
160 if (pCurField
->GetTypeId() == SwFieldTypesEnum::ExtendedUser
)
161 m_xAddressBT
->set_sensitive(true);
163 m_xAddressBT
->set_sensitive(false);
165 m_pSh
->DestroyCursor();
169 GetOKButton().set_sensitive(!m_pSh
->IsReadOnlyAvailable() ||
170 !m_pSh
->HasReadonlySel());
173 SfxTabPage
* SwFieldEditDlg::CreatePage(sal_uInt16 nGroup
)
176 std::unique_ptr
<SfxTabPage
> xTabPage
;
181 xTabPage
= SwFieldDokPage::Create(get_content_area(), this, nullptr);
184 xTabPage
= SwFieldFuncPage::Create(get_content_area(), this, nullptr);
187 xTabPage
= SwFieldRefPage::Create(get_content_area(), this, nullptr);
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
);
205 #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
207 xTabPage
= SwFieldDBPage::Create(get_content_area(), this, nullptr);
208 static_cast<SwFieldDBPage
*>(xTabPage
.get())->SetWrtShell(*m_pSh
);
212 xTabPage
= SwFieldVarPage::Create(get_content_area(), this, nullptr);
219 static_cast<SwFieldPage
*>(xTabPage
.get())->SetWrtShell(m_pSh
);
220 SetTabPage(std::move(xTabPage
));
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() )
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();
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();
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: */