summaryrefslogtreecommitdiffstats
path: root/cui/source/tabpages/macroass.cxx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--cui/source/tabpages/macroass.cxx397
1 files changed, 397 insertions, 0 deletions
diff --git a/cui/source/tabpages/macroass.cxx b/cui/source/tabpages/macroass.cxx
new file mode 100644
index 000000000..e80e471ff
--- /dev/null
+++ b/cui/source/tabpages/macroass.cxx
@@ -0,0 +1,397 @@
+/* -*- 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 <macroass.hxx>
+#include <o3tl/safeint.hxx>
+#include <o3tl/string_view.hxx>
+#include <osl/diagnose.h>
+#include <comphelper/string.hxx>
+#include <comphelper/processfactory.hxx>
+#include <svl/macitem.hxx>
+#include <svx/svxids.hrc>
+#include <tools/debug.hxx>
+#include <vcl/idle.hxx>
+#include <cfgutil.hxx>
+#include <sfx2/evntconf.hxx>
+#include <headertablistbox.hxx>
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::frame::XFrame;
+
+class SfxMacroTabPage_Impl
+{
+public:
+ SfxMacroTabPage_Impl();
+
+ OUString m_aStaticMacroLBLabel;
+ std::unique_ptr<weld::Button> m_xAssignPB;
+ std::unique_ptr<weld::Button> m_xDeletePB;
+ std::unique_ptr<MacroEventListBox> m_xEventLB;
+ std::unique_ptr<weld::Widget> m_xGroupFrame;
+ std::unique_ptr<CuiConfigGroupListBox> m_xGroupLB;
+ std::unique_ptr<weld::Frame> m_xMacroFrame;
+ std::unique_ptr<CuiConfigFunctionListBox> m_xMacroLB;
+
+ Idle m_aFillGroupIdle { "cui SfxMacroTabPage m_aFillGroupIdle" };
+ bool m_bGotEvents;
+};
+
+SfxMacroTabPage_Impl::SfxMacroTabPage_Impl()
+ : m_bGotEvents(false)
+{
+}
+
+static sal_uInt16 aPageRg[] = {
+ SID_ATTR_MACROITEM, SID_ATTR_MACROITEM,
+ 0
+};
+
+static OUString ConvertToUIName_Impl( SvxMacro const *pMacro )
+{
+ OUString aName( pMacro->GetMacName() );
+ if ( pMacro->GetLanguage() != "JavaScript" )
+ {
+ const sal_Int32 nCount = comphelper::string::getTokenCount(aName, '.');
+ OUString aEntry = aName.getToken( nCount-1, '.' );
+ if ( nCount > 2 )
+ {
+ aEntry += OUString::Concat("(") + o3tl::getToken(aName, 0, '.' ) + "." + o3tl::getToken(aName, nCount-2, '.' ) + ")";
+ }
+ return aEntry;
+ }
+ else
+ return aName;
+}
+
+void SfxMacroTabPage::EnableButtons()
+{
+ // don't do anything as long as the eventbox is empty
+ weld::TreeView& rTreeView = mpImpl->m_xEventLB->GetListBox();
+ int nSelected = rTreeView.get_selected_index();
+ if (nSelected != -1)
+ {
+ // get bound macro
+ const SvxMacro* pM = aTbl.Get(static_cast<SvMacroItemId>(rTreeView.get_selected_id().toInt32()));
+ mpImpl->m_xDeletePB->set_sensitive(nullptr != pM);
+
+ OUString sEventMacro = rTreeView.get_text(nSelected, 1);
+
+ OUString sScriptURI = mpImpl->m_xMacroLB->GetSelectedScriptURI();
+ mpImpl->m_xAssignPB->set_sensitive(!sScriptURI.equalsIgnoreAsciiCase(sEventMacro));
+ }
+ else
+ mpImpl->m_xAssignPB->set_sensitive(false);
+}
+
+SfxMacroTabPage::SfxMacroTabPage(weld::Container* pPage, weld::DialogController* pController, const Reference< XFrame >& rxDocumentFrame, const SfxItemSet& rAttrSet )
+ : SfxTabPage(pPage, pController, "cui/ui/eventassignpage.ui", "EventAssignPage", &rAttrSet)
+{
+ mpImpl.reset(new SfxMacroTabPage_Impl);
+
+ mpImpl->m_aFillGroupIdle.SetInvokeHandler( LINK( this, SfxMacroTabPage, TimeOut_Impl ) );
+ mpImpl->m_aFillGroupIdle.SetPriority( TaskPriority::HIGHEST );
+
+ mpImpl->m_xEventLB.reset(new MacroEventListBox(m_xBuilder->weld_tree_view("assignments")));
+ mpImpl->m_xAssignPB = m_xBuilder->weld_button("assign");
+ mpImpl->m_xDeletePB = m_xBuilder->weld_button("delete");
+ mpImpl->m_xGroupFrame = m_xBuilder->weld_widget("groupframe");
+ mpImpl->m_xGroupLB.reset(new CuiConfigGroupListBox(m_xBuilder->weld_tree_view("libraries")));
+ mpImpl->m_xMacroFrame = m_xBuilder->weld_frame("macroframe");
+ mpImpl->m_aStaticMacroLBLabel = mpImpl->m_xMacroFrame->get_label();
+ mpImpl->m_xMacroLB.reset(new CuiConfigFunctionListBox(m_xBuilder->weld_tree_view("macros")));
+
+ SetFrame( rxDocumentFrame );
+
+ InitAndSetHandler();
+
+ ScriptChanged();
+}
+
+SfxMacroTabPage::~SfxMacroTabPage()
+{
+ mpImpl.reset();
+}
+
+void SfxMacroTabPage::AddEvent(const OUString& rEventName, SvMacroItemId nEventId)
+{
+ weld::TreeView& rTreeView = mpImpl->m_xEventLB->GetListBox();
+ rTreeView.append(OUString::number(static_cast<sal_Int32>(nEventId)), rEventName);
+
+ // if the table is valid already
+ SvxMacro* pM = aTbl.Get(nEventId);
+ if (pM)
+ {
+ OUString sNew(ConvertToUIName_Impl(pM));
+ rTreeView.set_text(rTreeView.n_children() - 1, sNew, 1);
+ }
+}
+
+void SfxMacroTabPage::ScriptChanged()
+{
+ // get new areas and their functions
+ mpImpl->m_xGroupFrame->show();
+ mpImpl->m_xMacroFrame->show();
+
+ EnableButtons();
+}
+
+bool SfxMacroTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ SvxMacroItem aItem( GetWhich( aPageRg[0] ) );
+ const_cast<SvxMacroTableDtor&>(aItem.GetMacroTable()) = aTbl;
+
+ const SfxPoolItem* pItem = nullptr;
+ SfxItemState eState = GetItemSet().GetItemState(aItem.Which(), true, &pItem);
+ if (eState == SfxItemState::DEFAULT && aTbl.empty())
+ {
+ // Don't touch the item set if there was no input and our table is empty.
+ return false;
+ }
+ if (SfxItemState::SET != eState || aItem != *static_cast<const SvxMacroItem*>(pItem))
+ {
+ rSet->Put( aItem );
+ return true;
+ }
+ return false;
+}
+
+void SfxMacroTabPage::LaunchFillGroup()
+{
+ if (! mpImpl->m_aFillGroupIdle.IsActive() )
+ mpImpl->m_aFillGroupIdle.Start();
+}
+
+void SfxMacroTabPage::ActivatePage( const SfxItemSet& )
+{
+ LaunchFillGroup();
+}
+
+void SfxMacroTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ if( mpImpl->m_bGotEvents )
+ return;
+ if( const SfxEventNamesItem* pEventsItem = aSet.GetItemIfSet( SID_EVENTCONFIG ) )
+ {
+ mpImpl->m_bGotEvents = true;
+ const SfxEventNamesList& rList = pEventsItem->GetEvents();
+ for ( size_t nNo = 0, nCnt = rList.size(); nNo < nCnt; ++nNo )
+ {
+ const SfxEventName &rOwn = rList.at(nNo);
+ AddEvent( rOwn.maUIName, rOwn.mnId );
+ }
+ }
+}
+
+void SfxMacroTabPage::Reset( const SfxItemSet* rSet )
+{
+ const SfxPoolItem* pItem;
+ if( SfxItemState::SET == rSet->GetItemState( GetWhich( aPageRg[0] ), true, &pItem ))
+ aTbl = static_cast<const SvxMacroItem*>(pItem)->GetMacroTable();
+
+ const SfxEventNamesItem* pEventsItem;
+ if( !mpImpl->m_bGotEvents && (pEventsItem = rSet->GetItemIfSet( SID_EVENTCONFIG ) ) )
+ {
+ mpImpl->m_bGotEvents = true;
+ const SfxEventNamesList& rList = pEventsItem->GetEvents();
+ for ( size_t nNo = 0, nCnt = rList.size(); nNo < nCnt; ++nNo )
+ {
+ const SfxEventName &rOwn = rList.at(nNo);
+ AddEvent( rOwn.maUIName, rOwn.mnId );
+ }
+ }
+
+ FillEvents();
+
+ weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
+ std::unique_ptr<weld::TreeIter> xIter(rListBox.make_iterator());
+ if (rListBox.get_iter_first(*xIter))
+ rListBox.set_cursor(*xIter);
+}
+
+bool SfxMacroTabPage::IsReadOnly() const
+{
+ return false;
+}
+
+IMPL_LINK_NOARG(SfxMacroTabPage, SelectEvent_Impl, weld::TreeView&, void)
+{
+ weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
+ int nSelected = rListBox.get_selected_index();
+ if (nSelected == -1)
+ {
+ DBG_ASSERT(nSelected != -1, "Where does the empty entry come from?");
+ return;
+ }
+
+ ScriptChanged();
+ EnableButtons();
+}
+
+IMPL_LINK_NOARG(SfxMacroTabPage, SelectGroup_Impl, weld::TreeView&, void)
+{
+ mpImpl->m_xGroupLB->GroupSelected();
+ const OUString sScriptURI = mpImpl->m_xMacroLB->GetSelectedScriptURI();
+ OUString aLabelText;
+ if( !sScriptURI.isEmpty() )
+ aLabelText = mpImpl->m_aStaticMacroLBLabel;
+ mpImpl->m_xMacroFrame->set_label( aLabelText );
+
+ EnableButtons();
+}
+
+IMPL_LINK_NOARG(SfxMacroTabPage, SelectMacro_Impl, weld::TreeView&, void)
+{
+ EnableButtons();
+}
+
+IMPL_LINK(SfxMacroTabPage, AssignDeleteClickHdl_Impl, weld::Button&, rBtn, void)
+{
+ AssignDeleteHdl(&rBtn);
+}
+
+IMPL_LINK(SfxMacroTabPage, AssignDeleteHdl_Impl, weld::TreeView&, rBtn, bool)
+{
+ AssignDeleteHdl(&rBtn);
+ return true;
+}
+
+void SfxMacroTabPage::AssignDeleteHdl(const weld::Widget* pBtn)
+{
+ weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
+ int nSelected = rListBox.get_selected_index();
+ if (nSelected == -1)
+ {
+ DBG_ASSERT(nSelected != -1, "Where does the empty entry come from?");
+ return;
+ }
+
+ const bool bAssEnabled = pBtn != mpImpl->m_xDeletePB.get() && mpImpl->m_xAssignPB->get_sensitive();
+
+ // remove from the table
+ SvMacroItemId nEvent = static_cast<SvMacroItemId>(rListBox.get_selected_id().toInt32());
+ aTbl.Erase( nEvent );
+
+ OUString sScriptURI;
+ if( bAssEnabled )
+ {
+ sScriptURI = mpImpl->m_xMacroLB->GetSelectedScriptURI();
+ if( sScriptURI.startsWith( "vnd.sun.star.script:" ) )
+ {
+ aTbl.Insert(
+ nEvent, SvxMacro( sScriptURI, SVX_MACRO_LANGUAGE_SF ) );
+ }
+ else
+ {
+ OSL_ENSURE( false, "SfxMacroTabPage::AssignDeleteHdl_Impl: this branch is *not* dead? (out of interest: tell fs, please!)" );
+ aTbl.Insert(
+ nEvent, SvxMacro( sScriptURI, SVX_MACRO_LANGUAGE_STARBASIC ) );
+ }
+ }
+
+ rListBox.set_text(nSelected, sScriptURI, 1);
+
+ EnableButtons();
+}
+
+IMPL_LINK( SfxMacroTabPage, TimeOut_Impl, Timer*,, void )
+{
+ // FillMacroList() can take a long time -> show wait cursor and disable input
+ weld::Window* pDialog = GetFrameWeld();
+ // perhaps the tabpage is part of a SingleTabDialog then pDialog == nullptr
+ std::unique_ptr<weld::WaitObject> xWait(pDialog ? new weld::WaitObject(pDialog) : nullptr);
+ // fill macro list
+ mpImpl->m_xGroupLB->Init(comphelper::getProcessComponentContext(), GetFrame(),
+ OUString(), false);
+}
+
+void SfxMacroTabPage::InitAndSetHandler()
+{
+ weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
+ Link<weld::TreeView&,bool> aLnk(LINK(this, SfxMacroTabPage, AssignDeleteHdl_Impl));
+ mpImpl->m_xMacroLB->connect_row_activated( aLnk);
+ mpImpl->m_xDeletePB->connect_clicked(LINK(this, SfxMacroTabPage, AssignDeleteClickHdl_Impl));
+ mpImpl->m_xAssignPB->connect_clicked(LINK(this, SfxMacroTabPage, AssignDeleteClickHdl_Impl));
+ rListBox.connect_row_activated(aLnk);
+
+ rListBox.connect_changed(LINK(this, SfxMacroTabPage, SelectEvent_Impl));
+ mpImpl->m_xGroupLB->connect_changed(LINK(this, SfxMacroTabPage, SelectGroup_Impl));
+ mpImpl->m_xMacroLB->connect_changed(LINK(this, SfxMacroTabPage, SelectMacro_Impl));
+
+ std::vector<int> aWidths
+ {
+ o3tl::narrowing<int>(rListBox.get_approximate_digit_width() * 35)
+ };
+ rListBox.set_column_fixed_widths(aWidths);
+
+ mpImpl->m_xEventLB->show();
+
+ mpImpl->m_xEventLB->set_sensitive(true);
+ mpImpl->m_xGroupLB->set_sensitive(true);
+ mpImpl->m_xMacroLB->set_sensitive(true);
+
+ mpImpl->m_xGroupLB->SetFunctionListBox(mpImpl->m_xMacroLB.get());
+}
+
+void SfxMacroTabPage::FillEvents()
+{
+ weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
+
+ int nEntryCnt = rListBox.n_children();
+
+ // get events from the table and fill the EventListBox respectively
+ for (int n = 0 ; n < nEntryCnt; ++n)
+ {
+ OUString sOld = rListBox.get_text(n, 1);
+ OUString sNew;
+ SvMacroItemId nEventId = static_cast<SvMacroItemId>(rListBox.get_id(n).toInt32());
+ if (aTbl.IsKeyValid(nEventId))
+ sNew = ConvertToUIName_Impl(aTbl.Get(nEventId));
+
+ if (sOld == sNew)
+ continue;
+
+ rListBox.set_text(n, sNew, 1);
+ }
+}
+
+namespace
+{
+ std::unique_ptr<SfxMacroTabPage> CreateSfxMacroTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttrSet)
+ {
+ return std::make_unique<SfxMacroTabPage>( pPage, pController, nullptr, rAttrSet );
+ }
+}
+
+std::unique_ptr<SfxTabPage> SfxMacroTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return CreateSfxMacroTabPage(pPage, pController, *rAttrSet);
+}
+
+SfxMacroAssignDlg::SfxMacroAssignDlg(weld::Widget* pParent,
+ const Reference< XFrame >& rxDocumentFrame, const SfxItemSet& rSet)
+ : SfxSingleTabDialogController(pParent, &rSet,"cui/ui/eventassigndialog.ui",
+ "EventAssignDialog")
+{
+ std::unique_ptr<SfxMacroTabPage> xPage = CreateSfxMacroTabPage(get_content_area(), this, rSet);
+ xPage->SetFrame(rxDocumentFrame);
+ SetTabPage(std::move(xPage));
+ GetTabPage()->LaunchFillGroup();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */