bump product version to 5.0.4.1
[LibreOffice.git] / cui / source / customize / cfgutil.cxx
blobf5540623e83208667ab2d5064fc6f1cd284a5566
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "cfgutil.hxx"
22 #include <com/sun/star/beans/XPropertySet.hpp>
23 #include <com/sun/star/container/XEnumerationAccess.hpp>
24 #include <com/sun/star/container/XEnumeration.hpp>
25 #include <com/sun/star/document/XScriptInvocationContext.hpp>
26 #include <com/sun/star/frame/ModuleManager.hpp>
27 #include <com/sun/star/frame/Desktop.hpp>
28 #include <com/sun/star/frame/theUICommandDescription.hpp>
29 #include <com/sun/star/frame/XDispatchInformationProvider.hpp>
30 #include <com/sun/star/script/browse/XBrowseNode.hpp>
31 #include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
32 #include <com/sun/star/script/browse/theBrowseNodeFactory.hpp>
33 #include <com/sun/star/script/browse/BrowseNodeFactoryViewTypes.hpp>
34 #include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
35 #include <com/sun/star/script/provider/XScriptProvider.hpp>
36 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
37 #include <com/sun/star/uno/RuntimeException.hpp>
38 #include <com/sun/star/ui/theUICategoryDescription.hpp>
40 #include "acccfg.hrc"
41 #include "helpid.hrc"
42 #include <basic/sbx.hxx>
43 #include <basic/basicmanagerrepository.hxx>
44 #include <basic/sbstar.hxx>
45 #include <basic/sbxmeth.hxx>
46 #include <basic/sbmod.hxx>
47 #include <basic/basmgr.hxx>
48 #include <tools/urlobj.hxx>
49 #include "cuires.hrc"
50 #include <sfx2/app.hxx>
51 #include <sfx2/minfitem.hxx>
52 #include <comphelper/documentinfo.hxx>
53 #include <comphelper/processfactory.hxx>
54 #include <comphelper/sequenceashashmap.hxx>
55 #include <comphelper/string.hxx>
56 #include <svtools/imagemgr.hxx>
57 #include "svtools/treelistentry.hxx"
58 #include <rtl/ustrbuf.hxx>
59 #include <unotools/configmgr.hxx>
60 #include "dialmgr.hxx"
61 #include <svl/stritem.hxx>
62 #include <vcl/builderfactory.hxx>
64 using namespace ::com::sun::star;
65 using namespace ::com::sun::star::uno;
66 using namespace ::com::sun::star::script;
67 using namespace ::com::sun::star::frame;
68 using namespace ::com::sun::star::document;
70 SfxStylesInfo_Impl::SfxStylesInfo_Impl()
73 void SfxStylesInfo_Impl::setModel(const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xModel)
75 m_xDoc = xModel;
78 static const char CMDURL_SPART [] = ".uno:StyleApply?Style:string=";
79 static const char CMDURL_FPART2[] = "&FamilyName:string=";
81 static const char CMDURL_STYLEPROT_ONLY[] = ".uno:StyleApply?";
82 static const char CMDURL_SPART_ONLY [] = "Style:string=";
83 static const char CMDURL_FPART_ONLY [] = "FamilyName:string=";
85 static const char STYLEPROP_UINAME[] = "DisplayName";
87 OUString SfxStylesInfo_Impl::generateCommand(const OUString& sFamily, const OUString& sStyle)
89 OUStringBuffer sCommand(1024);
90 sCommand.append(CMDURL_SPART );
91 sCommand.append(sStyle );
92 sCommand.append(CMDURL_FPART2);
93 sCommand.append(sFamily );
94 return sCommand.makeStringAndClear();
97 bool SfxStylesInfo_Impl::parseStyleCommand(SfxStyleInfo_Impl& aStyle)
99 static const sal_Int32 LEN_STYLEPROT = strlen(CMDURL_STYLEPROT_ONLY);
100 static const sal_Int32 LEN_SPART = strlen(CMDURL_SPART_ONLY);
101 static const sal_Int32 LEN_FPART = strlen(CMDURL_FPART_ONLY);
103 if (!aStyle.sCommand.startsWith(CMDURL_STYLEPROT_ONLY))
104 return false;
106 aStyle.sFamily.clear();
107 aStyle.sStyle.clear();
109 sal_Int32 nCmdLen = aStyle.sCommand.getLength();
110 OUString sCmdArgs = aStyle.sCommand.copy(LEN_STYLEPROT, nCmdLen-LEN_STYLEPROT);
111 sal_Int32 i = sCmdArgs.indexOf('&');
112 if (i<0)
113 return false;
115 OUString sArg = sCmdArgs.copy(0, i);
116 if (sArg.startsWith(CMDURL_SPART_ONLY))
117 aStyle.sStyle = sArg.copy(LEN_SPART, sArg.getLength()-LEN_SPART);
118 else if (sArg.startsWith(CMDURL_FPART_ONLY))
119 aStyle.sFamily = sArg.copy(LEN_FPART, sArg.getLength()-LEN_FPART);
121 sArg = sCmdArgs.copy(i+1, sCmdArgs.getLength()-i-1);
122 if (sArg.startsWith(CMDURL_SPART_ONLY))
123 aStyle.sStyle = sArg.copy(LEN_SPART, sArg.getLength()-LEN_SPART);
124 else if (sArg.startsWith(CMDURL_FPART_ONLY))
125 aStyle.sFamily = sArg.copy(LEN_FPART, sArg.getLength()-LEN_FPART);
127 if (!(aStyle.sFamily.isEmpty() || aStyle.sStyle.isEmpty()))
128 return true;
130 return false;
133 void SfxStylesInfo_Impl::getLabel4Style(SfxStyleInfo_Impl& aStyle)
137 css::uno::Reference< css::style::XStyleFamiliesSupplier > xModel(m_xDoc, css::uno::UNO_QUERY);
139 css::uno::Reference< css::container::XNameAccess > xFamilies;
140 if (xModel.is())
141 xFamilies = xModel->getStyleFamilies();
143 css::uno::Reference< css::container::XNameAccess > xStyleSet;
144 if (xFamilies.is())
145 xFamilies->getByName(aStyle.sFamily) >>= xStyleSet;
147 css::uno::Reference< css::beans::XPropertySet > xStyle;
148 if (xStyleSet.is())
149 xStyleSet->getByName(aStyle.sStyle) >>= xStyle;
151 aStyle.sLabel.clear();
152 if (xStyle.is())
153 xStyle->getPropertyValue(STYLEPROP_UINAME) >>= aStyle.sLabel;
155 catch(const css::uno::RuntimeException&)
156 { throw; }
157 catch(const css::uno::Exception&)
158 { aStyle.sLabel.clear(); }
160 if (aStyle.sLabel.isEmpty())
162 aStyle.sLabel = aStyle.sCommand;
166 ::std::vector< SfxStyleInfo_Impl > SfxStylesInfo_Impl::getStyleFamilies()
168 // Its an optional interface!
169 css::uno::Reference< css::style::XStyleFamiliesSupplier > xModel(m_xDoc, css::uno::UNO_QUERY);
170 if (!xModel.is())
171 return ::std::vector< SfxStyleInfo_Impl >();
173 css::uno::Reference< css::container::XNameAccess > xCont = xModel->getStyleFamilies();
174 css::uno::Sequence< OUString > lFamilyNames = xCont->getElementNames();
175 ::std::vector< SfxStyleInfo_Impl > lFamilies;
176 sal_Int32 c = lFamilyNames.getLength();
177 sal_Int32 i = 0;
178 for(i=0; i<c; ++i)
180 SfxStyleInfo_Impl aFamilyInfo;
181 aFamilyInfo.sFamily = lFamilyNames[i];
185 css::uno::Reference< css::beans::XPropertySet > xFamilyInfo;
186 xCont->getByName(aFamilyInfo.sFamily) >>= xFamilyInfo;
187 if (!xFamilyInfo.is())
189 // TODO_AS currently there is no support for an UIName property .. use internal family name instead
190 aFamilyInfo.sLabel = aFamilyInfo.sFamily;
192 else
193 xFamilyInfo->getPropertyValue(STYLEPROP_UINAME) >>= aFamilyInfo.sLabel;
195 catch(const css::uno::RuntimeException&)
196 { throw; }
197 catch(const css::uno::Exception&)
198 { return ::std::vector< SfxStyleInfo_Impl >(); }
200 lFamilies.push_back(aFamilyInfo);
203 return lFamilies;
206 ::std::vector< SfxStyleInfo_Impl > SfxStylesInfo_Impl::getStyles(const OUString& sFamily)
208 static const char PROP_UINAME[] = "DisplayName";
210 css::uno::Sequence< OUString > lStyleNames;
211 css::uno::Reference< css::style::XStyleFamiliesSupplier > xModel(m_xDoc, css::uno::UNO_QUERY_THROW);
212 css::uno::Reference< css::container::XNameAccess > xFamilies = xModel->getStyleFamilies();
213 css::uno::Reference< css::container::XNameAccess > xStyleSet;
216 xFamilies->getByName(sFamily) >>= xStyleSet;
217 lStyleNames = xStyleSet->getElementNames();
219 catch(const css::uno::RuntimeException&)
220 { throw; }
221 catch(const css::uno::Exception&)
222 { return ::std::vector< SfxStyleInfo_Impl >(); }
224 ::std::vector< SfxStyleInfo_Impl > lStyles;
225 sal_Int32 c = lStyleNames.getLength();
226 sal_Int32 i = 0;
227 for (i=0; i<c; ++i)
229 SfxStyleInfo_Impl aStyleInfo;
230 aStyleInfo.sFamily = sFamily;
231 aStyleInfo.sStyle = lStyleNames[i];
232 aStyleInfo.sCommand = SfxStylesInfo_Impl::generateCommand(aStyleInfo.sFamily, aStyleInfo.sStyle);
236 css::uno::Reference< css::beans::XPropertySet > xStyle;
237 xStyleSet->getByName(aStyleInfo.sStyle) >>= xStyle;
238 if (!xStyle.is())
239 continue;
240 xStyle->getPropertyValue(PROP_UINAME) >>= aStyleInfo.sLabel;
242 catch(const css::uno::RuntimeException&)
243 { throw; }
244 catch(const css::uno::Exception&)
245 { continue; }
247 lStyles.push_back(aStyleInfo);
249 return lStyles;
252 SfxConfigFunctionListBox::SfxConfigFunctionListBox(vcl::Window* pParent, WinBits nStyle)
253 : SvTreeListBox( pParent, nStyle )
254 , pCurEntry( 0 )
255 , pStylesInfo( 0 )
257 SetStyle( GetStyle() | WB_CLIPCHILDREN | WB_HSCROLL | WB_SORT );
258 GetModel()->SetSortMode( SortAscending );
261 VCL_BUILDER_DECL_FACTORY(SfxConfigFunctionListBox)
263 WinBits nWinBits = WB_TABSTOP;
265 OString sBorder = VclBuilder::extractCustomProperty(rMap);
266 if (!sBorder.isEmpty())
267 nWinBits |= WB_BORDER;
269 rRet = VclPtr<SfxConfigFunctionListBox>::Create(pParent, nWinBits);
272 SfxConfigFunctionListBox::~SfxConfigFunctionListBox()
274 disposeOnce();
277 void SfxConfigFunctionListBox::dispose()
279 ClearAll();
280 SvTreeListBox::dispose();
283 void SfxConfigFunctionListBox::MouseMove( const MouseEvent& )
287 void SfxConfigFunctionListBox::ClearAll()
288 /* Description
289 Deletes all entries in the FunctionListBox, all UserData and all
290 possibly existing MacroInfo.
293 sal_uInt16 nCount = aArr.size();
294 for ( sal_uInt16 i=0; i<nCount; ++i )
296 SfxGroupInfo_Impl *pData = &aArr[i];
298 if ( pData->nKind == SFX_CFGFUNCTION_SCRIPT )
300 OUString* pScriptURI = static_cast<OUString*>(pData->pObject);
301 delete pScriptURI;
304 if ( pData->nKind == SFX_CFGGROUP_SCRIPTCONTAINER )
306 XInterface* xi = static_cast<XInterface *>(pData->pObject);
307 if (xi != NULL)
309 xi->release();
314 aArr.clear();
315 Clear();
318 OUString SfxConfigFunctionListBox::GetSelectedScriptURI()
320 SvTreeListEntry *pEntry = FirstSelected();
321 if ( pEntry )
323 SfxGroupInfo_Impl *pData = static_cast<SfxGroupInfo_Impl*>(pEntry->GetUserData());
324 if ( pData && ( pData->nKind == SFX_CFGFUNCTION_SCRIPT ) )
325 return *static_cast<OUString*>(pData->pObject);
327 return OUString();
330 OUString SfxConfigFunctionListBox::GetCurCommand()
332 SvTreeListEntry *pEntry = FirstSelected();
333 if (!pEntry)
334 return OUString();
335 SfxGroupInfo_Impl *pData = static_cast<SfxGroupInfo_Impl*>(pEntry->GetUserData());
336 if (!pData)
337 return OUString();
338 return pData->sCommand;
341 OUString SfxConfigFunctionListBox::GetCurLabel()
343 SvTreeListEntry *pEntry = FirstSelected();
344 if (!pEntry)
345 return OUString();
346 SfxGroupInfo_Impl *pData = static_cast<SfxGroupInfo_Impl*>(pEntry->GetUserData());
347 if (!pData)
348 return OUString();
349 if (!pData->sLabel.isEmpty())
350 return pData->sLabel;
351 return pData->sCommand;
354 void SfxConfigFunctionListBox::SetStylesInfo(SfxStylesInfo_Impl* pStyles)
356 pStylesInfo = pStyles;
359 struct SvxConfigGroupBoxResource_Impl : public Resource
361 Image m_hdImage;
362 Image m_libImage;
363 Image m_macImage;
364 Image m_docImage;
365 OUString m_sMyMacros;
366 OUString m_sProdMacros;
367 OUString m_sMacros;
368 OUString m_sDlgMacros;
369 OUString m_aHumanAppName;
370 OUString m_aStrGroupStyles;
371 Image m_collapsedImage;
372 Image m_expandedImage;
374 SvxConfigGroupBoxResource_Impl();
377 SvxConfigGroupBoxResource_Impl::SvxConfigGroupBoxResource_Impl() :
378 Resource(CUI_RES(RID_SVXPAGE_CONFIGGROUPBOX)),
379 m_hdImage(CUI_RES(RID_CUIIMG_HARDDISK)),
380 m_libImage(CUI_RES(RID_CUIIMG_LIB)),
381 m_macImage(CUI_RES(RID_CUIIMG_MACRO)),
382 m_docImage(CUI_RES(RID_CUIIMG_DOC)),
383 m_sMyMacros(CUI_RESSTR(RID_SVXSTR_MYMACROS)),
384 m_sProdMacros(CUI_RESSTR(RID_SVXSTR_PRODMACROS)),
385 m_sMacros(CUI_RESSTR(STR_BASICMACROS)),
386 m_sDlgMacros(CUI_RESSTR(RID_SVXSTR_PRODMACROS)),
387 m_aHumanAppName(CUI_RESSTR(STR_HUMAN_APPNAME)),
388 m_aStrGroupStyles(CUI_RESSTR(STR_GROUP_STYLES)),
389 m_collapsedImage(CUI_RES(BMP_COLLAPSED)),
390 m_expandedImage(CUI_RES(BMP_EXPANDED))
392 FreeResource();
395 SfxConfigGroupListBox::SfxConfigGroupListBox(vcl::Window* pParent, WinBits nStyle)
396 : SvTreeListBox(pParent, nStyle)
397 , pImp(new SvxConfigGroupBoxResource_Impl()), pFunctionListBox(0), pStylesInfo(0)
399 SetStyle( GetStyle() | WB_CLIPCHILDREN | WB_HSCROLL | WB_HASBUTTONS | WB_HASLINES | WB_HASLINESATROOT | WB_HASBUTTONSATROOT );
400 SetNodeBitmaps( pImp->m_collapsedImage, pImp->m_expandedImage );
403 VCL_BUILDER_DECL_FACTORY(SfxConfigGroupListBox)
405 WinBits nWinBits = WB_TABSTOP;
407 OString sBorder = VclBuilder::extractCustomProperty(rMap);
408 if (!sBorder.isEmpty())
409 nWinBits |= WB_BORDER;
411 rRet = VclPtr<SfxConfigGroupListBox>::Create(pParent, nWinBits);
414 SfxConfigGroupListBox::~SfxConfigGroupListBox()
416 disposeOnce();
419 void SfxConfigGroupListBox::dispose()
421 ClearAll();
422 pFunctionListBox.clear();
423 SvTreeListBox::dispose();
426 void SfxConfigGroupListBox::ClearAll()
428 sal_uInt16 nCount = aArr.size();
429 for ( sal_uInt16 i=0; i<nCount; ++i )
431 SfxGroupInfo_Impl *pData = &aArr[i];
432 if (pData->nKind == SFX_CFGGROUP_SCRIPTCONTAINER)
434 XInterface* xi = static_cast<XInterface *>(pData->pObject);
435 if (xi != NULL)
437 xi->release();
442 aArr.clear();
443 Clear();
446 void SfxConfigGroupListBox::SetStylesInfo(SfxStylesInfo_Impl* pStyles)
448 pStylesInfo = pStyles;
452 void SfxConfigGroupListBox::InitModule()
456 css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider(m_xFrame, css::uno::UNO_QUERY_THROW);
457 css::uno::Sequence< sal_Int16 > lGroups = xProvider->getSupportedCommandGroups();
458 sal_Int32 c1 = lGroups.getLength();
459 sal_Int32 i1 = 0;
461 for (i1=0; i1<c1; ++i1)
463 sal_Int16& rGroupID = lGroups[i1];
464 OUString sGroupID = OUString::number(rGroupID);
465 OUString sGroupName ;
469 m_xModuleCategoryInfo->getByName(sGroupID) >>= sGroupName;
470 if (sGroupName.isEmpty())
471 continue;
473 catch(const css::container::NoSuchElementException&)
474 { continue; }
476 SvTreeListEntry* pEntry = InsertEntry(sGroupName, NULL);
477 SfxGroupInfo_Impl* pInfo = new SfxGroupInfo_Impl(SFX_CFGGROUP_FUNCTION, rGroupID);
478 pEntry->SetUserData(pInfo);
481 catch(const css::uno::RuntimeException&)
482 { throw; }
483 catch(const css::uno::Exception&)
488 namespace
491 /** examines a component whether it supports XEmbeddedScripts, or provides access to such a
492 component by implementing XScriptInvocationContext.
493 @return
494 the model which supports the embedded scripts, or <NULL/> if it cannot find such a
495 model
497 static Reference< XModel > lcl_getDocumentWithScripts_throw( const Reference< XInterface >& _rxComponent )
499 Reference< XEmbeddedScripts > xScripts( _rxComponent, UNO_QUERY );
500 if ( !xScripts.is() )
502 Reference< XScriptInvocationContext > xContext( _rxComponent, UNO_QUERY );
503 if ( xContext.is() )
504 xScripts.set( xContext->getScriptContainer(), UNO_QUERY );
507 return Reference< XModel >( xScripts, UNO_QUERY );
511 static Reference< XModel > lcl_getScriptableDocument_nothrow( const Reference< XFrame >& _rxFrame )
513 Reference< XModel > xDocument;
515 // examine our associated frame
518 OSL_ENSURE( _rxFrame.is(), "lcl_getScriptableDocument_nothrow: you need to pass a frame to this dialog/tab page!" );
519 if ( _rxFrame.is() )
521 // first try the model in the frame
522 Reference< XController > xController( _rxFrame->getController(), UNO_SET_THROW );
523 xDocument = lcl_getDocumentWithScripts_throw( xController->getModel() );
525 if ( !xDocument.is() )
527 // if there is no suitable document in the frame, try the controller
528 xDocument = lcl_getDocumentWithScripts_throw( _rxFrame->getController() );
532 catch( const Exception& )
536 return xDocument;
541 void SfxConfigGroupListBox::Init(const css::uno::Reference< css::uno::XComponentContext >& xContext,
542 const css::uno::Reference< css::frame::XFrame >& xFrame,
543 const OUString& sModuleLongName,
544 bool bEventMode)
546 SetUpdateMode(false);
547 ClearAll(); // Remove all old entries from treelist box
549 m_xFrame = xFrame;
550 if( xContext.is() )
552 m_xContext = xContext;
553 m_sModuleLongName = sModuleLongName;
555 m_xGlobalCategoryInfo = css::ui::theUICategoryDescription::get( m_xContext );
556 m_xModuleCategoryInfo = css::uno::Reference< css::container::XNameAccess >(m_xGlobalCategoryInfo->getByName(m_sModuleLongName), css::uno::UNO_QUERY_THROW);
557 m_xUICmdDescription = css::frame::theUICommandDescription::get( m_xContext );
559 InitModule();
562 SAL_INFO("cui.customize", "** ** About to initialise SF Scripts");
563 // Add Scripting Framework entries
564 Reference< browse::XBrowseNode > rootNode;
565 Reference< XComponentContext > xCtx(
566 comphelper::getProcessComponentContext() );
569 Reference< browse::XBrowseNodeFactory > xFac = browse::theBrowseNodeFactory::get( xCtx );
570 rootNode.set( xFac->createView( browse::BrowseNodeFactoryViewTypes::MACROSELECTOR ) );
572 catch( Exception& e )
574 SAL_INFO("cui.customize", "Caught some exception whilst retrieving browse nodes from factory... Exception: " << e.Message);
575 // TODO exception handling
579 if ( rootNode.is() )
581 if ( bEventMode )
583 //We call acquire on the XBrowseNode so that it does not
584 //get autodestructed and become invalid when accessed later.
585 rootNode->acquire();
587 SfxGroupInfo_Impl *pInfo =
588 new SfxGroupInfo_Impl( SFX_CFGGROUP_SCRIPTCONTAINER, 0,
589 static_cast<void *>(rootNode.get()));
591 OUString aTitle(pImp->m_sDlgMacros);
592 SvTreeListEntry *pNewEntry = InsertEntry( aTitle, NULL );
593 pNewEntry->SetUserData( pInfo );
594 pNewEntry->EnableChildrenOnDemand( true );
595 aArr.push_back( pInfo );
597 else
599 //We are only showing scripts not slot APIs so skip
600 //Root node and show location nodes
601 try {
602 if ( rootNode->hasChildNodes() )
604 Sequence< Reference< browse::XBrowseNode > > children =
605 rootNode->getChildNodes();
606 bool bIsRootNode = false;
608 OUString user("user");
609 OUString share("share");
610 if ( rootNode->getName() == "Root" )
612 bIsRootNode = true;
615 //To mimic current starbasic behaviour we
616 //need to make sure that only the current document
617 //is displayed in the config tree. Tests below
618 //set the bDisplay flag to FALSE if the current
619 //node is a first level child of the Root and is NOT
620 //either the current document, user or share
621 OUString currentDocTitle;
622 Reference< XModel > xDocument( lcl_getScriptableDocument_nothrow( m_xFrame ) );
623 if ( xDocument.is() )
625 currentDocTitle = ::comphelper::DocumentInfo::getDocumentTitle( xDocument );
628 for ( sal_Int32 n = 0; n < children.getLength(); ++n )
630 Reference< browse::XBrowseNode >& theChild = children[n];
631 bool bDisplay = true;
632 OUString uiName = theChild->getName();
633 if ( bIsRootNode )
635 if ( ! ((theChild->getName().equals( user ) || theChild->getName().equals( share ) ||
636 theChild->getName().equals( currentDocTitle ) ) ) )
638 bDisplay=false;
640 else
642 if ( uiName.equals( user ) )
644 uiName = pImp->m_sMyMacros;
646 else if ( uiName.equals( share ) )
648 uiName = pImp->m_sProdMacros;
652 if (children[n]->getType() != browse::BrowseNodeTypes::SCRIPT && bDisplay )
654 // We call acquire on the XBrowseNode so that it does not
655 // get autodestructed and become invalid when accessed later.
656 theChild->acquire();
658 SfxGroupInfo_Impl* pInfo =
659 new SfxGroupInfo_Impl(SFX_CFGGROUP_SCRIPTCONTAINER,
660 0, static_cast<void *>( theChild.get()));
662 Image aImage = GetImage( theChild, xCtx, bIsRootNode );
663 SvTreeListEntry* pNewEntry =
664 InsertEntry( uiName, NULL);
665 SetExpandedEntryBmp( pNewEntry, aImage );
666 SetCollapsedEntryBmp( pNewEntry, aImage );
668 pNewEntry->SetUserData( pInfo );
669 aArr.push_back( pInfo );
671 if ( children[n]->hasChildNodes() )
673 Sequence< Reference< browse::XBrowseNode > > grandchildren =
674 children[n]->getChildNodes();
676 for ( sal_Int32 m = 0; m < grandchildren.getLength(); ++m )
678 if ( grandchildren[m]->getType() == browse::BrowseNodeTypes::CONTAINER )
680 pNewEntry->EnableChildrenOnDemand( true );
681 m = grandchildren.getLength();
689 catch (RuntimeException&) {
690 // do nothing, the entry will not be displayed in the UI
695 // add styles
696 if ( m_xContext.is() )
698 OUString sStyle( pImp->m_aStrGroupStyles );
699 SvTreeListEntry *pEntry = InsertEntry( sStyle, 0 );
700 SfxGroupInfo_Impl *pInfo = new SfxGroupInfo_Impl( SFX_CFGGROUP_STYLES, 0, 0 ); // TODO last parameter should contain user data
701 aArr.push_back( pInfo );
702 pEntry->SetUserData( pInfo );
703 pEntry->EnableChildrenOnDemand( true );
706 MakeVisible( GetEntry( 0,0 ) );
707 SetUpdateMode( true );
710 Image SfxConfigGroupListBox::GetImage(
711 Reference< browse::XBrowseNode > node,
712 Reference< XComponentContext > xCtx,
713 bool bIsRootNode
716 Image aImage;
717 if ( bIsRootNode )
719 OUString user("user");
720 OUString share("share");
721 if (node->getName().equals( user ) || node->getName().equals(share ) )
723 aImage = pImp->m_hdImage;
725 else
727 OUString factoryURL;
728 OUString nodeName = node->getName();
729 Reference<XInterface> xDocumentModel = getDocumentModel(xCtx, nodeName );
730 if ( xDocumentModel.is() )
732 Reference< frame::XModuleManager2 > xModuleManager( frame::ModuleManager::create(xCtx) );
733 // get the long name of the document:
734 OUString appModule( xModuleManager->identify(
735 xDocumentModel ) );
736 Sequence<beans::PropertyValue> moduleDescr;
737 Any aAny = xModuleManager->getByName(appModule);
738 if( !( aAny >>= moduleDescr ) )
740 throw RuntimeException("SFTreeListBox::Init: failed to get PropertyValue");
742 beans::PropertyValue const * pmoduleDescr =
743 moduleDescr.getConstArray();
744 for ( sal_Int32 pos = moduleDescr.getLength(); pos--; )
746 if ( pmoduleDescr[ pos ].Name == "ooSetupFactoryEmptyDocumentURL" )
748 pmoduleDescr[ pos ].Value >>= factoryURL;
749 SAL_INFO("cui.customize", "factory url for doc images is " << factoryURL);
750 break;
754 if( !factoryURL.isEmpty() )
756 aImage = SvFileInformationManager::GetFileImage( INetURLObject(factoryURL), false );
758 else
760 aImage = pImp->m_docImage;
764 else
766 if( node->getType() == browse::BrowseNodeTypes::SCRIPT )
767 aImage = pImp->m_macImage;
768 else
769 aImage = pImp->m_libImage;
771 return aImage;
774 Reference< XInterface >
775 SfxConfigGroupListBox::getDocumentModel( Reference< XComponentContext >& xCtx, OUString& docName )
777 Reference< XInterface > xModel;
778 Reference< frame::XDesktop2 > desktop = frame::Desktop::create( xCtx );
780 Reference< container::XEnumerationAccess > componentsAccess =
781 desktop->getComponents();
782 Reference< container::XEnumeration > components =
783 componentsAccess->createEnumeration();
784 while (components->hasMoreElements())
786 Reference< frame::XModel > model(
787 components->nextElement(), UNO_QUERY );
788 if ( model.is() )
790 OUString sTdocUrl =
791 ::comphelper::DocumentInfo::getDocumentTitle( model );
792 if( sTdocUrl.equals( docName ) )
794 xModel = model;
795 break;
799 return xModel;
803 OUString SfxConfigGroupListBox::MapCommand2UIName(const OUString& sCommand)
805 OUString sUIName;
808 css::uno::Reference< css::container::XNameAccess > xModuleConf;
809 m_xUICmdDescription->getByName(m_sModuleLongName) >>= xModuleConf;
810 if (xModuleConf.is())
812 ::comphelper::SequenceAsHashMap lProps(xModuleConf->getByName(sCommand));
813 sUIName = lProps.getUnpackedValueOrDefault("Name", OUString());
816 catch(const css::uno::RuntimeException&)
817 { throw; }
818 catch(css::uno::Exception&)
819 { sUIName.clear(); }
821 // fallback for missing UINames !?
822 if (sUIName.isEmpty())
824 sUIName = sCommand;
827 return sUIName;
831 void SfxConfigGroupListBox::GroupSelected()
832 /* Description
833 A function group or a basic module has been selected.
834 All functions/macros are displayed in the functionlistbox.
837 SvTreeListEntry *pEntry = FirstSelected();
838 SfxGroupInfo_Impl *pInfo = static_cast<SfxGroupInfo_Impl*>(pEntry->GetUserData());
839 pFunctionListBox->SetUpdateMode(false);
840 pFunctionListBox->ClearAll();
841 if ( pInfo->nKind != SFX_CFGGROUP_FUNCTION &&
842 pInfo->nKind != SFX_CFGGROUP_SCRIPTCONTAINER &&
843 pInfo->nKind != SFX_CFGGROUP_STYLES )
845 pFunctionListBox->SetUpdateMode(true);
846 return;
849 switch ( pInfo->nKind )
851 case SFX_CFGGROUP_FUNCTION :
853 sal_uInt16 nGroup = pInfo->nUniqueID;
854 css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider (m_xFrame, css::uno::UNO_QUERY_THROW);
855 css::uno::Sequence< css::frame::DispatchInformation > lCommands = xProvider->getConfigurableDispatchInformation(nGroup);
856 sal_Int32 c = lCommands.getLength();
857 sal_Int32 i = 0;
859 for (i=0; i<c; ++i)
861 const css::frame::DispatchInformation& rInfo = lCommands[i];
862 OUString sUIName = MapCommand2UIName(rInfo.Command);
863 SvTreeListEntry* pFuncEntry = pFunctionListBox->InsertEntry(sUIName, NULL);
864 SfxGroupInfo_Impl* pGrpInfo = new SfxGroupInfo_Impl(SFX_CFGFUNCTION_SLOT, 0);
865 pGrpInfo->sCommand = rInfo.Command;
866 pGrpInfo->sLabel = sUIName;
867 pFuncEntry->SetUserData(pGrpInfo);
870 break;
873 case SFX_CFGGROUP_SCRIPTCONTAINER:
875 if ( !GetChildCount( pEntry ) )
877 Reference< browse::XBrowseNode > rootNode(
878 static_cast< browse::XBrowseNode* >( pInfo->pObject ) ) ;
880 try {
881 if ( rootNode->hasChildNodes() )
883 Sequence< Reference< browse::XBrowseNode > > children =
884 rootNode->getChildNodes();
886 for ( sal_Int32 n = 0; n < children.getLength(); ++n )
888 if (children[n]->getType() == browse::BrowseNodeTypes::SCRIPT)
890 OUString uri;
892 Reference < beans::XPropertySet >xPropSet( children[n], UNO_QUERY );
893 if (!xPropSet.is())
895 continue;
898 Any value =
899 xPropSet->getPropertyValue("URI");
900 value >>= uri;
902 OUString* pScriptURI = new OUString( uri );
903 SfxGroupInfo_Impl* pGrpInfo = new SfxGroupInfo_Impl( SFX_CFGFUNCTION_SCRIPT, 0, pScriptURI );
905 Image aImage = GetImage( children[n], Reference< XComponentContext >(), false );
906 SvTreeListEntry* pNewEntry =
907 pFunctionListBox->InsertEntry( children[n]->getName(), NULL );
908 pFunctionListBox->SetExpandedEntryBmp( pNewEntry, aImage );
909 pFunctionListBox->SetCollapsedEntryBmp(pNewEntry, aImage );
911 pGrpInfo->sCommand = uri;
912 pGrpInfo->sLabel = children[n]->getName();
913 pNewEntry->SetUserData( pGrpInfo );
915 pFunctionListBox->aArr.push_back( pGrpInfo );
921 catch (RuntimeException&) {
922 // do nothing, the entry will not be displayed in the UI
925 break;
928 case SFX_CFGGROUP_STYLES :
930 SfxStyleInfo_Impl* pFamily = static_cast<SfxStyleInfo_Impl*>(pInfo->pObject);
931 if (pFamily)
933 const ::std::vector< SfxStyleInfo_Impl > lStyles = pStylesInfo->getStyles(pFamily->sFamily);
934 ::std::vector< SfxStyleInfo_Impl >::const_iterator pIt;
935 for ( pIt = lStyles.begin();
936 pIt != lStyles.end() ;
937 ++pIt )
939 SfxStyleInfo_Impl* pStyle = new SfxStyleInfo_Impl(*pIt);
940 SvTreeListEntry* pFuncEntry = pFunctionListBox->InsertEntry( pStyle->sLabel, NULL );
941 SfxGroupInfo_Impl *pGrpInfo = new SfxGroupInfo_Impl( SFX_CFGGROUP_STYLES, 0, pStyle );
942 pFunctionListBox->aArr.push_back( pGrpInfo );
943 pGrpInfo->sCommand = pStyle->sCommand;
944 pGrpInfo->sLabel = pStyle->sLabel;
945 pFuncEntry->SetUserData( pGrpInfo );
948 break;
951 default:
952 return;
955 if ( pFunctionListBox->GetEntryCount() )
956 pFunctionListBox->Select( pFunctionListBox->GetEntry( 0, 0 ) );
958 pFunctionListBox->SetUpdateMode(true);
961 bool SfxConfigGroupListBox::Expand( SvTreeListEntry* pParent )
963 bool bRet = SvTreeListBox::Expand( pParent );
964 if ( bRet )
966 sal_uLong nEntries = GetOutputSizePixel().Height() / GetEntryHeight();
968 sal_uLong nChildCount = GetVisibleChildCount( pParent );
970 if ( nChildCount+1 > nEntries )
972 MakeVisible( pParent, true );
974 else
976 SvTreeListEntry *pEntry = GetFirstEntryInView();
977 sal_uLong nParentPos = 0;
978 while ( pEntry && pEntry != pParent )
980 ++nParentPos;
981 pEntry = GetNextEntryInView( pEntry );
984 if ( nParentPos + nChildCount + 1 > nEntries )
985 ScrollOutputArea( (short)( nEntries - ( nParentPos + nChildCount + 1 ) ) );
989 return bRet;
992 void SfxConfigGroupListBox::RequestingChildren( SvTreeListEntry *pEntry )
993 /* Description
994 A basic or a library is opened.
997 SfxGroupInfo_Impl *pInfo = static_cast<SfxGroupInfo_Impl*>(pEntry->GetUserData());
998 pInfo->bWasOpened = true;
999 switch ( pInfo->nKind )
1001 case SFX_CFGGROUP_SCRIPTCONTAINER:
1003 if ( !GetChildCount( pEntry ) )
1005 Reference< browse::XBrowseNode > rootNode(
1006 static_cast< browse::XBrowseNode* >( pInfo->pObject ) ) ;
1008 try {
1009 if ( rootNode->hasChildNodes() )
1011 Sequence< Reference< browse::XBrowseNode > > children =
1012 rootNode->getChildNodes();
1013 bool bIsRootNode = false;
1015 OUString user("user");
1016 OUString share("share" );
1017 if ( rootNode->getName() == "Root" )
1019 bIsRootNode = true;
1022 /* To mimic current starbasic behaviour we
1023 need to make sure that only the current document
1024 is displayed in the config tree. Tests below
1025 set the bDisplay flag to sal_False if the current
1026 node is a first level child of the Root and is NOT
1027 either the current document, user or share */
1028 OUString currentDocTitle;
1029 Reference< XModel > xDocument( lcl_getScriptableDocument_nothrow( m_xFrame ) );
1030 if ( xDocument.is() )
1032 currentDocTitle = ::comphelper::DocumentInfo::getDocumentTitle( xDocument );
1035 sal_Int32 nLen = children.getLength();
1036 for ( sal_Int32 n = 0; n < nLen; ++n )
1038 Reference< browse::XBrowseNode >& theChild = children[n];
1039 OUString aName( theChild->getName() );
1040 bool bDisplay = true;
1041 if ( bIsRootNode )
1043 if ( !( (aName.equals(user) || aName.equals(share) || aName.equals(currentDocTitle) ) ) )
1044 bDisplay=false;
1046 if ( children[n].is() && children[n]->getType() != browse::BrowseNodeTypes::SCRIPT && bDisplay )
1050 We call acquire on the XBrowseNode so that it does not
1051 get autodestructed and become invalid when accessed later.
1053 theChild->acquire();
1055 SfxGroupInfo_Impl* pGrpInfo =
1056 new SfxGroupInfo_Impl(SFX_CFGGROUP_SCRIPTCONTAINER,
1057 0, static_cast<void *>( theChild.get()));
1059 Image aImage = GetImage( theChild, Reference< XComponentContext >(), false );
1060 SvTreeListEntry* pNewEntry =
1061 InsertEntry( theChild->getName(), pEntry );
1062 SetExpandedEntryBmp( pNewEntry, aImage );
1063 SetCollapsedEntryBmp(pNewEntry, aImage );
1065 pNewEntry->SetUserData( pGrpInfo );
1066 aArr.push_back( pGrpInfo );
1068 if ( children[n]->hasChildNodes() )
1070 Sequence< Reference< browse::XBrowseNode > > grandchildren =
1071 children[n]->getChildNodes();
1073 for ( sal_Int32 m = 0; m < grandchildren.getLength(); ++m )
1075 if ( grandchildren[m]->getType() == browse::BrowseNodeTypes::CONTAINER )
1077 pNewEntry->EnableChildrenOnDemand( true );
1078 m = grandchildren.getLength();
1086 catch (RuntimeException&) {
1087 // do nothing, the entry will not be displayed in the UI
1090 break;
1093 case SFX_CFGGROUP_STYLES:
1095 if ( !GetChildCount( pEntry ) )
1097 const ::std::vector< SfxStyleInfo_Impl > lStyleFamilies = pStylesInfo->getStyleFamilies();
1098 ::std::vector< SfxStyleInfo_Impl >::const_iterator pIt;
1099 for ( pIt = lStyleFamilies.begin();
1100 pIt != lStyleFamilies.end() ;
1101 ++pIt )
1103 SfxStyleInfo_Impl* pFamily = new SfxStyleInfo_Impl(*pIt);
1104 SvTreeListEntry* pStyleEntry = InsertEntry( pFamily->sLabel, pEntry );
1105 SfxGroupInfo_Impl *pGrpInfo = new SfxGroupInfo_Impl( SFX_CFGGROUP_STYLES, 0, pFamily );
1106 aArr.push_back( pGrpInfo );
1107 pStyleEntry->SetUserData( pGrpInfo );
1108 pStyleEntry->EnableChildrenOnDemand( false );
1111 break;
1114 default:
1115 OSL_FAIL( "Falscher Gruppentyp!" );
1116 break;
1120 void SfxConfigGroupListBox::SelectMacro( const SfxMacroInfoItem *pItem )
1122 SelectMacro( pItem->GetBasicManager()->GetName(),
1123 pItem->GetQualifiedName() );
1126 void SfxConfigGroupListBox::SelectMacro( const OUString& rBasic,
1127 const OUString& rMacro )
1129 OUString aBasicName( rBasic );
1130 aBasicName += " ";
1131 aBasicName += pImp->m_sMacros;
1132 OUString aLib, aModule, aMethod;
1133 sal_uInt16 nCount = comphelper::string::getTokenCount(rMacro, '.');
1134 aMethod = rMacro.getToken( nCount-1, '.' );
1135 if ( nCount > 2 )
1137 aLib = rMacro.getToken( 0, '.' );
1138 aModule = rMacro.getToken( nCount-2, '.' );
1141 SvTreeListEntry *pEntry = FirstChild(0);
1142 while ( pEntry )
1144 OUString aEntryBas = GetEntryText( pEntry );
1145 if ( aEntryBas == aBasicName )
1147 Expand( pEntry );
1148 SvTreeListEntry *pLib = FirstChild( pEntry );
1149 while ( pLib )
1151 OUString aEntryLib = GetEntryText( pLib );
1152 if ( aEntryLib == aLib )
1154 Expand( pLib );
1155 SvTreeListEntry *pMod = FirstChild( pLib );
1156 while ( pMod )
1158 OUString aEntryMod = GetEntryText( pMod );
1159 if ( aEntryMod == aModule )
1161 Expand( pMod );
1162 MakeVisible( pMod );
1163 Select( pMod );
1164 SvTreeListEntry *pMethod = pFunctionListBox->First();
1165 while ( pMethod )
1167 OUString aEntryMethod = GetEntryText( pMethod );
1168 if ( aEntryMethod == aMethod )
1170 pFunctionListBox->Select( pMethod );
1171 pFunctionListBox->MakeVisible( pMethod );
1172 return;
1174 pMethod = pFunctionListBox->Next( pMethod );
1177 pMod = NextSibling( pMod );
1180 pLib = NextSibling( pLib );
1183 pEntry = NextSibling( pEntry );
1187 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */