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>
22 #include <config_wasm_strip.h>
24 #include <comphelper/propertysequence.hxx>
25 #include <sfx2/dispatch.hxx>
26 #include <sfx2/event.hxx>
27 #include <sfx2/objitem.hxx>
28 #include <svx/dataaccessdescriptor.hxx>
29 #include <svtools/restartdialog.hxx>
30 #include <svl/eitem.hxx>
31 #include <svl/whiter.hxx>
32 #include <svl/isethint.hxx>
33 #include <svl/stritem.hxx>
34 #include <sfx2/request.hxx>
35 #include <sfx2/fcontnr.hxx>
36 #include <svl/ctloptions.hxx>
37 #include <svtools/colorcfg.hxx>
38 #include <svtools/accessibilityoptions.hxx>
39 #include <comphelper/diagnose_ex.hxx>
40 #include <unotools/useroptions.hxx>
41 #include <com/sun/star/document/UpdateDocMode.hpp>
42 #include <sfx2/docfile.hxx>
43 #include <sfx2/objface.hxx>
44 #include <vcl/settings.hxx>
45 #include <vcl/svapp.hxx>
46 #include <o3tl/string_view.hxx>
50 #include <srcview.hxx>
56 #include <swmodule.hxx>
58 #include <usrpref.hxx>
59 #include <gloslst.hxx>
60 #include <glosdoc.hxx>
62 #include <IDocumentLayoutAccess.hxx>
63 #include <IDocumentFieldsAccess.hxx>
66 #include <fontcfg.hxx>
68 #include <navicfg.hxx>
70 #include <dbconfig.hxx>
71 #include <mmconfigitem.hxx>
72 #include <strings.hrc>
73 #include <com/sun/star/container/XChild.hpp>
74 #include <com/sun/star/sdbc/XConnection.hpp>
75 #include <com/sun/star/sdb/TextConnectionSettings.hpp>
76 #include <com/sun/star/sdbc/XDataSource.hpp>
77 #include <com/sun/star/task/OfficeRestartManager.hpp>
78 #include <org/freedesktop/PackageKit/SyncDbusSessionHelper.hpp>
79 #include <swabstdlg.hxx>
80 #include <comphelper/dispatchcommand.hxx>
81 #include <comphelper/processfactory.hxx>
82 #include <comphelper/lok.hxx>
83 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
85 #include <salhelper/simplereferenceobject.hxx>
86 #include <rtl/ref.hxx>
88 #include <officecfg/Office/Common.hxx>
90 using namespace ::com::sun::star
;
92 // Slotmaps for the application's methods
94 // here are the SlotID's being included
96 #define ShellClass_SwModule
97 #include <sfx2/msg.hxx>
98 #include <swslots.hxx>
100 SFX_IMPL_INTERFACE(SwModule
, SfxModule
)
102 void SwModule::InitInterface_Impl()
104 GetStaticInterface()->RegisterStatusBar(StatusBarId::WriterStatusBar
);
106 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_APPLICATION
,
107 SfxVisibilityFlags::Standard
| SfxVisibilityFlags::Client
| SfxVisibilityFlags::Viewer
,
108 ToolbarId::Module_Toolbox
);
112 void SwModule::StateOther(SfxItemSet
&rSet
)
114 SfxWhichIter
aIter(rSet
);
115 sal_uInt16 nWhich
= aIter
.FirstWhich();
117 SwView
* pActView
= ::GetActiveView();
118 bool bWebView
= dynamic_cast<SwWebView
*>( pActView
) != nullptr;
124 case FN_BUSINESS_CARD
:
128 bool bDisable
= false;
129 SfxViewShell
* pCurrView
= SfxViewShell::Current();
130 if( !pCurrView
|| dynamic_cast< const SwView
*>( pCurrView
) == nullptr )
132 SwDocShell
*pDocSh
= static_cast<SwDocShell
*>( SfxObjectShell::Current());
134 (pDocSh
&& (pDocSh
->IsReadOnly() ||
135 pDocSh
->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)) )
136 rSet
.DisableItem( nWhich
);
141 // slot is always active!
143 case FN_EDIT_FORMULA
:
145 SwWrtShell
* pSh
= nullptr;
146 SelectionType nSelection
= SelectionType::NONE
;
148 pSh
= &pActView
->GetWrtShell();
150 nSelection
= pSh
->GetSelectionType();
152 if( (pSh
&& pSh
->HasSelection()) ||
153 !(nSelection
& (SelectionType::Text
| SelectionType::Table
)))
154 rSet
.DisableItem(nWhich
);
157 case SID_ATTR_METRIC
:
158 rSet
.Put( SfxUInt16Item( SID_ATTR_METRIC
, static_cast< sal_uInt16
>(::GetDfltMetric(bWebView
))));
160 case FN_SET_MODOPT_TBLNUMFMT
:
161 rSet
.Put( SfxBoolItem( nWhich
, m_pModuleConfig
->
162 IsInsTableFormatNum( bWebView
)));
164 case FN_MAILMERGE_WIZARD
:
166 SfxObjectShell
* pObjectShell
= GetObjectShell();
167 if (pObjectShell
&& pObjectShell
->isExportLocked())
168 rSet
.DisableItem(nWhich
);
171 case FN_MAILMERGE_FIRST_ENTRY
:
172 case FN_MAILMERGE_PREV_ENTRY
:
173 case FN_MAILMERGE_NEXT_ENTRY
:
174 case FN_MAILMERGE_LAST_ENTRY
:
176 std::shared_ptr
<SwMailMergeConfigItem
> xConfigItem
;
177 if (SwView
* pView
= GetActiveView())
178 xConfigItem
= pView
->GetMailMergeConfigItem();
180 rSet
.DisableItem(nWhich
);
181 else if (xConfigItem
->GetConnection().is()
182 && !xConfigItem
->GetConnection()->isClosed())
185 bool bValid
= xConfigItem
->IsResultSetFirstLast(bFirst
, bLast
);
188 (bFirst
&& (nWhich
== FN_MAILMERGE_FIRST_ENTRY
|| nWhich
== FN_MAILMERGE_PREV_ENTRY
)) ||
189 (bLast
&& (nWhich
== FN_MAILMERGE_LAST_ENTRY
|| nWhich
== FN_MAILMERGE_NEXT_ENTRY
)))
191 rSet
.DisableItem(nWhich
);
196 case FN_MAILMERGE_CURRENT_ENTRY
:
197 case FN_MAILMERGE_EXCLUDE_ENTRY
:
199 // just trigger calling statusChanged() of MMExcludeEntryController
200 // resp. MMCurrentEntryController
201 rSet
.InvalidateItem(nWhich
);
204 case FN_MAILMERGE_CREATE_DOCUMENTS
:
205 case FN_MAILMERGE_SAVE_DOCUMENTS
:
206 case FN_MAILMERGE_PRINT_DOCUMENTS
:
207 case FN_MAILMERGE_EMAIL_DOCUMENTS
:
209 std::shared_ptr
<SwMailMergeConfigItem
> xConfigItem
;
210 if (SwView
* pView
= GetActiveView())
211 xConfigItem
= pView
->EnsureMailMergeConfigItem();
213 // #i51949# hide e-Mail option if e-Mail is not supported
214 // #i63267# printing might be disabled
215 // Without attempting to open the database, (in case it is remote or passworded),
216 // hide everything after determining there are no valid results. tdf#121606
218 xConfigItem
->GetCurrentDBData().sDataSource
.isEmpty() ||
219 xConfigItem
->GetCurrentDBData().sCommand
.isEmpty() ||
220 (xConfigItem
->GetConnection().is() && !xConfigItem
->GetConnection()->isClosed() && !xConfigItem
->GetResultSet().is()) ||
221 (nWhich
== FN_MAILMERGE_PRINT_DOCUMENTS
&& Application::GetSettings().GetMiscSettings().GetDisablePrinting()) ||
222 (nWhich
== FN_MAILMERGE_EMAIL_DOCUMENTS
&& !xConfigItem
->IsMailAvailable()))
224 rSet
.DisableItem(nWhich
);
229 OSL_FAIL("::StateOther: default");
231 nWhich
= aIter
.NextWhich();
235 // start field dialog
236 static void NewXForms( SfxRequest
& rReq
); // implementation: below
238 std::shared_ptr
<SwMailMergeConfigItem
> SwView::EnsureMailMergeConfigItem(const SfxItemSet
* pArgs
)
240 // create if it does not exist yet
241 std::shared_ptr
<SwMailMergeConfigItem
> xMMConfig
= GetMailMergeConfigItem();
244 xMMConfig
= std::make_shared
<SwMailMergeConfigItem
>();
245 xMMConfig
->SetSourceView(this);
247 //set the first used database as default source on the config item
248 const SfxUnoAnyItem
* pItem
= nullptr;
249 if (pArgs
&& (pItem
= pArgs
->GetItemIfSet(
250 FN_PARAM_DATABASE_PROPERTIES
, false)))
252 //mailmerge has been called from the database beamer
253 uno::Sequence
< beans::PropertyValue
> aDBValues
;
254 if (pItem
->GetValue() >>= aDBValues
)
257 svx::ODataAccessDescriptor
aDescriptor(aDBValues
);
258 aDescriptor
[svx::DataAccessDescriptorProperty::DataSource
] >>= aDBData
.sDataSource
;
259 aDescriptor
[svx::DataAccessDescriptorProperty::Command
] >>= aDBData
.sCommand
;
260 aDescriptor
[svx::DataAccessDescriptorProperty::CommandType
] >>= aDBData
.nCommandType
;
262 uno::Reference
< sdbc::XConnection
> xConnection
;
263 uno::Reference
< sdbc::XDataSource
> xSource
;
264 uno::Reference
< sdbcx::XColumnsSupplier
> xColumnsSupplier
;
265 if (aDescriptor
.has(svx::DataAccessDescriptorProperty::Connection
))
266 aDescriptor
[svx::DataAccessDescriptorProperty::Connection
] >>= xConnection
;
267 uno::Reference
<container::XChild
> xChild(xConnection
, uno::UNO_QUERY
);
269 xSource
.set(xChild
->getParent(), uno::UNO_QUERY
);
270 xMMConfig
->SetCurrentConnection(
271 xSource
, SharedConnection(xConnection
, SharedConnection::NoTakeOwnership
),
272 xColumnsSupplier
, aDBData
);
277 std::vector
<OUString
> aDBNameList
;
278 std::vector
<OUString
> aAllDBNames
;
279 GetWrtShell().GetAllUsedDB(aDBNameList
, &aAllDBNames
);
280 if (!aDBNameList
.empty())
282 OUString
sDBName(aDBNameList
[0]);
285 aDBData
.sDataSource
= sDBName
.getToken(0, DB_DELIM
, nIdx
);
286 aDBData
.sCommand
= sDBName
.getToken(0, DB_DELIM
, nIdx
);
287 aDBData
.nCommandType
= o3tl::toInt32(o3tl::getToken(sDBName
, 0, DB_DELIM
, nIdx
));
288 //set the currently used database for the wizard
289 xMMConfig
->SetCurrentDBData(aDBData
);
293 SetMailMergeConfigItem(xMMConfig
);
298 #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
303 SwView
* lcl_LoadDoc(SwView
* pView
, const OUString
& rURL
)
305 SwView
* pNewView
= nullptr;
308 SfxStringItem
aURL(SID_FILE_NAME
, rURL
);
309 SfxStringItem
aTargetFrameName( SID_TARGETNAME
, "_blank" );
310 SfxBoolItem
aHidden( SID_HIDDEN
, true );
311 SfxStringItem
aReferer(SID_REFERER
, pView
->GetDocShell()->GetTitle());
312 const SfxObjectItem
* pItem
= static_cast<const SfxObjectItem
*>(
313 pView
->GetViewFrame().GetDispatcher()->ExecuteList(SID_OPENDOC
,
314 SfxCallMode::SYNCHRON
,
315 { &aURL
, &aHidden
, &aReferer
, &aTargetFrameName
}));
316 SfxShell
* pShell
= pItem
? pItem
->GetShell() : nullptr;
320 SfxViewShell
* pViewShell
= pShell
->GetViewShell();
323 pNewView
= dynamic_cast<SwView
*>(pViewShell
);
326 pNewView
->GetViewFrame().GetFrame().Appear();
330 pViewShell
->GetViewFrame().DoClose();
337 SfxStringItem
aFactory(SID_NEWDOCDIRECT
, SwDocShell::Factory().GetFilterContainer()->GetName());
338 const SfxFrameItem
* pItem
= static_cast<const SfxFrameItem
*>(
339 pView
->GetViewFrame().GetDispatcher()->ExecuteList(
340 SID_NEWDOCDIRECT
, SfxCallMode::SYNCHRON
, { &aFactory
}));
341 SfxFrame
* pFrame
= pItem
? pItem
->GetFrame() : nullptr;
342 SfxViewFrame
* pViewFrame
= pFrame
? pFrame
->GetCurrentViewFrame() : nullptr;
343 pNewView
= pViewFrame
? dynamic_cast<SwView
*>( pViewFrame
->GetViewShell() ) : nullptr;
349 class SwMailMergeWizardExecutor
: public salhelper::SimpleReferenceObject
351 SwView
* m_pView
; // never owner
352 SwView
* m_pView2Close
; // never owner
353 VclPtr
<AbstractMailMergeWizard
> m_pWizard
; // always owner
354 VclPtr
<AbstractMailMergeWizard
> m_pWizardToDestroyInCallback
;
356 void EndDialogHdl(sal_Int32 nResponse
);
357 DECL_LINK( DestroyDialogHdl
, void*, void );
358 DECL_LINK( DestroyWizardHdl
, void*, void );
359 DECL_LINK( CancelHdl
, void*, void );
360 DECL_LINK( CloseFrameHdl
, void*, void );
362 void ExecutionFinished();
363 void ExecuteWizard();
366 SwMailMergeWizardExecutor();
367 virtual ~SwMailMergeWizardExecutor() override
;
369 void ExecuteMailMergeWizard( const SfxItemSet
* pArgs
);
372 SwMailMergeWizardExecutor::SwMailMergeWizardExecutor()
373 : m_pView( nullptr ),
374 m_pView2Close( nullptr ),
379 SwMailMergeWizardExecutor::~SwMailMergeWizardExecutor()
381 OSL_ENSURE( m_pWizard
== nullptr, "SwMailMergeWizardExecutor: m_pWizard must be Null!" );
384 bool lcl_hasAllComponentsAvailable()
388 return css::sdb::TextConnectionSettings::create(comphelper::getProcessComponentContext()).is();
390 catch (const css::uno::Exception
&)
392 TOOLS_INFO_EXCEPTION(
393 "sw.core", "assuming Base to be missing; caught ");
398 void SwMailMergeWizardExecutor::ExecuteMailMergeWizard( const SfxItemSet
* pArgs
)
400 if(!lcl_hasAllComponentsAvailable())
402 if (officecfg::Office::Common::PackageKit::EnableBaseInstallation::get())
406 using namespace org::freedesktop::PackageKit
;
407 using namespace svtools
;
408 css::uno::Reference
< XSyncDbusSessionHelper
> xSyncDbusSessionHelper(SyncDbusSessionHelper::create(comphelper::getProcessComponentContext()));
409 const css::uno::Sequence
< OUString
> vPackages
{ "libreoffice-base" };
410 xSyncDbusSessionHelper
->InstallPackageNames(vPackages
, OUString());
411 SolarMutexGuard aGuard
;
412 executeRestartDialog(comphelper::getProcessComponentContext(), nullptr, RESTART_REASON_MAILMERGE_INSTALL
);
414 catch (const css::uno::Exception
&)
416 TOOLS_INFO_EXCEPTION(
418 "trying to install LibreOffice Base, caught");
420 = css::task::OfficeRestartManager::get(comphelper::getProcessComponentContext());
421 if (!xRestartManager
->isRestartRequested(false))
423 // Base is absent, and could not initiate its install - ask user to do that manually
424 // Only show the dialog if restart is not initiated yet
425 std::unique_ptr
<weld::MessageDialog
> xWarnBox(Application::CreateMessageDialog(
426 nullptr, VclMessageType::Info
, VclButtonsType::Ok
,
427 SwResId(STR_NO_BASE_FOR_MERGE
)));
433 = css::task::OfficeRestartManager::get(comphelper::getProcessComponentContext());
434 if (!xRestartManager
->isRestartRequested(false))
436 // Base is absent, and could not initiate its install - ask user to do that manually
437 // Only show the dialog if restart is not initiated yet
438 std::unique_ptr
<weld::MessageDialog
> xWarnBox(Application::CreateMessageDialog(
439 nullptr, VclMessageType::Info
, VclButtonsType::Ok
,
440 SwResId(STR_NO_BASE_FOR_MERGE
)));
448 OSL_FAIL("SwMailMergeWizardExecutor::ExecuteMailMergeWizard: Already executing the wizard!" );
452 m_pView
= ::GetActiveView();
456 // keep self alive until done.
459 // create if it does not exist yet
460 std::shared_ptr
<SwMailMergeConfigItem
> xMMConfig
= m_pView
->EnsureMailMergeConfigItem(pArgs
);
462 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
463 m_pWizard
= pFact
->CreateMailMergeWizard(*m_pView
, xMMConfig
);
468 void SwMailMergeWizardExecutor::ExecutionFinished()
470 std::shared_ptr
<SwMailMergeConfigItem
> xMMConfig
= m_pView
->GetMailMergeConfigItem();
474 SwDoc
* pDoc
= m_pView
->GetDocShell()->GetDoc();
477 SwDBManager
* pDbManager
= pDoc
->GetDBManager();
479 pDbManager
->CommitLastRegistrations();
482 m_pView
->ShowUIElement("private:resource/toolbar/mailmerge");
484 // Update Mail Merge controls
485 const sal_uInt16 slotIds
[] = { FN_MAILMERGE_FIRST_ENTRY
,
486 FN_MAILMERGE_PREV_ENTRY
,
487 FN_MAILMERGE_NEXT_ENTRY
,
488 FN_MAILMERGE_LAST_ENTRY
,
489 FN_MAILMERGE_CURRENT_ENTRY
,
490 FN_MAILMERGE_EXCLUDE_ENTRY
,
491 FN_MAILMERGE_CREATE_DOCUMENTS
,
492 FN_MAILMERGE_SAVE_DOCUMENTS
,
493 FN_MAILMERGE_PRINT_DOCUMENTS
,
494 FN_MAILMERGE_EMAIL_DOCUMENTS
,
496 m_pView
->GetViewFrame().GetBindings().Invalidate(slotIds
);
499 // release/destroy asynchronously
500 Application::PostUserEvent( LINK( this, SwMailMergeWizardExecutor
, DestroyDialogHdl
) );
503 void SwMailMergeWizardExecutor::ExecuteWizard()
505 m_pWizard
->StartExecuteAsync([this](sal_Int32 nResult
){
506 EndDialogHdl(nResult
);
510 void SwMailMergeWizardExecutor::EndDialogHdl(sal_Int32 nRet
)
512 sal_uInt16 nRestartPage
= m_pWizard
->GetRestartPage();
518 SwView
* pNewView
= lcl_LoadDoc(m_pView
, m_pWizard
->GetReloadDocument());
520 // Destroy wizard asynchronously, since we are deep inside the wizard and dialog
521 // machinery code here
522 m_pWizardToDestroyInCallback
= m_pWizard
;
523 Application::PostUserEvent(
524 LINK( this, SwMailMergeWizardExecutor
, DestroyWizardHdl
), nullptr );
526 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
527 std::shared_ptr
<SwMailMergeConfigItem
> xMMConfig
= m_pView
->GetMailMergeConfigItem();
530 pNewView
->SetMailMergeConfigItem(xMMConfig
);
532 xMMConfig
->DocumentReloaded();
534 xMMConfig
->SetSourceView( m_pView
);
535 m_pWizard
= pFact
->CreateMailMergeWizard(*m_pView
, xMMConfig
);
536 m_pWizard
->ShowPage( nRestartPage
);
540 m_pWizard
= pFact
->CreateMailMergeWizard(*m_pView
, xMMConfig
);
543 // execute the wizard again
547 case RET_TARGET_CREATED
:
549 std::shared_ptr
<SwMailMergeConfigItem
> xMMConfig
= m_pView
->GetMailMergeConfigItem();
550 SwView
* pTargetView
= xMMConfig
->GetTargetView();
551 OSL_ENSURE(pTargetView
, "No target view has been created");
554 // destroy wizard asynchronously
555 m_pWizardToDestroyInCallback
= m_pWizard
;
556 Application::PostUserEvent(
557 LINK( this, SwMailMergeWizardExecutor
, DestroyWizardHdl
), nullptr );
559 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
560 m_pWizard
= pFact
->CreateMailMergeWizard(*pTargetView
, xMMConfig
);
561 m_pWizard
->ShowPage( nRestartPage
);
563 // execute the wizard again
568 // should not happen - just in case no target view has been created
573 case RET_REMOVE_TARGET
:
575 std::shared_ptr
<SwMailMergeConfigItem
> xMMConfig
= m_pView
->GetMailMergeConfigItem();
576 SwView
* pTargetView
= xMMConfig
->GetTargetView();
577 SwView
* pSourceView
= xMMConfig
->GetSourceView();
578 OSL_ENSURE(pTargetView
&& pSourceView
, "source or target view not available" );
579 if(pTargetView
&& pSourceView
)
581 m_pView2Close
= pTargetView
;
582 pTargetView
->GetViewFrame().GetTopViewFrame()->GetWindow().Hide();
583 pSourceView
->GetViewFrame().GetFrame().AppearWithUpdate();
584 // the current view has be set when the target is destroyed
585 m_pView
= pSourceView
;
586 xMMConfig
->SetTargetView(nullptr);
588 // destroy wizard asynchronously
589 m_pWizardToDestroyInCallback
= m_pWizard
;
590 Application::PostUserEvent(
591 LINK( this, SwMailMergeWizardExecutor
, CloseFrameHdl
), m_pWizard
);
593 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
594 m_pWizard
= pFact
->CreateMailMergeWizard(*pSourceView
, xMMConfig
);
595 m_pWizard
->ShowPage( nRestartPage
);
597 // execute the wizard again
602 // should not happen - just in case no target view has been created
609 // close frame and destroy wizard asynchronously
610 Application::PostUserEvent(
611 LINK( this, SwMailMergeWizardExecutor
, CancelHdl
), m_pWizard
);
616 std::shared_ptr
<SwMailMergeConfigItem
> xMMConfig
= m_pView
->GetMailMergeConfigItem();
617 SwView
* pSourceView
= xMMConfig
? xMMConfig
->GetSourceView() : nullptr;
620 xMMConfig
->GetSourceView()->GetViewFrame().GetFrame().Appear();
629 IMPL_LINK_NOARG(SwMailMergeWizardExecutor
, DestroyDialogHdl
, void*, void)
631 m_pWizard
.disposeAndClear();
636 IMPL_LINK_NOARG(SwMailMergeWizardExecutor
, DestroyWizardHdl
, void*, void)
638 m_pWizardToDestroyInCallback
.disposeAndClear();
641 IMPL_LINK_NOARG(SwMailMergeWizardExecutor
, CancelHdl
, void*, void)
643 std::shared_ptr
<SwMailMergeConfigItem
> xMMConfig
= m_pView
->GetMailMergeConfigItem();
646 if (xMMConfig
->GetTargetView())
648 xMMConfig
->GetTargetView()->GetViewFrame().DoClose();
649 xMMConfig
->SetTargetView(nullptr);
651 if (xMMConfig
->GetSourceView())
653 auto& rViewFrame(xMMConfig
->GetSourceView()->GetViewFrame());
654 rViewFrame
.GetFrame().AppearWithUpdate();
659 // Revoke created connections
660 SwDoc
* pDoc
= m_pView
->GetDocShell()->GetDoc();
661 SwDBManager
* pDbManager
= pDoc
->GetDBManager();
663 pDbManager
->RevokeLastRegistrations();
665 m_pWizard
.disposeAndClear();
669 IMPL_LINK_NOARG(SwMailMergeWizardExecutor
, CloseFrameHdl
, void*, void)
673 m_pView2Close
->GetViewFrame().DoClose();
674 m_pView2Close
= nullptr;
676 m_pWizardToDestroyInCallback
.disposeAndClear();
680 #endif // HAVE_FEATURE_DBCONNECTIVITY
682 void SwModule::ExecOther(SfxRequest
& rReq
)
684 const SfxItemSet
*pArgs
= rReq
.GetArgs();
685 const SfxPoolItem
* pItem
= nullptr;
687 sal_uInt16 nWhich
= rReq
.GetSlot();
694 case FN_BUSINESS_CARD
:
696 InsertLab(rReq
, nWhich
== FN_LABEL
);
703 case SID_ATTR_METRIC
:
704 if(pArgs
&& SfxItemState::SET
== pArgs
->GetItemState(nWhich
, false, &pItem
))
706 FieldUnit eUnit
= static_cast<FieldUnit
>(static_cast<const SfxUInt16Item
*>(pItem
)->GetValue());
711 case FieldUnit::INCH
:
712 case FieldUnit::PICA
:
713 case FieldUnit::POINT
:
715 SwView
* pActView
= ::GetActiveView();
716 bool bWebView
= dynamic_cast<SwWebView
*>( pActView
) != nullptr;
717 ::SetDfltMetric(eUnit
, bWebView
);
720 default:;//prevent warning
725 case FN_SET_MODOPT_TBLNUMFMT
:
727 bool bWebView
= dynamic_cast<SwWebView
*>( ::GetActiveView() )!= nullptr ,
730 if( pArgs
&& SfxItemState::SET
== pArgs
->GetItemState(
731 nWhich
, false, &pItem
))
732 bSet
= static_cast<const SfxBoolItem
*>(pItem
)->GetValue();
734 bSet
= !m_pModuleConfig
->IsInsTableFormatNum( bWebView
);
736 m_pModuleConfig
->SetInsTableFormatNum( bWebView
, bSet
);
739 #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
740 case FN_MAILMERGE_WIZARD
:
742 // show the mailmerge wizard
743 rtl::Reference
< SwMailMergeWizardExecutor
> xEx( new SwMailMergeWizardExecutor
);
744 xEx
->ExecuteMailMergeWizard( pArgs
);
747 case FN_MAILMERGE_FIRST_ENTRY
:
748 case FN_MAILMERGE_PREV_ENTRY
:
749 case FN_MAILMERGE_NEXT_ENTRY
:
750 case FN_MAILMERGE_LAST_ENTRY
:
751 case FN_MAILMERGE_CURRENT_ENTRY
:
753 SwView
* pView
= ::GetActiveView();
757 const std::shared_ptr
<SwMailMergeConfigItem
>& xConfigItem
= pView
->GetMailMergeConfigItem();
761 const bool bHadConnection
762 = xConfigItem
->GetConnection().is() && !xConfigItem
->GetConnection()->isClosed();
764 sal_Int32 nPos
= xConfigItem
->GetResultSetPosition();
767 case FN_MAILMERGE_FIRST_ENTRY
: xConfigItem
->MoveResultSet(1); break;
768 case FN_MAILMERGE_PREV_ENTRY
: xConfigItem
->MoveResultSet(nPos
- 1); break;
769 case FN_MAILMERGE_NEXT_ENTRY
: xConfigItem
->MoveResultSet(nPos
+ 1); break;
770 case FN_MAILMERGE_LAST_ENTRY
: xConfigItem
->MoveResultSet(-1); break;
771 case FN_MAILMERGE_CURRENT_ENTRY
: /* don't move the result set, just update the document */ break;
775 // now the record has to be merged into the source document
776 // TODO can we re-use PerformMailMerge() here somehow?
777 const SwDBData
& rDBData
= xConfigItem
->GetCurrentDBData();
778 uno::Sequence
<uno::Any
> vSelection({ uno::Any(xConfigItem
->GetResultSetPosition()) });
779 svx::ODataAccessDescriptor
aDescriptor(::comphelper::InitPropertySequence({
780 {"Selection", uno::Any(vSelection
)},
781 {"DataSourceName", uno::Any(rDBData
.sDataSource
)},
782 {"Command", uno::Any(rDBData
.sCommand
)},
783 {"CommandType", uno::Any(rDBData
.nCommandType
)},
784 {"ActiveConnection", uno::Any(xConfigItem
->GetConnection().getTyped())},
785 {"Filter", uno::Any(xConfigItem
->GetFilter())},
786 {"Cursor", uno::Any(xConfigItem
->GetResultSet())}
789 SwWrtShell
& rSh
= pView
->GetWrtShell();
790 SwMergeDescriptor
aMergeDesc(DBMGR_MERGE
, rSh
, aDescriptor
);
791 rSh
.GetDBManager()->Merge(aMergeDesc
);
793 // update enabled / disabled status of the buttons in the toolbar
794 SfxBindings
& rBindings
= rSh
.GetView().GetViewFrame().GetBindings();
795 rBindings
.Invalidate(FN_MAILMERGE_FIRST_ENTRY
);
796 rBindings
.Invalidate(FN_MAILMERGE_PREV_ENTRY
);
797 rBindings
.Invalidate(FN_MAILMERGE_NEXT_ENTRY
);
798 rBindings
.Invalidate(FN_MAILMERGE_LAST_ENTRY
);
799 rBindings
.Invalidate(FN_MAILMERGE_CURRENT_ENTRY
);
800 rBindings
.Invalidate(FN_MAILMERGE_EXCLUDE_ENTRY
);
801 if (!bHadConnection
&& xConfigItem
->GetConnection().is()
802 && !xConfigItem
->GetConnection()->isClosed())
804 // The connection has been activated. Update controls that were disabled
805 rBindings
.Invalidate(FN_MAILMERGE_CREATE_DOCUMENTS
);
806 rBindings
.Invalidate(FN_MAILMERGE_SAVE_DOCUMENTS
);
807 rBindings
.Invalidate(FN_MAILMERGE_PRINT_DOCUMENTS
);
808 rBindings
.Invalidate(FN_MAILMERGE_EMAIL_DOCUMENTS
);
813 case FN_MAILMERGE_CREATE_DOCUMENTS
:
814 case FN_MAILMERGE_SAVE_DOCUMENTS
:
815 case FN_MAILMERGE_PRINT_DOCUMENTS
:
816 case FN_MAILMERGE_EMAIL_DOCUMENTS
:
818 SwView
* pView
= ::GetActiveView();
822 std::shared_ptr
<SwMailMergeConfigItem
> xConfigItem
= pView
->GetMailMergeConfigItem();
824 if (!xConfigItem
->GetResultSet().is())
826 // The connection has been attempted, but failed or no results found,
827 // so invalidate the toolbar buttons in case they need to be disabled.
828 SfxBindings
& rBindings
829 = pView
->GetWrtShell().GetView().GetViewFrame().GetBindings();
830 rBindings
.Invalidate(FN_MAILMERGE_CREATE_DOCUMENTS
);
831 rBindings
.Invalidate(FN_MAILMERGE_SAVE_DOCUMENTS
);
832 rBindings
.Invalidate(FN_MAILMERGE_PRINT_DOCUMENTS
);
833 rBindings
.Invalidate(FN_MAILMERGE_EMAIL_DOCUMENTS
);
834 rBindings
.Invalidate(FN_MAILMERGE_FIRST_ENTRY
);
835 rBindings
.Invalidate(FN_MAILMERGE_PREV_ENTRY
);
836 rBindings
.Invalidate(FN_MAILMERGE_NEXT_ENTRY
);
837 rBindings
.Invalidate(FN_MAILMERGE_LAST_ENTRY
);
842 if (nWhich
== FN_MAILMERGE_CREATE_DOCUMENTS
)
844 xConfigItem
= SwDBManager::PerformMailMerge(pView
);
846 if (xConfigItem
&& xConfigItem
->GetTargetView())
847 xConfigItem
->GetTargetView()->GetViewFrame().GetFrame().Appear();
851 xConfigItem
->SetTargetView(nullptr);
852 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
853 if (nWhich
== FN_MAILMERGE_SAVE_DOCUMENTS
)
854 pFact
->ExecuteMMResultSaveDialog(rReq
.GetFrameWeld());
855 else if (nWhich
== FN_MAILMERGE_PRINT_DOCUMENTS
)
856 pFact
->ExecuteMMResultPrintDialog(rReq
.GetFrameWeld());
857 else if (nWhich
== FN_MAILMERGE_EMAIL_DOCUMENTS
)
858 pFact
->ExecuteMMResultEmailDialog(rReq
.GetFrameWeld());
866 // Catch notifications
868 // Catch hint for DocInfo
869 void SwModule::Notify( SfxBroadcaster
& /*rBC*/, const SfxHint
& rHint
)
871 if( const SfxEventHint
* pEvHint
= dynamic_cast<const SfxEventHint
*>( &rHint
) )
873 SwDocShell
* pDocSh
= dynamic_cast<SwDocShell
*>( pEvHint
->GetObjShell() );
876 SwWrtShell
* pWrtSh
= pDocSh
->GetWrtShell();
877 switch( pEvHint
->GetEventId() )
879 case SfxEventHintId::LoadFinished
:
880 // if it is a new document created from a template,
881 // update fixed fields
882 if (pDocSh
->GetMedium())
884 const SfxBoolItem
* pTemplateItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pDocSh
->GetMedium()->GetItemSet(), SID_TEMPLATE
, false);
885 if (pTemplateItem
&& pTemplateItem
->GetValue())
887 // assume that not calling via SwEditShell::SetFixFields
888 // is allowed, because the shell hasn't been created yet
889 assert(!pWrtSh
|| pWrtSh
->GetView().GetViewFrame().GetFrame().IsClosing_Impl());
890 pDocSh
->GetDoc()->getIDocumentFieldsAccess().SetFixFields(nullptr);
894 case SfxEventHintId::CreateDoc
:
895 // Update all FIX-Date/Time fields
898 const SfxUInt16Item
* pUpdateDocItem
= SfxItemSet::GetItem
<SfxUInt16Item
>(pDocSh
->GetMedium()->GetItemSet(), SID_UPDATEDOCMODE
, false);
899 bool bUpdateFields
= true;
900 if( pUpdateDocItem
&& pUpdateDocItem
->GetValue() == document::UpdateDocMode::NO_UPDATE
)
901 bUpdateFields
= false;
904 comphelper::dispatchCommand(".uno:UpdateInputFields", {});
906 // Are database fields contained?
907 // Get all used databases for the first time
908 SwDoc
*pDoc
= pDocSh
->GetDoc();
909 std::vector
<OUString
> aDBNameList
;
910 pDoc
->GetAllUsedDB( aDBNameList
);
911 if(!aDBNameList
.empty())
912 { // Open database beamer
913 ShowDBObj(pWrtSh
->GetView(), pDoc
->GetDBData());
922 else if(const SfxItemSetHint
* pSfxItemSetHint
= dynamic_cast<const SfxItemSetHint
*>(&rHint
))
924 if( SfxItemState::SET
== pSfxItemSetHint
->GetItemSet().GetItemState(SID_ATTR_PATHNAME
))
926 ::GetGlossaries()->UpdateGlosPath( false );
927 SwGlossaryList
* pList
= ::GetGlossaryList();
928 if(pList
->IsActive())
934 if (rHint
.GetId() == SfxHintId::Deinitializing
)
936 m_pWebUsrPref
.reset();
938 m_pModuleConfig
.reset();
939 m_pPrintOptions
.reset();
940 m_pWebPrintOptions
.reset();
941 m_pChapterNumRules
.reset();
942 m_pStdFontConfig
.reset();
943 m_pNavigationConfig
.reset();
944 m_pToolbarConfig
.reset();
945 m_pWebToolbarConfig
.reset();
949 m_pColorConfig
->RemoveListener(this);
950 m_pColorConfig
.reset();
952 if( m_pAccessibilityOptions
)
954 m_pAccessibilityOptions
->RemoveListener(this);
955 m_pAccessibilityOptions
.reset();
959 m_pCTLOptions
->RemoveListener(this);
960 m_pCTLOptions
.reset();
964 m_pUserOptions
->RemoveListener(this);
965 m_pUserOptions
.reset();
971 void SwModule::ConfigurationChanged( utl::ConfigurationBroadcaster
* pBrdCst
, ConfigurationHints
)
973 if( pBrdCst
== m_pUserOptions
.get() )
975 m_bAuthorInitialised
= false;
977 else if ( pBrdCst
== m_pColorConfig
.get() )
979 //invalidate only the current view in tiled rendering mode, or all views otherwise
980 bool bOnlyInvalidateCurrentView
= comphelper::LibreOfficeKit::isActive();
981 SfxViewShell
* pViewShell
= bOnlyInvalidateCurrentView
? SfxViewShell::Current() : SfxViewShell::GetFirst();
984 if(pViewShell
->GetWindow())
986 auto pSwView
= dynamic_cast<SwView
*>(pViewShell
);
989 SwViewOption aNewOptions
= *pSwView
->GetWrtShell().GetViewOptions();
990 aNewOptions
.SetThemeName(svtools::ColorConfig::GetCurrentSchemeName());
991 SwViewColors
aViewColors(*m_pColorConfig
);
992 aNewOptions
.SetColorConfig(aViewColors
);
993 pSwView
->GetWrtShell().ApplyViewOptions(aNewOptions
);
995 if (bOnlyInvalidateCurrentView
)
997 pViewShell
->libreOfficeKitViewCallback(LOK_CALLBACK_APPLICATION_BACKGROUND_COLOR
,
998 aViewColors
.m_aAppBackgroundColor
.AsRGBHexString().toUtf8());
1001 if(pSwView
!= nullptr ||
1002 dynamic_cast< const SwPagePreview
*>( pViewShell
) != nullptr ||
1003 dynamic_cast< const SwSrcView
*>( pViewShell
) != nullptr)
1005 pViewShell
->GetWindow()->Invalidate();
1008 if (bOnlyInvalidateCurrentView
)
1010 pViewShell
= SfxViewShell::GetNext( *pViewShell
);
1013 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
1014 else if ( pBrdCst
== m_pAccessibilityOptions
.get() )
1016 //set Accessibility options
1017 SfxViewShell
* pViewShell
= SfxViewShell::GetFirst();
1020 if(pViewShell
->GetWindow())
1022 auto pSwView
= dynamic_cast<SwView
*>( pViewShell
);
1023 auto pPagePreview
= dynamic_cast<SwPagePreview
*>( pViewShell
);
1026 pSwView
->ApplyAccessibilityOptions();
1027 else if(pPagePreview
)
1028 pPagePreview
->ApplyAccessibilityOptions();
1030 if(pSwView
|| pPagePreview
|| dynamic_cast< const SwSrcView
*>( pViewShell
) != nullptr)
1032 pViewShell
->GetWindow()->Invalidate();
1035 pViewShell
= SfxViewShell::GetNext( *pViewShell
);
1039 else if( pBrdCst
== m_pCTLOptions
.get() )
1041 const SfxObjectShell
* pObjSh
= SfxObjectShell::GetFirst();
1044 if( auto pDocShell
= dynamic_cast<const SwDocShell
*>(pObjSh
) )
1046 SwDoc
* pDoc
= const_cast<SwDocShell
*>(pDocShell
)->GetDoc();
1047 SwViewShell
* pVSh
= pDoc
->getIDocumentLayoutAccess().GetCurrentViewShell();
1049 pVSh
->ChgNumberDigits();
1051 pObjSh
= SfxObjectShell::GetNext(*pObjSh
);
1057 SwDBConfig
* SwModule::GetDBConfig()
1060 m_pDBConfig
.reset(new SwDBConfig
);
1061 return m_pDBConfig
.get();
1064 svtools::ColorConfig
& SwModule::GetColorConfig()
1068 m_pColorConfig
.reset(new svtools::ColorConfig
);
1069 SwViewOption::SetInitialColorConfig(*m_pColorConfig
);
1070 m_pColorConfig
->AddListener(this);
1072 return *m_pColorConfig
;
1075 SvtAccessibilityOptions
& SwModule::GetAccessibilityOptions()
1077 if(!m_pAccessibilityOptions
)
1079 m_pAccessibilityOptions
.reset(new SvtAccessibilityOptions
);
1080 m_pAccessibilityOptions
->AddListener(this);
1082 return *m_pAccessibilityOptions
;
1085 SvtCTLOptions
& SwModule::GetCTLOptions()
1089 m_pCTLOptions
.reset(new SvtCTLOptions
);
1090 m_pCTLOptions
->AddListener(this);
1092 return *m_pCTLOptions
;
1095 SvtUserOptions
& SwModule::GetUserOptions()
1099 m_pUserOptions
.reset(new SvtUserOptions
);
1100 m_pUserOptions
->AddListener(this);
1102 return *m_pUserOptions
;
1105 const SwMasterUsrPref
*SwModule::GetUsrPref(bool bWeb
) const
1107 SwModule
* pNonConstModule
= const_cast<SwModule
*>(this);
1108 if(bWeb
&& !m_pWebUsrPref
)
1110 // The SpellChecker is needed in SwMasterUsrPref's Load, but it must not
1111 // be created there #58256#
1112 pNonConstModule
->m_pWebUsrPref
.reset(new SwMasterUsrPref(true));
1114 else if(!bWeb
&& !m_pUsrPref
)
1116 pNonConstModule
->m_pUsrPref
.reset(new SwMasterUsrPref(false));
1118 return bWeb
? m_pWebUsrPref
.get() : m_pUsrPref
.get();
1121 void NewXForms( SfxRequest
& rReq
)
1123 // copied & excerpted from SwModule::InsertLab(..)
1125 // create new document
1126 SwDocShellRef
xDocSh( new SwDocShell( SfxObjectCreateMode::STANDARD
) );
1127 xDocSh
->DoInitNew();
1129 // initialize XForms
1130 xDocSh
->GetDoc()->initXForms(true);
1132 // load document into frame
1133 SfxViewFrame::DisplayNewDocument( *xDocSh
, rReq
);
1136 rReq
.SetReturnValue( SfxVoidItem( rReq
.GetSlot() ) );
1139 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */