summaryrefslogtreecommitdiffstats
path: root/sfx2/source/dialog/basedlgs.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sfx2/source/dialog/basedlgs.cxx')
-rw-r--r--sfx2/source/dialog/basedlgs.cxx329
1 files changed, 329 insertions, 0 deletions
diff --git a/sfx2/source/dialog/basedlgs.cxx b/sfx2/source/dialog/basedlgs.cxx
new file mode 100644
index 000000000..0604f035b
--- /dev/null
+++ b/sfx2/source/dialog/basedlgs.cxx
@@ -0,0 +1,329 @@
+/* -*- 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 <vcl/help.hxx>
+#include <svl/eitem.hxx>
+#include <unotools/viewoptions.hxx>
+#include <vcl/idle.hxx>
+
+#include <sfx2/basedlgs.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/childwin.hxx>
+#include <sfx2/viewsh.hxx>
+#include <workwin.hxx>
+#include <comphelper/lok.hxx>
+
+using namespace ::com::sun::star::uno;
+
+constexpr OUStringLiteral USERITEM_NAME = u"UserItem";
+
+class SfxModelessDialog_Impl : public SfxListener
+{
+public:
+ OString aWinState;
+ SfxChildWindow* pMgr;
+ bool bClosing;
+ void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;
+
+ Idle aMoveIdle { "SfxModelessDialog_Impl aMoveIdle" };
+};
+
+void SfxModelessDialog_Impl::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if (pMgr && rHint.GetId() == SfxHintId::Dying) {
+ pMgr->Destroy();
+ }
+}
+
+void SfxModelessDialogController::Initialize(SfxChildWinInfo const *pInfo)
+
+/* [Description]
+
+ Initialization of the class SfxModelessDialog via a SfxChildWinInfo.
+ The initialization is done only in a 2nd step after the constructor, this
+ constructor should be called from the derived class or from the
+ SfxChildWindows.
+*/
+
+{
+ if (!pInfo)
+ return;
+ m_xImpl->aWinState = pInfo->aWinState;
+ if (m_xImpl->aWinState.isEmpty())
+ return;
+ m_xDialog->set_window_state(m_xImpl->aWinState);
+}
+
+SfxModelessDialogController::SfxModelessDialogController(SfxBindings* pBindinx,
+ SfxChildWindow *pCW, weld::Window *pParent, const OUString& rUIXMLDescription,
+ const OString& rID)
+ : SfxDialogController(pParent, rUIXMLDescription, rID)
+{
+ Init(pBindinx, pCW);
+}
+
+/* [Description]
+
+ Fills a SfxChildWinInfo with specific data from SfxModelessDialog,
+ so that it can be written in the INI file. It is assumed that rinfo
+ receives all other possible relevant data in the ChildWindow class.
+ ModelessDialogs have no specific information, so that the base
+ implementation does nothing and therefore must not be called.
+*/
+void SfxModelessDialogController::FillInfo(SfxChildWinInfo& rInfo) const
+{
+ rInfo.aSize = m_xDialog->get_size();
+}
+
+void SfxModelessDialogController::Init(SfxBindings *pBindinx, SfxChildWindow *pCW)
+{
+ m_pBindings = pBindinx;
+ m_xImpl.reset(new SfxModelessDialog_Impl);
+ m_xImpl->pMgr = pCW;
+ m_xImpl->bClosing = false;
+ if (pBindinx)
+ m_xImpl->StartListening( *pBindinx );
+}
+
+/* [Description]
+
+ If a ModelessDialog is enabled its ViewFrame will be activated.
+ This is necessary by PluginInFrames.
+*/
+IMPL_LINK_NOARG(SfxDialogController, FocusChangeHdl, weld::Container&, void)
+{
+ if (m_xDialog->has_toplevel_focus())
+ Activate();
+ else
+ Deactivate();
+}
+
+void SfxModelessDialogController::Activate()
+{
+ if (!m_xImpl || !m_xImpl->pMgr)
+ return;
+ m_pBindings->SetActiveFrame(m_xImpl->pMgr->GetFrame());
+ m_xImpl->pMgr->Activate_Impl();
+}
+
+void SfxModelessDialogController::Deactivate()
+{
+ if (!m_xImpl)
+ return;
+ m_pBindings->SetActiveFrame(css::uno::Reference< css::frame::XFrame>());
+}
+
+SfxModelessDialogController::~SfxModelessDialogController()
+{
+ if (!m_xImpl->pMgr)
+ return;
+ auto xFrame = m_xImpl->pMgr->GetFrame();
+ if (!xFrame)
+ return;
+ if (xFrame == m_pBindings->GetActiveFrame())
+ m_pBindings->SetActiveFrame(nullptr);
+}
+
+void SfxDialogController::EndDialog(int nResponse)
+{
+ if (!m_xDialog->get_visible())
+ return;
+ response(nResponse);
+}
+
+bool SfxModelessDialogController::IsClosing() const
+{
+ return m_xImpl->bClosing;
+}
+
+void SfxModelessDialogController::EndDialog(int nResponse)
+{
+ if (m_xImpl->bClosing)
+ return;
+ // In the case of async dialogs, the call to SfxDialogController::EndDialog
+ // may delete this object, so keep myself alive for the duration of this
+ // stack frame.
+ auto aHoldSelf = shared_from_this();
+ m_xImpl->bClosing = true;
+ SfxDialogController::EndDialog(nResponse);
+ if (!m_xImpl)
+ return;
+ m_xImpl->bClosing = false;
+}
+
+void SfxModelessDialogController::ChildWinDispose()
+{
+ if (m_xImpl->pMgr)
+ {
+ WindowStateMask nMask = WindowStateMask::Pos | WindowStateMask::State;
+ if (m_xDialog->get_resizable())
+ nMask |= WindowStateMask::Size;
+ m_xImpl->aWinState = m_xDialog->get_window_state(nMask);
+ GetBindings().GetWorkWindow_Impl()->ConfigChild_Impl( SfxChildIdentifier::DOCKINGWINDOW, SfxDockingConfig::ALIGNDOCKINGWINDOW, m_xImpl->pMgr->GetType() );
+ }
+
+ m_xImpl->pMgr = nullptr;
+}
+
+/* [Description]
+
+ The window is closed when the ChildWindow is destroyed by running the
+ ChildWindow-slots.
+*/
+void SfxModelessDialogController::Close()
+{
+ if (m_xImpl->bClosing)
+ return;
+ // Execute with Parameters, since Toggle is ignored by some ChildWindows.
+ SfxBoolItem aValue(m_xImpl->pMgr->GetType(), false);
+ m_pBindings->GetDispatcher_Impl()->ExecuteList(
+ m_xImpl->pMgr->GetType(),
+ SfxCallMode::RECORD|SfxCallMode::SYNCHRON, { &aValue } );
+ SfxDialogController::Close();
+}
+
+SfxDialogController::SfxDialogController(weld::Widget* pParent, const OUString& rUIFile,
+ const OString& rDialogId)
+ : GenericDialogController(pParent, rUIFile, rDialogId,
+ comphelper::LibreOfficeKit::isActive()
+ && SfxViewShell::Current()
+ && SfxViewShell::Current()->isLOKMobilePhone())
+{
+ m_xDialog->SetInstallLOKNotifierHdl(LINK(this, SfxDialogController, InstallLOKNotifierHdl));
+ m_xDialog->connect_container_focus_changed(LINK(this, SfxDialogController, FocusChangeHdl));
+}
+
+void SfxDialogController::Close()
+{
+ // tdf3146571 ignore focus changes after we've closed
+ m_xDialog->connect_container_focus_changed(Link<weld::Container&, void>());
+}
+
+IMPL_STATIC_LINK_NOARG(SfxDialogController, InstallLOKNotifierHdl, void*, vcl::ILibreOfficeKitNotifier*)
+{
+ return SfxViewShell::Current();
+}
+
+SfxSingleTabDialogController::SfxSingleTabDialogController(weld::Widget *pParent, const SfxItemSet* pSet,
+ const OUString& rUIXMLDescription, const OString& rID)
+ : SfxOkDialogController(pParent, rUIXMLDescription, rID)
+ , m_pInputSet(pSet)
+ , m_xContainer(m_xDialog->weld_content_area())
+ , m_xOKBtn(m_xBuilder->weld_button("ok"))
+ , m_xHelpBtn(m_xBuilder->weld_button("help"))
+{
+ m_xOKBtn->connect_clicked(LINK(this, SfxSingleTabDialogController, OKHdl_Impl));
+}
+
+SfxSingleTabDialogController::~SfxSingleTabDialogController()
+{
+}
+
+/* [Description]
+
+ Insert a (new) TabPage; an existing page is deleted.
+ The passed on page is initialized with the initially given Itemset
+ through calling Reset().
+*/
+void SfxSingleTabDialogController::SetTabPage(std::unique_ptr<SfxTabPage> xTabPage)
+{
+ m_xSfxPage = std::move(xTabPage);
+ if (!m_xSfxPage)
+ return;
+
+ // First obtain the user data, only then Reset()
+ OUString sConfigId = OStringToOUString(m_xSfxPage->GetConfigId(), RTL_TEXTENCODING_UTF8);
+ SvtViewOptions aPageOpt(EViewType::TabPage, sConfigId);
+ Any aUserItem = aPageOpt.GetUserItem( USERITEM_NAME );
+ OUString sUserData;
+ aUserItem >>= sUserData;
+ m_xSfxPage->SetUserData(sUserData);
+ m_xSfxPage->Reset(GetInputItemSet());
+
+ m_xHelpBtn->set_visible(Help::IsContextHelpEnabled());
+
+ // Set TabPage text in the Dialog if there is any
+ OUString sTitle(m_xSfxPage->GetPageTitle());
+ if (!sTitle.isEmpty())
+ m_xDialog->set_title(sTitle);
+
+ // Dialog receives the HelpId of TabPage if there is any
+ OString sHelpId(m_xSfxPage->GetHelpId());
+ if (!sHelpId.isEmpty())
+ m_xDialog->set_help_id(sHelpId);
+}
+
+/* [Description]
+
+ Ok_Handler; FillItemSet() is called for setting of Page.
+*/
+IMPL_LINK_NOARG(SfxSingleTabDialogController, OKHdl_Impl, weld::Button&, void)
+{
+ const SfxItemSet* pInputSet = GetInputItemSet();
+ if (!pInputSet)
+ {
+ // TabPage without ItemSet
+ m_xDialog->response(RET_OK);
+ return;
+ }
+
+ if (!GetOutputItemSet())
+ {
+ CreateOutputItemSet(*pInputSet);
+ }
+
+ bool bModified = false;
+
+ if (m_xSfxPage->HasExchangeSupport())
+ {
+ DeactivateRC nRet = m_xSfxPage->DeactivatePage(m_xOutputSet.get());
+ if (nRet != DeactivateRC::LeavePage)
+ return;
+ else
+ bModified = m_xOutputSet->Count() > 0;
+ }
+ else
+ bModified = m_xSfxPage->FillItemSet(m_xOutputSet.get());
+
+ if (bModified)
+ {
+ // Save user data in IniManager.
+ m_xSfxPage->FillUserData();
+ OUString sData(m_xSfxPage->GetUserData());
+
+ OUString sConfigId = OStringToOUString(m_xSfxPage->GetConfigId(),
+ RTL_TEXTENCODING_UTF8);
+ SvtViewOptions aPageOpt(EViewType::TabPage, sConfigId);
+ aPageOpt.SetUserItem( USERITEM_NAME, Any( sData ) );
+ m_xDialog->response(RET_OK);
+ }
+ else
+ m_xDialog->response(RET_CANCEL);
+}
+
+void SfxSingleTabDialogController::CreateOutputItemSet(const SfxItemSet& rSet)
+{
+ assert(!m_xOutputSet && "Double creation of OutputSet!");
+ m_xOutputSet.reset(new SfxItemSet(rSet));
+ m_xOutputSet->ClearItem();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */