Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / uibase / app / apphdl.cxx
blobd7ab78d6e392560a24ccddcac2dde7bcf7a7dc0d
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>
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>
48 #include <view.hxx>
49 #include <pview.hxx>
50 #include <srcview.hxx>
51 #include <wrtsh.hxx>
52 #include <docsh.hxx>
53 #include <cmdid.h>
54 #include <initui.hxx>
55 #include <uitool.hxx>
56 #include <swmodule.hxx>
57 #include <wview.hxx>
58 #include <usrpref.hxx>
59 #include <gloslst.hxx>
60 #include <glosdoc.hxx>
61 #include <doc.hxx>
62 #include <IDocumentLayoutAccess.hxx>
63 #include <IDocumentFieldsAccess.hxx>
64 #include <prtopt.hxx>
65 #include <modcfg.hxx>
66 #include <fontcfg.hxx>
67 #include <barcfg.hxx>
68 #include <navicfg.hxx>
69 #include <uinums.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
95 // see Idl-file
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);
111 // other states
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;
120 while(nWhich)
122 switch(nWhich)
124 case FN_BUSINESS_CARD:
125 case FN_LABEL:
126 case FN_ENVELOP:
128 bool bDisable = false;
129 SfxViewShell* pCurrView = SfxViewShell::Current();
130 if( !pCurrView || dynamic_cast< const SwView *>( pCurrView ) == nullptr )
131 bDisable = true;
132 SwDocShell *pDocSh = static_cast<SwDocShell*>( SfxObjectShell::Current());
133 if ( bDisable ||
134 (pDocSh && (pDocSh->IsReadOnly() ||
135 pDocSh->GetCreateMode() == SfxObjectCreateMode::EMBEDDED)) )
136 rSet.DisableItem( nWhich );
139 break;
140 case FN_XFORMS_INIT:
141 // slot is always active!
142 break;
143 case FN_EDIT_FORMULA:
145 SwWrtShell* pSh = nullptr;
146 SelectionType nSelection = SelectionType::NONE;
147 if( pActView )
148 pSh = &pActView->GetWrtShell();
149 if( pSh )
150 nSelection = pSh->GetSelectionType();
152 if( (pSh && pSh->HasSelection()) ||
153 !(nSelection & (SelectionType::Text | SelectionType::Table)))
154 rSet.DisableItem(nWhich);
156 break;
157 case SID_ATTR_METRIC:
158 rSet.Put( SfxUInt16Item( SID_ATTR_METRIC, static_cast< sal_uInt16 >(::GetDfltMetric(bWebView))));
159 break;
160 case FN_SET_MODOPT_TBLNUMFMT:
161 rSet.Put( SfxBoolItem( nWhich, m_pModuleConfig->
162 IsInsTableFormatNum( bWebView )));
163 break;
164 case FN_MAILMERGE_WIZARD:
166 SfxObjectShell* pObjectShell = GetObjectShell();
167 if (pObjectShell && pObjectShell->isExportLocked())
168 rSet.DisableItem(nWhich);
169 break;
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();
179 if (!xConfigItem)
180 rSet.DisableItem(nWhich);
181 else if (xConfigItem->GetConnection().is()
182 && !xConfigItem->GetConnection()->isClosed())
184 bool bFirst, bLast;
185 bool bValid = xConfigItem->IsResultSetFirstLast(bFirst, bLast);
187 if (!bValid ||
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);
195 break;
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);
203 break;
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
217 if (!xConfigItem ||
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);
227 break;
228 default:
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();
242 if (!xMMConfig)
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)
256 SwDBData aDBData;
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);
268 if (xChild.is())
269 xSource.set(xChild->getParent(), uno::UNO_QUERY);
270 xMMConfig->SetCurrentConnection(
271 xSource, SharedConnection(xConnection, SharedConnection::NoTakeOwnership),
272 xColumnsSupplier, aDBData);
275 else
277 std::vector<OUString> aDBNameList;
278 std::vector<OUString> aAllDBNames;
279 GetWrtShell().GetAllUsedDB(aDBNameList, &aAllDBNames);
280 if (!aDBNameList.empty())
282 OUString sDBName(aDBNameList[0]);
283 SwDBData aDBData;
284 sal_Int32 nIdx{ 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);
295 return xMMConfig;
298 #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
300 namespace
303 SwView* lcl_LoadDoc(SwView* pView, const OUString& rURL)
305 SwView* pNewView = nullptr;
306 if(!rURL.isEmpty())
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;
318 if(pShell)
320 SfxViewShell* pViewShell = pShell->GetViewShell();
321 if(pViewShell)
323 pNewView = dynamic_cast<SwView*>(pViewShell);
324 if (pNewView)
326 pNewView->GetViewFrame().GetFrame().Appear();
328 else
330 pViewShell->GetViewFrame().DoClose();
335 else
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;
346 return pNewView;
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();
365 public:
366 SwMailMergeWizardExecutor();
367 virtual ~SwMailMergeWizardExecutor() override;
369 void ExecuteMailMergeWizard( const SfxItemSet * pArgs );
372 SwMailMergeWizardExecutor::SwMailMergeWizardExecutor()
373 : m_pView( nullptr ),
374 m_pView2Close( nullptr ),
375 m_pWizard( 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 ");
394 return false;
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(
417 "sw.core",
418 "trying to install LibreOffice Base, caught");
419 auto xRestartManager
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)));
428 xWarnBox->run();
431 } else {
432 auto xRestartManager
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)));
441 xWarnBox->run();
444 return;
446 if ( m_pView )
448 OSL_FAIL("SwMailMergeWizardExecutor::ExecuteMailMergeWizard: Already executing the wizard!" );
449 return;
452 m_pView = ::GetActiveView();
453 if (!m_pView)
454 return;
456 // keep self alive until done.
457 acquire();
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);
465 ExecuteWizard();
468 void SwMailMergeWizardExecutor::ExecutionFinished()
470 std::shared_ptr<SwMailMergeConfigItem> xMMConfig = m_pView->GetMailMergeConfigItem();
471 if (xMMConfig)
472 xMMConfig->Commit();
474 SwDoc* pDoc = m_pView->GetDocShell()->GetDoc();
475 if (pDoc)
477 SwDBManager* pDbManager = pDoc->GetDBManager();
478 if (pDbManager)
479 pDbManager->CommitLastRegistrations();
481 // Show the toolbar
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,
495 0 };
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();
514 switch ( nRet )
516 case RET_LOAD_DOC:
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();
528 if (pNewView)
530 pNewView->SetMailMergeConfigItem(xMMConfig);
531 m_pView = pNewView;
532 xMMConfig->DocumentReloaded();
533 //new source view!
534 xMMConfig->SetSourceView( m_pView );
535 m_pWizard = pFact->CreateMailMergeWizard(*m_pView, xMMConfig);
536 m_pWizard->ShowPage( nRestartPage );
538 else
540 m_pWizard = pFact->CreateMailMergeWizard(*m_pView, xMMConfig);
543 // execute the wizard again
544 ExecuteWizard();
545 break;
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");
552 if(pTargetView)
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
564 ExecuteWizard();
566 else
568 // should not happen - just in case no target view has been created
569 ExecutionFinished();
571 break;
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
598 ExecuteWizard();
600 else
602 // should not happen - just in case no target view has been created
603 ExecutionFinished();
605 break;
607 case RET_CANCEL:
609 // close frame and destroy wizard asynchronously
610 Application::PostUserEvent(
611 LINK( this, SwMailMergeWizardExecutor, CancelHdl ), m_pWizard );
612 break;
614 default: // finish
616 std::shared_ptr<SwMailMergeConfigItem> xMMConfig = m_pView->GetMailMergeConfigItem();
617 SwView* pSourceView = xMMConfig ? xMMConfig->GetSourceView() : nullptr;
618 if(pSourceView)
620 xMMConfig->GetSourceView()->GetViewFrame().GetFrame().Appear();
622 ExecutionFinished();
623 break;
626 } // switch
629 IMPL_LINK_NOARG(SwMailMergeWizardExecutor, DestroyDialogHdl, void*, void)
631 m_pWizard.disposeAndClear();
633 release();
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();
644 if (xMMConfig)
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();
656 xMMConfig->Commit();
659 // Revoke created connections
660 SwDoc* pDoc = m_pView->GetDocShell()->GetDoc();
661 SwDBManager* pDbManager = pDoc->GetDBManager();
662 if (pDbManager)
663 pDbManager->RevokeLastRegistrations();
665 m_pWizard.disposeAndClear();
666 release();
669 IMPL_LINK_NOARG(SwMailMergeWizardExecutor, CloseFrameHdl, void*, void)
671 if ( m_pView2Close )
673 m_pView2Close->GetViewFrame().DoClose();
674 m_pView2Close = nullptr;
676 m_pWizardToDestroyInCallback.disposeAndClear();
678 } // namespace
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();
688 switch (nWhich)
690 case FN_ENVELOP:
691 InsertEnv( rReq );
692 break;
694 case FN_BUSINESS_CARD:
695 case FN_LABEL:
696 InsertLab(rReq, nWhich == FN_LABEL);
697 break;
699 case FN_XFORMS_INIT:
700 NewXForms( rReq );
701 break;
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());
707 switch( eUnit )
709 case FieldUnit::MM:
710 case FieldUnit::CM:
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);
719 break;
720 default:;//prevent warning
723 break;
725 case FN_SET_MODOPT_TBLNUMFMT:
727 bool bWebView = dynamic_cast<SwWebView*>( ::GetActiveView() )!= nullptr ,
728 bSet;
730 if( pArgs && SfxItemState::SET == pArgs->GetItemState(
731 nWhich, false, &pItem ))
732 bSet = static_cast<const SfxBoolItem*>(pItem)->GetValue();
733 else
734 bSet = !m_pModuleConfig->IsInsTableFormatNum( bWebView );
736 m_pModuleConfig->SetInsTableFormatNum( bWebView, bSet );
738 break;
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 );
746 break;
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();
754 if (!pView)
755 return;
757 const std::shared_ptr<SwMailMergeConfigItem>& xConfigItem = pView->GetMailMergeConfigItem();
758 if (!xConfigItem)
759 return;
761 const bool bHadConnection
762 = xConfigItem->GetConnection().is() && !xConfigItem->GetConnection()->isClosed();
764 sal_Int32 nPos = xConfigItem->GetResultSetPosition();
765 switch (nWhich)
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;
772 default: 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())}
787 }));
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);
810 rBindings.Update();
812 break;
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();
819 if (!pView)
820 return;
822 std::shared_ptr<SwMailMergeConfigItem> xConfigItem = pView->GetMailMergeConfigItem();
823 assert(xConfigItem);
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);
838 rBindings.Update();
839 return;
842 if (nWhich == FN_MAILMERGE_CREATE_DOCUMENTS)
844 xConfigItem = SwDBManager::PerformMailMerge(pView);
846 if (xConfigItem && xConfigItem->GetTargetView())
847 xConfigItem->GetTargetView()->GetViewFrame().GetFrame().Appear();
849 else
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());
861 break;
862 #endif
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() );
874 if( pDocSh )
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);
893 break;
894 case SfxEventHintId::CreateDoc:
895 // Update all FIX-Date/Time fields
896 if( pWrtSh )
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;
902 if(bUpdateFields)
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());
917 break;
918 default: break;
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())
929 pList->Update();
932 else
934 if (rHint.GetId() == SfxHintId::Deinitializing)
936 m_pWebUsrPref.reset();
937 m_pUsrPref.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();
946 m_pDBConfig.reset();
947 if( m_pColorConfig )
949 m_pColorConfig->RemoveListener(this);
950 m_pColorConfig.reset();
952 if( m_pAccessibilityOptions )
954 m_pAccessibilityOptions->RemoveListener(this);
955 m_pAccessibilityOptions.reset();
957 if( m_pCTLOptions )
959 m_pCTLOptions->RemoveListener(this);
960 m_pCTLOptions.reset();
962 if( m_pUserOptions )
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();
982 while(pViewShell)
984 if(pViewShell->GetWindow())
986 auto pSwView = dynamic_cast<SwView *>(pViewShell);
987 if (pSwView)
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)
1009 break;
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();
1018 while(pViewShell)
1020 if(pViewShell->GetWindow())
1022 auto pSwView = dynamic_cast<SwView *>( pViewShell );
1023 auto pPagePreview = dynamic_cast<SwPagePreview *>( pViewShell );
1025 if(pSwView)
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 );
1038 #endif
1039 else if( pBrdCst == m_pCTLOptions.get() )
1041 const SfxObjectShell* pObjSh = SfxObjectShell::GetFirst();
1042 while( pObjSh )
1044 if( auto pDocShell = dynamic_cast<const SwDocShell*>(pObjSh) )
1046 SwDoc* pDoc = const_cast<SwDocShell*>(pDocShell)->GetDoc();
1047 SwViewShell* pVSh = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
1048 if ( pVSh )
1049 pVSh->ChgNumberDigits();
1051 pObjSh = SfxObjectShell::GetNext(*pObjSh);
1057 SwDBConfig* SwModule::GetDBConfig()
1059 if(!m_pDBConfig)
1060 m_pDBConfig.reset(new SwDBConfig);
1061 return m_pDBConfig.get();
1064 svtools::ColorConfig& SwModule::GetColorConfig()
1066 if(!m_pColorConfig)
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()
1087 if(!m_pCTLOptions)
1089 m_pCTLOptions.reset(new SvtCTLOptions);
1090 m_pCTLOptions->AddListener(this);
1092 return *m_pCTLOptions;
1095 SvtUserOptions& SwModule::GetUserOptions()
1097 if(!m_pUserOptions)
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 );
1135 // set return value
1136 rReq.SetReturnValue( SfxVoidItem( rReq.GetSlot() ) );
1139 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */