2520 lines
102 KiB
C++
2520 lines
102 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
|
/*
|
|
* 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/.
|
|
*/
|
|
|
|
#include <sal/config.h>
|
|
|
|
#include <MacroManagerDialog.hxx>
|
|
|
|
#include <bitmaps.hlst>
|
|
#include <cfgutil.hxx>
|
|
#include <dialmgr.hxx>
|
|
#include <scriptdlg.hxx>
|
|
#include <strings.hrc>
|
|
#include <basctl/basctldllpublic.hxx>
|
|
#include <basctl/sbxitem.hxx>
|
|
#include <basctl/scriptdocument.hxx>
|
|
#include <basic/basmgr.hxx>
|
|
#include <comphelper/SetFlagContextHelper.hxx>
|
|
#include <comphelper/diagnose_ex.hxx>
|
|
#include <comphelper/documentinfo.hxx>
|
|
#include <comphelper/lok.hxx>
|
|
#include <comphelper/processfactory.hxx>
|
|
#include <osl/file.hxx>
|
|
#include <sfx2/app.hxx>
|
|
#include <sfx2/dispatch.hxx>
|
|
#include <sfx2/inputdlg.hxx>
|
|
#include <sfx2/minfitem.hxx>
|
|
#include <sfx2/request.hxx>
|
|
#include <sfx2/sfxsids.hrc>
|
|
#include <sfx2/viewfrm.hxx>
|
|
#include <svl/itemset.hxx>
|
|
#include <svl/stritem.hxx>
|
|
#include <svtools/imagemgr.hxx>
|
|
#include <svx/passwd.hxx>
|
|
#include <tools/urlobj.hxx>
|
|
#include <unotools/viewoptions.hxx>
|
|
#include <vcl/commandevent.hxx>
|
|
#include <vcl/weldutils.hxx>
|
|
|
|
#include <com/sun/star/beans/XPropertySet.hpp>
|
|
#include <com/sun/star/container/XEnumerationAccess.hpp>
|
|
#include <com/sun/star/container/XEnumeration.hpp>
|
|
#include <com/sun/star/frame/Desktop.hpp>
|
|
#include <com/sun/star/document/XEmbeddedScripts.hpp>
|
|
#include <com/sun/star/document/XScriptInvocationContext.hpp>
|
|
#include <com/sun/star/frame/ModuleManager.hpp>
|
|
#include <com/sun/star/frame/XFrame.hpp>
|
|
#include <com/sun/star/frame/XModel.hpp>
|
|
#include <com/sun/star/script/browse/XBrowseNode.hpp>
|
|
#include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
|
|
#include <com/sun/star/script/browse/theBrowseNodeFactory.hpp>
|
|
#include <com/sun/star/script/browse/BrowseNodeFactoryViewTypes.hpp>
|
|
#include <com/sun/star/script/XLibraryContainer2.hpp>
|
|
#include <com/sun/star/script/XLibraryContainerPassword.hpp>
|
|
#include <com/sun/star/script/XPersistentLibraryContainer.hpp>
|
|
#include <com/sun/star/script/XInvocation.hpp>
|
|
#include <com/sun/star/uno/RuntimeException.hpp>
|
|
|
|
ScriptsListBox::ScriptsListBox(std::unique_ptr<weld::TreeView> xTreeView)
|
|
: m_xTreeView(std::move(xTreeView))
|
|
, m_xScratchIter(m_xTreeView->make_iterator())
|
|
{
|
|
m_xTreeView->make_sorted();
|
|
m_xTreeView->set_size_request(m_xTreeView->get_approximate_digit_width() * 35,
|
|
m_xTreeView->get_height_rows(9));
|
|
m_xTreeView->connect_query_tooltip(LINK(this, ScriptsListBox, QueryTooltip));
|
|
}
|
|
|
|
ScriptsListBox::~ScriptsListBox() { ClearAll(); }
|
|
|
|
void ScriptsListBox::ClearAll()
|
|
{
|
|
sal_uInt16 nCount = aArr.size();
|
|
for (sal_uInt16 i = 0; i < nCount; ++i)
|
|
{
|
|
ScriptInfo* pScriptInfo = aArr[i].get();
|
|
if (pScriptInfo && pScriptInfo->pBrowseNode)
|
|
pScriptInfo->pBrowseNode->release();
|
|
}
|
|
aArr.clear();
|
|
m_xTreeView->clear();
|
|
}
|
|
|
|
void ScriptsListBox::Remove(const weld::TreeIter& rEntry)
|
|
{
|
|
ScriptInfo* pScriptInfo = weld::fromId<ScriptInfo*>(m_xTreeView->get_id(rEntry));
|
|
if (pScriptInfo)
|
|
{
|
|
if (pScriptInfo->pBrowseNode)
|
|
pScriptInfo->pBrowseNode->release();
|
|
for (auto it = aArr.begin(); it != aArr.end(); ++it)
|
|
{
|
|
if ((*it).get() == pScriptInfo)
|
|
{
|
|
aArr.erase(it);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
m_xTreeView->remove(rEntry);
|
|
}
|
|
|
|
OUString ScriptsListBox::GetDescriptionText(const OUString& rId)
|
|
{
|
|
ScriptInfo* pScriptInfo = weld::fromId<ScriptInfo*>(rId);
|
|
if (pScriptInfo)
|
|
{
|
|
return pScriptInfo->sDescription;
|
|
}
|
|
return OUString();
|
|
}
|
|
|
|
OUString ScriptsListBox::GetSelectedScriptName()
|
|
{
|
|
std::unique_ptr<weld::TreeIter> xScriptsEntryIter = m_xTreeView->make_iterator();
|
|
if (!m_xTreeView->get_selected(xScriptsEntryIter.get()))
|
|
return OUString();
|
|
return m_xTreeView->get_text(*xScriptsEntryIter);
|
|
}
|
|
|
|
IMPL_LINK(ScriptsListBox, QueryTooltip, const weld::TreeIter&, rEntryIter, OUString)
|
|
{
|
|
return GetDescriptionText(m_xTreeView->get_id(rEntryIter));
|
|
}
|
|
|
|
ScriptContainersListBox::ScriptContainersListBox(std::unique_ptr<weld::TreeView> xTreeView,
|
|
MacroManagerDialog* pMacroManagerDialog)
|
|
: m_pScriptsListBox(nullptr)
|
|
, m_xTreeView(std::move(xTreeView))
|
|
, m_pMacroManagerDialog(pMacroManagerDialog)
|
|
{
|
|
m_xTreeView->set_size_request(m_xTreeView->get_approximate_digit_width() * 35,
|
|
m_xTreeView->get_height_rows(9));
|
|
m_xTreeView->connect_expanding(LINK(this, ScriptContainersListBox, ExpandingHdl));
|
|
m_xTreeView->connect_query_tooltip(LINK(this, ScriptContainersListBox, QueryTooltip));
|
|
}
|
|
|
|
ScriptContainersListBox::~ScriptContainersListBox() { ClearAll(); }
|
|
|
|
void ScriptContainersListBox::ClearAll()
|
|
{
|
|
sal_uInt16 nCount = m_xTreeView->n_children();
|
|
for (sal_uInt16 i = 0; i < nCount; ++i)
|
|
{
|
|
ScriptContainerInfo* pScriptContainerInfo
|
|
= weld::fromId<ScriptContainerInfo*>(m_xTreeView->get_id(i));
|
|
if (pScriptContainerInfo)
|
|
{
|
|
if (pScriptContainerInfo->pBrowseNode)
|
|
pScriptContainerInfo->pBrowseNode->release();
|
|
delete pScriptContainerInfo;
|
|
}
|
|
}
|
|
m_xTreeView->clear();
|
|
}
|
|
|
|
void ScriptContainersListBox::Init(const css::uno::Reference<css::uno::XComponentContext>& xContext,
|
|
const css::uno::Reference<css::frame::XFrame>& xFrame)
|
|
{
|
|
m_xContext = xContext;
|
|
m_xFrame = xFrame;
|
|
m_xTreeView->freeze();
|
|
Fill(nullptr);
|
|
m_xTreeView->thaw();
|
|
m_xTreeView->set_cursor(0);
|
|
}
|
|
|
|
void ScriptContainersListBox::Remove(const weld::TreeIter* pEntryIter, bool bRemoveEntryIter)
|
|
{
|
|
// remove all children of pEntryIter
|
|
std::unique_ptr<weld::TreeIter> xIter = m_xTreeView->make_iterator(pEntryIter);
|
|
if (m_xTreeView->iter_has_child(*pEntryIter) && m_xTreeView->iter_children(*xIter))
|
|
{
|
|
// set xIter to the last child of pEntryIter
|
|
do
|
|
{
|
|
std::unique_ptr<weld::TreeIter> xChildIter = m_xTreeView->make_iterator(xIter.get());
|
|
while (m_xTreeView->iter_next_sibling(*xChildIter))
|
|
m_xTreeView->copy_iterator(*xChildIter, *xIter);
|
|
} while (m_xTreeView->iter_has_child(*xIter) && m_xTreeView->iter_children(*xIter));
|
|
|
|
// children must be removed from the tree in reverse order
|
|
std::unique_ptr<weld::TreeIter> xRemoveIter = m_xTreeView->make_iterator();
|
|
while (m_xTreeView->iter_compare(*xIter, *pEntryIter) != 0)
|
|
{
|
|
m_xTreeView->copy_iterator(*xIter, *xRemoveIter);
|
|
(void)m_xTreeView->iter_previous(*xIter);
|
|
ScriptContainerInfo* pScriptContainerInfo
|
|
= weld::fromId<ScriptContainerInfo*>(m_xTreeView->get_id(*xRemoveIter));
|
|
if (pScriptContainerInfo)
|
|
{
|
|
if (pScriptContainerInfo->pBrowseNode)
|
|
pScriptContainerInfo->pBrowseNode->release();
|
|
delete pScriptContainerInfo;
|
|
}
|
|
m_xTreeView->remove(*xRemoveIter);
|
|
}
|
|
}
|
|
|
|
// maybe remove the entry
|
|
if (bRemoveEntryIter)
|
|
{
|
|
ScriptContainerInfo* pScriptContainerInfo
|
|
= weld::fromId<ScriptContainerInfo*>(m_xTreeView->get_id(*pEntryIter));
|
|
if (pScriptContainerInfo)
|
|
{
|
|
if (pScriptContainerInfo->pBrowseNode)
|
|
pScriptContainerInfo->pBrowseNode->release();
|
|
delete pScriptContainerInfo;
|
|
}
|
|
m_xTreeView->remove(*pEntryIter);
|
|
}
|
|
}
|
|
|
|
// inspired by CuiConfigGroupListBox::FillScriptList
|
|
// cui/source/customize/cfgutil.cxx
|
|
void ScriptContainersListBox::Fill(const weld::TreeIter* pEntryIter)
|
|
{
|
|
weld::WaitObject aWait(m_pMacroManagerDialog->getDialog());
|
|
|
|
css::uno::Reference<css::script::browse::XBrowseNode> xNode;
|
|
if (pEntryIter == nullptr)
|
|
{
|
|
ClearAll();
|
|
try
|
|
{
|
|
css::uno::Reference<css::script::browse::XBrowseNodeFactory> xFac
|
|
= css::script::browse::theBrowseNodeFactory::get(
|
|
comphelper::getProcessComponentContext());
|
|
xNode.set(
|
|
xFac->createView(css::script::browse::BrowseNodeFactoryViewTypes::MACROORGANIZER));
|
|
}
|
|
catch (const css::uno::Exception&)
|
|
{
|
|
TOOLS_WARN_EXCEPTION(
|
|
"cui.dialogs", "Caught some exception whilst retrieving browse nodes from factory");
|
|
// TODO exception handling
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ScriptContainerInfo* pScriptContainerInfoEntry
|
|
= weld::fromId<ScriptContainerInfo*>(m_xTreeView->get_id(*pEntryIter));
|
|
|
|
xNode.set(pScriptContainerInfoEntry->pBrowseNode);
|
|
|
|
Remove(pEntryIter, /*bRemoveEntryIter*/ false);
|
|
}
|
|
|
|
if (xNode->hasChildNodes())
|
|
{
|
|
// tdf#120362: Don't ask to enable disabled Java when filling script list
|
|
css::uno::ContextLayer layer(comphelper::NoEnableJavaInteractionContext());
|
|
|
|
bool bIsRootNode = false;
|
|
|
|
OUString user(u"user"_ustr);
|
|
OUString share(u"share"_ustr);
|
|
OUString uno_packages(u"uno_packages"_ustr);
|
|
if (xNode->getName() == "Root")
|
|
{
|
|
bIsRootNode = true;
|
|
}
|
|
|
|
//To mimic current starbasic behaviour we
|
|
//need to make sure that only the current document
|
|
//is displayed in the config tree. Tests below
|
|
//set the bDisplay flag to FALSE if the current
|
|
//node is a first level child of the Root and is NOT
|
|
//either the current document, user or share
|
|
//
|
|
// NOTE: This approach doesn't work for open documents with the same name, for example
|
|
// Untitled 1.odt and Untitled 1.ods will both be included as root containers.
|
|
OUString currentDocTitle;
|
|
if (css::uno::Reference<css::frame::XController> xController = m_xFrame->getController();
|
|
xController.is())
|
|
{
|
|
css::uno::Reference<css::frame::XModel> xModel = xController->getModel();
|
|
if (xModel.is())
|
|
currentDocTitle = comphelper::DocumentInfo::getDocumentTitle(xModel);
|
|
}
|
|
|
|
const css::uno::Sequence<css::uno::Reference<css::script::browse::XBrowseNode>> children
|
|
= xNode->getChildNodes();
|
|
for (css::uno::Reference<css::script::browse::XBrowseNode> const& theChild : children)
|
|
{
|
|
if (!theChild.is())
|
|
continue;
|
|
|
|
if (theChild->getType() == css::script::browse::BrowseNodeTypes::SCRIPT)
|
|
// we only want containers in this list box
|
|
continue;
|
|
if (theChild->getName() == uno_packages)
|
|
continue;
|
|
|
|
OUString uiName = theChild->getName();
|
|
if (bIsRootNode)
|
|
{
|
|
if (uiName == user)
|
|
{
|
|
uiName = CuiResId(RID_CUISTR_MYMACROS);
|
|
}
|
|
else if (uiName == share)
|
|
{
|
|
uiName = CuiResId(RID_CUISTR_PRODMACROS);
|
|
}
|
|
else if (uiName != currentDocTitle)
|
|
{
|
|
// as noted above
|
|
// NOTE: This approach doesn't work for open documents with the same name, for
|
|
// example, Untitled 1.odt and Untitled 1.ods will both be included as root
|
|
// containers.
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// We call acquire on the XBrowseNode so that it does not
|
|
// get autodestructed and become invalid when accessed later.
|
|
theChild->acquire();
|
|
|
|
bool bChildOnDemand = false;
|
|
|
|
if (theChild->hasChildNodes())
|
|
{
|
|
const css::uno::Sequence<css::uno::Reference<css::script::browse::XBrowseNode>>
|
|
grandchildren = theChild->getChildNodes();
|
|
for (const auto& rxNode : grandchildren)
|
|
{
|
|
if (!rxNode.is())
|
|
continue;
|
|
if (rxNode->getType() == css::script::browse::BrowseNodeTypes::CONTAINER)
|
|
{
|
|
bChildOnDemand = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
OUString aImage = CuiConfigGroupListBox::GetImage(theChild, m_xContext, bIsRootNode);
|
|
Insert(theChild, pEntryIter, uiName, aImage, bChildOnDemand);
|
|
}
|
|
}
|
|
|
|
// add Basic dialogs
|
|
if (pEntryIter && m_xTreeView->get_iter_depth(*pEntryIter) == 2) // library
|
|
{
|
|
// parent node of entry node is a language node
|
|
std::unique_ptr<weld::TreeIter> xIter = m_xTreeView->make_iterator(pEntryIter);
|
|
m_xTreeView->iter_parent(*xIter); // language
|
|
if (m_xTreeView->get_text(*xIter) == "Basic")
|
|
{
|
|
basctl::ScriptDocument aDocument = GetScriptDocument(pEntryIter);
|
|
if (!aDocument.isAlive())
|
|
{
|
|
return;
|
|
}
|
|
|
|
OUString aLibName = m_xTreeView->get_text(*pEntryIter);
|
|
|
|
css::uno::Reference<css::script::XLibraryContainer> xDlgLibContainer(
|
|
aDocument.getLibraryContainer(basctl::E_DIALOGS));
|
|
|
|
if (xDlgLibContainer.is() && xDlgLibContainer->hasByName(aLibName)
|
|
&& !xDlgLibContainer->isLibraryLoaded(aLibName))
|
|
{
|
|
xDlgLibContainer->loadLibrary(aLibName);
|
|
}
|
|
|
|
if (!(xDlgLibContainer.is() && xDlgLibContainer->hasByName(aLibName)
|
|
&& xDlgLibContainer->isLibraryLoaded(aLibName)))
|
|
{
|
|
return;
|
|
}
|
|
|
|
for (const OUString& rDlgName : aDocument.getObjectNames(basctl::E_DIALOGS, aLibName))
|
|
{
|
|
Insert(nullptr, pEntryIter, rDlgName, RID_CUIBMP_DIALOG, false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ScriptContainersListBox::Insert(
|
|
const css::uno::Reference<css::script::browse::XBrowseNode>& xInsertNode,
|
|
const weld::TreeIter* pIter, const OUString& rsUiName, const OUString& rsImage,
|
|
bool bChildOnDemand, int nPos, weld::TreeIter* pRet)
|
|
{
|
|
std::unique_ptr<weld::TreeIter> xNewEntryIter = m_xTreeView->make_iterator();
|
|
|
|
OUString sId(weld::toId(new ScriptContainerInfo(xInsertNode.get())));
|
|
m_xTreeView->insert(pIter, nPos, &rsUiName, &sId, nullptr, nullptr, bChildOnDemand,
|
|
xNewEntryIter.get());
|
|
m_xTreeView->set_image(*xNewEntryIter, rsImage);
|
|
|
|
// set password and linked image only for Basic libraries
|
|
if (m_xTreeView->get_iter_depth(*xNewEntryIter) == 2) // library
|
|
{
|
|
std::unique_ptr<weld::TreeIter> xLanguageIter
|
|
= m_xTreeView->make_iterator(xNewEntryIter.get());
|
|
m_xTreeView->iter_parent(*xLanguageIter);
|
|
if (m_xTreeView->get_text(*xLanguageIter) == "Basic")
|
|
{
|
|
basctl::ScriptDocument aDocument = GetScriptDocument(xNewEntryIter.get());
|
|
if (!aDocument.isAlive())
|
|
return;
|
|
|
|
OUString aLibName = m_xTreeView->get_text(*xNewEntryIter);
|
|
|
|
css::uno::Reference<css::script::XLibraryContainer2> xModLibContainer(
|
|
aDocument.getLibraryContainer(basctl::E_SCRIPTS), css::uno::UNO_QUERY);
|
|
if (xModLibContainer.is() && xModLibContainer->hasByName(aLibName))
|
|
{
|
|
css::uno::Reference<css::script::XLibraryContainerPassword> xPasswd(
|
|
xModLibContainer, css::uno::UNO_QUERY);
|
|
if (xPasswd.is() && xPasswd->isLibraryPasswordProtected(aLibName))
|
|
{
|
|
// password protected
|
|
m_xTreeView->set_image(*xNewEntryIter, RID_CUIBMP_LOCKED);
|
|
}
|
|
else if (xModLibContainer->isLibraryLink(aLibName))
|
|
{
|
|
// linked
|
|
m_xTreeView->set_image(*xNewEntryIter, RID_CUIBMP_LINKED);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (pRet)
|
|
pRet = xNewEntryIter.get();
|
|
}
|
|
|
|
// fills the scripts list box
|
|
// inspired by code in void CommandCategoryListBox::addChildren
|
|
// cui/source/customize/CommandCategoryListBox.cxx
|
|
// and void CuiConfigGroupListBox::GroupSelected()
|
|
// cui/source/customize/cfgutil.cxx
|
|
void ScriptContainersListBox::ScriptContainerSelected()
|
|
{
|
|
std::unique_ptr<weld::TreeIter> xIter(m_xTreeView->make_iterator());
|
|
if (!m_xTreeView->get_selected(xIter.get()))
|
|
return;
|
|
|
|
m_pScriptsListBox->freeze();
|
|
m_pScriptsListBox->ClearAll();
|
|
|
|
if (!m_xTreeView->iter_has_child(*xIter) && !m_xTreeView->get_children_on_demand(*xIter))
|
|
{
|
|
// maybe the browse node has children and those children are most likely script nodes
|
|
ScriptContainerInfo* pScriptContainerInfo
|
|
= weld::fromId<ScriptContainerInfo*>(m_xTreeView->get_id(*xIter));
|
|
css::uno::Reference<css::script::browse::XBrowseNode> xBrowseNode(
|
|
pScriptContainerInfo->pBrowseNode);
|
|
try
|
|
{
|
|
if (xBrowseNode->hasChildNodes())
|
|
{
|
|
const css::uno::Sequence<css::uno::Reference<css::script::browse::XBrowseNode>>
|
|
children = xBrowseNode->getChildNodes();
|
|
|
|
for (const css::uno::Reference<css::script::browse::XBrowseNode>& childNode :
|
|
children)
|
|
{
|
|
if (!childNode.is())
|
|
continue;
|
|
|
|
if (childNode->getType() == css::script::browse::BrowseNodeTypes::SCRIPT)
|
|
{
|
|
css::uno::Reference<css::beans::XPropertySet> xPropSet(childNode,
|
|
css::uno::UNO_QUERY);
|
|
if (!xPropSet.is())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
OUString sURI;
|
|
try
|
|
{
|
|
css::uno::Any value = xPropSet->getPropertyValue(u"URI"_ustr);
|
|
value >>= sURI;
|
|
}
|
|
catch (css::uno::Exception&)
|
|
{
|
|
// do nothing, the URI will be empty
|
|
}
|
|
|
|
OUString sDescription;
|
|
try
|
|
{
|
|
css::uno::Any value = xPropSet->getPropertyValue(u"Description"_ustr);
|
|
value >>= sDescription;
|
|
}
|
|
catch (css::uno::Exception&)
|
|
{
|
|
// do nothing, the description will be empty
|
|
}
|
|
|
|
childNode->acquire();
|
|
|
|
m_pScriptsListBox->aArr.push_back(
|
|
std::make_unique<ScriptInfo>(childNode.get(), sURI, sDescription));
|
|
|
|
OUString sId(weld::toId(m_pScriptsListBox->aArr.back().get()));
|
|
m_pScriptsListBox->append(sId, childNode->getName(), RID_CUIBMP_MACRO);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (css::uno::RuntimeException&)
|
|
{
|
|
// do nothing, the entry will not be displayed in the UI
|
|
}
|
|
}
|
|
|
|
m_pScriptsListBox->thaw();
|
|
|
|
if (m_pScriptsListBox->n_children())
|
|
m_pScriptsListBox->select(0);
|
|
}
|
|
|
|
OUString ScriptContainersListBox::GetContainerName(const weld::TreeIter& rIter,
|
|
const ScriptContainerType eScriptContainerType)
|
|
{
|
|
weld::TreeView& rScriptContainersTreeView = *m_xTreeView;
|
|
std::unique_ptr<weld::TreeIter> xSelectedEntryIter
|
|
= rScriptContainersTreeView.make_iterator(&rIter);
|
|
|
|
std::unique_ptr<weld::TreeIter> xIter
|
|
= rScriptContainersTreeView.make_iterator(xSelectedEntryIter.get());
|
|
|
|
int nEntryDepth;
|
|
while ((nEntryDepth = rScriptContainersTreeView.get_iter_depth(*xIter)))
|
|
{
|
|
if ((nEntryDepth == 3 && eScriptContainerType == ScriptContainerType::MODULEORDIALOG)
|
|
|| (nEntryDepth == 2 && eScriptContainerType == ScriptContainerType::LIBRARY)
|
|
|| (nEntryDepth == 1 && eScriptContainerType == ScriptContainerType::LANGUAGE))
|
|
return rScriptContainersTreeView.get_text(*xIter);
|
|
rScriptContainersTreeView.iter_parent(*xIter);
|
|
}
|
|
if (eScriptContainerType == ScriptContainerType::LOCATION)
|
|
return rScriptContainersTreeView.get_text(*xIter);
|
|
|
|
return OUString();
|
|
}
|
|
|
|
OUString
|
|
ScriptContainersListBox::GetSelectedEntryContainerName(ScriptContainerType eScriptContainerType)
|
|
{
|
|
std::unique_ptr<weld::TreeIter> xSelectedEntryIter = m_xTreeView->make_iterator();
|
|
if (!m_xTreeView->get_selected(xSelectedEntryIter.get()))
|
|
return OUString(); // should never happen
|
|
return GetContainerName(*xSelectedEntryIter, eScriptContainerType);
|
|
}
|
|
|
|
IMPL_LINK(ScriptContainersListBox, QueryTooltip, const weld::TreeIter&, rEntryIter, OUString)
|
|
{
|
|
// for Basic library check for linked library
|
|
if (m_xTreeView->get_iter_depth(rEntryIter) == 2) // library
|
|
{
|
|
// language
|
|
std::unique_ptr<weld::TreeIter> xLanguageIter = m_xTreeView->make_iterator(&rEntryIter);
|
|
m_xTreeView->iter_parent(*xLanguageIter);
|
|
if (m_xTreeView->get_text(*xLanguageIter) == "Basic")
|
|
{
|
|
basctl::ScriptDocument aDocument = GetScriptDocument(&rEntryIter);
|
|
if (!aDocument.isAlive())
|
|
return OUString();
|
|
|
|
css::uno::Reference<css::script::XLibraryContainer2> xModLibContainer(
|
|
aDocument.getLibraryContainer(basctl::E_SCRIPTS), css::uno::UNO_QUERY);
|
|
// check for linked library
|
|
OUString aLibName = m_xTreeView->get_text(rEntryIter);
|
|
if (xModLibContainer.is() && xModLibContainer->hasByName(aLibName)
|
|
&& xModLibContainer->isLibraryLink(aLibName))
|
|
{
|
|
OUString aLinkURL = xModLibContainer->getLibraryLinkURL(aLibName);
|
|
osl::File::getSystemPathFromFileURL(aLinkURL, aLinkURL);
|
|
return aLinkURL;
|
|
}
|
|
}
|
|
}
|
|
return OUString();
|
|
}
|
|
|
|
IMPL_LINK(ScriptContainersListBox, ExpandingHdl, const weld::TreeIter&, rEntryIter, bool)
|
|
{
|
|
// for Basic library check for password protected
|
|
if (m_xTreeView->get_iter_depth(rEntryIter) == 2) // library
|
|
{
|
|
// language
|
|
std::unique_ptr<weld::TreeIter> xLanguageIter = m_xTreeView->make_iterator(&rEntryIter);
|
|
m_xTreeView->iter_parent(*xLanguageIter);
|
|
if (m_xTreeView->get_text(*xLanguageIter) == "Basic")
|
|
{
|
|
basctl::ScriptDocument aDocument = GetScriptDocument(&rEntryIter);
|
|
if (!aDocument.isAlive())
|
|
return false; // not expanded
|
|
|
|
OUString aLibName = m_xTreeView->get_text(rEntryIter);
|
|
|
|
// check if the library is password protected
|
|
css::uno::Reference<css::script::XLibraryContainer2> xModLibContainer(
|
|
aDocument.getLibraryContainer(basctl::E_SCRIPTS), css::uno::UNO_QUERY);
|
|
if (xModLibContainer.is() && xModLibContainer->hasByName(aLibName))
|
|
{
|
|
css::uno::Reference<css::script::XLibraryContainerPassword> xPasswd(
|
|
xModLibContainer, css::uno::UNO_QUERY);
|
|
if (xPasswd.is() && xPasswd->isLibraryPasswordProtected(aLibName)
|
|
&& !xPasswd->isLibraryPasswordVerified(aLibName))
|
|
{
|
|
// ensure selection before password dialog is shown
|
|
m_xTreeView->select(rEntryIter);
|
|
OUString sPassword;
|
|
if (!basctl::QueryPassword(m_pMacroManagerDialog->getDialog(), xModLibContainer,
|
|
aLibName, sPassword, true, true))
|
|
{
|
|
return false; // indicates the expansion of the row is refused
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (m_xTreeView->get_children_on_demand(rEntryIter))
|
|
{
|
|
Fill(&rEntryIter);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
MacroManagerDialog::MacroManagerDialog(weld::Window* pParent,
|
|
const css::uno::Reference<css::frame::XFrame>& xDocFrame)
|
|
: GenericDialogController(pParent, u"cui/ui/macromanagerdialog.ui"_ustr,
|
|
u"MacroManagerDialog"_ustr)
|
|
, m_xDocumentFrame(xDocFrame)
|
|
, m_xScriptContainersListBox(
|
|
new ScriptContainersListBox(m_xBuilder->weld_tree_view(u"scriptcontainers"_ustr), this))
|
|
, m_xScriptsListBox(new ScriptsListBox(m_xBuilder->weld_tree_view(u"scripts"_ustr)))
|
|
, m_xScriptContainersListBoxLabel(m_xBuilder->weld_label(u"scriptcontainerlistboxlabel"_ustr))
|
|
, m_xScriptsListBoxLabel(m_xBuilder->weld_label(u"scriptslistboxlabel"_ustr))
|
|
, m_xRunButton(m_xBuilder->weld_button(u"run"_ustr))
|
|
, m_xCloseButton(m_xBuilder->weld_button(u"close"_ustr))
|
|
, m_xDescriptionText(m_xBuilder->weld_text_view(u"description"_ustr))
|
|
, m_xDescriptionFrame(m_xBuilder->weld_frame(u"descriptionframe"_ustr))
|
|
, m_xNewLibraryButton(m_xBuilder->weld_button(u"newlibrary"_ustr))
|
|
, m_xNewModuleButton(m_xBuilder->weld_button(u"newmodule"_ustr))
|
|
, m_xNewDialogButton(m_xBuilder->weld_button(u"newdialog"_ustr))
|
|
, m_xLibraryModuleDialogEditButton(m_xBuilder->weld_button(u"librarymoduledialogedit"_ustr))
|
|
, m_xLibraryModuleDialogRenameButton(m_xBuilder->weld_button(u"librarymoduledialogrename"_ustr))
|
|
, m_xLibraryModuleDialogDeleteButton(m_xBuilder->weld_button(u"librarymoduledialogdelete"_ustr))
|
|
, m_xLibraryPasswordButton(m_xBuilder->weld_button(u"librarypassword"_ustr))
|
|
, m_xLibraryImportButton(m_xBuilder->weld_button(u"libraryimport"_ustr))
|
|
, m_xLibraryExportButton(m_xBuilder->weld_button(u"libraryexport"_ustr))
|
|
, m_xMacroEditButton(m_xBuilder->weld_button(u"macroedit"_ustr))
|
|
, m_xMacroDeleteButton(m_xBuilder->weld_button(u"macrodelete"_ustr))
|
|
, m_xMacroCreateButton(m_xBuilder->weld_button(u"macrocreate"_ustr))
|
|
, m_xMacroRenameButton(m_xBuilder->weld_button(u"macrorename"_ustr))
|
|
, m_xAssignButton(m_xBuilder->weld_button(u"assign"_ustr))
|
|
{
|
|
m_aScriptsListBoxLabelBaseStr = m_xScriptsListBoxLabel->get_label();
|
|
|
|
m_xScriptContainersListBox->SetScriptsListBox(m_xScriptsListBox.get());
|
|
m_xScriptContainersListBox->Init(comphelper::getProcessComponentContext(), m_xDocumentFrame);
|
|
|
|
m_xScriptContainersListBox->connect_changed(LINK(this, MacroManagerDialog, SelectHdl));
|
|
|
|
m_xScriptsListBox->connect_changed(LINK(this, MacroManagerDialog, SelectHdl));
|
|
m_xScriptsListBox->connect_row_activated(
|
|
LINK(this, MacroManagerDialog, FunctionDoubleClickHdl));
|
|
m_xScriptsListBox->connect_popup_menu(LINK(this, MacroManagerDialog, ContextMenuHdl));
|
|
|
|
m_xAssignButton->connect_clicked(LINK(this, MacroManagerDialog, ClickHdl));
|
|
m_xRunButton->connect_clicked(LINK(this, MacroManagerDialog, ClickHdl));
|
|
m_xCloseButton->connect_clicked(LINK(this, MacroManagerDialog, ClickHdl));
|
|
m_xNewLibraryButton->connect_clicked(LINK(this, MacroManagerDialog, ClickHdl));
|
|
m_xNewModuleButton->connect_clicked(LINK(this, MacroManagerDialog, ClickHdl));
|
|
m_xNewDialogButton->connect_clicked(LINK(this, MacroManagerDialog, ClickHdl));
|
|
m_xLibraryModuleDialogEditButton->connect_clicked(LINK(this, MacroManagerDialog, ClickHdl));
|
|
m_xLibraryModuleDialogRenameButton->connect_clicked(LINK(this, MacroManagerDialog, ClickHdl));
|
|
m_xLibraryModuleDialogDeleteButton->connect_clicked(LINK(this, MacroManagerDialog, ClickHdl));
|
|
m_xLibraryPasswordButton->connect_clicked(LINK(this, MacroManagerDialog, ClickHdl));
|
|
m_xLibraryImportButton->connect_clicked(LINK(this, MacroManagerDialog, ClickHdl));
|
|
m_xLibraryExportButton->connect_clicked(LINK(this, MacroManagerDialog, ClickHdl));
|
|
m_xMacroCreateButton->connect_clicked(LINK(this, MacroManagerDialog, ClickHdl));
|
|
m_xMacroEditButton->connect_clicked(LINK(this, MacroManagerDialog, ClickHdl));
|
|
m_xMacroRenameButton->connect_clicked(LINK(this, MacroManagerDialog, ClickHdl));
|
|
m_xMacroDeleteButton->connect_clicked(LINK(this, MacroManagerDialog, ClickHdl));
|
|
|
|
StartListening(*SfxGetpApp());
|
|
}
|
|
|
|
MacroManagerDialog::~MacroManagerDialog() { EndListening(*SfxGetpApp()); }
|
|
|
|
void MacroManagerDialog::Notify(SfxBroadcaster&, const SfxHint& rHint)
|
|
{
|
|
if (rHint.GetId() == SfxHintId::ScriptDocumentChanged)
|
|
{
|
|
weld::TreeView& rScriptContainersTreeView = m_xScriptContainersListBox->get_widget();
|
|
|
|
auto get_path = [&rScriptContainersTreeView](const weld::TreeIter* pIter) {
|
|
std::unique_ptr<weld::TreeIter> xIter = rScriptContainersTreeView.make_iterator(pIter);
|
|
OUString sPath = rScriptContainersTreeView.get_text(*xIter);
|
|
while (rScriptContainersTreeView.iter_parent(*xIter))
|
|
sPath = rScriptContainersTreeView.get_text(*xIter) + "|" + sPath;
|
|
return sPath;
|
|
};
|
|
|
|
std::unique_ptr<weld::TreeIter> xIter = rScriptContainersTreeView.make_iterator();
|
|
|
|
// for use to restore the script container tree scroll position
|
|
int nOldScrollPos = rScriptContainersTreeView.vadjustment_get_value();
|
|
|
|
// save the current path of the selection in the script containers list for reselection
|
|
// and the selected entry in the scripts list box
|
|
OUString sScriptContainersListBoxSelectedEntryPath;
|
|
OUString sScriptsListBoxSelectedEntry;
|
|
if (rScriptContainersTreeView.get_selected(xIter.get()))
|
|
{
|
|
sScriptContainersListBoxSelectedEntryPath = get_path(xIter.get());
|
|
sScriptsListBoxSelectedEntry = m_xScriptsListBox->GetSelectedScriptName();
|
|
}
|
|
|
|
// create a set containing paths for use to restore the script containers tree expand state
|
|
std::unordered_set<OUString> aExpandedSet;
|
|
if (!rScriptContainersTreeView.get_iter_first(*xIter)) // no entries?
|
|
return;
|
|
do
|
|
{
|
|
if (rScriptContainersTreeView.get_row_expanded(*xIter))
|
|
aExpandedSet.insert(get_path(xIter.get()));
|
|
} while (rScriptContainersTreeView.iter_next(*xIter));
|
|
|
|
// fill
|
|
rScriptContainersTreeView.freeze();
|
|
m_xScriptContainersListBox->Fill(nullptr);
|
|
rScriptContainersTreeView.thaw();
|
|
|
|
// restore script container tree expand state or at least try
|
|
if (!rScriptContainersTreeView.get_iter_first(*xIter))
|
|
{
|
|
UpdateUI();
|
|
return;
|
|
}
|
|
do
|
|
{
|
|
if (aExpandedSet.erase(get_path(xIter.get())))
|
|
rScriptContainersTreeView.expand_row(*xIter);
|
|
} while (aExpandedSet.size() && rScriptContainersTreeView.iter_next(*xIter));
|
|
|
|
// restore the script containers tree scroll position
|
|
rScriptContainersTreeView.vadjustment_set_value(nOldScrollPos);
|
|
|
|
// if possible select the saved scripts container list entry
|
|
if (sScriptContainersListBoxSelectedEntryPath.isEmpty())
|
|
{
|
|
UpdateUI();
|
|
return;
|
|
}
|
|
bool bFound = false;
|
|
while (true)
|
|
{
|
|
if (!rScriptContainersTreeView.get_iter_first(*xIter))
|
|
{
|
|
UpdateUI();
|
|
return;
|
|
}
|
|
do
|
|
{
|
|
if (get_path(xIter.get()) == sScriptContainersListBoxSelectedEntryPath)
|
|
{
|
|
rScriptContainersTreeView.select(*xIter);
|
|
bFound = true;
|
|
break;
|
|
}
|
|
} while (rScriptContainersTreeView.iter_next(*xIter));
|
|
if (bFound)
|
|
break;
|
|
// when not found remove the last node from path and try again
|
|
auto i = sScriptContainersListBoxSelectedEntryPath.lastIndexOf('|');
|
|
if (i == -1)
|
|
{
|
|
// didn't find
|
|
UpdateUI();
|
|
return;
|
|
}
|
|
sScriptContainersListBoxSelectedEntryPath
|
|
= sScriptContainersListBoxSelectedEntryPath.copy(0, i);
|
|
}
|
|
|
|
// fill the scripts list box and set label
|
|
m_xScriptContainersListBox->ScriptContainerSelected();
|
|
m_xScriptsListBoxLabel->set_label(m_aScriptsListBoxLabelBaseStr + " "
|
|
+ rScriptContainersTreeView.get_text(*xIter));
|
|
|
|
// reselect the macro in the scripts list box
|
|
if (!sScriptsListBoxSelectedEntry.isEmpty())
|
|
{
|
|
weld::TreeView& rScriptsTreeView = m_xScriptsListBox->get_widget();
|
|
xIter = rScriptsTreeView.make_iterator();
|
|
if (!rScriptsTreeView.get_iter_first(*xIter))
|
|
{
|
|
UpdateUI();
|
|
return;
|
|
}
|
|
bool bIsIterValid = true;
|
|
while (bIsIterValid
|
|
&& rScriptsTreeView.get_text(*xIter) != sScriptsListBoxSelectedEntry)
|
|
bIsIterValid = rScriptsTreeView.iter_next_sibling(*xIter);
|
|
if (bIsIterValid)
|
|
{
|
|
rScriptsTreeView.scroll_to_row(*xIter);
|
|
rScriptsTreeView.select(*xIter);
|
|
}
|
|
}
|
|
|
|
UpdateUI();
|
|
}
|
|
}
|
|
|
|
IMPL_LINK(MacroManagerDialog, SelectHdl, weld::TreeView&, rTreeView, void)
|
|
{
|
|
if (&rTreeView == &m_xScriptContainersListBox->get_widget())
|
|
{
|
|
m_xScriptsListBoxLabel->set_label(m_aScriptsListBoxLabelBaseStr);
|
|
m_xScriptsListBox->ClearAll();
|
|
|
|
std::unique_ptr<weld::TreeIter> xSelectedEntryIter = rTreeView.make_iterator();
|
|
if (!rTreeView.get_selected(xSelectedEntryIter.get()))
|
|
{
|
|
UpdateUI();
|
|
return;
|
|
}
|
|
|
|
auto nSelectedEntryDepth = rTreeView.get_iter_depth(*xSelectedEntryIter);
|
|
bool bBasic = m_xScriptContainersListBox->GetContainerName(*xSelectedEntryIter,
|
|
ScriptContainerType::LANGUAGE)
|
|
== u"Basic"_ustr;
|
|
|
|
if (nSelectedEntryDepth > 1)
|
|
{
|
|
if (nSelectedEntryDepth > (!bBasic ? 1 : 2))
|
|
{
|
|
ScriptContainerInfo* pScriptContainerInfo
|
|
= weld::fromId<ScriptContainerInfo*>(rTreeView.get_id(*xSelectedEntryIter));
|
|
// pBrowseNode is nullptr for Basic Dialog entries
|
|
if (pScriptContainerInfo->pBrowseNode)
|
|
{
|
|
// fill the scripts list box and set the label
|
|
m_xScriptContainersListBox->ScriptContainerSelected();
|
|
m_xScriptsListBoxLabel->set_label(m_aScriptsListBoxLabelBaseStr + " "
|
|
+ rTreeView.get_text(*xSelectedEntryIter));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
UpdateUI();
|
|
}
|
|
|
|
// IMPL_LINK_NOARG(SvxScriptSelectorDialog, FunctionDoubleClickHdl, weld::TreeView&, bool)
|
|
// cui/source/customize/cfgutil.cxx
|
|
IMPL_LINK_NOARG(MacroManagerDialog, FunctionDoubleClickHdl, weld::TreeView&, bool)
|
|
{
|
|
if (m_xRunButton->get_sensitive())
|
|
ClickHdl(*m_xRunButton);
|
|
return true;
|
|
}
|
|
|
|
// IMPL_LINK(SvxScriptSelectorDialog, ContextMenuHdl, const CommandEvent&, rCEvt, bool)
|
|
// cui/source/customize/cfgutil.cxx
|
|
// and
|
|
// IMPL_LINK(MacroChooser, ContextMenuHdl, const CommandEvent&, rCEvt, bool)
|
|
// basctl/source/basicide/macrodlg.cxx
|
|
IMPL_LINK(MacroManagerDialog, ContextMenuHdl, const CommandEvent&, rCEvt, bool)
|
|
{
|
|
weld::TreeView& xTreeView = m_xScriptsListBox->get_widget();
|
|
if (rCEvt.GetCommand() != CommandEventId::ContextMenu || !xTreeView.n_children())
|
|
return false;
|
|
|
|
std::unique_ptr<weld::Builder> xBuilder(
|
|
Application::CreateBuilder(&xTreeView, u"modules/BasicIDE/ui/sortmenu.ui"_ustr));
|
|
std::unique_ptr<weld::Menu> xPopup(xBuilder->weld_menu(u"sortmenu"_ustr));
|
|
std::unique_ptr<weld::Menu> xDropMenu(xBuilder->weld_menu(u"sortsubmenu"_ustr));
|
|
xDropMenu->set_active(u"alphabetically"_ustr, xTreeView.get_sort_order());
|
|
xDropMenu->set_active(u"properorder"_ustr, !xTreeView.get_sort_order());
|
|
|
|
OUString sCommand(
|
|
xPopup->popup_at_rect(&xTreeView, tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1, 1))));
|
|
if (sCommand == "alphabetically")
|
|
{
|
|
xTreeView.make_sorted();
|
|
}
|
|
else if (sCommand == "properorder")
|
|
{
|
|
xTreeView.make_unsorted();
|
|
m_xScriptContainersListBox->ScriptContainerSelected();
|
|
}
|
|
else if (!sCommand.isEmpty())
|
|
{
|
|
SAL_WARN("cui.dialogs", "Unknown context menu action: " << sCommand);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// same as OUString SvxScriptOrgDialog::getBoolProperty((Reference<beans::XPropertySet> const& xProps, OUString const& propName)
|
|
// cui/source/dialogs/scriptdlg.cxx
|
|
bool MacroManagerDialog::getBoolProperty(
|
|
css::uno::Reference<css::beans::XPropertySet> const& xProps, OUString const& propName)
|
|
{
|
|
bool result = false;
|
|
try
|
|
{
|
|
xProps->getPropertyValue(propName) >>= result;
|
|
}
|
|
catch (css::uno::Exception&)
|
|
{
|
|
return result;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
css::uno::Reference<css::script::browse::XBrowseNode>
|
|
MacroManagerDialog::getBrowseNode(const weld::TreeView& rTreeView, const weld::TreeIter& rTreeIter)
|
|
{
|
|
if (&rTreeView == m_xScriptContainersListBox->m_xTreeView.get())
|
|
{
|
|
ScriptContainerInfo* pScriptContainerInfo;
|
|
pScriptContainerInfo = weld::fromId<ScriptContainerInfo*>(rTreeView.get_id(rTreeIter));
|
|
if (pScriptContainerInfo)
|
|
return pScriptContainerInfo->pBrowseNode;
|
|
}
|
|
else
|
|
{
|
|
ScriptInfo* pScriptInfo = weld::fromId<ScriptInfo*>(rTreeView.get_id(rTreeIter));
|
|
if (pScriptInfo)
|
|
return pScriptInfo->pBrowseNode;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
void MacroManagerDialog::UpdateUI()
|
|
{
|
|
OUString sDescriptionText
|
|
= ScriptsListBox::GetDescriptionText(m_xScriptsListBox->get_selected_id());
|
|
|
|
weld::TreeView& rTreeView = m_xScriptContainersListBox->get_widget();
|
|
std::unique_ptr<weld::TreeIter> xSelectedIter = rTreeView.make_iterator();
|
|
if (rTreeView.get_selected(xSelectedIter.get())
|
|
&& rTreeView.get_iter_depth(*xSelectedIter) == 2) // library
|
|
{
|
|
if (m_xScriptContainersListBox->GetSelectedEntryContainerName(ScriptContainerType::LANGUAGE)
|
|
== "Basic")
|
|
{
|
|
basctl::ScriptDocument aDocument
|
|
= m_xScriptContainersListBox->GetScriptDocument(xSelectedIter.get());
|
|
if (aDocument.isAlive())
|
|
{
|
|
// if this is a Basic linked library use the link url name for the description string
|
|
css::uno::Reference<css::script::XLibraryContainer2> xModLibContainer(
|
|
aDocument.getLibraryContainer(basctl::E_SCRIPTS), css::uno::UNO_QUERY);
|
|
OUString aLibName = rTreeView.get_text(*xSelectedIter);
|
|
if (xModLibContainer.is() && xModLibContainer->hasByName(aLibName)
|
|
&& xModLibContainer->isLibraryLink(aLibName))
|
|
{
|
|
OUString aLinkURL = xModLibContainer->getLibraryLinkURL(aLibName);
|
|
OUString aSysPath;
|
|
if (osl::File::getSystemPathFromFileURL(aLinkURL, aSysPath)
|
|
== osl::FileBase::E_None)
|
|
sDescriptionText = aSysPath;
|
|
else
|
|
sDescriptionText = aLinkURL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
m_xDescriptionText->set_text(sDescriptionText);
|
|
CheckButtons();
|
|
}
|
|
|
|
void MacroManagerDialog::CheckButtons()
|
|
{
|
|
bool bSensitiveNewLibraryButton = false;
|
|
bool bSensitiveNewModuleButton = false;
|
|
bool bSensitiveNewDialogButton = false;
|
|
bool bSensitiveLibraryModuleDialogEditButton = false;
|
|
bool bSensitiveLibraryModuleDialogRenameButton = false;
|
|
bool bSensitiveLibraryModuleDialogDeleteButton = false;
|
|
bool bSensitiveLibraryPasswordButton = false;
|
|
bool bSensitiveLibraryImportButton = false;
|
|
bool bSensitiveLibraryExportButton = false;
|
|
|
|
bool bSensitiveMacroRunButton = false;
|
|
bool bSensitiveMacroCreateButton = false;
|
|
bool bSensitiveMacroEditButton = false;
|
|
bool bSensitiveMacroRenameButton = false;
|
|
bool bSensitiveMacroDeleteButton = false;
|
|
|
|
bool bSensitiveAssignButton = false;
|
|
|
|
weld::TreeView& rScriptContainersTreeView = m_xScriptContainersListBox->get_widget();
|
|
std::unique_ptr<weld::TreeIter> xScriptContainersSelectedIter
|
|
= rScriptContainersTreeView.make_iterator();
|
|
if (rScriptContainersTreeView.get_selected(xScriptContainersSelectedIter.get()))
|
|
{
|
|
if (auto nSelectedIterDepth
|
|
= rScriptContainersTreeView.get_iter_depth(*xScriptContainersSelectedIter))
|
|
{
|
|
std::unique_ptr<weld::TreeIter> xLocationContainerIter
|
|
= rScriptContainersTreeView.make_iterator(xScriptContainersSelectedIter.get());
|
|
while (rScriptContainersTreeView.get_iter_depth(*xLocationContainerIter))
|
|
rScriptContainersTreeView.iter_parent(*xLocationContainerIter);
|
|
bool bSharedLocationContainer
|
|
= getBrowseNode(rScriptContainersTreeView, *xLocationContainerIter)->getName()
|
|
== u"share"_ustr;
|
|
|
|
bool bBasic = m_xScriptContainersListBox->GetSelectedEntryContainerName(
|
|
ScriptContainerType::LANGUAGE)
|
|
== u"Basic"_ustr;
|
|
|
|
if (nSelectedIterDepth == 1) // language node
|
|
{
|
|
if (!bSharedLocationContainer)
|
|
{
|
|
if (bBasic)
|
|
{
|
|
bSensitiveNewLibraryButton = true;
|
|
bSensitiveLibraryImportButton = true;
|
|
}
|
|
else
|
|
{
|
|
css::uno::Reference<css::script::browse::XBrowseNode> node = getBrowseNode(
|
|
rScriptContainersTreeView, *xScriptContainersSelectedIter);
|
|
if (node.is())
|
|
{
|
|
css::uno::Reference<css::beans::XPropertySet> xProps(
|
|
node, css::uno::UNO_QUERY);
|
|
if (xProps.is())
|
|
{
|
|
if (getBoolProperty(xProps, "Creatable"))
|
|
{
|
|
bSensitiveNewLibraryButton = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (bBasic && nSelectedIterDepth == 2) // library node
|
|
{
|
|
basctl::ScriptDocument aDocument = m_xScriptContainersListBox->GetScriptDocument();
|
|
if (!aDocument.isAlive())
|
|
return;
|
|
|
|
OUString aLibName = m_xScriptContainersListBox->GetSelectedEntryContainerName(
|
|
ScriptContainerType::LIBRARY);
|
|
|
|
css::uno::Reference<css::script::XLibraryContainerPassword> xPasswd(
|
|
aDocument.getLibraryContainer(basctl::E_SCRIPTS), css::uno::UNO_QUERY);
|
|
|
|
if (xPasswd.is() && xPasswd->isLibraryPasswordProtected(aLibName)
|
|
&& !xPasswd->isLibraryPasswordVerified(aLibName))
|
|
{
|
|
bSensitiveLibraryPasswordButton = true;
|
|
}
|
|
else if (bSharedLocationContainer)
|
|
{
|
|
bSensitiveLibraryModuleDialogEditButton = true;
|
|
}
|
|
else
|
|
{
|
|
// check, if library is readonly
|
|
css::uno::Reference<css::script::XLibraryContainer2> xModLibContainer(
|
|
aDocument.getLibraryContainer(basctl::E_SCRIPTS), css::uno::UNO_QUERY);
|
|
|
|
bool bReadOnly = xModLibContainer.is() && xModLibContainer->hasByName(aLibName)
|
|
&& xModLibContainer->isLibraryReadOnly(aLibName);
|
|
|
|
bSensitiveNewModuleButton = !bReadOnly;
|
|
bSensitiveNewDialogButton = !bReadOnly;
|
|
bSensitiveLibraryModuleDialogEditButton = true;
|
|
if (aLibName != u"Standard"_ustr) // need to use a ResId?
|
|
{
|
|
bSensitiveLibraryModuleDialogRenameButton = !bReadOnly;
|
|
bSensitiveLibraryModuleDialogDeleteButton = true; //!bReadOnly;
|
|
bSensitiveLibraryPasswordButton = !bReadOnly;
|
|
// why not export for "Standard"?
|
|
bSensitiveLibraryExportButton = true;
|
|
}
|
|
}
|
|
}
|
|
else if (bBasic && nSelectedIterDepth == 3) // module/dialog node
|
|
{
|
|
if (bSharedLocationContainer)
|
|
{
|
|
bSensitiveLibraryModuleDialogEditButton = true;
|
|
}
|
|
else
|
|
{
|
|
basctl::ScriptDocument aDocument
|
|
= m_xScriptContainersListBox->GetScriptDocument();
|
|
assert(aDocument.isAlive());
|
|
|
|
OUString aLibName = m_xScriptContainersListBox->GetSelectedEntryContainerName(
|
|
ScriptContainerType::LIBRARY);
|
|
|
|
css::uno::Reference<css::script::XLibraryContainer2> xModLibContainer(
|
|
aDocument.getLibraryContainer(basctl::E_SCRIPTS), css::uno::UNO_QUERY);
|
|
css::uno::Reference<css::script::XLibraryContainer2> xDlgLibContainer(
|
|
aDocument.getLibraryContainer(basctl::E_DIALOGS), css::uno::UNO_QUERY);
|
|
|
|
bool bReadOnly
|
|
= (xModLibContainer.is() && xModLibContainer->hasByName(aLibName)
|
|
&& (xModLibContainer->isLibraryReadOnly(aLibName)
|
|
|| xModLibContainer->isLibraryLink(aLibName)))
|
|
|| (xDlgLibContainer.is() && xDlgLibContainer->hasByName(aLibName)
|
|
&& (xDlgLibContainer->isLibraryReadOnly(aLibName)
|
|
|| xDlgLibContainer->isLibraryLink(aLibName)));
|
|
|
|
bSensitiveLibraryModuleDialogEditButton = true;
|
|
bSensitiveLibraryModuleDialogRenameButton = !bReadOnly;
|
|
bSensitiveLibraryModuleDialogDeleteButton = !bReadOnly;
|
|
}
|
|
}
|
|
|
|
if (!bSharedLocationContainer && nSelectedIterDepth > 1)
|
|
{
|
|
css::uno::Reference<css::script::browse::XBrowseNode> node
|
|
= getBrowseNode(rScriptContainersTreeView, *xScriptContainersSelectedIter);
|
|
if (node.is())
|
|
{
|
|
css::uno::Reference<css::beans::XPropertySet> xProps(node, css::uno::UNO_QUERY);
|
|
if (xProps.is())
|
|
{
|
|
if (getBoolProperty(xProps, "Creatable")
|
|
&& rScriptContainersTreeView.get_iter_depth(
|
|
*xScriptContainersSelectedIter)
|
|
== 2) // library entry
|
|
{
|
|
bSensitiveMacroCreateButton = true;
|
|
}
|
|
if (getBoolProperty(xProps, "Editable"))
|
|
{
|
|
bSensitiveLibraryModuleDialogEditButton = true;
|
|
}
|
|
if (getBoolProperty(xProps, "Deletable"))
|
|
{
|
|
bSensitiveLibraryModuleDialogDeleteButton = true;
|
|
}
|
|
if (getBoolProperty(xProps, "Renamable"))
|
|
{
|
|
bSensitiveLibraryModuleDialogRenameButton = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// scripts list box state dependant buttons
|
|
weld::TreeView& rScriptsTreeView = m_xScriptsListBox->get_widget();
|
|
std::unique_ptr<weld::TreeIter> xScriptsSelectedIter = rScriptsTreeView.make_iterator();
|
|
if (rScriptsTreeView.n_children()
|
|
&& rScriptsTreeView.get_selected(xScriptsSelectedIter.get()))
|
|
{
|
|
bSensitiveAssignButton = true;
|
|
|
|
css::uno::Reference<css::script::browse::XBrowseNode> node;
|
|
node = getBrowseNode(rScriptsTreeView, *xScriptsSelectedIter);
|
|
if (node.is())
|
|
{
|
|
bSensitiveMacroRunButton = true;
|
|
|
|
css::uno::Reference<css::beans::XPropertySet> xProps(node, css::uno::UNO_QUERY);
|
|
if (xProps.is())
|
|
{
|
|
if (getBoolProperty(xProps, "Editable"))
|
|
{
|
|
bSensitiveMacroEditButton = true;
|
|
}
|
|
if (!bSharedLocationContainer)
|
|
{
|
|
if (getBoolProperty(xProps, "Deletable"))
|
|
{
|
|
bSensitiveMacroDeleteButton = true;
|
|
}
|
|
if (getBoolProperty(xProps, "Renamable"))
|
|
{
|
|
bSensitiveMacroRenameButton = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
m_xNewLibraryButton->set_sensitive(bSensitiveNewLibraryButton);
|
|
m_xNewModuleButton->set_sensitive(bSensitiveNewModuleButton);
|
|
m_xNewDialogButton->set_sensitive(bSensitiveNewDialogButton);
|
|
m_xLibraryModuleDialogEditButton->set_sensitive(bSensitiveLibraryModuleDialogEditButton);
|
|
m_xLibraryModuleDialogRenameButton->set_sensitive(bSensitiveLibraryModuleDialogRenameButton);
|
|
m_xLibraryModuleDialogDeleteButton->set_sensitive(bSensitiveLibraryModuleDialogDeleteButton);
|
|
m_xLibraryPasswordButton->set_sensitive(bSensitiveLibraryPasswordButton);
|
|
m_xLibraryImportButton->set_sensitive(bSensitiveLibraryImportButton);
|
|
m_xLibraryExportButton->set_sensitive(bSensitiveLibraryExportButton);
|
|
m_xRunButton->set_sensitive(bSensitiveMacroRunButton);
|
|
m_xMacroCreateButton->set_sensitive(bSensitiveMacroCreateButton);
|
|
m_xMacroEditButton->set_sensitive(bSensitiveMacroEditButton);
|
|
m_xMacroRenameButton->set_sensitive(bSensitiveMacroRenameButton);
|
|
m_xMacroDeleteButton->set_sensitive(bSensitiveMacroDeleteButton);
|
|
m_xAssignButton->set_sensitive(bSensitiveAssignButton);
|
|
}
|
|
|
|
// void createLibImpl(weld::Window* pWin, const ScriptDocument& rDocument,
|
|
// weld::TreeView* pLibBox, SbTreeListBox* pBasicBox)
|
|
// basctl/source/basicide/moduldl2.cxx
|
|
void MacroManagerDialog::BasicScriptsCreateLibrary(const basctl::ScriptDocument& rDocument)
|
|
{
|
|
// create a unique library name
|
|
OUString aLibName = CuiResId(STR_LIBRARY) + OUString::number(1);
|
|
for (sal_uInt32 i = 1; rDocument.hasLibrary(basctl::E_SCRIPTS, aLibName)
|
|
|| rDocument.hasLibrary(basctl::E_DIALOGS, aLibName);
|
|
aLibName = CuiResId(STR_LIBRARY) + OUString::number(++i))
|
|
;
|
|
|
|
InputDialog aInputDlg(m_xDialog.get(), CuiResId(STR_INPUTDIALOG_NEWLIBRARYLABEL));
|
|
aInputDlg.set_title(CuiResId(STR_INPUTDIALOG_NEWLIBRARYTITLE));
|
|
aInputDlg.SetEntryText(aLibName);
|
|
aInputDlg.HideHelpBtn();
|
|
aInputDlg.setCheckEntry([&](OUString sNewName) {
|
|
if (sNewName.isEmpty() || rDocument.hasLibrary(basctl::E_SCRIPTS, sNewName)
|
|
|| rDocument.hasLibrary(basctl::E_DIALOGS, sNewName) || sNewName.getLength() > 30
|
|
|| !basctl::IsValidSbxName(sNewName))
|
|
return false;
|
|
return true;
|
|
});
|
|
|
|
if (!aInputDlg.run())
|
|
return;
|
|
|
|
aLibName = aInputDlg.GetEntryText();
|
|
|
|
try
|
|
{
|
|
// create library container for modules
|
|
rDocument.getOrCreateLibrary(basctl::E_SCRIPTS, aLibName);
|
|
|
|
// create a module
|
|
OUString aModName = rDocument.createObjectName(basctl::E_SCRIPTS, aLibName);
|
|
OUString sModuleCode;
|
|
if (!rDocument.createModule(aLibName, aModName, true, sModuleCode))
|
|
throw css::uno::Exception("could not create module " + aModName, nullptr);
|
|
|
|
// tdf#151741 - store all libraries to the file system, otherwise they
|
|
// cannot be renamed/moved since the SfxLibraryContainer::renameLibrary
|
|
// moves the folders/files on the file system
|
|
css::uno::Reference<css::script::XLibraryContainer2> xModLibContainer(
|
|
rDocument.getLibraryContainer(basctl::E_SCRIPTS), css::uno::UNO_QUERY);
|
|
css::uno::Reference<css::script::XPersistentLibraryContainer> xModPersLibContainer(
|
|
xModLibContainer, css::uno::UNO_QUERY);
|
|
if (xModPersLibContainer.is())
|
|
xModPersLibContainer->storeLibraries();
|
|
|
|
// update Basic IDE object catalog
|
|
SbxItem aModuleSbxItem(SID_BASICIDE_ARG_SBX, rDocument, aLibName, aModName,
|
|
basctl::SBX_TYPE_MODULE);
|
|
if (SfxDispatcher* pDispatcher = basctl::GetDispatcher())
|
|
pDispatcher->ExecuteList(SID_BASICIDE_SBXINSERTED, SfxCallMode::SYNCHRON,
|
|
{ &aModuleSbxItem });
|
|
}
|
|
catch (const css::uno::Exception&)
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
}
|
|
|
|
void MacroManagerDialog::BasicScriptsCreateModule(const basctl::ScriptDocument& rDocument)
|
|
{
|
|
// library name is the selected tree entry
|
|
weld::TreeView& rTreeView = m_xScriptContainersListBox->get_widget();
|
|
std::unique_ptr<weld::TreeIter> xSelectedIter = rTreeView.make_iterator();
|
|
if (!rTreeView.get_selected(xSelectedIter.get()))
|
|
return; // should never happen
|
|
|
|
OUString aLibName = rTreeView.get_text(*xSelectedIter);
|
|
|
|
// create an unused module name
|
|
OUString aModName = CuiResId(STR_MODULE) + OUString::number(1);
|
|
for (sal_uInt32 i = 1; rDocument.hasModule(aLibName, aModName);
|
|
aModName = CuiResId(STR_MODULE) + OUString::number(++i))
|
|
;
|
|
|
|
InputDialog aInputDlg(m_xDialog.get(), CuiResId(STR_INPUTDIALOG_NEWMODULELABEL));
|
|
aInputDlg.set_title(CuiResId(STR_INPUTDIALOG_NEWMODULETITLE));
|
|
aInputDlg.SetEntryText(aModName);
|
|
aInputDlg.HideHelpBtn();
|
|
aInputDlg.setCheckEntry([&](OUString sNewName) {
|
|
if (sNewName.isEmpty() || rDocument.hasModule(aLibName, sNewName)
|
|
|| sNewName.getLength() > 30 || !basctl::IsValidSbxName(sNewName))
|
|
return false;
|
|
return true;
|
|
});
|
|
|
|
if (!aInputDlg.run())
|
|
return;
|
|
|
|
aModName = aInputDlg.GetEntryText();
|
|
|
|
OUString sModuleCode;
|
|
if (!rDocument.createModule(aLibName, aModName, true /*create main sub*/, sModuleCode))
|
|
return;
|
|
|
|
// update Basic IDE object catalog
|
|
SbxItem aSbxItem(SID_BASICIDE_ARG_SBX, rDocument, aLibName, aModName, basctl::SBX_TYPE_MODULE);
|
|
if (SfxDispatcher* pDispatcher = basctl::GetDispatcher())
|
|
{
|
|
pDispatcher->ExecuteList(SID_BASICIDE_SBXINSERTED, SfxCallMode::SYNCHRON, { &aSbxItem });
|
|
}
|
|
}
|
|
|
|
void MacroManagerDialog::BasicScriptsCreateDialog(const basctl::ScriptDocument& rDocument)
|
|
{
|
|
// library name is the selected tree entry
|
|
weld::TreeView& rTreeView = m_xScriptContainersListBox->get_widget();
|
|
std::unique_ptr<weld::TreeIter> xSelectedIter = rTreeView.make_iterator();
|
|
if (!rTreeView.get_selected(xSelectedIter.get()))
|
|
return; // should never happen
|
|
|
|
OUString aLibName = rTreeView.get_text(*xSelectedIter);
|
|
|
|
// create an unused dialog name
|
|
OUString sDialogName = CuiResId(STR_DIALOG) + OUString::number(1);
|
|
for (sal_uInt32 i = 1; rDocument.hasDialog(aLibName, sDialogName);
|
|
sDialogName = CuiResId(STR_DIALOG) + OUString::number(++i))
|
|
;
|
|
|
|
InputDialog aInputDlg(m_xDialog.get(), CuiResId(STR_INPUTDIALOG_NEWDIALOGLABEL));
|
|
aInputDlg.set_title(CuiResId(STR_INPUTDIALOG_NEWDIALOGTITLE));
|
|
aInputDlg.SetEntryText(sDialogName);
|
|
aInputDlg.HideHelpBtn();
|
|
aInputDlg.setCheckEntry([&](OUString sNewName) {
|
|
if (sNewName.isEmpty() || rDocument.hasDialog(aLibName, sNewName)
|
|
|| sNewName.getLength() > 30 || !basctl::IsValidSbxName(sNewName))
|
|
return false;
|
|
return true;
|
|
});
|
|
|
|
if (!aInputDlg.run())
|
|
return;
|
|
|
|
sDialogName = aInputDlg.GetEntryText();
|
|
|
|
try
|
|
{
|
|
rDocument.getOrCreateLibrary(basctl::E_DIALOGS, aLibName);
|
|
|
|
css::uno::Reference<css::io::XInputStreamProvider> xISP;
|
|
if (!rDocument.createDialog(aLibName, sDialogName, xISP))
|
|
return;
|
|
|
|
// update Basic IDE object catalog
|
|
SbxItem aSbxItem(SID_BASICIDE_ARG_SBX, rDocument, aLibName, sDialogName,
|
|
basctl::SBX_TYPE_DIALOG);
|
|
if (SfxDispatcher* pDispatcher = basctl::GetDispatcher())
|
|
{
|
|
pDispatcher->ExecuteList(SID_BASICIDE_SBXINSERTED, SfxCallMode::SYNCHRON,
|
|
{ &aSbxItem });
|
|
}
|
|
}
|
|
catch (const css::container::ElementExistException&)
|
|
{
|
|
std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(
|
|
m_xDialog.get(), VclMessageType::Warning, VclButtonsType::Ok,
|
|
CuiResId(STR_SBXNAMEALLREADYUSED)));
|
|
xError->run();
|
|
}
|
|
catch (const css::container::NoSuchElementException&)
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("basctl.basicide");
|
|
}
|
|
}
|
|
|
|
void MacroManagerDialog::BasicScriptsLibraryModuleDialogEdit(
|
|
const basctl::ScriptDocument& rDocument)
|
|
{
|
|
weld::TreeView& rTreeView = m_xScriptContainersListBox->get_widget();
|
|
std::unique_ptr<weld::TreeIter> xSelectedIter = rTreeView.make_iterator();
|
|
if (!rTreeView.get_selected(xSelectedIter.get()))
|
|
return; // should never happen
|
|
|
|
m_xDialog->hide();
|
|
|
|
// show the Basic IDE
|
|
SfxAllItemSet aArgs(SfxGetpApp()->GetPool());
|
|
SfxRequest aRequest(SID_BASICIDE_APPEAR, SfxCallMode::SYNCHRON, aArgs);
|
|
SfxGetpApp()->ExecuteSlot(aRequest);
|
|
|
|
if (rTreeView.get_iter_depth(*xSelectedIter) == 2) // library
|
|
{
|
|
SfxUnoAnyItem aDocItem(SID_BASICIDE_ARG_DOCUMENT_MODEL,
|
|
css::uno::Any(rDocument.getDocumentOrNull()));
|
|
SfxStringItem aLibNameItem(SID_BASICIDE_ARG_LIBNAME,
|
|
m_xScriptContainersListBox->GetSelectedEntryContainerName(
|
|
ScriptContainerType::LIBRARY));
|
|
if (SfxDispatcher* pDispatcher = basctl::GetDispatcher())
|
|
pDispatcher->ExecuteList(SID_BASICIDE_LIBSELECTED, SfxCallMode::ASYNCHRON,
|
|
{ &aDocItem, &aLibNameItem });
|
|
}
|
|
else // module/dialog
|
|
{
|
|
ScriptContainerInfo* pScriptContainerInfo
|
|
= weld::fromId<ScriptContainerInfo*>(rTreeView.get_id(*xSelectedIter));
|
|
// pScriptContainerInfo->pBrowseNode is nullptr for Dialog entries
|
|
SbxItem aSbxItem(
|
|
SID_BASICIDE_ARG_SBX, rDocument,
|
|
m_xScriptContainersListBox->GetSelectedEntryContainerName(ScriptContainerType::LIBRARY),
|
|
m_xScriptContainersListBox->GetSelectedEntryContainerName(
|
|
ScriptContainerType::MODULEORDIALOG),
|
|
pScriptContainerInfo->pBrowseNode ? basctl::SBX_TYPE_MODULE : basctl::SBX_TYPE_DIALOG);
|
|
if (SfxDispatcher* pDispatcher = basctl::GetDispatcher())
|
|
pDispatcher->ExecuteList(SID_BASICIDE_SHOWSBX, SfxCallMode::ASYNCHRON, { &aSbxItem });
|
|
}
|
|
|
|
// close the MacroManagerDialog
|
|
m_xDialog->response(0);
|
|
}
|
|
|
|
IMPL_LINK(MacroManagerDialog, CheckPasswordHdl, SvxPasswordDialog*, pDlg, bool)
|
|
{
|
|
basctl::ScriptDocument aDocument = m_xScriptContainersListBox->GetScriptDocument();
|
|
if (!aDocument.isAlive())
|
|
return false;
|
|
|
|
bool bRet = false;
|
|
|
|
css::uno::Reference<css::script::XLibraryContainerPassword> xPasswd(
|
|
aDocument.getLibraryContainer(basctl::E_SCRIPTS), css::uno::UNO_QUERY);
|
|
|
|
if (xPasswd.is())
|
|
{
|
|
try
|
|
{
|
|
OUString aOldPassword(pDlg->GetOldPassword());
|
|
OUString aNewPassword(pDlg->GetNewPassword());
|
|
OUString aLibName = m_xScriptContainersListBox->GetSelectedEntryContainerName(
|
|
ScriptContainerType::LIBRARY);
|
|
xPasswd->changeLibraryPassword(aLibName, aOldPassword, aNewPassword);
|
|
bRet = true;
|
|
}
|
|
catch (...)
|
|
{
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
basctl::ScriptDocument ScriptContainersListBox::GetScriptDocument(const weld::TreeIter* pIter)
|
|
{
|
|
std::unique_ptr<weld::TreeIter> xIter = m_xTreeView->make_iterator(pIter);
|
|
if (pIter == nullptr)
|
|
{
|
|
if (!m_xTreeView->get_selected(xIter.get()))
|
|
return basctl::ScriptDocument::getApplicationScriptDocument();
|
|
}
|
|
|
|
while (m_xTreeView->get_iter_depth(*xIter))
|
|
m_xTreeView->iter_parent(*xIter);
|
|
|
|
ScriptContainerInfo* pScriptContainerInfo
|
|
= weld::fromId<ScriptContainerInfo*>(m_xTreeView->get_id(*xIter));
|
|
if (pScriptContainerInfo && pScriptContainerInfo->pBrowseNode)
|
|
{
|
|
css::uno::Reference<css::script::browse::XBrowseNode> aRootNode;
|
|
aRootNode = pScriptContainerInfo->pBrowseNode;
|
|
if (aRootNode->getName() == u"user"_ustr || aRootNode->getName() == u"share"_ustr)
|
|
return basctl::ScriptDocument::getApplicationScriptDocument();
|
|
return basctl::ScriptDocument::getDocumentWithURLOrCaption(aRootNode->getName());
|
|
}
|
|
|
|
return basctl::ScriptDocument::getApplicationScriptDocument();
|
|
}
|
|
|
|
IMPL_LINK(MacroManagerDialog, ClickHdl, weld::Button&, rButton, void)
|
|
{
|
|
if (&rButton == m_xCloseButton.get())
|
|
{
|
|
m_xDialog->response(RET_CANCEL);
|
|
return;
|
|
}
|
|
if (&rButton == m_xRunButton.get())
|
|
{
|
|
SaveLastUsedMacro();
|
|
m_xDialog->response(RET_OK);
|
|
return;
|
|
}
|
|
|
|
if (m_xScriptContainersListBox->GetSelectedEntryContainerName(ScriptContainerType::LANGUAGE)
|
|
== "Basic")
|
|
{
|
|
basctl::ScriptDocument aDocument = m_xScriptContainersListBox->GetScriptDocument();
|
|
if (!aDocument.isAlive())
|
|
return;
|
|
|
|
if (&rButton == m_xNewLibraryButton.get())
|
|
{
|
|
BasicScriptsCreateLibrary(aDocument);
|
|
}
|
|
else if (&rButton == m_xNewModuleButton.get())
|
|
{
|
|
BasicScriptsCreateModule(aDocument);
|
|
}
|
|
else if (&rButton == m_xNewDialogButton.get())
|
|
{
|
|
BasicScriptsCreateDialog(aDocument);
|
|
}
|
|
else if (&rButton == m_xLibraryModuleDialogEditButton.get())
|
|
{
|
|
BasicScriptsLibraryModuleDialogEdit(aDocument);
|
|
}
|
|
else if (&rButton == m_xLibraryModuleDialogRenameButton.get())
|
|
{
|
|
BasicScriptsLibraryModuleDialogRename(aDocument);
|
|
}
|
|
else if (&rButton == m_xLibraryModuleDialogDeleteButton.get())
|
|
{
|
|
BasicScriptsLibraryModuleDialogDelete(aDocument);
|
|
}
|
|
else if (&rButton == m_xLibraryPasswordButton.get())
|
|
{
|
|
BasicScriptsLibraryPassword(aDocument);
|
|
}
|
|
else if (&rButton == m_xLibraryImportButton.get())
|
|
{
|
|
auto insert_entries = [this]() {
|
|
weld::TreeView& rTreeView = m_xScriptContainersListBox->get_widget();
|
|
std::unique_ptr<weld::TreeIter> xSelectedIter = rTreeView.make_iterator();
|
|
if (!rTreeView.get_selected(xSelectedIter.get()))
|
|
return; // should never happen
|
|
m_xScriptContainersListBox->Fill(xSelectedIter.get());
|
|
rTreeView.expand_row(*xSelectedIter);
|
|
rTreeView.select(*xSelectedIter);
|
|
};
|
|
basctl::ImportLib(aDocument, m_xDialog.get(), {}, {}, insert_entries);
|
|
}
|
|
else if (&rButton == m_xLibraryExportButton.get())
|
|
{
|
|
basctl::Export(aDocument,
|
|
m_xScriptContainersListBox->GetSelectedEntryContainerName(
|
|
ScriptContainerType::LIBRARY),
|
|
m_xDialog.get());
|
|
}
|
|
else if (&rButton == m_xMacroEditButton.get())
|
|
{
|
|
BasicScriptsMacroEdit(aDocument);
|
|
}
|
|
else if (&rButton == m_xMacroDeleteButton.get())
|
|
{
|
|
// todo
|
|
// see: void MacroChooser::DeleteMacro()
|
|
return;
|
|
}
|
|
else if (&rButton == m_xAssignButton.get())
|
|
{
|
|
SfxAllItemSet Args(SfxGetpApp()->GetPool());
|
|
SfxAllItemSet aInternalSet(SfxGetpApp()->GetPool());
|
|
if (m_xDocumentFrame.is())
|
|
aInternalSet.Put(SfxUnoFrameItem(SID_FILLFRAME, m_xDocumentFrame));
|
|
SfxRequest aRequest(SID_CONFIGACCEL, SfxCallMode::SYNCHRON, Args, aInternalSet);
|
|
|
|
SfxMacroInfoItem aMacroInfoItem(
|
|
SID_MACROINFO, aDocument.getBasicManager(),
|
|
m_xScriptContainersListBox->GetSelectedEntryContainerName(
|
|
ScriptContainerType::LIBRARY),
|
|
m_xScriptContainersListBox->GetSelectedEntryContainerName(
|
|
ScriptContainerType::MODULEORDIALOG),
|
|
m_xScriptsListBox->GetSelectedScriptName(), OUString(),
|
|
m_xScriptContainersListBox->GetSelectedEntryContainerName(
|
|
ScriptContainerType::LOCATION));
|
|
aRequest.AppendItem(aMacroInfoItem);
|
|
|
|
SfxGetpApp()->ExecuteSlot(aRequest);
|
|
}
|
|
return;
|
|
}
|
|
|
|
//
|
|
// button operations on Scripting Framework languages
|
|
//
|
|
if (&rButton == m_xNewLibraryButton.get())
|
|
{
|
|
ScriptingFrameworkScriptsCreateEntry(InputDialogMode::NEWLIB);
|
|
}
|
|
else if (&rButton == m_xMacroCreateButton.get())
|
|
{
|
|
ScriptingFrameworkScriptsCreateEntry(InputDialogMode::NEWMACRO);
|
|
}
|
|
else if (&rButton == m_xMacroEditButton.get())
|
|
{
|
|
weld::TreeView& rTreeView = m_xScriptsListBox->get_widget();
|
|
std::unique_ptr<weld::TreeIter> xSelectedIter = rTreeView.make_iterator();
|
|
if (!rTreeView.get_selected(xSelectedIter.get()))
|
|
return; // should never happen
|
|
css::uno::Reference<css::script::browse::XBrowseNode> node
|
|
= getBrowseNode(rTreeView, *xSelectedIter);
|
|
css::uno::Reference<css::script::XInvocation> xInv(node, css::uno::UNO_QUERY);
|
|
if (xInv.is())
|
|
{
|
|
m_xDialog->response(RET_CANCEL);
|
|
css::uno::Sequence<css::uno::Any> args(0);
|
|
css::uno::Sequence<css::uno::Any> outArgs(0);
|
|
css::uno::Sequence<sal_Int16> outIndex;
|
|
try
|
|
{
|
|
// ISSUE need code to run script here
|
|
xInv->invoke(u"Editable"_ustr, args, outIndex, outArgs);
|
|
}
|
|
catch (css::uno::Exception const&)
|
|
{
|
|
TOOLS_WARN_EXCEPTION("cui.dialogs", "Caught exception trying to invoke");
|
|
}
|
|
}
|
|
}
|
|
else if (&rButton == m_xLibraryModuleDialogDeleteButton.get())
|
|
{
|
|
weld::TreeView& rTreeView = m_xScriptContainersListBox->get_widget();
|
|
std::unique_ptr<weld::TreeIter> xSelectedIter = rTreeView.make_iterator();
|
|
if (!rTreeView.get_selected(xSelectedIter.get()))
|
|
return; // should never happen
|
|
ScriptingFrameworkScriptsDeleteEntry(rTreeView, *xSelectedIter);
|
|
}
|
|
else if (&rButton == m_xMacroDeleteButton.get())
|
|
{
|
|
weld::TreeView& rTreeView = m_xScriptsListBox->get_widget();
|
|
std::unique_ptr<weld::TreeIter> xSelectedIter = rTreeView.make_iterator();
|
|
if (!rTreeView.get_selected(xSelectedIter.get()))
|
|
return; // should never happen
|
|
ScriptingFrameworkScriptsDeleteEntry(rTreeView, *xSelectedIter);
|
|
}
|
|
else if (&rButton == m_xLibraryModuleDialogRenameButton.get())
|
|
{
|
|
weld::TreeView& rTreeView = m_xScriptContainersListBox->get_widget();
|
|
std::unique_ptr<weld::TreeIter> xSelectedIter = rTreeView.make_iterator();
|
|
if (!rTreeView.get_selected(xSelectedIter.get()))
|
|
return; // should never happen
|
|
ScriptingFrameworkScriptsRenameEntry(rTreeView, *xSelectedIter);
|
|
}
|
|
else if (&rButton == m_xMacroRenameButton.get())
|
|
{
|
|
weld::TreeView& rTreeView = m_xScriptsListBox->get_widget();
|
|
std::unique_ptr<weld::TreeIter> xSelectedIter = rTreeView.make_iterator();
|
|
if (!rTreeView.get_selected(xSelectedIter.get()))
|
|
return; // should never happen
|
|
ScriptingFrameworkScriptsRenameEntry(rTreeView, *xSelectedIter);
|
|
}
|
|
else if (&rButton == m_xAssignButton.get())
|
|
{
|
|
SfxAllItemSet Args(SfxGetpApp()->GetPool());
|
|
SfxAllItemSet aInternalSet(SfxGetpApp()->GetPool());
|
|
if (m_xDocumentFrame.is())
|
|
aInternalSet.Put(SfxUnoFrameItem(SID_FILLFRAME, m_xDocumentFrame));
|
|
SfxRequest aRequest(SID_CONFIGACCEL, SfxCallMode::SYNCHRON, Args, aInternalSet);
|
|
|
|
SfxMacroInfoItem aMacroInfoItem(
|
|
SID_MACROINFO, nullptr,
|
|
m_xScriptContainersListBox->GetSelectedEntryContainerName(ScriptContainerType::LIBRARY),
|
|
OUString(), m_xScriptsListBox->GetSelectedScriptName(), OUString(),
|
|
m_xScriptContainersListBox->GetSelectedEntryContainerName(
|
|
ScriptContainerType::LOCATION));
|
|
aRequest.AppendItem(aMacroInfoItem);
|
|
SfxGetpApp()->ExecuteSlot(aRequest);
|
|
}
|
|
}
|
|
|
|
bool MacroManagerDialog::IsLibraryReadOnlyOrFailedPasswordQuery(
|
|
const basctl::ScriptDocument& rDocument, weld::TreeIter* pIter)
|
|
{
|
|
css::uno::Reference<css::script::XLibraryContainer2> xModLibContainer(
|
|
rDocument.getLibraryContainer(basctl::E_SCRIPTS), css::uno::UNO_QUERY);
|
|
css::uno::Reference<css::script::XLibraryContainer2> xDlgLibContainer(
|
|
rDocument.getLibraryContainer(basctl::E_DIALOGS), css::uno::UNO_QUERY);
|
|
|
|
OUString aLibName
|
|
= m_xScriptContainersListBox->GetContainerName(*pIter, ScriptContainerType::LIBRARY);
|
|
|
|
// check if library is readonly
|
|
if ((xModLibContainer.is() && xModLibContainer->hasByName(aLibName)
|
|
&& xModLibContainer->isLibraryReadOnly(aLibName)
|
|
&& !xModLibContainer->isLibraryLink(aLibName))
|
|
|| (xDlgLibContainer.is() && xDlgLibContainer->hasByName(aLibName)
|
|
&& xDlgLibContainer->isLibraryReadOnly(aLibName)
|
|
&& !xDlgLibContainer->isLibraryLink(aLibName)))
|
|
{
|
|
std::unique_ptr<weld::MessageDialog> xErrorBox(
|
|
Application::CreateMessageDialog(m_xDialog.get(), VclMessageType::Warning,
|
|
VclButtonsType::Ok, CuiResId(STR_LIBISREADONLY)));
|
|
xErrorBox->run();
|
|
return true;
|
|
}
|
|
|
|
// password
|
|
if (xModLibContainer.is() && xModLibContainer->hasByName(aLibName)
|
|
/*&& !xModLibContainer->isLibraryLoaded(aLibName)*/)
|
|
{
|
|
bool bOK = true;
|
|
// check password
|
|
css::uno::Reference<css::script::XLibraryContainerPassword> xPasswd(xModLibContainer,
|
|
css::uno::UNO_QUERY);
|
|
if (xPasswd.is() && xPasswd->isLibraryPasswordProtected(aLibName)
|
|
&& !xPasswd->isLibraryPasswordVerified(aLibName))
|
|
{
|
|
OUString sPassword;
|
|
bOK = basctl::QueryPassword(m_xDialog.get(), xModLibContainer, aLibName, sPassword,
|
|
true, true);
|
|
}
|
|
if (!bOK)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// adapted from LibPage inline renaming
|
|
// IMPL_LINK(LibPage, EditingEntryHdl, const weld::TreeIter&, rIter, bool)
|
|
// IMPL_LINK(LibPage, EditedEntryHdl, const IterString&, rIterString, bool)
|
|
// basctl/source/basicide/moduldl2.cxx
|
|
void MacroManagerDialog::BasicScriptsLibraryModuleDialogRename(
|
|
const basctl::ScriptDocument& rDocument)
|
|
{
|
|
weld::TreeView& rTreeView = m_xScriptContainersListBox->get_widget();
|
|
std::unique_ptr<weld::TreeIter> xSelectedIter = rTreeView.make_iterator();
|
|
if (!rTreeView.get_selected(xSelectedIter.get()))
|
|
return; // should never happen
|
|
|
|
if (IsLibraryReadOnlyOrFailedPasswordQuery(rDocument, xSelectedIter.get()))
|
|
return;
|
|
|
|
OUString sOldName = rTreeView.get_text(*xSelectedIter);
|
|
|
|
if (rTreeView.get_iter_depth(*xSelectedIter) == 2) // library
|
|
{
|
|
InputDialog aInputDlg(m_xDialog.get(), CuiResId(STR_INPUTDIALOG_RENAMELIBRARYLABEL));
|
|
aInputDlg.HideHelpBtn();
|
|
aInputDlg.set_title(CuiResId(STR_INPUTDIALOG_RENAMELIBRARYTITLE));
|
|
aInputDlg.SetEntryText(sOldName);
|
|
aInputDlg.setCheckEntry([&](OUString sNewName) {
|
|
if (sNewName != sOldName
|
|
&& (sNewName.isEmpty() || rDocument.hasLibrary(basctl::E_SCRIPTS, sNewName)
|
|
|| rDocument.hasLibrary(basctl::E_DIALOGS, sNewName)
|
|
|| sNewName.getLength() > 30 || !basctl::IsValidSbxName(sNewName)))
|
|
return false;
|
|
return true;
|
|
});
|
|
|
|
if (!aInputDlg.run())
|
|
return;
|
|
|
|
OUString sNewName = aInputDlg.GetEntryText();
|
|
if (sNewName == sOldName)
|
|
return;
|
|
|
|
bool bSuccess = true;
|
|
try
|
|
{
|
|
css::uno::Reference<css::script::XLibraryContainer2> xModLibContainer(
|
|
rDocument.getLibraryContainer(basctl::E_SCRIPTS), css::uno::UNO_QUERY);
|
|
if (xModLibContainer.is() && xModLibContainer->hasByName(sOldName))
|
|
xModLibContainer->renameLibrary(sOldName, sNewName);
|
|
css::uno::Reference<css::script::XLibraryContainer2> xDlgLibContainer(
|
|
rDocument.getLibraryContainer(basctl::E_DIALOGS), css::uno::UNO_QUERY);
|
|
if (xDlgLibContainer.is() && xDlgLibContainer->hasByName(sOldName))
|
|
xDlgLibContainer->renameLibrary(sOldName, sNewName);
|
|
}
|
|
catch (css::uno::Exception const&)
|
|
{
|
|
bSuccess = false;
|
|
TOOLS_WARN_EXCEPTION("cui.dialogs", "Caught exception trying to Rename");
|
|
}
|
|
|
|
if (bSuccess)
|
|
{
|
|
basctl::MarkDocumentModified(rDocument);
|
|
// rTreeView.set_text(*xSelectedIter, sNewName);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// module/dialog
|
|
ScriptContainerInfo* pScriptContainerInfo
|
|
= weld::fromId<ScriptContainerInfo*>(rTreeView.get_id(*xSelectedIter));
|
|
if (!pScriptContainerInfo)
|
|
return; // should never happen
|
|
|
|
OUString aLibName = m_xScriptContainersListBox->GetSelectedEntryContainerName(
|
|
ScriptContainerType::LIBRARY);
|
|
|
|
InputDialog aInputDlg(m_xDialog.get(), CuiResId(pScriptContainerInfo->pBrowseNode
|
|
? STR_INPUTDIALOG_RENAMEMODULELABEL
|
|
: STR_INPUTDIALOG_RENAMEDIALOGLABEL));
|
|
aInputDlg.HideHelpBtn();
|
|
aInputDlg.set_title(CuiResId(pScriptContainerInfo->pBrowseNode
|
|
? STR_INPUTDIALOG_RENAMEMODULETITLE
|
|
: STR_INPUTDIALOG_RENAMEMODULETITLE));
|
|
aInputDlg.SetEntryText(sOldName);
|
|
aInputDlg.setCheckEntry([&](OUString sNewName) {
|
|
if (sNewName != sOldName
|
|
&& (sNewName.isEmpty() || sNewName.getLength() > 30
|
|
|| !basctl::IsValidSbxName(sNewName)
|
|
|| pScriptContainerInfo->pBrowseNode
|
|
? rDocument.hasModule(aLibName, sNewName)
|
|
: rDocument.hasDialog(aLibName, sNewName)))
|
|
return false;
|
|
return true;
|
|
});
|
|
|
|
if (!aInputDlg.run())
|
|
return;
|
|
|
|
OUString sNewName = aInputDlg.GetEntryText();
|
|
if (sNewName == sOldName)
|
|
return;
|
|
|
|
if (pScriptContainerInfo->pBrowseNode
|
|
? rDocument.renameModule(aLibName, sOldName, sNewName)
|
|
: rDocument.renameDialog(aLibName, sOldName, sNewName, nullptr))
|
|
{
|
|
basctl::MarkDocumentModified(rDocument);
|
|
// rTreeView.set_text(*xSelectedIter, sNewName);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MacroManagerDialog::BasicScriptsLibraryModuleDialogDelete(
|
|
const basctl::ScriptDocument& rDocument)
|
|
{
|
|
weld::TreeView& rTreeView = m_xScriptContainersListBox->get_widget();
|
|
std::unique_ptr<weld::TreeIter> xSelectedIter = rTreeView.make_iterator();
|
|
if (!rTreeView.get_selected(xSelectedIter.get()))
|
|
return; // should never happen
|
|
|
|
if (IsLibraryReadOnlyOrFailedPasswordQuery(rDocument, xSelectedIter.get()))
|
|
return;
|
|
|
|
if (rTreeView.get_iter_depth(*xSelectedIter) == 2) // library
|
|
{
|
|
// see: void LibPage::DeleteCurrent()
|
|
// basctl/source/basicide/moduldl2.cxx
|
|
OUString aLibName = rTreeView.get_text(*xSelectedIter);
|
|
|
|
// check, if library is link
|
|
bool bIsLibraryLink = false;
|
|
css::uno::Reference<css::script::XLibraryContainer2> xModLibContainer(
|
|
rDocument.getLibraryContainer(basctl::E_SCRIPTS), css::uno::UNO_QUERY);
|
|
css::uno::Reference<css::script::XLibraryContainer2> xDlgLibContainer(
|
|
rDocument.getLibraryContainer(basctl::E_DIALOGS), css::uno::UNO_QUERY);
|
|
if ((xModLibContainer.is() && xModLibContainer->hasByName(aLibName)
|
|
&& xModLibContainer->isLibraryLink(aLibName))
|
|
|| (xDlgLibContainer.is() && xDlgLibContainer->hasByName(aLibName)
|
|
&& xDlgLibContainer->isLibraryLink(aLibName)))
|
|
{
|
|
bIsLibraryLink = true;
|
|
}
|
|
|
|
if (!basctl::QueryDelLib(aLibName, bIsLibraryLink, m_xDialog.get()))
|
|
return;
|
|
|
|
// inform BasicIDE
|
|
SfxUnoAnyItem aDocItem(SID_BASICIDE_ARG_DOCUMENT_MODEL,
|
|
css::uno::Any(rDocument.getDocumentOrNull()));
|
|
SfxStringItem aLibNameItem(SID_BASICIDE_ARG_LIBNAME, aLibName);
|
|
if (SfxDispatcher* pDispatcher = basctl::GetDispatcher())
|
|
pDispatcher->ExecuteList(SID_BASICIDE_LIBREMOVED, SfxCallMode::SYNCHRON,
|
|
{ &aDocItem, &aLibNameItem });
|
|
|
|
// remove library from module and dialog library containers
|
|
if (xModLibContainer.is() && xModLibContainer->hasByName(aLibName))
|
|
xModLibContainer->removeLibrary(aLibName);
|
|
if (xDlgLibContainer.is() && xDlgLibContainer->hasByName(aLibName))
|
|
xDlgLibContainer->removeLibrary(aLibName);
|
|
|
|
basctl::MarkDocumentModified(rDocument);
|
|
}
|
|
else
|
|
{
|
|
// delete Basic module or dialog
|
|
// adapted from void ObjectPage::DeleteCurrent() basctl/source/basicide/moduldlg.cxx
|
|
ScriptContainerInfo* pScriptContainerInfo
|
|
= weld::fromId<ScriptContainerInfo*>(rTreeView.get_id(*xSelectedIter));
|
|
if (!pScriptContainerInfo)
|
|
return; // shouldn't happen
|
|
|
|
// pBrowseNode points to nullptr for dialog entries
|
|
if (pScriptContainerInfo->pBrowseNode)
|
|
{
|
|
if (!basctl::QueryDelModule(m_xScriptContainersListBox->GetSelectedEntryContainerName(
|
|
ScriptContainerType::MODULEORDIALOG),
|
|
m_xDialog.get()))
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
if (!basctl::QueryDelDialog(m_xScriptContainersListBox->GetSelectedEntryContainerName(
|
|
ScriptContainerType::MODULEORDIALOG),
|
|
m_xDialog.get()))
|
|
return;
|
|
}
|
|
|
|
bool bSuccess = false;
|
|
if (pScriptContainerInfo->pBrowseNode)
|
|
bSuccess
|
|
= rDocument.removeModule(m_xScriptContainersListBox->GetSelectedEntryContainerName(
|
|
ScriptContainerType::LIBRARY),
|
|
m_xScriptContainersListBox->GetSelectedEntryContainerName(
|
|
ScriptContainerType::MODULEORDIALOG));
|
|
else
|
|
bSuccess
|
|
= rDocument.removeDialog(m_xScriptContainersListBox->GetSelectedEntryContainerName(
|
|
ScriptContainerType::LIBRARY),
|
|
m_xScriptContainersListBox->GetSelectedEntryContainerName(
|
|
ScriptContainerType::MODULEORDIALOG));
|
|
|
|
if (bSuccess)
|
|
{
|
|
if (SfxDispatcher* pDispatcher = basctl::GetDispatcher())
|
|
{
|
|
SbxItem aSbxItem(SID_BASICIDE_ARG_SBX, rDocument,
|
|
m_xScriptContainersListBox->GetSelectedEntryContainerName(
|
|
ScriptContainerType::LIBRARY),
|
|
m_xScriptContainersListBox->GetSelectedEntryContainerName(
|
|
ScriptContainerType::MODULEORDIALOG),
|
|
pScriptContainerInfo->pBrowseNode ? basctl::SBX_TYPE_MODULE
|
|
: basctl::SBX_TYPE_DIALOG);
|
|
pDispatcher->ExecuteList(SID_BASICIDE_SBXDELETED, SfxCallMode::SYNCHRON,
|
|
{ &aSbxItem });
|
|
}
|
|
basctl::MarkDocumentModified(rDocument);
|
|
}
|
|
}
|
|
}
|
|
|
|
// inspired by IMPL_LINK( LibPage, ButtonHdl, weld::Button&, rButton, void )
|
|
// else if (&rButton == m_xPasswordButton.get())
|
|
// basctl/source/basicide/moduldl2.cxx
|
|
void MacroManagerDialog::BasicScriptsLibraryPassword(const basctl::ScriptDocument& rDocument)
|
|
{
|
|
weld::TreeView& rTreeView = m_xScriptContainersListBox->get_widget();
|
|
std::unique_ptr<weld::TreeIter> xSelectedIter = rTreeView.make_iterator();
|
|
if (!rTreeView.get_selected(xSelectedIter.get()))
|
|
return; // should never happen
|
|
|
|
OUString aLibName = rTreeView.get_text(*xSelectedIter);
|
|
|
|
// load module library (if not loaded)
|
|
css::uno::Reference<css::script::XLibraryContainer> xModLibContainer
|
|
= rDocument.getLibraryContainer(basctl::E_SCRIPTS);
|
|
if (xModLibContainer.is() && xModLibContainer->hasByName(aLibName)
|
|
&& !xModLibContainer->isLibraryLoaded(aLibName))
|
|
{
|
|
xModLibContainer->loadLibrary(aLibName);
|
|
}
|
|
|
|
// check if library is password protected --> this is for setting and removing password
|
|
if (xModLibContainer.is() && xModLibContainer->hasByName(aLibName))
|
|
{
|
|
css::uno::Reference<css::script::XLibraryContainerPassword> xPasswd(xModLibContainer,
|
|
css::uno::UNO_QUERY);
|
|
if (xPasswd.is())
|
|
{
|
|
if (xPasswd->isLibraryPasswordProtected(aLibName)
|
|
&& !xPasswd->isLibraryPasswordVerified(aLibName))
|
|
{
|
|
// password not verified
|
|
OUString sPassword;
|
|
if (basctl::QueryPassword(m_xDialog.get(), xModLibContainer, aLibName, sPassword,
|
|
true, true))
|
|
{
|
|
CheckButtons();
|
|
}
|
|
return;
|
|
}
|
|
|
|
// set/change password dialog
|
|
SvxPasswordDialog aDlg(m_xDialog.get(), !xPasswd->isLibraryPasswordProtected(aLibName));
|
|
aDlg.SetCheckPasswordHdl(LINK(this, MacroManagerDialog, CheckPasswordHdl));
|
|
|
|
if (aDlg.run() == RET_OK)
|
|
{
|
|
if (xPasswd->isLibraryPasswordProtected(aLibName))
|
|
rTreeView.set_image(*xSelectedIter, RID_CUIBMP_LOCKED);
|
|
else
|
|
rTreeView.set_image(*xSelectedIter, RID_CUIBMP_LIB);
|
|
basctl::MarkDocumentModified(rDocument);
|
|
}
|
|
|
|
rTreeView.grab_focus();
|
|
}
|
|
}
|
|
}
|
|
|
|
void MacroManagerDialog::BasicScriptsMacroEdit(const basctl::ScriptDocument& rDocument)
|
|
{
|
|
// hide the scripts organizer selector dialog before opening the basic ide
|
|
m_xDialog->hide();
|
|
|
|
// open the basic ide
|
|
SfxAllItemSet aArgs(SfxGetpApp()->GetPool());
|
|
SfxRequest aRequest(SID_BASICIDE_APPEAR, SfxCallMode::SYNCHRON, aArgs);
|
|
SfxGetpApp()->ExecuteSlot(aRequest);
|
|
|
|
// navigate to the method
|
|
SbxItem aSbxItem(
|
|
SID_BASICIDE_ARG_SBX, rDocument,
|
|
m_xScriptContainersListBox->GetSelectedEntryContainerName(ScriptContainerType::LIBRARY),
|
|
m_xScriptContainersListBox->GetSelectedEntryContainerName(
|
|
ScriptContainerType::MODULEORDIALOG),
|
|
m_xScriptsListBox->GetSelectedScriptName(), basctl::SBX_TYPE_METHOD);
|
|
// need to use basctl::GetDispatcher() to have expected results with qt5 and x11,
|
|
// gtk3 works with SfxGetpApp()->GetDispatcher()
|
|
if (SfxDispatcher* pDispatcher = basctl::GetDispatcher())
|
|
pDispatcher->ExecuteList(SID_BASICIDE_SHOWSBX, SfxCallMode::ASYNCHRON, { &aSbxItem });
|
|
// alternate way to do this
|
|
// BasicManager* pBasMgr = rDocument.getBasicManager();
|
|
// SfxMacroInfoItem aInfoItem( SID_BASICIDE_ARG_MACROINFO, pBasMgr, aLibName, aModName, aMethodName, OUString() );
|
|
// if (SfxDispatcher* pDispatcher = basctl::GetDispatcher())
|
|
// pDispatcher->ExecuteList(SID_BASICIDE_EDITMACRO, SfxCallMode::ASYNCHRON, { &aInfoItem });
|
|
|
|
// now it is safe to close the scripts organizer selector dialog
|
|
m_xDialog->response(0);
|
|
}
|
|
|
|
// modified version of void SvxScriptOrgDialog::renameEntry(const weld::TreeIter& rEntry)
|
|
// cui/source/dialogs/scriptdlg.cxx
|
|
void MacroManagerDialog::ScriptingFrameworkScriptsRenameEntry(weld::TreeView& rTreeView,
|
|
const weld::TreeIter& rEntry)
|
|
{
|
|
css::uno::Reference<css::script::browse::XBrowseNode> xBrowseNode
|
|
= getBrowseNode(rTreeView, rEntry);
|
|
css::uno::Reference<css::script::XInvocation> xInv(xBrowseNode, css::uno::UNO_QUERY);
|
|
|
|
if (xInv.is())
|
|
{
|
|
OUString aNewName = xBrowseNode->getName();
|
|
sal_Int32 extnPos = aNewName.lastIndexOf('.');
|
|
if (extnPos > 0)
|
|
{
|
|
aNewName = aNewName.copy(0, extnPos);
|
|
}
|
|
|
|
InputDialog aInputDlg(m_xDialog.get(),
|
|
xBrowseNode->getType()
|
|
== css::script::browse::BrowseNodeTypes::CONTAINER
|
|
? CuiResId(STR_INPUTDIALOG_RENAMELIBRARYLABEL)
|
|
: CuiResId(STR_INPUTDIALOG_RENAMEMACROLABEL));
|
|
aInputDlg.set_title(xBrowseNode->getType()
|
|
== css::script::browse::BrowseNodeTypes::CONTAINER
|
|
? CuiResId(STR_INPUTDIALOG_RENAMELIBRARYTITLE)
|
|
: CuiResId(STR_INPUTDIALOG_RENAMEMACROTITLE));
|
|
aInputDlg.SetEntryText(aNewName);
|
|
aInputDlg.HideHelpBtn();
|
|
// doesn't check if the name already exists, that will be caught below by invoke
|
|
aInputDlg.setCheckEntry([](OUString sNewName) {
|
|
if (sNewName.isEmpty() || sNewName.getLength() > 30
|
|
|| !basctl::IsValidSbxName(sNewName))
|
|
return false;
|
|
return true;
|
|
});
|
|
|
|
if (!aInputDlg.run())
|
|
return;
|
|
|
|
aNewName = aInputDlg.GetEntryText();
|
|
|
|
css::uno::Sequence<css::uno::Any> args{ css::uno::Any(aNewName) };
|
|
css::uno::Sequence<css::uno::Any> outArgs;
|
|
css::uno::Sequence<sal_Int16> outIndex;
|
|
try
|
|
{
|
|
css::uno::Any aResult = xInv->invoke(u"Renamable"_ustr, args, outIndex, outArgs);
|
|
xBrowseNode.set(aResult, css::uno::UNO_QUERY);
|
|
}
|
|
catch (css::uno::Exception const&)
|
|
{
|
|
TOOLS_WARN_EXCEPTION("cui.dialogs", "Caught exception trying to Rename");
|
|
}
|
|
}
|
|
if (xBrowseNode.is())
|
|
{
|
|
if (xBrowseNode->getType() == css::script::browse::BrowseNodeTypes::CONTAINER)
|
|
{
|
|
m_xScriptContainersListBox->ScriptContainerSelected();
|
|
}
|
|
else
|
|
{
|
|
ScriptInfo* pScriptInfo = weld::fromId<ScriptInfo*>(m_xScriptsListBox->get_id(rEntry));
|
|
if (pScriptInfo)
|
|
{
|
|
css::uno::Reference<css::beans::XPropertySet> xPropSet(xBrowseNode,
|
|
css::uno::UNO_QUERY);
|
|
if (xPropSet.is())
|
|
{
|
|
OUString sURI;
|
|
try
|
|
{
|
|
css::uno::Any value = xPropSet->getPropertyValue(u"URI"_ustr);
|
|
value >>= sURI;
|
|
}
|
|
catch (css::uno::Exception&)
|
|
{
|
|
// do nothing, the URI will be empty
|
|
}
|
|
pScriptInfo->sURL = sURI;
|
|
}
|
|
}
|
|
}
|
|
rTreeView.set_text(rEntry, xBrowseNode->getName());
|
|
rTreeView.set_cursor(rEntry);
|
|
}
|
|
else
|
|
{
|
|
//ISSUE L10N & message from exception?
|
|
OUString aError(CuiResId(RID_CUISTR_RENAMEFAILED));
|
|
std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(
|
|
m_xDialog.get(), VclMessageType::Warning, VclButtonsType::Ok, aError));
|
|
xErrorBox->set_title(CuiResId(RID_CUISTR_RENAMEFAILED_TITLE));
|
|
xErrorBox->run();
|
|
}
|
|
}
|
|
|
|
// for Scripting Framework entries
|
|
// duplicate of OUString SvxScriptOrgDialog::getListOfChildren
|
|
// cui/source/dialogs/scriptdlg.cxx
|
|
OUString MacroManagerDialog::getListOfChildren(
|
|
const css::uno::Reference<css::script::browse::XBrowseNode>& node, int depth)
|
|
{
|
|
OUStringBuffer result = "\n";
|
|
for (int i = 0; i <= depth; i++)
|
|
{
|
|
result.append("\t");
|
|
}
|
|
result.append(node->getName());
|
|
|
|
try
|
|
{
|
|
if (node->hasChildNodes())
|
|
{
|
|
const css::uno::Sequence<css::uno::Reference<css::script::browse::XBrowseNode>> children
|
|
= node->getChildNodes();
|
|
for (const css::uno::Reference<css::script::browse::XBrowseNode>& n : children)
|
|
{
|
|
result.append(getListOfChildren(n, depth + 1));
|
|
}
|
|
}
|
|
}
|
|
catch (css::uno::Exception&)
|
|
{
|
|
// ignore, will return an empty string
|
|
}
|
|
|
|
return result.makeStringAndClear();
|
|
}
|
|
|
|
// modified verson of void SvxScriptOrgDialog::deleteEntry(const weld::TreeIter& rEntry)
|
|
// cui/source/dialogs/scriptdlg.cxx
|
|
void MacroManagerDialog::ScriptingFrameworkScriptsDeleteEntry(weld::TreeView& rTreeView,
|
|
const weld::TreeIter& rEntry)
|
|
{
|
|
bool result = false;
|
|
css::uno::Reference<css::script::browse::XBrowseNode> node = getBrowseNode(rTreeView, rEntry);
|
|
// ISSUE L10N string & can we center list?
|
|
OUString aQuery = CuiResId(RID_CUISTR_DELQUERY) + getListOfChildren(node, 0);
|
|
std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(
|
|
m_xDialog.get(), VclMessageType::Question, VclButtonsType::YesNo, aQuery));
|
|
xQueryBox->set_title(CuiResId(RID_CUISTR_DELQUERY_TITLE));
|
|
if (xQueryBox->run() == RET_NO)
|
|
{
|
|
return;
|
|
}
|
|
|
|
css::uno::Reference<css::script::XInvocation> xInv(node, css::uno::UNO_QUERY);
|
|
if (xInv.is())
|
|
{
|
|
css::uno::Sequence<css::uno::Any> args(0);
|
|
css::uno::Sequence<css::uno::Any> outArgs(0);
|
|
css::uno::Sequence<sal_Int16> outIndex;
|
|
try
|
|
{
|
|
css::uno::Any aResult = xInv->invoke(u"Deletable"_ustr, args, outIndex, outArgs);
|
|
aResult >>= result; // or do we just assume true if no exception ?
|
|
}
|
|
catch (css::uno::Exception const&)
|
|
{
|
|
TOOLS_WARN_EXCEPTION("cui.dialogs", "Caught exception trying to delete");
|
|
}
|
|
}
|
|
if (result)
|
|
{
|
|
if (&rTreeView == &m_xScriptContainersListBox->get_widget())
|
|
{
|
|
m_xScriptContainersListBox->Remove(&rEntry, true);
|
|
SelectHdl(rTreeView);
|
|
}
|
|
else
|
|
{
|
|
m_xScriptsListBox->Remove(rEntry);
|
|
}
|
|
UpdateUI();
|
|
}
|
|
else
|
|
{
|
|
//ISSUE L10N & message from exception?
|
|
std::unique_ptr<weld::MessageDialog> xErrorBox(
|
|
Application::CreateMessageDialog(m_xDialog.get(), VclMessageType::Warning,
|
|
VclButtonsType::Ok, CuiResId(RID_CUISTR_DELFAILED)));
|
|
xErrorBox->set_title(CuiResId(RID_CUISTR_CREATEFAILED_TITLE));
|
|
xErrorBox->run();
|
|
}
|
|
}
|
|
|
|
// Modified version of SvxScriptOrgDialog::CreateEntry
|
|
// cui/source/dialogs/scriptdlg.cxx
|
|
void MacroManagerDialog::ScriptingFrameworkScriptsCreateEntry(InputDialogMode eInputDialogMode)
|
|
{
|
|
weld::TreeView& rTreeView = m_xScriptContainersListBox->get_widget();
|
|
std::unique_ptr<weld::TreeIter> xSelectedIter = rTreeView.make_iterator();
|
|
if (!rTreeView.get_selected(xSelectedIter.get()))
|
|
return; // should never happen
|
|
|
|
css::uno::Reference<css::script::browse::XBrowseNode> aChildNode;
|
|
css::uno::Reference<css::script::browse::XBrowseNode> xBrowseNode
|
|
= getBrowseNode(rTreeView, *xSelectedIter);
|
|
css::uno::Reference<css::script::XInvocation> xInv(xBrowseNode, css::uno::UNO_QUERY);
|
|
|
|
// Currently, invocation is not implemented for python, only beanshell, javascript, and java.
|
|
if (xInv.is())
|
|
{
|
|
OUString aNewName;
|
|
OUString aNewStdName;
|
|
if (eInputDialogMode == InputDialogMode::NEWLIB)
|
|
{
|
|
aNewStdName = CuiResId(STR_LIBRARY);
|
|
}
|
|
else
|
|
{
|
|
aNewStdName = CuiResId(STR_MACRO);
|
|
}
|
|
|
|
bool bValid = false;
|
|
sal_Int32 i = 1;
|
|
|
|
css::uno::Sequence<css::uno::Reference<css::script::browse::XBrowseNode>> childNodes;
|
|
// no children => ok to create Parcel1 or Script1 without checking ?
|
|
try
|
|
{
|
|
if (!xBrowseNode->hasChildNodes())
|
|
{
|
|
aNewName = aNewStdName + OUString::number(i);
|
|
bValid = true;
|
|
}
|
|
else
|
|
{
|
|
childNodes = xBrowseNode->getChildNodes();
|
|
}
|
|
}
|
|
catch (css::uno::Exception&)
|
|
{
|
|
// ignore, will continue on with empty sequence
|
|
}
|
|
|
|
OUString extn;
|
|
while (!bValid)
|
|
{
|
|
aNewName = aNewStdName + OUString::number(i);
|
|
bool bFound = false;
|
|
if (childNodes.hasElements())
|
|
{
|
|
OUString nodeName = childNodes[0]->getName();
|
|
sal_Int32 extnPos = nodeName.lastIndexOf('.');
|
|
if (extnPos > 0)
|
|
extn = nodeName.copy(extnPos);
|
|
}
|
|
for (const css::uno::Reference<css::script::browse::XBrowseNode>& n : childNodes)
|
|
{
|
|
if (Concat2View(aNewName + extn) == n->getName())
|
|
{
|
|
bFound = true;
|
|
break;
|
|
}
|
|
}
|
|
if (bFound)
|
|
{
|
|
i++;
|
|
}
|
|
else
|
|
{
|
|
bValid = true;
|
|
}
|
|
}
|
|
|
|
InputDialog aInputDlg(m_xDialog.get(), eInputDialogMode == InputDialogMode::NEWLIB
|
|
? CuiResId(STR_INPUTDIALOG_NEWLIBRARYLABEL)
|
|
: CuiResId(STR_INPUTDIALOG_NEWMACROLABEL));
|
|
aInputDlg.set_title(eInputDialogMode == InputDialogMode::NEWLIB
|
|
? CuiResId(STR_INPUTDIALOG_NEWLIBRARYTITLE)
|
|
: CuiResId(STR_INPUTDIALOG_NEWMACROTITLE));
|
|
aInputDlg.SetEntryText(aNewName);
|
|
aInputDlg.HideHelpBtn();
|
|
|
|
// setCheckEntry doesn't check if the name already exists. It is checked after the dialog
|
|
// in the Creatable invocation call - this could be improved by including a check for
|
|
// existing name
|
|
aInputDlg.setCheckEntry([](OUString sNewName) {
|
|
if (sNewName.isEmpty() || sNewName.getLength() > 30
|
|
|| !basctl::IsValidSbxName(sNewName))
|
|
return false;
|
|
return true;
|
|
});
|
|
|
|
do
|
|
{
|
|
if (aInputDlg.run())
|
|
{
|
|
OUString aUserSuppliedName = aInputDlg.GetEntryText();
|
|
bValid = true;
|
|
for (const css::uno::Reference<css::script::browse::XBrowseNode>& n : childNodes)
|
|
{
|
|
if (Concat2View(aUserSuppliedName + extn) == n->getName())
|
|
{
|
|
bValid = false;
|
|
OUString aError = CuiResId(RID_CUISTR_CREATEFAILED)
|
|
+ CuiResId(RID_CUISTR_CREATEFAILEDDUP);
|
|
|
|
std::unique_ptr<weld::MessageDialog> xErrorBox(
|
|
Application::CreateMessageDialog(m_xDialog.get(),
|
|
VclMessageType::Warning,
|
|
VclButtonsType::Ok, aError));
|
|
xErrorBox->set_title(CuiResId(RID_CUISTR_CREATEFAILED_TITLE));
|
|
xErrorBox->run();
|
|
aInputDlg.SetEntryText(aNewName);
|
|
break;
|
|
}
|
|
}
|
|
if (bValid)
|
|
aNewName = aUserSuppliedName;
|
|
}
|
|
else
|
|
{
|
|
// user hit cancel
|
|
return;
|
|
}
|
|
} while (!bValid);
|
|
|
|
// open up parent node (which ensures it's loaded)
|
|
rTreeView.expand_row(*xSelectedIter);
|
|
|
|
css::uno::Sequence<css::uno::Any> args{ css::uno::Any(aNewName) };
|
|
css::uno::Sequence<css::uno::Any> outArgs;
|
|
css::uno::Sequence<sal_Int16> outIndex;
|
|
try
|
|
{
|
|
css::uno::Any aResult = xInv->invoke(u"Creatable"_ustr, args, outIndex, outArgs);
|
|
aChildNode.set(aResult, css::uno::UNO_QUERY);
|
|
}
|
|
catch (css::uno::Exception const&)
|
|
{
|
|
TOOLS_WARN_EXCEPTION("cui.dialogs", "Caught exception trying to Create");
|
|
}
|
|
}
|
|
if (aChildNode.is())
|
|
{
|
|
if (rTreeView.get_iter_depth(*xSelectedIter) == 1) // language node
|
|
{
|
|
m_xScriptContainersListBox->Fill(xSelectedIter.get());
|
|
rTreeView.expand_row(*xSelectedIter);
|
|
rTreeView.select(*xSelectedIter);
|
|
}
|
|
else
|
|
{
|
|
m_xScriptContainersListBox->ScriptContainerSelected();
|
|
}
|
|
UpdateUI();
|
|
}
|
|
else
|
|
{
|
|
//ISSUE L10N & message from exception?
|
|
OUString aError(CuiResId(RID_CUISTR_CREATEFAILED));
|
|
std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(
|
|
m_xDialog.get(), VclMessageType::Warning, VclButtonsType::Ok, aError));
|
|
xErrorBox->set_title(CuiResId(RID_CUISTR_CREATEFAILED_TITLE));
|
|
xErrorBox->run();
|
|
}
|
|
}
|
|
|
|
// called from OUString AbstractMacroManagerDialog_Impl::GetScriptURL() const
|
|
// cui/source/factory/dlgfact.cxx
|
|
OUString MacroManagerDialog::GetScriptURL() const
|
|
{
|
|
OUString result;
|
|
std::unique_ptr<weld::TreeIter> xIter = m_xScriptsListBox->make_iterator();
|
|
if (m_xScriptsListBox->get_selected(xIter.get()))
|
|
{
|
|
ScriptInfo* pScriptInfo = weld::fromId<ScriptInfo*>(m_xScriptsListBox->get_id(*xIter));
|
|
if (pScriptInfo)
|
|
result = pScriptInfo->sURL;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
constexpr OUString MACRO_MANAGER_CONFIGNAME = u"MacroManagerDialog"_ustr;
|
|
constexpr OUString LAST_RUN_MACRO_INFO = u"LastRunMacro"_ustr;
|
|
|
|
// adapted from SvxScriptSelectorDialog::SaveLastUsedMacro()
|
|
// cui/source/customize/cfgutil.cxx
|
|
void MacroManagerDialog::SaveLastUsedMacro()
|
|
{
|
|
// Gets the current selection in the dialog as a series of selected entries
|
|
OUString sMacroInfo = m_xScriptsListBox->GetSelectedScriptName();
|
|
|
|
weld::TreeView& rScriptContainersTreeView = m_xScriptContainersListBox->get_widget();
|
|
std::unique_ptr<weld::TreeIter> xIter = rScriptContainersTreeView.make_iterator();
|
|
|
|
if (!rScriptContainersTreeView.get_selected(xIter.get()))
|
|
return;
|
|
|
|
do
|
|
{
|
|
sMacroInfo = rScriptContainersTreeView.get_text(*xIter) + "|" + sMacroInfo;
|
|
} while (rScriptContainersTreeView.iter_parent(*xIter));
|
|
|
|
SvtViewOptions(EViewType::Dialog, MACRO_MANAGER_CONFIGNAME)
|
|
.SetUserItem(LAST_RUN_MACRO_INFO, css::uno::Any(sMacroInfo));
|
|
}
|
|
|
|
// adapted from SvxScriptSelectorDialog::LoadLastUsedMacro()
|
|
// cui/source/customize/cfgutil.cxx
|
|
void MacroManagerDialog::LoadLastUsedMacro()
|
|
{
|
|
SvtViewOptions aDlgOpt(EViewType::Dialog, MACRO_MANAGER_CONFIGNAME);
|
|
if (!aDlgOpt.Exists())
|
|
return;
|
|
|
|
OUString sMacroInfo;
|
|
aDlgOpt.GetUserItem(LAST_RUN_MACRO_INFO) >>= sMacroInfo;
|
|
if (sMacroInfo.isEmpty())
|
|
return;
|
|
|
|
// Counts how many entries exist in the macro info string
|
|
sal_Int16 nInfoParts = 0;
|
|
sal_Int16 nLastIndex = sMacroInfo.indexOf('|');
|
|
if (nLastIndex > -1)
|
|
{
|
|
nInfoParts = 1;
|
|
while (nLastIndex != -1)
|
|
{
|
|
nInfoParts++;
|
|
nLastIndex = sMacroInfo.indexOf('|', nLastIndex + 1);
|
|
}
|
|
}
|
|
|
|
weld::TreeView& rScriptContainersTreeView = m_xScriptContainersListBox->get_widget();
|
|
std::unique_ptr<weld::TreeIter> xIter = rScriptContainersTreeView.make_iterator();
|
|
|
|
if (!rScriptContainersTreeView.get_iter_first(*xIter))
|
|
return;
|
|
|
|
// Expand the nodes in the script containers tree
|
|
OUString sNodeToExpand;
|
|
bool bIsIterValid;
|
|
sal_Int16 nOpenedNodes = 0;
|
|
for (sal_Int16 i = 0; i < nInfoParts - 1; i++)
|
|
{
|
|
sNodeToExpand = sMacroInfo.getToken(i, '|');
|
|
bIsIterValid = true;
|
|
while (bIsIterValid && rScriptContainersTreeView.get_text(*xIter) != sNodeToExpand)
|
|
bIsIterValid = rScriptContainersTreeView.iter_next_sibling(*xIter);
|
|
|
|
if (bIsIterValid)
|
|
{
|
|
rScriptContainersTreeView.expand_row(*xIter);
|
|
nOpenedNodes++;
|
|
}
|
|
if (rScriptContainersTreeView.iter_has_child(*xIter))
|
|
(void)rScriptContainersTreeView.iter_children(*xIter);
|
|
else if (nOpenedNodes < nInfoParts - 1)
|
|
// If the number of levels in the tree is smaller than the
|
|
// number of parts in the macro info string, then return
|
|
return;
|
|
}
|
|
rScriptContainersTreeView.select(*xIter);
|
|
rScriptContainersTreeView.scroll_to_row(*xIter);
|
|
|
|
// fill the scripts list box and set the label
|
|
m_xScriptContainersListBox->ScriptContainerSelected();
|
|
m_xScriptsListBoxLabel->set_label(m_aScriptsListBoxLabelBaseStr + " "
|
|
+ rScriptContainersTreeView.get_text(*xIter));
|
|
|
|
// Select the macro in the scripts tree
|
|
weld::TreeView& rScriptsTreeView = m_xScriptsListBox->get_widget();
|
|
xIter = rScriptsTreeView.make_iterator();
|
|
if (rScriptsTreeView.get_iter_first(*xIter))
|
|
{
|
|
OUString sMacroName = sMacroInfo.getToken(nInfoParts - 1, '|');
|
|
bIsIterValid = true;
|
|
while (bIsIterValid && rScriptsTreeView.get_text(*xIter) != sMacroName)
|
|
bIsIterValid = rScriptsTreeView.iter_next_sibling(*xIter);
|
|
if (bIsIterValid)
|
|
{
|
|
rScriptsTreeView.scroll_to_row(*xIter);
|
|
rScriptsTreeView.select(*xIter);
|
|
}
|
|
}
|
|
|
|
UpdateUI();
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|