blob: 3ca42e4c826a32212f4708ff29e499e35e42fd48 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_cui.hxx"
#include "cfgutil.hxx"
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/frame/XDispatchInformationProvider.hpp>
#include <com/sun/star/uno/RuntimeException.hpp>
#include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
#include <com/sun/star/script/provider/XScriptProvider.hpp>
#include <com/sun/star/script/browse/XBrowseNode.hpp>
#include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
#include <com/sun/star/script/browse/XBrowseNodeFactory.hpp>
#include <com/sun/star/script/browse/BrowseNodeFactoryViewTypes.hpp>
#include <com/sun/star/frame/XModuleManager.hpp>
#include <com/sun/star/frame/XDesktop.hpp>
#include <com/sun/star/container/XEnumerationAccess.hpp>
#include <com/sun/star/container/XEnumeration.hpp>
#include <com/sun/star/document/XDocumentInfoSupplier.hpp>
#include <com/sun/star/document/XScriptInvocationContext.hpp>
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include "acccfg.hrc"
#include "helpid.hrc"
#include <basic/sbx.hxx>
#include <basic/basicmanagerrepository.hxx>
#include <basic/sbstar.hxx>
#include <basic/sbxmeth.hxx>
#include <basic/sbmod.hxx>
#include <basic/basmgr.hxx>
#include <tools/urlobj.hxx>
#include "cuires.hrc"
#include <sfx2/app.hxx>
#include <sfx2/minfitem.hxx>
#include <unotools/processfactory.hxx>
#include <comphelper/documentinfo.hxx>
#include <svtools/imagemgr.hxx>
#include <rtl/ustrbuf.hxx>
#include <comphelper/sequenceashashmap.hxx>
#include <unotools/configmgr.hxx>
#include "dialmgr.hxx"
#include <svl/stritem.hxx>
#define _SVSTDARR_STRINGSDTOR
#include <svl/svstdarr.hxx>
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::script;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::document;
namespace css = ::com::sun::star;
static ::rtl::OUString SERVICE_UICATEGORYDESCRIPTION = ::rtl::OUString::createFromAscii("com.sun.star.ui.UICategoryDescription" );
static ::rtl::OUString SERVICE_UICMDDESCRIPTION = ::rtl::OUString::createFromAscii("com.sun.star.frame.UICommandDescription");
SfxStylesInfo_Impl::SfxStylesInfo_Impl()
{}
void SfxStylesInfo_Impl::setModel(const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xModel)
{
m_xDoc = xModel;
}
static ::rtl::OUString FAMILY_CHARACTERSTYLE = ::rtl::OUString::createFromAscii("CharacterStyles");
static ::rtl::OUString FAMILY_PARAGRAPHSTYLE = ::rtl::OUString::createFromAscii("ParagraphStyles");
static ::rtl::OUString FAMILY_FRAMESTYLE = ::rtl::OUString::createFromAscii("FrameStyles" );
static ::rtl::OUString FAMILY_PAGESTYLE = ::rtl::OUString::createFromAscii("PageStyles" );
static ::rtl::OUString FAMILY_NUMBERINGSTYLE = ::rtl::OUString::createFromAscii("NumberingStyles");
static ::rtl::OUString CMDURL_SPART = ::rtl::OUString::createFromAscii(".uno:StyleApply?Style:string=");
static ::rtl::OUString CMDURL_FPART2 = ::rtl::OUString::createFromAscii("&FamilyName:string=");
static ::rtl::OUString CMDURL_STYLEPROT_ONLY = ::rtl::OUString::createFromAscii(".uno:StyleApply?");
static ::rtl::OUString CMDURL_SPART_ONLY = ::rtl::OUString::createFromAscii("Style:string=");
static ::rtl::OUString CMDURL_FPART_ONLY = ::rtl::OUString::createFromAscii("FamilyName:string=");
static ::rtl::OUString STYLEPROP_UINAME = ::rtl::OUString::createFromAscii("DisplayName");
::rtl::OUString SfxStylesInfo_Impl::generateCommand(const ::rtl::OUString& sFamily, const ::rtl::OUString& sStyle)
{
::rtl::OUStringBuffer sCommand(1024);
sCommand.append(CMDURL_SPART );
sCommand.append(sStyle );
sCommand.append(CMDURL_FPART2);
sCommand.append(sFamily );
return sCommand.makeStringAndClear();
}
sal_Bool SfxStylesInfo_Impl::parseStyleCommand(SfxStyleInfo_Impl& aStyle)
{
static sal_Int32 LEN_STYLEPROT = CMDURL_STYLEPROT_ONLY.getLength();
static sal_Int32 LEN_SPART = CMDURL_SPART_ONLY.getLength();
static sal_Int32 LEN_FPART = CMDURL_FPART_ONLY.getLength();
if (aStyle.sCommand.indexOf(CMDURL_STYLEPROT_ONLY, 0) != 0)
return sal_False;
aStyle.sFamily = ::rtl::OUString();
aStyle.sStyle = ::rtl::OUString();
sal_Int32 nCmdLen = aStyle.sCommand.getLength();
::rtl::OUString sCmdArgs = aStyle.sCommand.copy(LEN_STYLEPROT, nCmdLen-LEN_STYLEPROT);
sal_Int32 i = sCmdArgs.indexOf('&');
if (i<0)
return sal_False;
::rtl::OUString sArg = sCmdArgs.copy(0, i);
if (sArg.indexOf(CMDURL_SPART_ONLY) == 0)
aStyle.sStyle = sArg.copy(LEN_SPART, sArg.getLength()-LEN_SPART);
else
if (sArg.indexOf(CMDURL_FPART_ONLY) == 0)
aStyle.sFamily = sArg.copy(LEN_FPART, sArg.getLength()-LEN_FPART);
sArg = sCmdArgs.copy(i+1, sCmdArgs.getLength()-i-1);
if (sArg.indexOf(CMDURL_SPART_ONLY) == 0)
aStyle.sStyle = sArg.copy(LEN_SPART, sArg.getLength()-LEN_SPART);
else
if (sArg.indexOf(CMDURL_FPART_ONLY) == 0)
aStyle.sFamily = sArg.copy(LEN_FPART, sArg.getLength()-LEN_FPART);
if (aStyle.sFamily.getLength() && aStyle.sStyle.getLength())
return sal_True;
return sal_False;
}
void SfxStylesInfo_Impl::getLabel4Style(SfxStyleInfo_Impl& aStyle)
{
try
{
css::uno::Reference< css::style::XStyleFamiliesSupplier > xModel(m_xDoc, css::uno::UNO_QUERY);
css::uno::Reference< css::container::XNameAccess > xFamilies;
if (xModel.is())
xFamilies = xModel->getStyleFamilies();
css::uno::Reference< css::container::XNameAccess > xStyleSet;
if (xFamilies.is())
xFamilies->getByName(aStyle.sFamily) >>= xStyleSet;
css::uno::Reference< css::beans::XPropertySet > xStyle;
if (xStyleSet.is())
xStyleSet->getByName(aStyle.sStyle) >>= xStyle;
aStyle.sLabel = ::rtl::OUString();
if (xStyle.is())
xStyle->getPropertyValue(STYLEPROP_UINAME) >>= aStyle.sLabel;
}
catch(const css::uno::RuntimeException& exRun)
{ throw exRun; }
catch(const css::uno::Exception&)
{ aStyle.sLabel = ::rtl::OUString(); }
if (!aStyle.sLabel.getLength())
{
aStyle.sLabel = aStyle.sCommand;
/*
#if OSL_DEBUG_LEVEL > 1
::rtl::OUStringBuffer sMsg(256);
sMsg.appendAscii("There is no UIName for the style command \"");
sMsg.append (aStyle.sCommand );
sMsg.appendAscii("\". The UI will be invalid then ..." );
OSL_ENSURE(sal_False, ::rtl::OUStringToOString(sMsg.makeStringAndClear(), RTL_TEXTENCODING_UTF8).getStr());
#endif
*/
}
}
::std::vector< SfxStyleInfo_Impl > SfxStylesInfo_Impl::getStyleFamilies()
{
// Its an optional interface!
css::uno::Reference< css::style::XStyleFamiliesSupplier > xModel(m_xDoc, css::uno::UNO_QUERY);
if (!xModel.is())
return ::std::vector< SfxStyleInfo_Impl >();
css::uno::Reference< css::container::XNameAccess > xCont = xModel->getStyleFamilies();
css::uno::Sequence< ::rtl::OUString > lFamilyNames = xCont->getElementNames();
::std::vector< SfxStyleInfo_Impl > lFamilies;
sal_Int32 c = lFamilyNames.getLength();
sal_Int32 i = 0;
for(i=0; i<c; ++i)
{
SfxStyleInfo_Impl aFamilyInfo;
aFamilyInfo.sFamily = lFamilyNames[i];
try
{
css::uno::Reference< css::beans::XPropertySet > xFamilyInfo;
xCont->getByName(aFamilyInfo.sFamily) >>= xFamilyInfo;
if (!xFamilyInfo.is())
{
// TODO_AS currently there is no support for an UIName property .. use internal family name instead
aFamilyInfo.sLabel = aFamilyInfo.sFamily;
}
else
xFamilyInfo->getPropertyValue(STYLEPROP_UINAME) >>= aFamilyInfo.sLabel;
}
catch(const css::uno::RuntimeException& exRun)
{ throw exRun; }
catch(const css::uno::Exception&)
{ return ::std::vector< SfxStyleInfo_Impl >(); }
lFamilies.push_back(aFamilyInfo);
}
return lFamilies;
}
::std::vector< SfxStyleInfo_Impl > SfxStylesInfo_Impl::getStyles(const ::rtl::OUString& sFamily)
{
static ::rtl::OUString PROP_UINAME = ::rtl::OUString::createFromAscii("DisplayName");
css::uno::Sequence< ::rtl::OUString > lStyleNames;
css::uno::Reference< css::style::XStyleFamiliesSupplier > xModel(m_xDoc, css::uno::UNO_QUERY_THROW);
css::uno::Reference< css::container::XNameAccess > xFamilies = xModel->getStyleFamilies();
css::uno::Reference< css::container::XNameAccess > xStyleSet;
try
{
xFamilies->getByName(sFamily) >>= xStyleSet;
lStyleNames = xStyleSet->getElementNames();
}
catch(const css::uno::RuntimeException& exRun)
{ throw exRun; }
catch(const css::uno::Exception&)
{ return ::std::vector< SfxStyleInfo_Impl >(); }
::std::vector< SfxStyleInfo_Impl > lStyles;
sal_Int32 c = lStyleNames.getLength();
sal_Int32 i = 0;
for (i=0; i<c; ++i)
{
SfxStyleInfo_Impl aStyleInfo;
aStyleInfo.sFamily = sFamily;
aStyleInfo.sStyle = lStyleNames[i];
aStyleInfo.sCommand = SfxStylesInfo_Impl::generateCommand(aStyleInfo.sFamily, aStyleInfo.sStyle);
try
{
css::uno::Reference< css::beans::XPropertySet > xStyle;
xStyleSet->getByName(aStyleInfo.sStyle) >>= xStyle;
if (!xStyle.is())
continue;
xStyle->getPropertyValue(PROP_UINAME) >>= aStyleInfo.sLabel;
}
catch(const css::uno::RuntimeException& exRun)
{ throw exRun; }
catch(const css::uno::Exception&)
{ continue; }
lStyles.push_back(aStyleInfo);
}
return lStyles;
}
SV_IMPL_PTRARR(SfxGroupInfoArr_Impl, SfxGroupInfoPtr);
SfxConfigFunctionListBox_Impl::SfxConfigFunctionListBox_Impl( Window* pParent, const ResId& rResId)
: SvTreeListBox( pParent, rResId )
, pCurEntry( 0 )
, pStylesInfo( 0 )
{
SetStyle( GetStyle() | WB_CLIPCHILDREN | WB_HSCROLL | WB_SORT );
GetModel()->SetSortMode( SortAscending );
// Timer f"ur die BallonHelp
aTimer.SetTimeout( 200 );
aTimer.SetTimeoutHdl(
LINK( this, SfxConfigFunctionListBox_Impl, TimerHdl ) );
}
SfxConfigFunctionListBox_Impl::~SfxConfigFunctionListBox_Impl()
{
ClearAll();
}
void SfxConfigFunctionListBox_Impl::MouseMove( const MouseEvent& )
{
/* --> PB 2004-12-01 #i37000# - no own help text needed any longer
Point aMousePos = rMEvt.GetPosPixel();
pCurEntry = GetCurEntry();
if ( pCurEntry && GetEntry( aMousePos ) == pCurEntry )
aTimer.Start();
else
{
Help::ShowBalloon( this, aMousePos, String() );
aTimer.Stop();
}
*/
}
IMPL_LINK( SfxConfigFunctionListBox_Impl, TimerHdl, Timer*, pTimer)
/* Beschreibung
Timer-Handler f"ur die Einblendung eines Hilfetextes. Wenn nach Ablauf des Timers
der Mauszeiger immer noch auf dem aktuell selektierten Eintrag steht, wird der
Helptext des Entries als Balloon-Help eingeblendet.
*/
{
(void)pTimer; // unused
/* --> PB 2004-12-01 #i37000# - no own help text needed any longer
aTimer.Stop();
Point aMousePos = GetPointerPosPixel();
SvLBoxEntry *pEntry = GetCurEntry();
if ( pEntry && GetEntry( aMousePos ) == pEntry && pCurEntry == pEntry )
{
String sHelpText = GetHelpText( pEntry );
Help::ShowBalloon( this, OutputToScreenPixel( aMousePos ), sHelpText );
}
*/
return 0L;
}
void SfxConfigFunctionListBox_Impl::ClearAll()
/* Beschreibung
L"oscht alle Eintr"age in der FunctionListBox, alle UserDaten und alle evtl.
vorhandenen MacroInfos.
*/
{
sal_uInt16 nCount = aArr.Count();
for ( sal_uInt16 i=0; i<nCount; i++ )
{
SfxGroupInfo_Impl *pData = aArr[i];
if ( pData->nKind == SFX_CFGFUNCTION_SCRIPT )
{
String* pScriptURI = (String*)pData->pObject;
delete pScriptURI;
}
if ( pData->nKind == SFX_CFGGROUP_SCRIPTCONTAINER
)
{
XInterface* xi = static_cast<XInterface *>(pData->pObject);
if (xi != NULL)
{
xi->release();
}
}
delete pData;
}
aArr.Remove( 0, nCount );
Clear();
}
String SfxConfigFunctionListBox_Impl::GetSelectedScriptURI()
{
SvLBoxEntry *pEntry = FirstSelected();
if ( pEntry )
{
SfxGroupInfo_Impl *pData = (SfxGroupInfo_Impl*) pEntry->GetUserData();
if ( pData && ( pData->nKind == SFX_CFGFUNCTION_SCRIPT ) )
return *(String*)pData->pObject;
}
return String();
}
String SfxConfigFunctionListBox_Impl::GetCurCommand()
{
SvLBoxEntry *pEntry = FirstSelected();
if (!pEntry)
return String();
SfxGroupInfo_Impl *pData = (SfxGroupInfo_Impl*) pEntry->GetUserData();
if (!pData)
return String();
return pData->sCommand;
}
String SfxConfigFunctionListBox_Impl::GetCurLabel()
{
SvLBoxEntry *pEntry = FirstSelected();
if (!pEntry)
return String();
SfxGroupInfo_Impl *pData = (SfxGroupInfo_Impl*) pEntry->GetUserData();
if (!pData)
return String();
if (pData->sLabel.Len())
return pData->sLabel;
return pData->sCommand;
}
void SfxConfigFunctionListBox_Impl::FunctionSelected()
/* Beschreibung
Setzt die Balloonhelp zur"uck, da diese immer den Helptext des selektierten
Entry anzeigen soll.
*/
{
/* --> PB 2004-12-01 #i37000# - no own help text needed any longer
Help::ShowBalloon( this, Point(), String() );
*/
}
void SfxConfigFunctionListBox_Impl::SetStylesInfo(SfxStylesInfo_Impl* pStyles)
{
pStylesInfo = pStyles;
}
struct SvxConfigGroupBoxResource_Impl : public Resource
{
Image m_hdImage;
Image m_hdImage_hc;
Image m_libImage;
Image m_libImage_hc;
Image m_macImage;
Image m_macImage_hc;
Image m_docImage;
Image m_docImage_hc;
::rtl::OUString m_sMyMacros;
::rtl::OUString m_sProdMacros;
String m_sMacros;
String m_sDlgMacros;
String m_aHumanAppName;
String m_aStrGroupStyles;
Image m_collapsedImage;
Image m_collapsedImage_hc;
Image m_expandedImage;
Image m_expandedImage_hc;
SvxConfigGroupBoxResource_Impl();
};
SvxConfigGroupBoxResource_Impl::SvxConfigGroupBoxResource_Impl() :
Resource(CUI_RES(RID_SVXPAGE_CONFIGGROUPBOX)),
m_hdImage(CUI_RES(IMG_HARDDISK)),
m_hdImage_hc(CUI_RES(IMG_HARDDISK_HC)),
m_libImage(CUI_RES(IMG_LIB)),
m_libImage_hc(CUI_RES(IMG_LIB_HC)),
m_macImage(CUI_RES(IMG_MACRO)),
m_macImage_hc(CUI_RES(IMG_MACRO_HC)),
m_docImage(CUI_RES(IMG_DOC)),
m_docImage_hc(CUI_RES(IMG_DOC_HC)),
m_sMyMacros(String(CUI_RES(STR_MYMACROS))),
m_sProdMacros(String(CUI_RES(STR_PRODMACROS))),
m_sMacros(String(CUI_RES(STR_BASICMACROS))),
m_sDlgMacros(String(CUI_RES(STR_DLG_MACROS))),
m_aHumanAppName(String(CUI_RES(STR_HUMAN_APPNAME))),
m_aStrGroupStyles(String(CUI_RES(STR_GROUP_STYLES))),
m_collapsedImage(CUI_RES(BMP_COLLAPSED)),
m_collapsedImage_hc(CUI_RES(BMP_COLLAPSED_HC)),
m_expandedImage(CUI_RES(BMP_EXPANDED)),
m_expandedImage_hc(CUI_RES(BMP_EXPANDED_HC))
{
FreeResource();
}
SfxConfigGroupListBox_Impl::SfxConfigGroupListBox_Impl(
Window* pParent, const ResId& rResId, sal_uLong nConfigMode )
: SvTreeListBox( pParent, rResId )
, pImp(new SvxConfigGroupBoxResource_Impl()), pFunctionListBox(0), nMode( nConfigMode ), pStylesInfo(0)
{
SetStyle( GetStyle() | WB_CLIPCHILDREN | WB_HSCROLL | WB_HASBUTTONS | WB_HASLINES | WB_HASLINESATROOT | WB_HASBUTTONSATROOT );
SetNodeBitmaps( pImp->m_collapsedImage, pImp->m_expandedImage, BMP_COLOR_NORMAL );
SetNodeBitmaps( pImp->m_collapsedImage_hc, pImp->m_expandedImage_hc, BMP_COLOR_HIGHCONTRAST );
}
SfxConfigGroupListBox_Impl::~SfxConfigGroupListBox_Impl()
{
ClearAll();
}
void SfxConfigGroupListBox_Impl::ClearAll()
{
sal_uInt16 nCount = aArr.Count();
for ( sal_uInt16 i=0; i<nCount; i++ )
{
SfxGroupInfo_Impl *pData = aArr[i];
if ( pData->nKind == SFX_CFGGROUP_SCRIPTCONTAINER
)
{
XInterface* xi = static_cast<XInterface *>(pData->pObject);
if (xi != NULL)
{
xi->release();
}
}
delete pData;
}
aArr.Remove( 0, nCount );
Clear();
}
void SfxConfigGroupListBox_Impl::SetStylesInfo(SfxStylesInfo_Impl* pStyles)
{
pStylesInfo = pStyles;
}
String SfxConfigGroupListBox_Impl::GetGroup()
/* Beschreibung
Gibt den Namen der selektierten Funktionsgruppe bzw. des selektierten
Basics zur"uck.
*/
{
SvLBoxEntry *pEntry = FirstSelected();
while ( pEntry )
{
SfxGroupInfo_Impl *pInfo = (SfxGroupInfo_Impl*) pEntry->GetUserData();
if ( pInfo->nKind == SFX_CFGGROUP_FUNCTION )
return GetEntryText( pEntry );
pEntry = GetParent( pEntry );
}
return String();
}
//-----------------------------------------------
void SfxConfigGroupListBox_Impl::InitModule()
{
try
{
css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider(m_xFrame, css::uno::UNO_QUERY_THROW);
css::uno::Sequence< sal_Int16 > lGroups = xProvider->getSupportedCommandGroups();
sal_Int32 c1 = lGroups.getLength();
sal_Int32 i1 = 0;
for (i1=0; i1<c1; ++i1)
{
sal_Int16& rGroupID = lGroups[i1];
::rtl::OUString sGroupID = ::rtl::OUString::valueOf((sal_Int32)rGroupID);
::rtl::OUString sGroupName ;
try
{
m_xModuleCategoryInfo->getByName(sGroupID) >>= sGroupName;
if (!sGroupName.getLength())
continue;
}
catch(const css::container::NoSuchElementException&)
{ continue; }
SvLBoxEntry* pEntry = InsertEntry(sGroupName, NULL);
SfxGroupInfo_Impl* pInfo = new SfxGroupInfo_Impl(SFX_CFGGROUP_FUNCTION, rGroupID);
pEntry->SetUserData(pInfo);
}
}
catch(const css::uno::RuntimeException& exRun)
{ throw exRun; }
catch(const css::uno::Exception&)
{}
}
//-----------------------------------------------
void SfxConfigGroupListBox_Impl::InitBasic()
{
}
//-----------------------------------------------
void SfxConfigGroupListBox_Impl::InitStyles()
{
}
//-----------------------------------------------
namespace
{
//...........................................
/** examines a component whether it supports XEmbeddedScripts, or provides access to such a
component by implementing XScriptInvocationContext.
@return
the model which supports the embedded scripts, or <NULL/> if it cannot find such a
model
*/
static Reference< XModel > lcl_getDocumentWithScripts_throw( const Reference< XInterface >& _rxComponent )
{
Reference< XEmbeddedScripts > xScripts( _rxComponent, UNO_QUERY );
if ( !xScripts.is() )
{
Reference< XScriptInvocationContext > xContext( _rxComponent, UNO_QUERY );
if ( xContext.is() )
xScripts.set( xContext->getScriptContainer(), UNO_QUERY );
}
return Reference< XModel >( xScripts, UNO_QUERY );
}
//...........................................
static Reference< XModel > lcl_getScriptableDocument_nothrow( const Reference< XFrame >& _rxFrame )
{
Reference< XModel > xDocument;
// examine our associated frame
try
{
OSL_ENSURE( _rxFrame.is(), "lcl_getScriptableDocument_nothrow: you need to pass a frame to this dialog/tab page!" );
if ( _rxFrame.is() )
{
// first try the model in the frame
Reference< XController > xController( _rxFrame->getController(), UNO_SET_THROW );
xDocument = lcl_getDocumentWithScripts_throw( xController->getModel() );
if ( !xDocument.is() )
{
// if there is no suitable document in the frame, try the controller
xDocument = lcl_getDocumentWithScripts_throw( _rxFrame->getController() );
}
}
}
catch( const Exception& )
{
//DBG_UNHANDLED_EXCEPTION();
}
return xDocument;
}
}
//-----------------------------------------------
void SfxConfigGroupListBox_Impl::Init(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
const css::uno::Reference< css::frame::XFrame >& xFrame ,
const ::rtl::OUString& sModuleLongName)
{
SetUpdateMode(sal_False);
ClearAll(); // Remove all old entries from treelist box
m_xFrame = xFrame;
if ( xSMGR.is())
{
m_xSMGR = xSMGR;
m_sModuleLongName = sModuleLongName;
m_xGlobalCategoryInfo = css::uno::Reference< css::container::XNameAccess >(m_xSMGR->createInstance(SERVICE_UICATEGORYDESCRIPTION), css::uno::UNO_QUERY_THROW);
m_xModuleCategoryInfo = css::uno::Reference< css::container::XNameAccess >(m_xGlobalCategoryInfo->getByName(m_sModuleLongName) , css::uno::UNO_QUERY_THROW);
m_xUICmdDescription = css::uno::Reference< css::container::XNameAccess >(m_xSMGR->createInstance(SERVICE_UICMDDESCRIPTION) , css::uno::UNO_QUERY_THROW);
InitModule();
InitBasic();
InitStyles();
}
OSL_TRACE("** ** About to initialise SF Scripts");
// Add Scripting Framework entries
Reference< browse::XBrowseNode > rootNode;
Reference< XComponentContext > xCtx;
try
{
Reference < beans::XPropertySet > xProps(
::comphelper::getProcessServiceFactory(), UNO_QUERY_THROW );
xCtx.set( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))), UNO_QUERY_THROW );
Reference< browse::XBrowseNodeFactory > xFac( xCtx->getValueByName(
::rtl::OUString::createFromAscii( "/singletons/com.sun.star.script.browse.theBrowseNodeFactory") ), UNO_QUERY_THROW );
rootNode.set( xFac->createView( browse::BrowseNodeFactoryViewTypes::MACROSELECTOR ) );
//rootNode.set( xFac->createView( browse::BrowseNodeFactoryViewTypes::MACROORGANIZER ) );
}
catch( Exception& e )
{
OSL_TRACE(" Caught some exception whilst retrieving browse nodes from factory... Exception: %s",
::rtl::OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US ).pData->buffer );
// TODO exception handling
}
if ( rootNode.is() )
{
if ( nMode )
{
//We call acquire on the XBrowseNode so that it does not
//get autodestructed and become invalid when accessed later.
rootNode->acquire();
SfxGroupInfo_Impl *pInfo =
new SfxGroupInfo_Impl( SFX_CFGGROUP_SCRIPTCONTAINER, 0,
static_cast<void *>(rootNode.get()));
String aTitle(pImp->m_sDlgMacros);
SvLBoxEntry *pNewEntry = InsertEntry( aTitle, NULL );
pNewEntry->SetUserData( pInfo );
pNewEntry->EnableChildsOnDemand( sal_True );
aArr.Insert( pInfo, aArr.Count() );
}
else
{
//We are only showing scripts not slot APIs so skip
//Root node and show location nodes
try {
if ( rootNode->hasChildNodes() )
{
Sequence< Reference< browse::XBrowseNode > > children =
rootNode->getChildNodes();
sal_Bool bIsRootNode = sal_False;
::rtl::OUString user = ::rtl::OUString::createFromAscii("user");
::rtl::OUString share = ::rtl::OUString::createFromAscii("share");
if ( rootNode->getName().equals(::rtl::OUString::createFromAscii("Root") ))
{
bIsRootNode = sal_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
::rtl::OUString currentDocTitle;
Reference< XModel > xDocument( lcl_getScriptableDocument_nothrow( m_xFrame ) );
if ( xDocument.is() )
{
currentDocTitle = ::comphelper::DocumentInfo::getDocumentTitle( xDocument );
}
for ( sal_Int32 n = 0; n < children.getLength(); n++ )
{
Reference< browse::XBrowseNode >& theChild = children[n];
sal_Bool bDisplay = sal_True;
::rtl::OUString uiName = theChild->getName();
if ( bIsRootNode )
{
if ( ! ((theChild->getName().equals( user ) || theChild->getName().equals( share ) ||
theChild->getName().equals( currentDocTitle ) ) ) )
{
bDisplay=sal_False;
}
else
{
if ( uiName.equals( user ) )
{
uiName = pImp->m_sMyMacros;
}
else if ( uiName.equals( share ) )
{
uiName = pImp->m_sProdMacros;
}
}
}
if (children[n]->getType() != browse::BrowseNodeTypes::SCRIPT && bDisplay )
{
// We call acquire on the XBrowseNode so that it does not
// get autodestructed and become invalid when accessed later.
theChild->acquire();
SfxGroupInfo_Impl* pInfo =
new SfxGroupInfo_Impl(SFX_CFGGROUP_SCRIPTCONTAINER,
0, static_cast<void *>( theChild.get()));
Image aImage = GetImage( theChild, xCtx, bIsRootNode,BMP_COLOR_NORMAL );
SvLBoxEntry* pNewEntry =
InsertEntry( uiName, NULL);
SetExpandedEntryBmp(pNewEntry, aImage, BMP_COLOR_NORMAL);
SetCollapsedEntryBmp(pNewEntry, aImage, BMP_COLOR_NORMAL);
aImage = GetImage( theChild, xCtx, bIsRootNode,BMP_COLOR_HIGHCONTRAST );
SetExpandedEntryBmp(pNewEntry, aImage, BMP_COLOR_HIGHCONTRAST);
SetCollapsedEntryBmp(pNewEntry, aImage, BMP_COLOR_HIGHCONTRAST);
pNewEntry->SetUserData( pInfo );
aArr.Insert( pInfo, aArr.Count() );
if ( children[n]->hasChildNodes() )
{
Sequence< Reference< browse::XBrowseNode > > grandchildren =
children[n]->getChildNodes();
for ( sal_Int32 m = 0; m < grandchildren.getLength(); m++ )
{
if ( grandchildren[m]->getType() == browse::BrowseNodeTypes::CONTAINER )
{
pNewEntry->EnableChildsOnDemand( sal_True );
m = grandchildren.getLength();
}
}
}
}
}
}
}
catch (RuntimeException&) {
// do nothing, the entry will not be displayed in the UI
}
}
}
// add styles
if ( m_xSMGR.is() )
{
String sStyle( pImp->m_aStrGroupStyles );
SvLBoxEntry *pEntry = InsertEntry( sStyle, 0 );
SfxGroupInfo_Impl *pInfo = new SfxGroupInfo_Impl( SFX_CFGGROUP_STYLES, 0, 0 ); // TODO last parameter should contain user data
aArr.Insert( pInfo, aArr.Count() );
pEntry->SetUserData( pInfo );
pEntry->EnableChildsOnDemand( sal_True );
}
MakeVisible( GetEntry( 0,0 ) );
SetUpdateMode( sal_True );
}
Image SfxConfigGroupListBox_Impl::GetImage( Reference< browse::XBrowseNode > node, Reference< XComponentContext > xCtx, bool bIsRootNode, bool bHighContrast )
{
Image aImage;
if ( bIsRootNode )
{
::rtl::OUString user = ::rtl::OUString::createFromAscii("user");
::rtl::OUString share = ::rtl::OUString::createFromAscii("share");
if (node->getName().equals( user ) || node->getName().equals(share ) )
{
if( bHighContrast == BMP_COLOR_NORMAL )
aImage = pImp->m_hdImage;
else
aImage = pImp->m_hdImage_hc;
}
else
{
::rtl::OUString factoryURL;
::rtl::OUString nodeName = node->getName();
Reference<XInterface> xDocumentModel = getDocumentModel(xCtx, nodeName );
if ( xDocumentModel.is() )
{
Reference< ::com::sun::star::frame::XModuleManager >
xModuleManager(
xCtx->getServiceManager()
->createInstanceWithContext(
::rtl::OUString::createFromAscii("" // xxx todo
"com.sun.star.frame.ModuleManager"),
xCtx ),
UNO_QUERY_THROW );
Reference<container::XNameAccess> xModuleConfig(
xModuleManager, UNO_QUERY_THROW );
// get the long name of the document:
::rtl::OUString appModule( xModuleManager->identify(
xDocumentModel ) );
Sequence<beans::PropertyValue> moduleDescr;
Any aAny = xModuleConfig->getByName(appModule);
if( sal_True != ( aAny >>= moduleDescr ) )
{
throw RuntimeException(::rtl::OUString::createFromAscii("SFTreeListBox::Init: failed to get PropertyValue"), Reference< XInterface >());
}
beans::PropertyValue const * pmoduleDescr =
moduleDescr.getConstArray();
for ( sal_Int32 pos = moduleDescr.getLength(); pos--; )
{
if (pmoduleDescr[ pos ].Name.equalsAsciiL(
RTL_CONSTASCII_STRINGPARAM(
"ooSetupFactoryEmptyDocumentURL") ))
{
pmoduleDescr[ pos ].Value >>= factoryURL;
OSL_TRACE("factory url for doc images is %s",
::rtl::OUStringToOString( factoryURL , RTL_TEXTENCODING_ASCII_US ).pData->buffer );
break;
}
}
}
if( factoryURL.getLength() > 0 )
{
if( bHighContrast == BMP_COLOR_NORMAL )
aImage = SvFileInformationManager::GetFileImage(
INetURLObject(factoryURL), false,
BMP_COLOR_NORMAL );
else
aImage = SvFileInformationManager::GetFileImage(
INetURLObject(factoryURL), false,
BMP_COLOR_HIGHCONTRAST );
}
else
{
if( bHighContrast == BMP_COLOR_NORMAL )
aImage = pImp->m_docImage;
else
aImage = pImp->m_docImage_hc;
}
}
}
else
{
if( node->getType() == browse::BrowseNodeTypes::SCRIPT )
{
if( bHighContrast == BMP_COLOR_NORMAL )
aImage = pImp->m_macImage;
else
aImage = pImp->m_macImage_hc;
}
else
{
if( bHighContrast == BMP_COLOR_NORMAL )
aImage = pImp->m_libImage;
else
aImage = pImp->m_libImage_hc;
}
}
return aImage;
}
Reference< XInterface >
SfxConfigGroupListBox_Impl::getDocumentModel( Reference< XComponentContext >& xCtx, ::rtl::OUString& docName )
{
Reference< XInterface > xModel;
Reference< lang::XMultiComponentFactory > mcf =
xCtx->getServiceManager();
Reference< frame::XDesktop > desktop (
mcf->createInstanceWithContext(
::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop"), xCtx ),
UNO_QUERY );
Reference< container::XEnumerationAccess > componentsAccess =
desktop->getComponents();
Reference< container::XEnumeration > components =
componentsAccess->createEnumeration();
while (components->hasMoreElements())
{
Reference< frame::XModel > model(
components->nextElement(), UNO_QUERY );
if ( model.is() )
{
::rtl::OUString sTdocUrl =
::comphelper::DocumentInfo::getDocumentTitle( model );
if( sTdocUrl.equals( docName ) )
{
xModel = model;
break;
}
}
}
return xModel;
}
//-----------------------------------------------
::rtl::OUString SfxConfigGroupListBox_Impl::MapCommand2UIName(const ::rtl::OUString& sCommand)
{
::rtl::OUString sUIName;
try
{
css::uno::Reference< css::container::XNameAccess > xModuleConf;
m_xUICmdDescription->getByName(m_sModuleLongName) >>= xModuleConf;
if (xModuleConf.is())
{
::comphelper::SequenceAsHashMap lProps(xModuleConf->getByName(sCommand));
sUIName = lProps.getUnpackedValueOrDefault(::rtl::OUString::createFromAscii("Name"), ::rtl::OUString());
}
}
catch(const css::uno::RuntimeException& exRun)
{ throw exRun; }
catch(css::uno::Exception&)
{ sUIName = ::rtl::OUString(); }
// fallback for missing UINames !?
if (!sUIName.getLength())
{
sUIName = sCommand;
/*
#if OSL_DEBUG_LEVEL > 1
::rtl::OUStringBuffer sMsg(256);
sMsg.appendAscii("There is no UIName for the internal command \"");
sMsg.append (sCommand );
sMsg.appendAscii("\". The UI will be invalid then ..." );
OSL_ENSURE(sal_False, ::rtl::OUStringToOString(sMsg.makeStringAndClear(), RTL_TEXTENCODING_UTF8).getStr());
#endif
*/
}
return sUIName;
}
//-----------------------------------------------
void SfxConfigGroupListBox_Impl::GroupSelected()
/* Beschreibung
Eine Funktionsgruppe oder eine Basicmodul wurde selektiert. Alle Funktionen bzw.
Macros werden in der Functionlistbox anzeigt.
*/
{
SvLBoxEntry *pEntry = FirstSelected();
SfxGroupInfo_Impl *pInfo = (SfxGroupInfo_Impl*) pEntry->GetUserData();
pFunctionListBox->SetUpdateMode(sal_False);
pFunctionListBox->ClearAll();
if ( pInfo->nKind != SFX_CFGGROUP_FUNCTION &&
pInfo->nKind != SFX_CFGGROUP_SCRIPTCONTAINER &&
pInfo->nKind != SFX_CFGGROUP_STYLES )
{
pFunctionListBox->SetUpdateMode(sal_True);
return;
}
switch ( pInfo->nKind )
{
case SFX_CFGGROUP_FUNCTION :
{
sal_uInt16 nGroup = pInfo->nUniqueID;
css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider (m_xFrame, css::uno::UNO_QUERY_THROW);
css::uno::Sequence< css::frame::DispatchInformation > lCommands = xProvider->getConfigurableDispatchInformation(nGroup);
sal_Int32 c = lCommands.getLength();
sal_Int32 i = 0;
for (i=0; i<c; ++i)
{
const css::frame::DispatchInformation& rInfo = lCommands[i];
::rtl::OUString sUIName = MapCommand2UIName(rInfo.Command);
SvLBoxEntry* pFuncEntry = pFunctionListBox->InsertEntry(sUIName, NULL);
SfxGroupInfo_Impl* pGrpInfo = new SfxGroupInfo_Impl(SFX_CFGFUNCTION_SLOT, 0);
pGrpInfo->sCommand = rInfo.Command;
pGrpInfo->sLabel = sUIName;
pFuncEntry->SetUserData(pGrpInfo);
}
break;
}
case SFX_CFGGROUP_SCRIPTCONTAINER:
{
if ( !GetChildCount( pEntry ) )
{
Reference< browse::XBrowseNode > rootNode(
reinterpret_cast< browse::XBrowseNode* >( pInfo->pObject ) ) ;
try {
if ( rootNode->hasChildNodes() )
{
Sequence< Reference< browse::XBrowseNode > > children =
rootNode->getChildNodes();
for ( sal_Int32 n = 0; n < children.getLength(); n++ )
{
if (children[n]->getType() == browse::BrowseNodeTypes::SCRIPT)
{
::rtl::OUString uri;
Reference < beans::XPropertySet >xPropSet( children[n], UNO_QUERY );
if (!xPropSet.is())
{
continue;
}
Any value =
xPropSet->getPropertyValue( String::CreateFromAscii( "URI" ) );
value >>= uri;
String* pScriptURI = new String( uri );
SfxGroupInfo_Impl* pGrpInfo = new SfxGroupInfo_Impl( SFX_CFGFUNCTION_SCRIPT, 0, pScriptURI );
Image aImage = GetImage( children[n], Reference< XComponentContext >(), sal_False, BMP_COLOR_NORMAL );
SvLBoxEntry* pNewEntry =
pFunctionListBox->InsertEntry( children[n]->getName(), NULL );
pFunctionListBox->SetExpandedEntryBmp(pNewEntry, aImage, BMP_COLOR_NORMAL);
pFunctionListBox->SetCollapsedEntryBmp(pNewEntry, aImage, BMP_COLOR_NORMAL);
aImage = GetImage( children[n], Reference< XComponentContext >(), sal_False, BMP_COLOR_HIGHCONTRAST );
pFunctionListBox->SetExpandedEntryBmp(pNewEntry, aImage, BMP_COLOR_HIGHCONTRAST);
pFunctionListBox->SetCollapsedEntryBmp(pNewEntry, aImage, BMP_COLOR_HIGHCONTRAST);
pGrpInfo->sCommand = uri;
pGrpInfo->sLabel = children[n]->getName();
pNewEntry->SetUserData( pGrpInfo );
pFunctionListBox->aArr.Insert(
pGrpInfo, pFunctionListBox->aArr.Count() );
}
}
}
}
catch (RuntimeException&) {
// do nothing, the entry will not be displayed in the UI
}
}
break;
}
case SFX_CFGGROUP_STYLES :
{
SfxStyleInfo_Impl* pFamily = (SfxStyleInfo_Impl*)(pInfo->pObject);
if (pFamily)
{
const ::std::vector< SfxStyleInfo_Impl > lStyles = pStylesInfo->getStyles(pFamily->sFamily);
::std::vector< SfxStyleInfo_Impl >::const_iterator pIt;
for ( pIt = lStyles.begin();
pIt != lStyles.end() ;
++pIt )
{
SfxStyleInfo_Impl* pStyle = new SfxStyleInfo_Impl(*pIt);
SvLBoxEntry* pFuncEntry = pFunctionListBox->InsertEntry( pStyle->sLabel, NULL );
SfxGroupInfo_Impl *pGrpInfo = new SfxGroupInfo_Impl( SFX_CFGGROUP_STYLES, 0, pStyle );
pFunctionListBox->aArr.Insert( pGrpInfo, pFunctionListBox->aArr.Count() );
pGrpInfo->sCommand = pStyle->sCommand;
pGrpInfo->sLabel = pStyle->sLabel;
pFuncEntry->SetUserData( pGrpInfo );
}
}
break;
}
default:
return;
}
if ( pFunctionListBox->GetEntryCount() )
pFunctionListBox->Select( pFunctionListBox->GetEntry( 0, 0 ) );
pFunctionListBox->SetUpdateMode(sal_True);
}
sal_Bool SfxConfigGroupListBox_Impl::Expand( SvLBoxEntry* pParent )
{
sal_Bool bRet = SvTreeListBox::Expand( pParent );
if ( bRet )
{
// Wieviele Entries k"onnen angezeigt werden ?
sal_uLong nEntries = GetOutputSizePixel().Height() / GetEntryHeight();
// Wieviele Kinder sollen angezeigt werden ?
sal_uLong nChildCount = GetVisibleChildCount( pParent );
// Passen alle Kinder und der parent gleichzeitig in die View ?
if ( nChildCount+1 > nEntries )
{
// Wenn nicht, wenigstens parent ganz nach oben schieben
MakeVisible( pParent, sal_True );
}
else
{
// An welcher relativen ViewPosition steht der aufzuklappende parent
SvLBoxEntry *pEntry = GetFirstEntryInView();
sal_uLong nParentPos = 0;
while ( pEntry && pEntry != pParent )
{
nParentPos++;
pEntry = GetNextEntryInView( pEntry );
}
// Ist unter dem parent noch genug Platz f"ur alle Kinder ?
if ( nParentPos + nChildCount + 1 > nEntries )
ScrollOutputArea( (short)( nEntries - ( nParentPos + nChildCount + 1 ) ) );
}
}
return bRet;
}
void SfxConfigGroupListBox_Impl::RequestingChilds( SvLBoxEntry *pEntry )
/* Beschreibung
Ein Basic oder eine Bibliothek werden ge"offnet
*/
{
SfxGroupInfo_Impl *pInfo = (SfxGroupInfo_Impl*) pEntry->GetUserData();
pInfo->bWasOpened = sal_True;
switch ( pInfo->nKind )
{
case SFX_CFGGROUP_SCRIPTCONTAINER:
{
if ( !GetChildCount( pEntry ) )
{
Reference< browse::XBrowseNode > rootNode(
reinterpret_cast< browse::XBrowseNode* >( pInfo->pObject ) ) ;
try {
if ( rootNode->hasChildNodes() )
{
Sequence< Reference< browse::XBrowseNode > > children =
rootNode->getChildNodes();
sal_Bool bIsRootNode = sal_False;
::rtl::OUString user = ::rtl::OUString::createFromAscii("user");
::rtl::OUString share = ::rtl::OUString::createFromAscii("share");
if ( rootNode->getName().equals(::rtl::OUString::createFromAscii("Root") ))
{
bIsRootNode = sal_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 sal_False if the current
node is a first level child of the Root and is NOT
either the current document, user or share */
::rtl::OUString currentDocTitle;
Reference< XModel > xDocument( lcl_getScriptableDocument_nothrow( m_xFrame ) );
if ( xDocument.is() )
{
currentDocTitle = ::comphelper::DocumentInfo::getDocumentTitle( xDocument );
}
sal_Int32 nLen = children.getLength();
for ( sal_Int32 n = 0; n < nLen; n++ )
{
Reference< browse::XBrowseNode >& theChild = children[n];
::rtl::OUString aName( theChild->getName() );
sal_Bool bDisplay = sal_True;
if ( bIsRootNode )
{
if ( !( (aName.equals(user) || aName.equals(share) || aName.equals(currentDocTitle) ) ) )
bDisplay=sal_False;
}
if ( children[n].is() && children[n]->getType() != browse::BrowseNodeTypes::SCRIPT && bDisplay )
{
/*
We call acquire on the XBrowseNode so that it does not
get autodestructed and become invalid when accessed later.
*/
theChild->acquire();
SfxGroupInfo_Impl* pGrpInfo =
new SfxGroupInfo_Impl(SFX_CFGGROUP_SCRIPTCONTAINER,
0, static_cast<void *>( theChild.get()));
Image aImage = GetImage( theChild, Reference< XComponentContext >(), sal_False, BMP_COLOR_NORMAL );
SvLBoxEntry* pNewEntry =
InsertEntry( theChild->getName(), pEntry );
SetExpandedEntryBmp(pNewEntry, aImage, BMP_COLOR_NORMAL);
SetCollapsedEntryBmp(pNewEntry, aImage, BMP_COLOR_NORMAL);
aImage = GetImage( theChild, Reference< XComponentContext >(), sal_False, BMP_COLOR_HIGHCONTRAST );
SetExpandedEntryBmp(pNewEntry, aImage, BMP_COLOR_HIGHCONTRAST);
SetCollapsedEntryBmp(pNewEntry, aImage, BMP_COLOR_HIGHCONTRAST);
pNewEntry->SetUserData( pGrpInfo );
aArr.Insert( pGrpInfo, aArr.Count() );
if ( children[n]->hasChildNodes() )
{
Sequence< Reference< browse::XBrowseNode > > grandchildren =
children[n]->getChildNodes();
for ( sal_Int32 m = 0; m < grandchildren.getLength(); m++ )
{
if ( grandchildren[m]->getType() == browse::BrowseNodeTypes::CONTAINER )
{
pNewEntry->EnableChildsOnDemand( sal_True );
m = grandchildren.getLength();
}
}
}
}
}
}
}
catch (RuntimeException&) {
// do nothing, the entry will not be displayed in the UI
}
}
break;
}
case SFX_CFGGROUP_STYLES:
{
if ( !GetChildCount( pEntry ) )
{
const ::std::vector< SfxStyleInfo_Impl > lStyleFamilies = pStylesInfo->getStyleFamilies();
::std::vector< SfxStyleInfo_Impl >::const_iterator pIt;
for ( pIt = lStyleFamilies.begin();
pIt != lStyleFamilies.end() ;
++pIt )
{
SfxStyleInfo_Impl* pFamily = new SfxStyleInfo_Impl(*pIt);
SvLBoxEntry* pStyleEntry = InsertEntry( pFamily->sLabel, pEntry );
SfxGroupInfo_Impl *pGrpInfo = new SfxGroupInfo_Impl( SFX_CFGGROUP_STYLES, 0, pFamily );
aArr.Insert( pGrpInfo, aArr.Count() );
pStyleEntry->SetUserData( pGrpInfo );
pStyleEntry->EnableChildsOnDemand( sal_False );
}
}
break;
}
default:
DBG_ERROR( "Falscher Gruppentyp!" );
break;
}
}
void SfxConfigGroupListBox_Impl::SelectMacro( const SfxMacroInfoItem *pItem )
{
SelectMacro( pItem->GetBasicManager()->GetName(),
pItem->GetQualifiedName() );
}
void SfxConfigGroupListBox_Impl::SelectMacro( const String& rBasic,
const String& rMacro )
{
String aBasicName( rBasic );
aBasicName += ' ';
aBasicName += pImp->m_sMacros;
String aLib, aModule, aMethod;
sal_uInt16 nCount = rMacro.GetTokenCount('.');
aMethod = rMacro.GetToken( nCount-1, '.' );
if ( nCount > 2 )
{
aLib = rMacro.GetToken( 0, '.' );
aModule = rMacro.GetToken( nCount-2, '.' );
}
SvLBoxEntry *pEntry = FirstChild(0);
while ( pEntry )
{
String aEntryBas = GetEntryText( pEntry );
if ( aEntryBas == aBasicName )
{
Expand( pEntry );
SvLBoxEntry *pLib = FirstChild( pEntry );
while ( pLib )
{
String aEntryLib = GetEntryText( pLib );
if ( aEntryLib == aLib )
{
Expand( pLib );
SvLBoxEntry *pMod = FirstChild( pLib );
while ( pMod )
{
String aEntryMod = GetEntryText( pMod );
if ( aEntryMod == aModule )
{
Expand( pMod );
MakeVisible( pMod );
Select( pMod );
SvLBoxEntry *pMethod = pFunctionListBox->First();
while ( pMethod )
{
String aEntryMethod = GetEntryText( pMethod );
if ( aEntryMethod == aMethod )
{
pFunctionListBox->Select( pMethod );
pFunctionListBox->MakeVisible( pMethod );
return;
}
pMethod = pFunctionListBox->Next( pMethod );
}
}
pMod = NextSibling( pMod );
}
}
pLib = NextSibling( pLib );
}
}
pEntry = NextSibling( pEntry );
}
}