The browse node factory had a wrapper using XAggregation that wraps every XBrowseNode. As far as I can tell this was used to replace the implementation of getChildNodes with one that checks for exceptions from the underlying provider and then sorts all of the resulting nodes by name. The trouble with this is that it prevents the script providers from detecting when a node is one from the same script provider and thus makes it difficult to implement the XCopyableBrowseNode interface. The documentation for XAggregation mentions this problem and also states that the interface is deprecated. To avoid this overhead, this patch replaces the aggregation with a helper function in comphelper that should be used to retrieve children from a browse node. That takes care of catching exceptions and sorting the results. Change-Id: I319888fee1b84ddcef397317d2cf7e72bd2867cd Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208160 Tested-by: Jenkins Reviewed-by: Neil Roberts <nroberts@libreoffice.org>
2664 lines
105 KiB
C++
2664 lines
105 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 <GetDocumentModel.hxx>
|
||
#include <scriptdlg.hxx>
|
||
#include <strings.hrc>
|
||
#include <basctl/basctldllpublic.hxx>
|
||
#include <basctl/sbxitem.hxx>
|
||
#include <basctl/scriptdocument.hxx>
|
||
#include <basic/basmgr.hxx>
|
||
#include <basic/sbmeth.hxx>
|
||
#include <comphelper/SetFlagContextHelper.hxx>
|
||
#include <comphelper/diagnose_ex.hxx>
|
||
#include <comphelper/documentinfo.hxx>
|
||
#include <comphelper/processfactory.hxx>
|
||
#include <comphelper/scriptbrowse.hxx>
|
||
#include <osl/file.hxx>
|
||
#include <rtl/ustrbuf.hxx>
|
||
#include <sfx2/app.hxx>
|
||
#include <sfx2/dispatch.hxx>
|
||
#include <sfx2/frame.hxx>
|
||
#include <sfx2/minfitem.hxx>
|
||
#include <sfx2/request.hxx>
|
||
#include <sfx2/sfxsids.hrc>
|
||
#include <svl/itemset.hxx>
|
||
#include <svl/stritem.hxx>
|
||
#include <svtools/dlgname.hxx>
|
||
#include <svtools/viewoptions.hxx>
|
||
#include <svx/passwd.hxx>
|
||
#include <tools/debug.hxx>
|
||
#include <vcl/commandevent.hxx>
|
||
#include <vcl/svapp.hxx>
|
||
#include <vcl/vclenum.hxx>
|
||
#include <vcl/weld/Builder.hxx>
|
||
#include <vcl/weld/Dialog.hxx>
|
||
#include <vcl/weld/MessageDialog.hxx>
|
||
#include <vcl/weld/Menu.hxx>
|
||
#include <vcl/weld/WaitObject.hxx>
|
||
#include <vcl/weld/weldutils.hxx>
|
||
|
||
#include <com/sun/star/beans/XPropertySet.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/browse/XCopyableBrowseNode.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/XStorageBasedLibraryContainer.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()
|
||
{
|
||
if (std::unique_ptr<weld::TreeIter> xScriptsEntryIter = m_xTreeView->get_selected())
|
||
return m_xTreeView->get_text(*xScriptsEntryIter);
|
||
return OUString();
|
||
}
|
||
|
||
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 (!xIter->equal(*pEntryIter))
|
||
{
|
||
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;
|
||
css::uno::Reference<css::frame::XModel> xParentDocumentModel;
|
||
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);
|
||
xParentDocumentModel.set(pScriptContainerInfoEntry->xModel);
|
||
|
||
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);
|
||
}
|
||
|
||
std::vector<css::uno::Reference<css::script::browse::XBrowseNode>> children
|
||
= comphelper::scriptbrowse::getChildNodes(xNode);
|
||
|
||
if (!bIsRootNode)
|
||
comphelper::scriptbrowse::sortNodes(children);
|
||
|
||
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();
|
||
css::uno::Reference<css::frame::XModel> xDocumentModel;
|
||
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;
|
||
}
|
||
else
|
||
{
|
||
xDocumentModel = getDocumentModel(m_xContext, uiName);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
xDocumentModel = xParentDocumentModel;
|
||
}
|
||
|
||
// 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 std::vector<css::uno::Reference<css::script::browse::XBrowseNode>>
|
||
grandchildren = comphelper::scriptbrowse::getChildNodes(theChild);
|
||
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, xDocumentModel, 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, xParentDocumentModel, pEntryIter, rDlgName, RID_CUIBMP_DIALOG,
|
||
false);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void ScriptContainersListBox::Insert(
|
||
const css::uno::Reference<css::script::browse::XBrowseNode>& xInsertNode,
|
||
const css::uno::Reference<css::frame::XModel>& xDocumentModel, 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(), xDocumentModel)));
|
||
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));
|
||
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->get_selected();
|
||
if (!xIter)
|
||
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 std::vector<css::uno::Reference<css::script::browse::XBrowseNode>> children
|
||
= comphelper::scriptbrowse::getSortedChildNodes(xBrowseNode);
|
||
|
||
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, pScriptContainerInfo->xModel));
|
||
|
||
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->get_selected();
|
||
if (!xSelectedEntryIter)
|
||
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));
|
||
// 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));
|
||
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_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_xModuleCopyButton(m_xBuilder->weld_button(u"modulecopy"_ustr))
|
||
, m_xModulePasteButton(m_xBuilder->weld_button(u"modulepaste"_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_item_activated(
|
||
LINK(this, MacroManagerDialog, FunctionDoubleClickHdl));
|
||
m_xScriptsListBox->connect_command(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));
|
||
m_xModuleCopyButton->connect_clicked(LINK(this, MacroManagerDialog, ClickHdl));
|
||
m_xModulePasteButton->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;
|
||
};
|
||
|
||
// 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 (std::unique_ptr<weld::TreeIter> xIter = rScriptContainersTreeView.get_selected())
|
||
{
|
||
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;
|
||
std::unique_ptr<weld::TreeIter> xIter = rScriptContainersTreeView.make_iterator();
|
||
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::ItemView&, rItemView, void)
|
||
{
|
||
weld::TreeView& rTreeView = m_xScriptContainersListBox->get_widget();
|
||
if (&rItemView == &rTreeView)
|
||
{
|
||
m_xScriptsListBoxLabel->set_label(m_aScriptsListBoxLabelBaseStr);
|
||
m_xScriptsListBox->ClearAll();
|
||
|
||
std::unique_ptr<weld::TreeIter> xSelectedEntryIter = rTreeView.get_selected();
|
||
if (!xSelectedEntryIter)
|
||
{
|
||
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, const weld::TreeIter&, 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;
|
||
}
|
||
|
||
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.get_selected();
|
||
if (xSelectedIter && 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));
|
||
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 bSensitiveModuleCopyButton = false;
|
||
bool bSensitiveModulePasteButton = 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();
|
||
if (std::unique_ptr<weld::TreeIter> xScriptContainersSelectedIter
|
||
= rScriptContainersTreeView.get_selected())
|
||
{
|
||
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())
|
||
{
|
||
if (comphelper::scriptbrowse::isCreatable(node))
|
||
{
|
||
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));
|
||
|
||
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::Reference<css::script::XLibraryContainer2> xDlgLibContainer(
|
||
aDocument.getLibraryContainer(basctl::E_DIALOGS));
|
||
|
||
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)
|
||
{
|
||
css::uno::Reference<css::script::browse::XBrowseNode> node
|
||
= getBrowseNode(rScriptContainersTreeView, *xScriptContainersSelectedIter);
|
||
if (node.is())
|
||
{
|
||
if (nSelectedIterDepth > 1)
|
||
{
|
||
if (comphelper::scriptbrowse::isCreatable(node)
|
||
&& rScriptContainersTreeView.get_iter_depth(
|
||
*xScriptContainersSelectedIter)
|
||
== 2) // library entry
|
||
{
|
||
bSensitiveMacroCreateButton = true;
|
||
}
|
||
if (comphelper::scriptbrowse::isEditable(node))
|
||
{
|
||
bSensitiveLibraryModuleDialogEditButton = true;
|
||
}
|
||
if (comphelper::scriptbrowse::isDeletable(node))
|
||
{
|
||
bSensitiveLibraryModuleDialogDeleteButton = true;
|
||
}
|
||
if (comphelper::scriptbrowse::isRenamable(node))
|
||
{
|
||
bSensitiveLibraryModuleDialogRenameButton = true;
|
||
}
|
||
|
||
css::uno::Reference<css::script::browse::XCopyableBrowseNode> xCopyableNode(
|
||
node, css::uno::UNO_QUERY);
|
||
if (xCopyableNode.is() && xCopyableNode->isCopyableNode())
|
||
bSensitiveModuleCopyButton = true;
|
||
}
|
||
|
||
if (m_xCopiedNode.is() && m_xCopiedNode->nodeCanBeCopiedTo(node))
|
||
{
|
||
bSensitiveModulePasteButton = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
// scripts list box state dependent buttons
|
||
weld::TreeView& rScriptsTreeView = m_xScriptsListBox->get_widget();
|
||
std::unique_ptr<weld::TreeIter> xScriptsSelectedIter = rScriptsTreeView.get_selected();
|
||
if (rScriptsTreeView.n_children() && xScriptsSelectedIter)
|
||
{
|
||
bSensitiveAssignButton = true;
|
||
|
||
if (bBasic)
|
||
bSensitiveMacroDeleteButton = true;
|
||
|
||
css::uno::Reference<css::script::browse::XBrowseNode> node;
|
||
node = getBrowseNode(rScriptsTreeView, *xScriptsSelectedIter);
|
||
if (node.is())
|
||
{
|
||
bSensitiveMacroRunButton = true;
|
||
|
||
if (comphelper::scriptbrowse::isEditable(node))
|
||
{
|
||
bSensitiveMacroEditButton = true;
|
||
}
|
||
if (!bSharedLocationContainer)
|
||
{
|
||
if (comphelper::scriptbrowse::isDeletable(node))
|
||
{
|
||
bSensitiveMacroDeleteButton = true;
|
||
}
|
||
if (comphelper::scriptbrowse::isRenamable(node))
|
||
{
|
||
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_xModuleCopyButton->set_sensitive(bSensitiveModuleCopyButton);
|
||
m_xModulePasteButton->set_sensitive(bSensitiveModulePasteButton);
|
||
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))
|
||
;
|
||
|
||
OUString aDesc = CuiResId(STR_INPUTDIALOG_NEWLIBRARYLABEL);
|
||
|
||
SvxNameDialog aNameDialog(m_xDialog.get(), aLibName, aDesc,
|
||
CuiResId(STR_INPUTDIALOG_NEWLIBRARYTITLE));
|
||
|
||
aNameDialog.SetCheckName([&](OUString sNewName) -> bool {
|
||
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 (aNameDialog.run() != RET_OK)
|
||
return;
|
||
|
||
aLibName = aNameDialog.GetName();
|
||
|
||
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::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.get_selected();
|
||
if (!xSelectedIter)
|
||
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))
|
||
;
|
||
|
||
OUString aDesc = CuiResId(STR_INPUTDIALOG_NEWMODULELABEL);
|
||
|
||
SvxNameDialog aNameDialog(m_xDialog.get(), aModName, aDesc,
|
||
CuiResId(STR_INPUTDIALOG_NEWMODULETITLE));
|
||
|
||
aNameDialog.SetCheckName([&](OUString sNewName) -> bool {
|
||
if (sNewName.isEmpty() || rDocument.hasModule(aLibName, sNewName)
|
||
|| sNewName.getLength() > 30 || !basctl::IsValidSbxName(sNewName))
|
||
return false;
|
||
return true;
|
||
});
|
||
|
||
if (!aNameDialog.run())
|
||
return;
|
||
|
||
aModName = aNameDialog.GetName();
|
||
|
||
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.get_selected();
|
||
if (!xSelectedIter)
|
||
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))
|
||
;
|
||
|
||
OUString aDesc = CuiResId(STR_INPUTDIALOG_NEWDIALOGLABEL);
|
||
|
||
SvxNameDialog aNameDialog(m_xDialog.get(), sDialogName, aDesc,
|
||
CuiResId(STR_INPUTDIALOG_NEWDIALOGTITLE));
|
||
|
||
aNameDialog.SetCheckName([&](OUString sNewName) -> bool {
|
||
if (sNewName.isEmpty() || rDocument.hasDialog(aLibName, sNewName)
|
||
|| sNewName.getLength() > 30 || !basctl::IsValidSbxName(sNewName))
|
||
return false;
|
||
return true;
|
||
});
|
||
|
||
if (!aNameDialog.run())
|
||
return;
|
||
|
||
sDialogName = aNameDialog.GetName();
|
||
|
||
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.get_selected();
|
||
if (!xSelectedIter)
|
||
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)
|
||
{
|
||
xIter = m_xTreeView->get_selected();
|
||
if (!xIter)
|
||
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.get_selected();
|
||
if (!xSelectedIter)
|
||
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())
|
||
{
|
||
BasicScriptsMacroDelete();
|
||
}
|
||
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.get_selected();
|
||
if (!xSelectedIter)
|
||
return; // should never happen
|
||
css::uno::Reference<css::script::browse::XBrowseNode> node
|
||
= getBrowseNode(rTreeView, *xSelectedIter);
|
||
if (node.is())
|
||
{
|
||
m_xDialog->response(RET_CANCEL);
|
||
try
|
||
{
|
||
// ISSUE need code to run script here
|
||
comphelper::scriptbrowse::editNode(node);
|
||
}
|
||
catch (css::uno::Exception const&)
|
||
{
|
||
TOOLS_WARN_EXCEPTION("cui.dialogs", "Caught exception trying to edit");
|
||
}
|
||
}
|
||
}
|
||
else if (&rButton == m_xLibraryModuleDialogDeleteButton.get())
|
||
{
|
||
weld::TreeView& rTreeView = m_xScriptContainersListBox->get_widget();
|
||
std::unique_ptr<weld::TreeIter> xSelectedIter = rTreeView.get_selected();
|
||
if (!xSelectedIter)
|
||
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.get_selected();
|
||
if (!xSelectedIter)
|
||
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.get_selected();
|
||
if (!xSelectedIter)
|
||
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.get_selected();
|
||
if (!xSelectedIter)
|
||
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);
|
||
}
|
||
else if (&rButton == m_xModuleCopyButton.get())
|
||
{
|
||
weld::TreeView& rTreeView = m_xScriptContainersListBox->get_widget();
|
||
std::unique_ptr<weld::TreeIter> xSelectedIter = rTreeView.get_selected();
|
||
if (!xSelectedIter)
|
||
return; // should never happen
|
||
m_xCopiedNode.set(getBrowseNode(rTreeView, *xSelectedIter), css::uno::UNO_QUERY);
|
||
CheckButtons();
|
||
}
|
||
else if (&rButton == m_xModulePasteButton.get())
|
||
{
|
||
if (!m_xCopiedNode.is())
|
||
return;
|
||
|
||
weld::TreeView& rTreeView = m_xScriptContainersListBox->get_widget();
|
||
std::unique_ptr<weld::TreeIter> xSelectedIter = rTreeView.get_selected();
|
||
if (!xSelectedIter)
|
||
return; // should never happen
|
||
ScriptingFrameworkScriptsPasteEntry(rTreeView, *xSelectedIter);
|
||
}
|
||
}
|
||
|
||
bool MacroManagerDialog::IsLibraryReadOnlyOrFailedPasswordQuery(
|
||
const basctl::ScriptDocument& rDocument, const weld::TreeIter* pIter)
|
||
{
|
||
css::uno::Reference<css::script::XLibraryContainer2> xModLibContainer(
|
||
rDocument.getLibraryContainer(basctl::E_SCRIPTS));
|
||
css::uno::Reference<css::script::XLibraryContainer2> xDlgLibContainer(
|
||
rDocument.getLibraryContainer(basctl::E_DIALOGS));
|
||
|
||
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.get_selected();
|
||
if (!xSelectedIter)
|
||
return; // should never happen
|
||
|
||
if (IsLibraryReadOnlyOrFailedPasswordQuery(rDocument, xSelectedIter.get()))
|
||
return;
|
||
|
||
OUString sOldName = rTreeView.get_text(*xSelectedIter);
|
||
|
||
if (rTreeView.get_iter_depth(*xSelectedIter) == 2) // library
|
||
{
|
||
OUString aDesc = CuiResId(STR_INPUTDIALOG_RENAMELIBRARYLABEL);
|
||
|
||
SvxNameDialog aNameDialog(m_xDialog.get(), sOldName, aDesc,
|
||
CuiResId(STR_INPUTDIALOG_RENAMELIBRARYTITLE));
|
||
|
||
aNameDialog.SetCheckName([&](OUString sNewName) -> bool {
|
||
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 (!aNameDialog.run())
|
||
return;
|
||
|
||
OUString sNewName = aNameDialog.GetName();
|
||
if (sNewName == sOldName)
|
||
return;
|
||
|
||
bool bSuccess = true;
|
||
try
|
||
{
|
||
css::uno::Reference<css::script::XLibraryContainer2> xModLibContainer(
|
||
rDocument.getLibraryContainer(basctl::E_SCRIPTS));
|
||
if (xModLibContainer.is() && xModLibContainer->hasByName(sOldName))
|
||
xModLibContainer->renameLibrary(sOldName, sNewName);
|
||
css::uno::Reference<css::script::XLibraryContainer2> xDlgLibContainer(
|
||
rDocument.getLibraryContainer(basctl::E_DIALOGS));
|
||
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);
|
||
|
||
OUString aDesc
|
||
= CuiResId(pScriptContainerInfo->pBrowseNode ? STR_INPUTDIALOG_RENAMEMODULELABEL
|
||
: STR_INPUTDIALOG_RENAMEDIALOGLABEL);
|
||
|
||
SvxNameDialog aNameDialog(m_xDialog.get(), sOldName, aDesc,
|
||
CuiResId(pScriptContainerInfo->pBrowseNode
|
||
? STR_INPUTDIALOG_RENAMEMODULETITLE
|
||
: STR_INPUTDIALOG_RENAMEMODULETITLE));
|
||
|
||
aNameDialog.SetCheckName([&](OUString sNewName) -> bool {
|
||
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 (!aNameDialog.run())
|
||
return;
|
||
|
||
OUString sNewName = aNameDialog.GetName();
|
||
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.get_selected();
|
||
if (!xSelectedIter)
|
||
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::Reference<css::script::XLibraryContainer2> xDlgLibContainer(
|
||
rDocument.getLibraryContainer(basctl::E_DIALOGS));
|
||
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.get_selected();
|
||
if (!xSelectedIter)
|
||
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);
|
||
}
|
||
|
||
void MacroManagerDialog::BasicScriptsMacroDelete()
|
||
{
|
||
SbMethod* pMethod = GetSelectedBasicMethod();
|
||
|
||
DBG_ASSERT(pMethod, "BasicScriptsMacroDelete: no macro found!");
|
||
|
||
if (!pMethod || !basctl::QueryDelMacro(pMethod->GetName(), m_xDialog.get()))
|
||
return;
|
||
|
||
// Remove the macro from the list. We need to do this before calling DeleteMacro because that
|
||
// can trigger a notification which will cause the list of macros to be reloaded so if we do it
|
||
// after we’ll delete the wrong node.
|
||
if (std::unique_ptr<weld::TreeIter> xScriptsEntryIter
|
||
= m_xScriptsListBox->get_widget().get_selected())
|
||
{
|
||
m_xScriptsListBox->Remove(*xScriptsEntryIter);
|
||
}
|
||
|
||
basctl::DeleteMacro(*pMethod);
|
||
}
|
||
|
||
// 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);
|
||
|
||
if (xBrowseNode.is())
|
||
{
|
||
OUString aNewName = xBrowseNode->getName();
|
||
sal_Int32 extnPos = aNewName.lastIndexOf('.');
|
||
if (extnPos > 0)
|
||
{
|
||
aNewName = aNewName.copy(0, extnPos);
|
||
}
|
||
|
||
OUString aDesc = xBrowseNode->getType() == css::script::browse::BrowseNodeTypes::CONTAINER
|
||
? CuiResId(STR_INPUTDIALOG_RENAMELIBRARYLABEL)
|
||
: CuiResId(STR_INPUTDIALOG_RENAMEMACROLABEL);
|
||
|
||
SvxNameDialog aNameDialog(m_xDialog.get(), aNewName, aDesc,
|
||
xBrowseNode->getType()
|
||
== css::script::browse::BrowseNodeTypes::CONTAINER
|
||
? CuiResId(STR_INPUTDIALOG_RENAMELIBRARYTITLE)
|
||
: CuiResId(STR_INPUTDIALOG_RENAMEMACROTITLE));
|
||
|
||
aNameDialog.SetCheckName([](OUString sNewName) -> bool {
|
||
if (sNewName.isEmpty() || sNewName.getLength() > 30
|
||
|| !basctl::IsValidSbxName(sNewName))
|
||
return false;
|
||
return true;
|
||
});
|
||
|
||
if (!aNameDialog.run())
|
||
return;
|
||
|
||
aNewName = aNameDialog.GetName();
|
||
|
||
try
|
||
{
|
||
xBrowseNode = comphelper::scriptbrowse::renameNode(xBrowseNode, aNewName);
|
||
}
|
||
catch (css::uno::Exception const&)
|
||
{
|
||
TOOLS_WARN_EXCEPTION("cui.dialogs", "Caught exception trying to Rename");
|
||
xBrowseNode.clear();
|
||
}
|
||
}
|
||
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();
|
||
}
|
||
}
|
||
|
||
void MacroManagerDialog::ScriptingFrameworkScriptsPasteEntry(weld::TreeView& rTreeView,
|
||
const weld::TreeIter& rEntry)
|
||
{
|
||
css::uno::Reference<css::script::browse::XBrowseNode> node = getBrowseNode(rTreeView, rEntry);
|
||
if (!node.is() || !m_xCopiedNode->nodeCanBeCopiedTo(node))
|
||
return;
|
||
|
||
try
|
||
{
|
||
node = m_xCopiedNode->copyNode(node);
|
||
}
|
||
catch (const css::uno::Exception&)
|
||
{
|
||
return;
|
||
}
|
||
|
||
// If we don’t expand the row before filling it then it will end up with two copies of all the
|
||
// entries
|
||
rTreeView.expand_row(rEntry);
|
||
m_xScriptContainersListBox->Fill(&rEntry);
|
||
// Filling it causes the node to close so we need to expand it again
|
||
rTreeView.expand_row(rEntry);
|
||
|
||
// Try to select the new entry
|
||
if (rTreeView.iter_has_child(rEntry))
|
||
{
|
||
OUString sNodeName = node->getName();
|
||
|
||
std::unique_ptr<weld::TreeIter> xIter = rTreeView.make_iterator(&rEntry);
|
||
if (rTreeView.iter_children(*xIter))
|
||
{
|
||
do
|
||
{
|
||
if (rTreeView.get_text(*xIter) == sNodeName)
|
||
{
|
||
rTreeView.select(*xIter);
|
||
SelectHdl(rTreeView);
|
||
break;
|
||
}
|
||
} while (rTreeView.iter_next_sibling(*xIter));
|
||
}
|
||
}
|
||
}
|
||
|
||
// 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 std::vector<css::uno::Reference<css::script::browse::XBrowseNode>> children
|
||
= comphelper::scriptbrowse::getSortedChildNodes(node);
|
||
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 version 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;
|
||
}
|
||
|
||
if (node.is())
|
||
{
|
||
try
|
||
{
|
||
result = comphelper::scriptbrowse::deleteNode(node);
|
||
// 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.get_selected();
|
||
if (!xSelectedIter)
|
||
return; // should never happen
|
||
|
||
css::uno::Reference<css::script::browse::XBrowseNode> aChildNode;
|
||
css::uno::Reference<css::script::browse::XBrowseNode> xBrowseNode
|
||
= getBrowseNode(rTreeView, *xSelectedIter);
|
||
|
||
if (xBrowseNode.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;
|
||
|
||
std::vector<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 = comphelper::scriptbrowse::getChildNodes(xBrowseNode);
|
||
}
|
||
}
|
||
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.empty())
|
||
{
|
||
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;
|
||
}
|
||
}
|
||
|
||
OUString aDesc = eInputDialogMode == InputDialogMode::NEWLIB
|
||
? CuiResId(STR_INPUTDIALOG_NEWLIBRARYLABEL)
|
||
: CuiResId(STR_INPUTDIALOG_NEWMACROLABEL);
|
||
|
||
SvxNameDialog aNameDialog(m_xDialog.get(), aNewName, aDesc,
|
||
eInputDialogMode == InputDialogMode::NEWLIB
|
||
? CuiResId(STR_INPUTDIALOG_NEWLIBRARYTITLE)
|
||
: CuiResId(STR_INPUTDIALOG_NEWMACROTITLE));
|
||
|
||
// SetCheckName 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
|
||
aNameDialog.SetCheckName([](OUString sNewName) -> bool {
|
||
if (sNewName.isEmpty() || sNewName.getLength() > 30
|
||
|| !basctl::IsValidSbxName(sNewName))
|
||
return false;
|
||
return true;
|
||
});
|
||
|
||
do
|
||
{
|
||
if (aNameDialog.run())
|
||
{
|
||
OUString aUserSuppliedName = aNameDialog.GetName();
|
||
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();
|
||
aNameDialog.SetNameText(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);
|
||
|
||
try
|
||
{
|
||
aChildNode = comphelper::scriptbrowse::createNode(xBrowseNode, aNewName);
|
||
}
|
||
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;
|
||
if (std::unique_ptr<weld::TreeIter> xIter = m_xScriptsListBox->get_selected())
|
||
{
|
||
ScriptInfo* pScriptInfo = weld::fromId<ScriptInfo*>(m_xScriptsListBox->get_id(*xIter));
|
||
if (pScriptInfo)
|
||
result = pScriptInfo->sURL;
|
||
}
|
||
return result;
|
||
}
|
||
|
||
css::uno::Reference<css::frame::XModel> MacroManagerDialog::GetScriptModel() const
|
||
{
|
||
css::uno::Reference<css::frame::XModel> xModel;
|
||
|
||
if (std::unique_ptr<weld::TreeIter> xIter = m_xScriptsListBox->get_selected())
|
||
{
|
||
ScriptInfo* pScriptInfo = weld::fromId<ScriptInfo*>(m_xScriptsListBox->get_id(*xIter));
|
||
if (pScriptInfo)
|
||
xModel = pScriptInfo->xModel;
|
||
}
|
||
|
||
return xModel;
|
||
}
|
||
|
||
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.get_selected();
|
||
if (!xIter)
|
||
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();
|
||
}
|
||
|
||
SbModule* MacroManagerDialog::GetSelectedBasicModule() const
|
||
{
|
||
weld::TreeView& rScriptContainersTreeView = m_xScriptContainersListBox->get_widget();
|
||
std::unique_ptr<weld::TreeIter> xIter = rScriptContainersTreeView.get_selected();
|
||
|
||
if (!xIter)
|
||
return nullptr;
|
||
|
||
OUString aParts[3];
|
||
|
||
// The selected node needs to be at least 4 branches deep, ie,
|
||
// Document->Language->Library->Module. Here we store the names of the last three and also check
|
||
// that the language part has a parent node.
|
||
for (auto& aPart : aParts)
|
||
{
|
||
aPart = rScriptContainersTreeView.get_text(*xIter);
|
||
|
||
if (!rScriptContainersTreeView.iter_parent(*xIter))
|
||
return nullptr;
|
||
}
|
||
|
||
if (aParts[2] != u"Basic"_ustr)
|
||
return nullptr;
|
||
|
||
basctl::ScriptDocument aDocument = m_xScriptContainersListBox->GetScriptDocument(xIter.get());
|
||
BasicManager* pBasicManager = aDocument.getBasicManager();
|
||
|
||
if (!pBasicManager)
|
||
return nullptr;
|
||
|
||
StarBASIC* pLibrary = pBasicManager->GetLib(aParts[1]);
|
||
if (!pLibrary)
|
||
return nullptr;
|
||
|
||
return pLibrary->FindModule(aParts[0]);
|
||
}
|
||
|
||
SbMethod* MacroManagerDialog::GetSelectedBasicMethod() const
|
||
{
|
||
SbModule* pModule = GetSelectedBasicModule();
|
||
|
||
if (!pModule)
|
||
return nullptr;
|
||
|
||
OUString sScriptName = m_xScriptsListBox->GetSelectedScriptName();
|
||
|
||
if (sScriptName.getLength() <= 0)
|
||
return nullptr;
|
||
|
||
return pModule->FindMethod(sScriptName, SbxClassType::Method);
|
||
}
|
||
|
||
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|