/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <config_features.h>
#include <sal/log.hxx>
#include <comphelper/propertysequence.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/event.hxx>
#include <sfx2/objitem.hxx>
#include <svx/dataaccessdescriptor.hxx>
#include <svtools/restartdialog.hxx>
#include <svl/whiter.hxx>
#include <svl/isethint.hxx>
#include <sfx2/request.hxx>
#include <sfx2/fcontnr.hxx>
#include <svl/ctloptions.hxx>
#include <unotools/useroptions.hxx>
#include <com/sun/star/document/UpdateDocMode.hpp>
#include <sfx2/docfile.hxx>
#include <sfx2/objface.hxx>
#include <view.hxx>
#include <pview.hxx>
#include <srcview.hxx>
#include <wrtsh.hxx>
#include <docsh.hxx>
#include <cmdid.h>
#include <initui.hxx>
#include <uitool.hxx>
#include <swmodule.hxx>
#include <wview.hxx>
#include <usrpref.hxx>
#include <gloslst.hxx>
#include <glosdoc.hxx>
#include <doc.hxx>
#include <IDocumentLayoutAccess.hxx>
#include <IDocumentFieldsAccess.hxx>
#include <prtopt.hxx>
#include <modcfg.hxx>
#include <fontcfg.hxx>
#include <barcfg.hxx>
#include <navicfg.hxx>
#include <uinums.hxx>
#include <dbconfig.hxx>
#include <mmconfigitem.hxx>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/sdbc/XConnection.hpp>
#include <com/sun/star/sdb/TextConnectionSettings.hpp>
#include <com/sun/star/sdbc/XDataSource.hpp>
#include <org/freedesktop/PackageKit/SyncDbusSessionHelper.hpp>
#include <swabstdlg.hxx>
#include <salhelper/simplereferenceobject.hxx>
#include <rtl/ref.hxx>
using namespace ::com::sun::star;
// Slotmaps for the application's methods
// here are the SlotID's being included
// see Idl-file
#define ShellClass_SwModule
#include <sfx2/msg.hxx>
#include <swslots.hxx>
SFX_IMPL_INTERFACE(SwModule, SfxModule)
void SwModule::InitInterface_Impl()
{
GetStaticInterface()->RegisterStatusBar(StatusBarId::WriterStatusBar);
GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_APPLICATION,
SfxVisibilityFlags::Standard | SfxVisibilityFlags::Client | SfxVisibilityFlags::Viewer,
ToolbarId::Module_Toolbox);
}
// other states
void SwModule::StateOther(SfxItemSet &rSet)
{
SfxWhichIter aIter(rSet);
sal_uInt16 nWhich = aIter.FirstWhich();
SwView* pActView = ::GetActiveView();
bool bWebView = dynamic_cast<SwWebView*>( pActView ) != nullptr;
while(nWhich)
{
switch(nWhich)
{
case FN_BUSINESS_CARD:
case FN_LABEL:
case FN_ENVELOP:
{
bool bDisable = false;
SfxViewShell* pCurrView = SfxViewShell::Current();
if( !pCurrView || dynamic_cast< const SwView *>( pCurrView ) == nullptr )
bDisable = true;
SwDocShell *pDocSh = static_cast<SwDocShell*>( SfxObjectShell::Current());
if ( bDisable ||
(pDocSh && (pDocSh->IsReadOnly() ||
pDocSh->GetCreateMode() == SfxObjectCreateMode::EMBEDDED)) )
rSet.DisableItem( nWhich );
}
break;
case FN_XFORMS_INIT:
// slot is always active!
break;
case FN_EDIT_FORMULA:
{
SwWrtShell* pSh = nullptr;
SelectionType nSelection = SelectionType::NONE;
if( pActView )
pSh = &pActView->GetWrtShell();
if( pSh )
nSelection = pSh->GetSelectionType();
if( (pSh && pSh->HasSelection()) ||
!(nSelection & (SelectionType::Text | SelectionType::Table)))
rSet.DisableItem(nWhich);
}
break;
case SID_ATTR_METRIC:
rSet.Put( SfxUInt16Item( SID_ATTR_METRIC, static_cast< sal_uInt16 >(::GetDfltMetric(bWebView))));
break;
case FN_SET_MODOPT_TBLNUMFMT:
rSet.Put( SfxBoolItem( nWhich, m_pModuleConfig->
IsInsTableFormatNum( bWebView )));
break;
case FN_MAILMERGE_FIRST_ENTRY:
case FN_MAILMERGE_PREV_ENTRY:
case FN_MAILMERGE_NEXT_ENTRY:
case FN_MAILMERGE_LAST_ENTRY:
{
SwView* pView = ::GetActiveView();
std::shared_ptr<SwMailMergeConfigItem> xConfigItem;
if (pView)
xConfigItem = pView->GetMailMergeConfigItem();
if (!xConfigItem)
rSet.DisableItem(nWhich);
else
{
bool bFirst, bLast;
bool bValid = xConfigItem->IsResultSetFirstLast(bFirst, bLast);
if (!bValid ||
(bFirst && (nWhich == FN_MAILMERGE_FIRST_ENTRY || nWhich == FN_MAILMERGE_PREV_ENTRY)) ||
(bLast && (nWhich == FN_MAILMERGE_LAST_ENTRY || nWhich == FN_MAILMERGE_NEXT_ENTRY)))
{
rSet.DisableItem(nWhich);
}
}
}
break;
case FN_MAILMERGE_CURRENT_ENTRY:
case FN_MAILMERGE_EXCLUDE_ENTRY:
{
// just trigger calling statusChanged() of MMExcludeEntryController
// resp. MMCurrentEntryController
rSet.InvalidateItem(nWhich);
}
break;
case FN_MAILMERGE_CREATE_DOCUMENTS:
case FN_MAILMERGE_SAVE_DOCUMENTS:
case FN_MAILMERGE_PRINT_DOCUMENTS:
case FN_MAILMERGE_EMAIL_DOCUMENTS:
{
SwView* pView = ::GetActiveView();
std::shared_ptr<SwMailMergeConfigItem> xConfigItem;
if (pView)
xConfigItem = pView->EnsureMailMergeConfigItem();
// #i51949# hide e-Mail option if e-Mail is not supported
// #i63267# printing might be disabled
if (!xConfigItem ||
!xConfigItem->GetResultSet().is() ||
xConfigItem->GetCurrentDBData().sDataSource.isEmpty() ||
xConfigItem->GetCurrentDBData().sCommand.isEmpty() ||
(nWhich == FN_MAILMERGE_PRINT_DOCUMENTS && Application::GetSettings().GetMiscSettings().GetDisablePrinting()) ||
(nWhich == FN_MAILMERGE_EMAIL_DOCUMENTS && !xConfigItem->IsMailAvailable()))
{
rSet.DisableItem(nWhich);
}
}
break;
default:
OSL_FAIL("::StateOther: default");
}
nWhich = aIter.NextWhich();
}
}
// start field dialog
void NewXForms( SfxRequest& rReq ); // implementation: below
std::shared_ptr<SwMailMergeConfigItem> SwView::EnsureMailMergeConfigItem(const SfxItemSet* pArgs)
{
// create if it does not exist yet
std::shared_ptr<SwMailMergeConfigItem> xMMConfig = GetMailMergeConfigItem();
if (!xMMConfig)
{
xMMConfig.reset(new SwMailMergeConfigItem);
xMMConfig->SetSourceView(this);
//set the first used database as default source on the config item
const SfxPoolItem* pItem = nullptr;
if (pArgs && SfxItemState::SET == pArgs->GetItemState(
FN_PARAM_DATABASE_PROPERTIES, false, &pItem))
{
//mailmerge has been called from the database beamer
uno::Sequence< beans::PropertyValue> aDBValues;
if (static_cast<const SfxUnoAnyItem*>(pItem)->GetValue() >>= aDBValues)
{
SwDBData aDBData;
svx::ODataAccessDescriptor aDescriptor(aDBValues);
aDescriptor[svx::DataAccessDescriptorProperty::DataSource] >>= aDBData.sDataSource;
aDescriptor[svx::DataAccessDescriptorProperty::Command] >>= aDBData.sCommand;
aDescriptor[svx::DataAccessDescriptorProperty::CommandType] >>= aDBData.nCommandType;
uno::Sequence< uno::Any > aSelection;
uno::Reference< sdbc::XConnection> xConnection;
uno::Reference< sdbc::XDataSource> xSource;
uno::Reference< sdbcx::XColumnsSupplier> xColumnsSupplier;
if (aDescriptor.has(svx::DataAccessDescriptorProperty::Selection))
aDescriptor[svx::DataAccessDescriptorProperty::Selection] >>= aSelection;
if (aDescriptor.has(svx::DataAccessDescriptorProperty::Connection))
aDescriptor[svx::DataAccessDescriptorProperty::Connection] >>= xConnection;
uno::Reference<container::XChild> xChild(xConnection, uno::UNO_QUERY);
if (xChild.is())
xSource.set(xChild->getParent(), uno::UNO_QUERY);
xMMConfig->SetCurrentConnection(
xSource, SharedConnection(xConnection, SharedConnection::NoTakeOwnership),
xColumnsSupplier, aDBData);
}
}
else
{
std::vector<OUString> aDBNameList;
std::vector<OUString> aAllDBNames;
GetWrtShell().GetAllUsedDB(aDBNameList, &aAllDBNames);
if (!aDBNameList.empty())
{
OUString sDBName(aDBNameList[0]);
SwDBData aDBData;
aDBData.sDataSource = sDBName.getToken(0, DB_DELIM);
aDBData.sCommand = sDBName.getToken(1, DB_DELIM);
aDBData.nCommandType = sDBName.getToken(2, DB_DELIM).toInt32();
//set the currently used database for the wizard
xMMConfig->SetCurrentDBData(aDBData);
}
}
SetMailMergeConfigItem(xMMConfig);
}
return xMMConfig;
}
#if HAVE_FEATURE_DBCONNECTIVITY
namespace
{
SwView* lcl_LoadDoc(SwView* pView, const OUString& rURL)
{
SwView* pNewView = nullptr;
if(!rURL.isEmpty())
{
SfxStringItem aURL(SID_FILE_NAME, rURL);
SfxStringItem aTargetFrameName( SID_TARGETNAME, OUString("_blank") );
SfxBoolItem aHidden( SID_HIDDEN, true );
SfxStringItem aReferer(SID_REFERER, pView->GetDocShell()->GetTitle());
const SfxObjectItem* pItem = static_cast<const SfxObjectItem*>(
pView->GetViewFrame()->GetDispatcher()->ExecuteList(SID_OPENDOC,
SfxCallMode::SYNCHRON,
{ &aURL, &aHidden, &aReferer, &aTargetFrameName }));
SfxShell* pShell = pItem ? pItem->GetShell() : nullptr;
if(pShell)
{
SfxViewShell* pViewShell = pShell->GetViewShell();
if(pViewShell)
{
if( nullptr!= dynamic_cast<SwView*>(pViewShell) )
{
pNewView = dynamic_cast< SwView* >(pViewShell);
pNewView->GetViewFrame()->GetFrame().Appear();
}
else
{
pViewShell->GetViewFrame()->DoClose();
}
}
}
}
else
{
SfxStringItem aFactory(SID_NEWDOCDIRECT, SwDocShell::Factory().GetFilterContainer()->GetName());
const SfxFrameItem* pItem = static_cast<const SfxFrameItem*>(
pView->GetViewFrame()->GetDispatcher()->ExecuteList(
SID_NEWDOCDIRECT, SfxCallMode::SYNCHRON, { &aFactory }));
SfxFrame* pFrame = pItem ? pItem->GetFrame() : nullptr;
SfxViewFrame* pViewFrame = pFrame ? pFrame->GetCurrentViewFrame() : nullptr;
pNewView = pViewFrame ? dynamic_cast<SwView*>( pViewFrame->GetViewShell() ) : nullptr;
}
return pNewView;
}
class SwMailMergeWizardExecutor : public salhelper::SimpleReferenceObject
{
SwView* m_pView; // never owner
SwView* m_pView2Close; // never owner
VclPtr<AbstractMailMergeWizard> m_pWizard; // always owner
VclPtr<AbstractMailMergeWizard> m_pWizardToDestroyInCallback;
DECL_LINK( EndDialogHdl, Dialog&, void );
DECL_LINK( DestroyDialogHdl, void*, void );
DECL_LINK( DestroyWizardHdl, void*, void );
DECL_LINK( CancelHdl, void*, void );
DECL_LINK( CloseFrameHdl, void*, void );
void ExecutionFinished();
void ExecuteWizard();
public:
SwMailMergeWizardExecutor();
virtual ~SwMailMergeWizardExecutor() override;
void ExecuteMailMergeWizard( const SfxItemSet * pArgs );
};
SwMailMergeWizardExecutor::SwMailMergeWizardExecutor()
: m_pView( nullptr ),
m_pView2Close( nullptr ),
m_pWizard( nullptr )
{
}
SwMailMergeWizardExecutor::~SwMailMergeWizardExecutor()
{
OSL_ENSURE( m_pWizard == nullptr, "SwMailMergeWizardExecutor: m_pWizard must be Null!" );
}
bool lcl_hasAllComponentsAvailable()
{
try
{
return css::sdb::TextConnectionSettings::create(comphelper::getProcessComponentContext()).is();
}
catch (css::uno::Exception & e)
{
SAL_INFO(
"sw.core",
"assuming Base to be missing; caught " << e);
return false;
}
}
void SwMailMergeWizardExecutor::ExecuteMailMergeWizard( const SfxItemSet * pArgs )
{
if(!lcl_hasAllComponentsAvailable())
{
try
{
using namespace org::freedesktop::PackageKit;
using namespace svtools;
css::uno::Reference< XSyncDbusSessionHelper > xSyncDbusSessionHelper(SyncDbusSessionHelper::create(comphelper::getProcessComponentContext()));
const css::uno::Sequence< OUString > vPackages{ "libreoffice-base" };
xSyncDbusSessionHelper->InstallPackageNames(vPackages, OUString());
SolarMutexGuard aGuard;
executeRestartDialog(comphelper::getProcessComponentContext(), nullptr, RESTART_REASON_MAILMERGE_INSTALL);
}
catch (const css::uno::Exception & e)
{
SAL_INFO(
"sw.core",
"trying to install LibreOffice Base, caught " << e);
}
return;
}
if ( m_pView )
{
OSL_FAIL("SwMailMergeWizardExecutor::ExecuteMailMergeWizard: Already executing the wizard!" );
return;
}
m_pView = ::GetActiveView();
if (!m_pView)
return;
// keep self alive until done.
acquire();
// create if it does not exist yet
std::shared_ptr<SwMailMergeConfigItem> xMMConfig = m_pView->EnsureMailMergeConfigItem(pArgs);
SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
m_pWizard = pFact->CreateMailMergeWizard(*m_pView, xMMConfig);
ExecuteWizard();
}
void SwMailMergeWizardExecutor::ExecutionFinished()
{
std::shared_ptr<SwMailMergeConfigItem> xMMConfig = m_pView->GetMailMergeConfigItem();
if (xMMConfig)
xMMConfig->Commit();
SwDoc* pDoc = m_pView->GetDocShell()->GetDoc();
if (pDoc)
{
SwDBManager* pDbManager = pDoc->GetDBManager();
if (pDbManager)
pDbManager->CommitLastRegistrations();
// Show the toolbar
m_pView->ShowUIElement("private:resource/toolbar/mailmerge");
// Update Mail Merge controls
const sal_uInt16 slotIds[] = { FN_MAILMERGE_FIRST_ENTRY,
FN_MAILMERGE_PREV_ENTRY,
FN_MAILMERGE_NEXT_ENTRY,
FN_MAILMERGE_LAST_ENTRY,
FN_MAILMERGE_CURRENT_ENTRY,
FN_MAILMERGE_EXCLUDE_ENTRY,
FN_MAILMERGE_CREATE_DOCUMENTS,
FN_MAILMERGE_SAVE_DOCUMENTS,
FN_MAILMERGE_PRINT_DOCUMENTS,
FN_MAILMERGE_EMAIL_DOCUMENTS,
0 };
m_pView->GetViewFrame()->GetBindings().Invalidate(slotIds);
}
// release/destroy asynchronously
Application::PostUserEvent( LINK( this, SwMailMergeWizardExecutor, DestroyDialogHdl ) );
}
void SwMailMergeWizardExecutor::ExecuteWizard()
{
m_pWizard->StartExecuteModal(
LINK( this, SwMailMergeWizardExecutor, EndDialogHdl ) );
}
IMPL_LINK_NOARG( SwMailMergeWizardExecutor, EndDialogHdl, Dialog&, void )
{
long nRet = m_pWizard->GetResult();
sal_uInt16 nRestartPage = m_pWizard->GetRestartPage();
switch ( nRet )
{
case RET_LOAD_DOC:
{
SwView* pNewView = lcl_LoadDoc(m_pView, m_pWizard->GetReloadDocument());
// Destroy wizard asynchronously, since we are deep inside the wizard and dialog
// machinery code here
m_pWizardToDestroyInCallback = m_pWizard;
Application::PostUserEvent(
LINK( this, SwMailMergeWizardExecutor, DestroyWizardHdl ), nullptr );
SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
std::shared_ptr<SwMailMergeConfigItem> xMMConfig = m_pView->GetMailMergeConfigItem();
if (pNewView)
{
pNewView->SetMailMergeConfigItem(xMMConfig);
m_pView = pNewView;
xMMConfig->DocumentReloaded();
//new source view!
xMMConfig->SetSourceView( m_pView );
m_pWizard = pFact->CreateMailMergeWizard(*m_pView, xMMConfig);
m_pWizard->ShowPage( nRestartPage );
}
else
{
m_pWizard = pFact->CreateMailMergeWizard(*m_pView, xMMConfig);
}
// execute the wizard again
ExecuteWizard();
break;
}
case RET_TARGET_CREATED:
{
std::shared_ptr<SwMailMergeConfigItem> xMMConfig = m_pView->GetMailMergeConfigItem();
SwView* pTargetView = xMMConfig->GetTargetView();
OSL_ENSURE(pTargetView, "No target view has been created");
if(pTargetView)
{
// destroy wizard asynchronously
m_pWizardToDestroyInCallback = m_pWizard;
Application::PostUserEvent(
LINK( this, SwMailMergeWizardExecutor, DestroyWizardHdl ), nullptr );
SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
m_pWizard = pFact->CreateMailMergeWizard(*pTargetView, xMMConfig);
m_pWizard->ShowPage( nRestartPage );
// execute the wizard again
ExecuteWizard();
}
else
{
// should not happen - just in case no target view has been created
ExecutionFinished();
}
break;
}
case RET_REMOVE_TARGET:
{
std::shared_ptr<SwMailMergeConfigItem> xMMConfig = m_pView->GetMailMergeConfigItem();
SwView* pTargetView = xMMConfig->GetTargetView();
SwView* pSourceView = xMMConfig->GetSourceView();
OSL_ENSURE(pTargetView && pSourceView, "source or target view not available" );
if(pTargetView && pSourceView)
{
m_pView2Close = pTargetView;
pTargetView->GetViewFrame()->GetTopViewFrame()->GetWindow().Hide();
pSourceView->GetViewFrame()->GetFrame().AppearWithUpdate();
// the current view has be set when the target is destroyed
m_pView = pSourceView;
xMMConfig->SetTargetView(nullptr);
// destroy wizard asynchronously
m_pWizardToDestroyInCallback = m_pWizard;
Application::PostUserEvent(
LINK( this, SwMailMergeWizardExecutor, CloseFrameHdl ), m_pWizard );
SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
m_pWizard = pFact->CreateMailMergeWizard(*pSourceView, xMMConfig);
m_pWizard->ShowPage( nRestartPage );
// execute the wizard again
ExecuteWizard();
}
else
{
// should not happen - just in case no target view has been created
ExecutionFinished();
}
break;
}
case RET_CANCEL:
{
// close frame and destroy wizard asynchronously
Application::PostUserEvent(
LINK( this, SwMailMergeWizardExecutor, CancelHdl ), m_pWizard );
break;
}
default: // finish
{
std::shared_ptr<SwMailMergeConfigItem> xMMConfig = m_pView->GetMailMergeConfigItem();
SwView* pSourceView = xMMConfig.get() ? xMMConfig->GetSourceView() : nullptr;
if(pSourceView)
{
xMMConfig->GetSourceView()->GetViewFrame()->GetFrame().Appear();
}
ExecutionFinished();
break;
}
} // switch
}
IMPL_LINK_NOARG(SwMailMergeWizardExecutor, DestroyDialogHdl, void*, void)
{
m_pWizard.disposeAndClear();
release();
}
IMPL_LINK_NOARG(SwMailMergeWizardExecutor, DestroyWizardHdl, void*, void)
{
m_pWizardToDestroyInCallback.disposeAndClear();
}
IMPL_LINK_NOARG(SwMailMergeWizardExecutor, CancelHdl, void*, void)
{
std::shared_ptr<SwMailMergeConfigItem> xMMConfig = m_pView->GetMailMergeConfigItem();
if (xMMConfig)
{
if (xMMConfig->GetTargetView())
{
xMMConfig->GetTargetView()->GetViewFrame()->DoClose();
xMMConfig->SetTargetView(nullptr);
}
if (xMMConfig->GetSourceView())
{
auto pViewFrame(xMMConfig->GetSourceView()->GetViewFrame());
pViewFrame->GetFrame().AppearWithUpdate();
}
xMMConfig->Commit();
}
// Revoke created connections
SwDoc* pDoc = m_pView->GetDocShell()->GetDoc();
SwDBManager* pDbManager = pDoc->GetDBManager();
if (pDbManager)
pDbManager->RevokeLastRegistrations();
m_pWizard.disposeAndClear();
release();
}
IMPL_LINK_NOARG(SwMailMergeWizardExecutor, CloseFrameHdl, void*, void)
{
if ( m_pView2Close )
{
m_pView2Close->GetViewFrame()->DoClose();
m_pView2Close = nullptr;
}
m_pWizardToDestroyInCallback.disposeAndClear();
}
} // namespace
#endif // HAVE_FEATURE_DBCONNECTIVITY
void SwModule::ExecOther(SfxRequest& rReq)
{
const SfxItemSet *pArgs = rReq.GetArgs();
const SfxPoolItem* pItem = nullptr;
sal_uInt16 nWhich = rReq.GetSlot();
switch (nWhich)
{
case FN_ENVELOP:
InsertEnv( rReq );
break;
case FN_BUSINESS_CARD:
case FN_LABEL:
InsertLab(rReq, nWhich == FN_LABEL);
break;
case FN_XFORMS_INIT:
NewXForms( rReq );
break;
case SID_ATTR_METRIC:
if(pArgs && SfxItemState::SET == pArgs->GetItemState(nWhich, false, &pItem))
{
FieldUnit eUnit = static_cast<FieldUnit>(static_cast<const SfxUInt16Item*>(pItem)->GetValue());
switch( eUnit )
{
case FUNIT_MM:
case FUNIT_CM:
case FUNIT_INCH:
case FUNIT_PICA:
case FUNIT_POINT:
{
SwView* pActView = ::GetActiveView();
bool bWebView = dynamic_cast<SwWebView*>( pActView ) != nullptr;
::SetDfltMetric(eUnit, bWebView);
}
break;
default:;//prevent warning
}
}
break;
case FN_SET_MODOPT_TBLNUMFMT:
{
bool bWebView = dynamic_cast<SwWebView*>( ::GetActiveView() )!= nullptr ,
bSet;
if( pArgs && SfxItemState::SET == pArgs->GetItemState(
nWhich, false, &pItem ))
bSet = static_cast<const SfxBoolItem*>(pItem)->GetValue();
else
bSet = !m_pModuleConfig->IsInsTableFormatNum( bWebView );
m_pModuleConfig->SetInsTableFormatNum( bWebView, bSet );
}
break;
#if HAVE_FEATURE_DBCONNECTIVITY
case FN_MAILMERGE_WIZARD:
{
// show the mailmerge wizard
rtl::Reference< SwMailMergeWizardExecutor > xEx( new SwMailMergeWizardExecutor );
xEx->ExecuteMailMergeWizard( pArgs );
}
break;
case FN_MAILMERGE_FIRST_ENTRY:
case FN_MAILMERGE_PREV_ENTRY:
case FN_MAILMERGE_NEXT_ENTRY:
case FN_MAILMERGE_LAST_ENTRY:
case FN_MAILMERGE_CURRENT_ENTRY:
{
SwView* pView = ::GetActiveView();
std::shared_ptr<SwMailMergeConfigItem> xConfigItem = pView->GetMailMergeConfigItem();
if (!xConfigItem)
return;
sal_Int32 nPos = xConfigItem->GetResultSetPosition();
switch (nWhich)
{
case FN_MAILMERGE_FIRST_ENTRY: xConfigItem->MoveResultSet(1); break;
case FN_MAILMERGE_PREV_ENTRY: xConfigItem->MoveResultSet(nPos - 1); break;
case FN_MAILMERGE_NEXT_ENTRY: xConfigItem->MoveResultSet(nPos + 1); break;
case FN_MAILMERGE_LAST_ENTRY: xConfigItem->MoveResultSet(-1); break;
case FN_MAILMERGE_CURRENT_ENTRY: /* don't move the result set, just update the document */ break;
default: break;
}
// now the record has to be merged into the source document
// TODO can we re-use PerformMailMerge() here somehow?
const SwDBData& rDBData = xConfigItem->GetCurrentDBData();
uno::Sequence<uno::Any> vSelection({ uno::makeAny(xConfigItem->GetResultSetPosition()) });
svx::ODataAccessDescriptor aDescriptor(::comphelper::InitPropertySequence({
{"Selection", uno::makeAny(vSelection)},
{"DataSourceName", uno::makeAny(rDBData.sDataSource)},
{"Command", uno::makeAny(rDBData.sCommand)},
{"CommandType", uno::makeAny(rDBData.nCommandType)},
{"ActiveConnection", uno::makeAny(xConfigItem->GetConnection().getTyped())},
{"Filter", uno::makeAny(xConfigItem->GetFilter())},
{"Cursor", uno::makeAny(xConfigItem->GetResultSet())}
}));
SwWrtShell& rSh = pView->GetWrtShell();
SwMergeDescriptor aMergeDesc(DBMGR_MERGE, rSh, aDescriptor);
rSh.GetDBManager()->Merge(aMergeDesc);
// update enabled / disabled status of the buttons in the toolbar
SfxBindings& rBindings = rSh.GetView().GetViewFrame()->GetBindings();
rBindings.Invalidate(FN_MAILMERGE_FIRST_ENTRY);
rBindings.Invalidate(FN_MAILMERGE_PREV_ENTRY);
rBindings.Invalidate(FN_MAILMERGE_NEXT_ENTRY);
rBindings.Invalidate(FN_MAILMERGE_LAST_ENTRY);
rBindings.Invalidate(FN_MAILMERGE_CURRENT_ENTRY);
rBindings.Invalidate(FN_MAILMERGE_EXCLUDE_ENTRY);
rBindings.Update();
}
break;
case FN_MAILMERGE_CREATE_DOCUMENTS:
{
std::shared_ptr<SwMailMergeConfigItem> xConfigItem = SwDBManager::PerformMailMerge(GetActiveView());
if (xConfigItem && xConfigItem->GetTargetView())
xConfigItem->GetTargetView()->GetViewFrame()->GetFrame().Appear();
}
break;
case FN_MAILMERGE_SAVE_DOCUMENTS:
case FN_MAILMERGE_PRINT_DOCUMENTS:
case FN_MAILMERGE_EMAIL_DOCUMENTS:
{
std::shared_ptr<SwMailMergeConfigItem> xConfigItem = GetActiveView()->GetMailMergeConfigItem();
if(!xConfigItem)
return;
xConfigItem->SetTargetView(nullptr);
SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
switch (nWhich)
{
case FN_MAILMERGE_SAVE_DOCUMENTS: pFact->ExecuteMMResultSaveDialog(rReq.GetFrameWeld()); break;
case FN_MAILMERGE_PRINT_DOCUMENTS: pFact->ExecuteMMResultPrintDialog(rReq.GetFrameWeld()); break;
case FN_MAILMERGE_EMAIL_DOCUMENTS: pFact->ExecuteMMResultEmailDialog(); break;
}
}
break;
#endif
}
}
// Catch notifications
// Catch hint for DocInfo
void SwModule::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
{
if( const SfxEventHint* pEvHint = dynamic_cast<const SfxEventHint*>( &rHint) )
{
SwDocShell* pDocSh = dynamic_cast<SwDocShell*>( pEvHint->GetObjShell() );
if( pDocSh )
{
SwWrtShell* pWrtSh = pDocSh->GetWrtShell();
switch( pEvHint->GetEventId() )
{
case SfxEventHintId::LoadFinished:
// if it is a new document created from a template,
// update fixed fields
if (pDocSh->GetMedium())
{
const SfxBoolItem* pTemplateItem = SfxItemSet::GetItem<SfxBoolItem>(pDocSh->GetMedium()->GetItemSet(), SID_TEMPLATE, false);
if (pTemplateItem && pTemplateItem->GetValue())
{
// assume that not calling via SwEditShell::SetFixFields
// is allowed, because the shell hasn't been created yet
assert(!pWrtSh);
pDocSh->GetDoc()->getIDocumentFieldsAccess().SetFixFields(nullptr);
}
}
break;
case SfxEventHintId::CreateDoc:
// Update all FIX-Date/Time fields
if( pWrtSh )
{
const SfxUInt16Item* pUpdateDocItem = SfxItemSet::GetItem<SfxUInt16Item>(pDocSh->GetMedium()->GetItemSet(), SID_UPDATEDOCMODE, false);
bool bUpdateFields = true;
if( pUpdateDocItem && pUpdateDocItem->GetValue() == document::UpdateDocMode::NO_UPDATE)
bUpdateFields = false;
if(bUpdateFields)
{
pWrtSh->UpdateInputFields();
// Are database fields contained?
// Get all used databases for the first time
SwDoc *pDoc = pDocSh->GetDoc();
std::vector<OUString> aDBNameList;
pDoc->GetAllUsedDB( aDBNameList );
if(!aDBNameList.empty())
{ // Open database beamer
ShowDBObj(pWrtSh->GetView(), pDoc->GetDBData());
}
}
}
break;
default: break;
}
}
}
else if(const SfxItemSetHint* pSfxItemSetHint = dynamic_cast<const SfxItemSetHint*>(&rHint))
{
if( SfxItemState::SET == pSfxItemSetHint->GetItemSet().GetItemState(SID_ATTR_PATHNAME))
{
::GetGlossaries()->UpdateGlosPath( false );
SwGlossaryList* pList = ::GetGlossaryList();
if(pList->IsActive())
pList->Update();
}
}
else
{
if (rHint.GetId() == SfxHintId::Deinitializing)
{
DELETEZ(m_pWebUsrPref);
DELETEZ(m_pUsrPref);
DELETEZ(m_pModuleConfig);
DELETEZ(m_pPrintOptions);
DELETEZ(m_pWebPrintOptions);
DELETEZ(m_pChapterNumRules);
DELETEZ(m_pStdFontConfig);
DELETEZ(m_pNavigationConfig);
DELETEZ(m_pToolbarConfig);
DELETEZ(m_pWebToolbarConfig);
DELETEZ(m_pDBConfig);
if( m_pColorConfig )
{
m_pColorConfig->RemoveListener(this);
DELETEZ(m_pColorConfig);
}
if( m_pAccessibilityOptions )
{
m_pAccessibilityOptions->RemoveListener(this);
DELETEZ(m_pAccessibilityOptions);
}
if( m_pCTLOptions )
{
m_pCTLOptions->RemoveListener(this);
DELETEZ(m_pCTLOptions);
}
if( m_pUserOptions )
{
m_pUserOptions->RemoveListener(this);
DELETEZ(m_pUserOptions);
}
}
}
}
void SwModule::ConfigurationChanged( utl::ConfigurationBroadcaster* pBrdCst, ConfigurationHints )
{
if( pBrdCst == m_pUserOptions )
{
m_bAuthorInitialised = false;
}
else if ( pBrdCst == m_pColorConfig || pBrdCst == m_pAccessibilityOptions )
{
bool bAccessibility = false;
if( pBrdCst == m_pColorConfig )
SwViewOption::ApplyColorConfigValues(*m_pColorConfig);
else
bAccessibility = true;
//invalidate all edit windows
SfxViewShell* pViewShell = SfxViewShell::GetFirst();
while(pViewShell)
{
if(pViewShell->GetWindow())
{
if(dynamic_cast< const SwView *>( pViewShell ) != nullptr ||
dynamic_cast< const SwPagePreview *>( pViewShell ) != nullptr ||
dynamic_cast< const SwSrcView *>( pViewShell ) != nullptr)
{
if(bAccessibility)
{
if(dynamic_cast< const SwView *>( pViewShell ) != nullptr)
static_cast<SwView*>(pViewShell)->ApplyAccessiblityOptions(*m_pAccessibilityOptions);
else if(dynamic_cast< const SwPagePreview *>( pViewShell ) != nullptr)
static_cast<SwPagePreview*>(pViewShell)->ApplyAccessiblityOptions(*m_pAccessibilityOptions);
}
pViewShell->GetWindow()->Invalidate();
}
}
pViewShell = SfxViewShell::GetNext( *pViewShell );
}
}
else if( pBrdCst == m_pCTLOptions )
{
const SfxObjectShell* pObjSh = SfxObjectShell::GetFirst();
while( pObjSh )
{
if( auto pDocShell = dynamic_cast<const SwDocShell*>(pObjSh) )
{
SwDoc* pDoc = const_cast<SwDocShell*>(pDocShell)->GetDoc();
SwViewShell* pVSh = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
if ( pVSh )
pVSh->ChgNumberDigits();
}
pObjSh = SfxObjectShell::GetNext(*pObjSh);
}
}
}
SwDBConfig* SwModule::GetDBConfig()
{
if(!m_pDBConfig)
m_pDBConfig = new SwDBConfig;
return m_pDBConfig;
}
svtools::ColorConfig& SwModule::GetColorConfig()
{
if(!m_pColorConfig)
{
m_pColorConfig = new svtools::ColorConfig;
SwViewOption::ApplyColorConfigValues(*m_pColorConfig);
m_pColorConfig->AddListener(this);
}
return *m_pColorConfig;
}
SvtAccessibilityOptions& SwModule::GetAccessibilityOptions()
{
if(!m_pAccessibilityOptions)
{
m_pAccessibilityOptions = new SvtAccessibilityOptions;
m_pAccessibilityOptions->AddListener(this);
}
return *m_pAccessibilityOptions;
}
SvtCTLOptions& SwModule::GetCTLOptions()
{
if(!m_pCTLOptions)
{
m_pCTLOptions = new SvtCTLOptions;
m_pCTLOptions->AddListener(this);
}
return *m_pCTLOptions;
}
SvtUserOptions& SwModule::GetUserOptions()
{
if(!m_pUserOptions)
{
m_pUserOptions = new SvtUserOptions;
m_pUserOptions->AddListener(this);
}
return *m_pUserOptions;
}
const SwMasterUsrPref *SwModule::GetUsrPref(bool bWeb) const
{
SwModule* pNonConstModule = const_cast<SwModule*>(this);
if(bWeb && !m_pWebUsrPref)
{
// The SpellChecker is needed in SwMasterUsrPref's Load, but it must not
// be created there #58256#
pNonConstModule->m_pWebUsrPref = new SwMasterUsrPref(true);
}
else if(!bWeb && !m_pUsrPref)
{
pNonConstModule->m_pUsrPref = new SwMasterUsrPref(false);
}
return bWeb ? m_pWebUsrPref : m_pUsrPref;
}
void NewXForms( SfxRequest& rReq )
{
// copied & excerpted from SwModule::InsertLab(..)
// create new document
SfxObjectShellLock xDocSh( new SwDocShell( SfxObjectCreateMode::STANDARD) );
xDocSh->DoInitNew();
// initialize XForms
static_cast<SwDocShell*>( &xDocSh )->GetDoc()->initXForms( true );
// load document into frame
SfxViewFrame::DisplayNewDocument( *xDocSh, rReq );
// set return value
rReq.SetReturnValue( SfxVoidItem( rReq.GetSlot() ) );
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
↑ V522 There might be dereferencing of a potential null pointer 'pNewView'.