1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
22 #include <bastypes.hxx>
23 #include <bastype2.hxx>
24 #include <strings.hrc>
25 #include <bitmaps.hlst>
27 #include <tools/urlobj.hxx>
28 #include <comphelper/diagnose_ex.hxx>
29 #include <svtools/imagemgr.hxx>
30 #include <com/sun/star/script/XLibraryContainerPassword.hpp>
31 #include <com/sun/star/frame/ModuleManager.hpp>
32 #include <comphelper/processfactory.hxx>
33 #include <sfx2/dispatch.hxx>
34 #include <sfx2/sfxsids.hrc>
36 #include <initializer_list>
38 #include <string_view>
40 #include <com/sun/star/script/ModuleType.hpp>
41 #include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
42 #include <com/sun/star/lang/XServiceInfo.hpp>
43 #include <com/sun/star/container/XNamed.hpp>
49 using namespace ::com::sun::star::uno
;
50 using namespace ::com::sun::star
;
52 void ModuleInfoHelper::getObjectName( const uno::Reference
< container::XNameContainer
>& rLib
, const OUString
& rModName
, OUString
& rObjName
)
56 uno::Reference
< script::vba::XVBAModuleInfo
> xVBAModuleInfo( rLib
, uno::UNO_QUERY
);
57 if ( xVBAModuleInfo
.is() && xVBAModuleInfo
->hasModuleInfo( rModName
) )
59 script::ModuleInfo aModuleInfo
= xVBAModuleInfo
->getModuleInfo( rModName
);
60 uno::Any
aObject( aModuleInfo
.ModuleObject
);
61 uno::Reference
< lang::XServiceInfo
> xServiceInfo( aObject
, uno::UNO_QUERY
);
62 if( xServiceInfo
.is() && xServiceInfo
->supportsService( "ooo.vba.excel.Worksheet" ) )
64 uno::Reference
< container::XNamed
> xNamed( aObject
, uno::UNO_QUERY
);
66 rObjName
= xNamed
->getName();
70 catch(const uno::Exception
& )
75 sal_Int32
ModuleInfoHelper::getModuleType( const uno::Reference
< container::XNameContainer
>& rLib
, const OUString
& rModName
)
77 sal_Int32 nType
= script::ModuleType::NORMAL
;
78 uno::Reference
< script::vba::XVBAModuleInfo
> xVBAModuleInfo( rLib
, uno::UNO_QUERY
);
79 if ( xVBAModuleInfo
.is() && xVBAModuleInfo
->hasModuleInfo( rModName
) )
81 script::ModuleInfo aModuleInfo
= xVBAModuleInfo
->getModuleInfo( rModName
);
82 nType
= aModuleInfo
.ModuleType
;
90 DocumentEntry::DocumentEntry (
91 ScriptDocument aDocument
,
92 LibraryLocation eLocation
,
96 m_aDocument(std::move(aDocument
)),
97 m_eLocation(eLocation
)
99 OSL_ENSURE( m_aDocument
.isValid(), "DocumentEntry::DocumentEntry: illegal document!" );
102 DocumentEntry::~DocumentEntry()
106 ScriptDocument
const& rDocument
,
107 LibraryLocation eLocation
,
110 DocumentEntry(rDocument
, eLocation
, OBJ_TYPE_LIBRARY
),
111 m_aLibName(std::move(aLibName
))
114 LibEntry::~LibEntry()
117 EntryDescriptor::EntryDescriptor () :
118 m_aDocument(ScriptDocument::getApplicationScriptDocument()),
119 m_eLocation(LIBRARY_LOCATION_UNKNOWN
),
120 m_eType(OBJ_TYPE_UNKNOWN
)
123 EntryDescriptor::EntryDescriptor (
124 ScriptDocument aDocument
,
125 LibraryLocation eLocation
,
127 OUString aLibSubName
,
131 m_aDocument(std::move(aDocument
)),
132 m_eLocation(eLocation
),
133 m_aLibName(std::move(aLibName
)),
134 m_aLibSubName(std::move(aLibSubName
)),
135 m_aName(std::move(aName
)),
138 OSL_ENSURE( m_aDocument
.isValid(), "EntryDescriptor::EntryDescriptor: invalid document!" );
141 EntryDescriptor::EntryDescriptor (
142 ScriptDocument aDocument
,
143 LibraryLocation eLocation
,
145 OUString aLibSubName
,
147 OUString aMethodName
,
150 m_aDocument(std::move(aDocument
)),
151 m_eLocation(eLocation
),
152 m_aLibName(std::move(aLibName
)),
153 m_aLibSubName(std::move(aLibSubName
)),
154 m_aName(std::move(aName
)),
155 m_aMethodName(std::move(aMethodName
)),
158 OSL_ENSURE( m_aDocument
.isValid(), "EntryDescriptor::EntryDescriptor: invalid document!" );
161 SbTreeListBox::SbTreeListBox(std::unique_ptr
<weld::TreeView
> xControl
, weld::Window
* pTopLevel
)
162 : m_xControl(std::move(xControl
))
163 , m_xScratchIter(m_xControl
->make_iterator())
164 , m_pTopLevel(pTopLevel
)
165 , m_bFreezeOnFirstAddRemove(false)
168 m_xControl
->connect_row_activated(LINK(this, SbTreeListBox
, OpenCurrentHdl
));
169 m_xControl
->connect_expanding(LINK(this, SbTreeListBox
, RequestingChildrenHdl
));
170 nMode
= BrowseMode::All
; // everything
173 SbTreeListBox::~SbTreeListBox()
175 m_aNotifier
.dispose();
177 bool bValidIter
= m_xControl
->get_iter_first(*m_xScratchIter
);
180 Entry
* pBasicEntry
= weld::fromId
<Entry
*>(m_xControl
->get_id(*m_xScratchIter
));
182 bValidIter
= m_xControl
->iter_next(*m_xScratchIter
);
186 void SbTreeListBox::ScanEntry( const ScriptDocument
& rDocument
, LibraryLocation eLocation
)
188 OSL_ENSURE( rDocument
.isAlive(), "TreeListBox::ScanEntry: illegal document!" );
189 if ( !rDocument
.isAlive() )
192 // can be called multiple times for updating!
194 // actually test if basic's in the tree already?!
195 // level 1: BasicManager (application, document, ...)
196 bool bDocumentRootEntry
= FindRootEntry(rDocument
, eLocation
, *m_xScratchIter
);
197 if (bDocumentRootEntry
&& m_xControl
->get_row_expanded(*m_xScratchIter
))
198 ImpCreateLibEntries(*m_xScratchIter
, rDocument
, eLocation
);
199 if (!bDocumentRootEntry
)
201 OUString
aRootName(GetRootEntryName(rDocument
, eLocation
));
202 OUString
aImage(GetRootEntryBitmaps(rDocument
));
203 AddEntry(aRootName
, aImage
, nullptr, true, std::make_unique
<DocumentEntry
>(rDocument
, eLocation
));
207 void SbTreeListBox::ImpCreateLibEntries(const weld::TreeIter
& rIter
, const ScriptDocument
& rDocument
, LibraryLocation eLocation
)
209 // get a sorted list of library names
210 Sequence
< OUString
> aLibNames( rDocument
.getLibraryNames() );
211 sal_Int32 nLibCount
= aLibNames
.getLength();
212 const OUString
* pLibNames
= aLibNames
.getConstArray();
214 for ( sal_Int32 i
= 0 ; i
< nLibCount
; i
++ )
216 OUString aLibName
= pLibNames
[ i
];
218 if ( eLocation
== rDocument
.getLibraryLocation( aLibName
) )
220 // check, if the module library is loaded
221 bool bModLibLoaded
= false;
222 Reference
< script::XLibraryContainer
> xModLibContainer( rDocument
.getLibraryContainer( E_SCRIPTS
) );
223 if ( xModLibContainer
.is() && xModLibContainer
->hasByName( aLibName
) && xModLibContainer
->isLibraryLoaded( aLibName
) )
224 bModLibLoaded
= true;
226 // check, if the dialog library is loaded
227 bool bDlgLibLoaded
= false;
228 Reference
< script::XLibraryContainer
> xDlgLibContainer( rDocument
.getLibraryContainer( E_DIALOGS
) );
229 if ( xDlgLibContainer
.is() && xDlgLibContainer
->hasByName( aLibName
) && xDlgLibContainer
->isLibraryLoaded( aLibName
) )
230 bDlgLibLoaded
= true;
232 bool bLoaded
= bModLibLoaded
|| bDlgLibLoaded
;
234 // if only one of the libraries is loaded, load also the other
237 if ( xModLibContainer
.is() && xModLibContainer
->hasByName( aLibName
) && !xModLibContainer
->isLibraryLoaded( aLibName
) )
238 xModLibContainer
->loadLibrary( aLibName
);
240 if ( xDlgLibContainer
.is() && xDlgLibContainer
->hasByName( aLibName
) && !xDlgLibContainer
->isLibraryLoaded( aLibName
) )
241 xDlgLibContainer
->loadLibrary( aLibName
);
244 // create tree list box entry
246 if ( ( nMode
& BrowseMode::Dialogs
) && !( nMode
& BrowseMode::Modules
) )
247 sId
= bLoaded
? OUString(RID_BMP_DLGLIB
) : OUString(RID_BMP_DLGLIBNOTLOADED
);
249 sId
= bLoaded
? OUString(RID_BMP_MODLIB
) : OUString(RID_BMP_MODLIBNOTLOADED
);
250 std::unique_ptr
<weld::TreeIter
> xLibRootEntry(m_xControl
->make_iterator(&rIter
));
251 bool bLibRootEntry
= FindEntry(aLibName
, OBJ_TYPE_LIBRARY
, *xLibRootEntry
);
254 SetEntryBitmaps(*xLibRootEntry
, sId
);
255 bool bRowExpanded
= m_xControl
->get_row_expanded(*xLibRootEntry
);
256 bool bRowExpandAttempted
= !m_xControl
->get_children_on_demand(*xLibRootEntry
);
257 if (bRowExpanded
|| bRowExpandAttempted
)
258 ImpCreateLibSubEntries(*xLibRootEntry
, rDocument
, aLibName
);
262 AddEntry(aLibName
, sId
, &rIter
, true, std::make_unique
<Entry
>(OBJ_TYPE_LIBRARY
));
268 void SbTreeListBox::ImpCreateLibSubEntries(const weld::TreeIter
& rLibRootEntry
, const ScriptDocument
& rDocument
, const OUString
& rLibName
)
271 if ( nMode
& BrowseMode::Modules
)
273 Reference
< script::XLibraryContainer
> xModLibContainer( rDocument
.getLibraryContainer( E_SCRIPTS
) );
275 if ( xModLibContainer
.is() && xModLibContainer
->hasByName( rLibName
) && xModLibContainer
->isLibraryLoaded( rLibName
) )
279 if( rDocument
.isInVBAMode() )
281 ImpCreateLibSubEntriesInVBAMode(rLibRootEntry
, rDocument
, rLibName
);
285 // get a sorted list of module names
286 Sequence
< OUString
> aModNames
= rDocument
.getObjectNames( E_SCRIPTS
, rLibName
);
287 sal_Int32 nModCount
= aModNames
.getLength();
288 const OUString
* pModNames
= aModNames
.getConstArray();
290 auto xTreeIter
= m_xControl
->make_iterator();
292 for ( sal_Int32 i
= 0 ; i
< nModCount
; i
++ )
294 OUString aModName
= pModNames
[ i
];
295 m_xControl
->copy_iterator(rLibRootEntry
, *xTreeIter
);
296 bool bModuleEntry
= FindEntry(aModName
, OBJ_TYPE_MODULE
, *xTreeIter
);
299 AddEntry(aModName
, RID_BMP_MODULE
, &rLibRootEntry
, false, std::make_unique
<Entry
>(OBJ_TYPE_MODULE
), xTreeIter
.get());
303 if ( nMode
& BrowseMode::Subs
)
305 Sequence
< OUString
> aNames
= GetMethodNames( rDocument
, rLibName
, aModName
);
306 sal_Int32 nCount
= aNames
.getLength();
307 const OUString
* pNames
= aNames
.getConstArray();
309 auto xSubTreeIter
= m_xControl
->make_iterator();
311 for ( sal_Int32 j
= 0 ; j
< nCount
; j
++ )
313 OUString aName
= pNames
[ j
];
314 m_xControl
->copy_iterator(*xTreeIter
, *xSubTreeIter
);
315 bool bEntry
= FindEntry(aName
, OBJ_TYPE_METHOD
, *xSubTreeIter
);
318 AddEntry(aName
, RID_BMP_MACRO
, xTreeIter
.get(), false, std::make_unique
<Entry
>(OBJ_TYPE_METHOD
));
325 catch ( const container::NoSuchElementException
& )
327 DBG_UNHANDLED_EXCEPTION("basctl.basicide");
333 if ( !(nMode
& BrowseMode::Dialogs
) )
336 Reference
< script::XLibraryContainer
> xDlgLibContainer( rDocument
.getLibraryContainer( E_DIALOGS
) );
338 if ( !(xDlgLibContainer
.is() && xDlgLibContainer
->hasByName( rLibName
) && xDlgLibContainer
->isLibraryLoaded( rLibName
)) )
343 // get a sorted list of dialog names
344 Sequence
< OUString
> aDlgNames( rDocument
.getObjectNames( E_DIALOGS
, rLibName
) );
345 sal_Int32 nDlgCount
= aDlgNames
.getLength();
346 const OUString
* pDlgNames
= aDlgNames
.getConstArray();
348 auto xTreeIter
= m_xControl
->make_iterator();
350 for ( sal_Int32 i
= 0 ; i
< nDlgCount
; i
++ )
352 OUString aDlgName
= pDlgNames
[ i
];
353 m_xControl
->copy_iterator(rLibRootEntry
, *xTreeIter
);
354 bool bDialogEntry
= FindEntry(aDlgName
, OBJ_TYPE_DIALOG
, *xTreeIter
);
357 AddEntry(aDlgName
, RID_BMP_DIALOG
, &rLibRootEntry
, false, std::make_unique
<Entry
>(OBJ_TYPE_DIALOG
));
361 catch (const container::NoSuchElementException
& )
363 DBG_UNHANDLED_EXCEPTION("basctl.basicide");
367 void SbTreeListBox::ImpCreateLibSubEntriesInVBAMode(const weld::TreeIter
& rLibRootEntry
, const ScriptDocument
& rDocument
, const OUString
& rLibName
)
369 auto const aEntries
= {
370 std::make_pair( OBJ_TYPE_DOCUMENT_OBJECTS
, IDEResId(RID_STR_DOCUMENT_OBJECTS
) ),
371 std::make_pair( OBJ_TYPE_USERFORMS
, IDEResId(RID_STR_USERFORMS
) ),
372 std::make_pair( OBJ_TYPE_NORMAL_MODULES
, IDEResId(RID_STR_NORMAL_MODULES
) ),
373 std::make_pair( OBJ_TYPE_CLASS_MODULES
, IDEResId(RID_STR_CLASS_MODULES
) ) };
374 for( auto const & iter
: aEntries
)
376 EntryType eType
= iter
.first
;
377 OUString
const & aEntryName
= iter
.second
;
378 std::unique_ptr
<weld::TreeIter
> xLibSubRootEntry(m_xControl
->make_iterator(&rLibRootEntry
));
379 bool bLibSubRootEntry
= FindEntry(aEntryName
, eType
, *xLibSubRootEntry
);
380 if (bLibSubRootEntry
)
382 SetEntryBitmaps(*xLibSubRootEntry
, RID_BMP_MODLIB
);
383 if (m_xControl
->get_row_expanded(*xLibSubRootEntry
))
384 ImpCreateLibSubSubEntriesInVBAMode(*xLibSubRootEntry
, rDocument
, rLibName
);
388 m_xControl
->copy_iterator(rLibRootEntry
, *xLibSubRootEntry
);
389 AddEntry(aEntryName
, RID_BMP_MODLIB
, xLibSubRootEntry
.get(), true, std::make_unique
<Entry
>(eType
));
394 void SbTreeListBox::ImpCreateLibSubSubEntriesInVBAMode(const weld::TreeIter
& rLibSubRootEntry
, const ScriptDocument
& rDocument
, const OUString
& rLibName
)
396 uno::Reference
< container::XNameContainer
> xLib
= rDocument
.getOrCreateLibrary( E_SCRIPTS
, rLibName
);
402 // get a sorted list of module names
403 Sequence
< OUString
> aModNames
= rDocument
.getObjectNames( E_SCRIPTS
, rLibName
);
404 sal_Int32 nModCount
= aModNames
.getLength();
405 const OUString
* pModNames
= aModNames
.getConstArray();
407 EntryDescriptor
aDesc(GetEntryDescriptor(&rLibSubRootEntry
));
408 EntryType
eCurrentType(aDesc
.GetType());
410 for ( sal_Int32 i
= 0 ; i
< nModCount
; i
++ )
412 OUString aModName
= pModNames
[ i
];
413 EntryType eType
= OBJ_TYPE_UNKNOWN
;
414 switch( ModuleInfoHelper::getModuleType( xLib
, aModName
) )
416 case script::ModuleType::DOCUMENT
:
417 eType
= OBJ_TYPE_DOCUMENT_OBJECTS
;
419 case script::ModuleType::FORM
:
420 eType
= OBJ_TYPE_USERFORMS
;
422 case script::ModuleType::NORMAL
:
423 eType
= OBJ_TYPE_NORMAL_MODULES
;
425 case script::ModuleType::CLASS
:
426 eType
= OBJ_TYPE_CLASS_MODULES
;
429 if( eType
!= eCurrentType
)
432 // display a nice friendly name in the ObjectModule tab,
433 // combining the objectname and module name, e.g. Sheet1 ( Financials )
434 OUString aEntryName
= aModName
;
435 if( eType
== OBJ_TYPE_DOCUMENT_OBJECTS
)
438 ModuleInfoHelper::getObjectName( xLib
, aModName
, sObjName
);
439 if( !sObjName
.isEmpty() )
441 aEntryName
+= " (" + sObjName
+ ")";
444 std::unique_ptr
<weld::TreeIter
> xModuleEntry(m_xControl
->make_iterator(&rLibSubRootEntry
));
445 bool bModuleEntry
= FindEntry(aEntryName
, OBJ_TYPE_MODULE
, *xModuleEntry
);
448 m_xControl
->copy_iterator(rLibSubRootEntry
, *xModuleEntry
);
449 AddEntry(aEntryName
, RID_BMP_MODULE
, xModuleEntry
.get(), false,
450 std::make_unique
<Entry
>(OBJ_TYPE_MODULE
));
454 if ( nMode
& BrowseMode::Subs
)
456 Sequence
< OUString
> aNames
= GetMethodNames( rDocument
, rLibName
, aModName
);
457 sal_Int32 nCount
= aNames
.getLength();
458 const OUString
* pNames
= aNames
.getConstArray();
460 for ( sal_Int32 j
= 0 ; j
< nCount
; j
++ )
462 OUString aName
= pNames
[ j
];
463 std::unique_ptr
<weld::TreeIter
> xEntry(m_xControl
->make_iterator(xModuleEntry
.get()));
464 bool bEntry
= FindEntry(aName
, OBJ_TYPE_METHOD
, *xEntry
);
467 AddEntry(aName
, RID_BMP_MACRO
, xModuleEntry
.get(), false, std::make_unique
<Entry
>(OBJ_TYPE_METHOD
));
473 catch ( const container::NoSuchElementException
& )
475 DBG_UNHANDLED_EXCEPTION("basctl.basicide");
479 bool SbTreeListBox::ImpFindEntry(weld::TreeIter
& rIter
, std::u16string_view rText
)
481 bool bValidIter
= m_xControl
->iter_children(rIter
);
484 if (rText
== m_xControl
->get_text(rIter
))
486 bValidIter
= m_xControl
->iter_next_sibling(rIter
);
491 void SbTreeListBox::onDocumentCreated( const ScriptDocument
& /*_rDocument*/ )
496 void SbTreeListBox::onDocumentOpened( const ScriptDocument
& /*_rDocument*/ )
501 void SbTreeListBox::onDocumentSave( const ScriptDocument
& /*_rDocument*/ )
506 void SbTreeListBox::onDocumentSaveDone( const ScriptDocument
& /*_rDocument*/ )
511 void SbTreeListBox::onDocumentSaveAs( const ScriptDocument
& /*_rDocument*/ )
516 void SbTreeListBox::onDocumentSaveAsDone( const ScriptDocument
& /*_rDocument*/ )
521 void SbTreeListBox::onDocumentClosed( const ScriptDocument
& rDocument
)
524 // The document is not yet actually deleted, so we need to remove its entry
526 RemoveEntry(rDocument
);
529 void SbTreeListBox::onDocumentTitleChanged( const ScriptDocument
& /*_rDocument*/ )
534 void SbTreeListBox::onDocumentModeChanged( const ScriptDocument
& /*_rDocument*/ )
539 void SbTreeListBox::UpdateEntries()
541 bool bValidIter
= m_xControl
->get_selected(m_xScratchIter
.get());
542 EntryDescriptor
aCurDesc(GetEntryDescriptor(bValidIter
? m_xScratchIter
.get() : nullptr));
544 // removing the invalid entries
545 std::unique_ptr
<weld::TreeIter
> xLastValid(m_xControl
->make_iterator(nullptr));
546 bool bLastValid
= false;
547 bValidIter
= m_xControl
->get_iter_first(*m_xScratchIter
);
550 if (IsValidEntry(*m_xScratchIter
))
552 m_xControl
->copy_iterator(*m_xScratchIter
, *xLastValid
);
556 RemoveEntry(*m_xScratchIter
);
559 m_xControl
->copy_iterator(*xLastValid
, *m_xScratchIter
);
560 bValidIter
= m_xControl
->iter_next(*m_xScratchIter
);
563 bValidIter
= m_xControl
->get_iter_first(*m_xScratchIter
);
568 SetCurrentEntry( aCurDesc
);
571 // Removes the entry from the tree.
572 void SbTreeListBox::RemoveEntry(const weld::TreeIter
& rIter
)
574 if (m_bFreezeOnFirstAddRemove
)
576 m_xControl
->freeze();
577 m_bFreezeOnFirstAddRemove
= false;
580 // removing the associated user data
581 Entry
* pBasicEntry
= weld::fromId
<Entry
*>(m_xControl
->get_id(rIter
));
583 // removing the entry
584 m_xControl
->remove(rIter
);
587 // Removes the entry of rDocument.
588 void SbTreeListBox::RemoveEntry (ScriptDocument
const& rDocument
)
590 // finding the entry of rDocument
591 bool bValidIter
= m_xControl
->get_iter_first(*m_xScratchIter
);
594 if (rDocument
== GetEntryDescriptor(m_xScratchIter
.get()).GetDocument())
596 RemoveEntry(*m_xScratchIter
);
599 bValidIter
= m_xControl
->iter_next(*m_xScratchIter
);
603 bool SbTreeListBox::FindEntry(std::u16string_view rText
, EntryType eType
, weld::TreeIter
& rIter
)
605 bool bValidIter
= m_xControl
->iter_children(rIter
);
608 Entry
* pBasicEntry
= weld::fromId
<Entry
*>(m_xControl
->get_id(rIter
));
609 assert(pBasicEntry
&& "FindEntry: no Entry ?!");
610 if (pBasicEntry
->GetType() == eType
&& rText
== m_xControl
->get_text(rIter
))
612 bValidIter
= m_xControl
->iter_next_sibling(rIter
);
617 bool SbTreeListBox::IsEntryProtected(const weld::TreeIter
* pEntry
)
619 bool bProtected
= false;
620 if (pEntry
&& m_xControl
->get_iter_depth(*pEntry
) == 1)
622 EntryDescriptor
aDesc(GetEntryDescriptor(pEntry
));
623 const ScriptDocument
& rDocument( aDesc
.GetDocument() );
624 OSL_ENSURE( rDocument
.isAlive(), "TreeListBox::IsEntryProtected: no document, or document is dead!" );
625 if ( rDocument
.isAlive() )
627 const OUString
& aOULibName( aDesc
.GetLibName() );
628 Reference
< script::XLibraryContainer
> xModLibContainer( rDocument
.getLibraryContainer( E_SCRIPTS
) );
629 if ( xModLibContainer
.is() && xModLibContainer
->hasByName( aOULibName
) )
631 Reference
< script::XLibraryContainerPassword
> xPasswd( xModLibContainer
, UNO_QUERY
);
632 if ( xPasswd
.is() && xPasswd
->isLibraryPasswordProtected( aOULibName
) && !xPasswd
->isLibraryPasswordVerified( aOULibName
) )
642 void SbTreeListBox::AddEntry(
643 const OUString
& rText
,
644 const OUString
& rImage
,
645 const weld::TreeIter
* pParent
,
646 bool bChildrenOnDemand
,
647 std::unique_ptr
<Entry
>&& rUserData
,
648 weld::TreeIter
* pRet
)
650 if (m_bFreezeOnFirstAddRemove
)
652 m_xControl
->freeze();
653 m_bFreezeOnFirstAddRemove
= false;
655 std::unique_ptr
<weld::TreeIter
> xScratch
= pRet
? nullptr : m_xControl
->make_iterator();
657 pRet
= xScratch
.get();
658 OUString
sId(weld::toId(rUserData
.release()));
659 m_xControl
->insert(pParent
, -1, &rText
, &sId
, nullptr, nullptr, bChildrenOnDemand
, pRet
);
660 m_xControl
->set_image(*pRet
, rImage
);
663 void SbTreeListBox::SetEntryBitmaps(const weld::TreeIter
& rIter
, const OUString
& rImage
)
665 m_xControl
->set_image(rIter
, rImage
, -1);
668 LibraryType
SbTreeListBox::GetLibraryType() const
670 LibraryType eType
= LibraryType::All
;
671 if ( ( nMode
& BrowseMode::Modules
) && !( nMode
& BrowseMode::Dialogs
) )
672 eType
= LibraryType::Module
;
673 else if ( !( nMode
& BrowseMode::Modules
) && ( nMode
& BrowseMode::Dialogs
) )
674 eType
= LibraryType::Dialog
;
678 OUString
SbTreeListBox::GetRootEntryName( const ScriptDocument
& rDocument
, LibraryLocation eLocation
) const
680 return rDocument
.getTitle( eLocation
, GetLibraryType() );
683 OUString
SbTreeListBox::GetRootEntryBitmaps(const ScriptDocument
& rDocument
)
685 OSL_ENSURE( rDocument
.isValid(), "TreeListBox::GetRootEntryBitmaps: illegal document!" );
686 if (!rDocument
.isValid())
689 if ( rDocument
.isDocument() )
691 OUString sFactoryURL
;
692 Reference
<uno::XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
693 Reference
< frame::XModuleManager2
> xModuleManager( frame::ModuleManager::create(xContext
) );
696 OUString
sModule( xModuleManager
->identify( rDocument
.getDocument() ) );
697 Sequence
< beans::PropertyValue
> aModuleDescr
;
698 xModuleManager
->getByName( sModule
) >>= aModuleDescr
;
699 sal_Int32 nCount
= aModuleDescr
.getLength();
700 const beans::PropertyValue
* pModuleDescr
= aModuleDescr
.getConstArray();
701 for ( sal_Int32 i
= 0; i
< nCount
; ++i
)
703 if ( pModuleDescr
[ i
].Name
== "ooSetupFactoryEmptyDocumentURL" )
705 pModuleDescr
[ i
].Value
>>= sFactoryURL
;
710 catch( const Exception
& )
712 DBG_UNHANDLED_EXCEPTION("basctl.basicide");
715 if ( !sFactoryURL
.isEmpty() )
717 return SvFileInformationManager::GetFileImageId(INetURLObject(sFactoryURL
));
722 return RID_BMP_DOCUMENT
;
725 return RID_BMP_INSTALLATION
;
728 void SbTreeListBox::SetCurrentEntry (EntryDescriptor
const & rDesc
)
730 bool bCurEntry
= false;
731 auto xCurIter
= m_xControl
->make_iterator();
732 EntryDescriptor aDesc
= rDesc
;
733 if ( aDesc
.GetType() == OBJ_TYPE_UNKNOWN
)
735 aDesc
= EntryDescriptor(
736 ScriptDocument::getApplicationScriptDocument(),
737 LIBRARY_LOCATION_USER
, "Standard",
738 OUString(), ".", OBJ_TYPE_UNKNOWN
741 ScriptDocument aDocument
= aDesc
.GetDocument();
742 OSL_ENSURE( aDocument
.isValid(), "TreeListBox::SetCurrentEntry: invalid document!" );
743 LibraryLocation eLocation
= aDesc
.GetLocation();
744 bool bRootEntry
= FindRootEntry(aDocument
, eLocation
, *m_xScratchIter
);
747 m_xControl
->copy_iterator(*m_xScratchIter
, *xCurIter
);
749 const OUString
& aLibName( aDesc
.GetLibName() );
750 if ( !aLibName
.isEmpty() )
752 m_xControl
->expand_row(*m_xScratchIter
);
753 auto xLibIter
= m_xControl
->make_iterator(m_xScratchIter
.get());
754 bool bLibEntry
= FindEntry(aLibName
, OBJ_TYPE_LIBRARY
, *xLibIter
);
757 m_xControl
->copy_iterator(*xLibIter
, *xCurIter
);
758 const OUString
& aLibSubName( aDesc
.GetLibSubName() );
759 if( !aLibSubName
.isEmpty() )
761 m_xControl
->expand_row(*xLibIter
);
762 auto xSubLibIter
= m_xControl
->make_iterator(xLibIter
.get());
763 bool bSubLibEntry
= ImpFindEntry(*xSubLibIter
, aLibSubName
);
766 m_xControl
->copy_iterator(*xSubLibIter
, *xCurIter
);
769 const OUString
& aName( aDesc
.GetName() );
770 if ( !aName
.isEmpty() )
772 m_xControl
->expand_row(*xCurIter
);
773 EntryType eType
= OBJ_TYPE_MODULE
;
774 if ( aDesc
.GetType() == OBJ_TYPE_DIALOG
)
775 eType
= OBJ_TYPE_DIALOG
;
776 auto xEntryIter
= m_xControl
->make_iterator(xCurIter
.get());
777 bool bEntry
= FindEntry(aName
, eType
, *xEntryIter
);
780 m_xControl
->copy_iterator(*xEntryIter
, *xCurIter
);
781 const OUString
& aMethodName( aDesc
.GetMethodName() );
782 if (!aMethodName
.isEmpty())
784 m_xControl
->expand_row(*xCurIter
);
785 auto xSubEntryIter
= m_xControl
->make_iterator(xCurIter
.get());
786 bool bSubEntry
= FindEntry(aMethodName
, OBJ_TYPE_METHOD
, *xSubEntryIter
);
789 m_xControl
->copy_iterator(*xSubEntryIter
, *xCurIter
);
793 m_xControl
->copy_iterator(*xCurIter
, *xSubEntryIter
);
794 if (m_xControl
->iter_children(*xSubEntryIter
))
795 m_xControl
->copy_iterator(*xSubEntryIter
, *xCurIter
);
801 auto xSubEntryIter
= m_xControl
->make_iterator(xCurIter
.get());
802 if (m_xControl
->iter_children(*xSubEntryIter
))
803 m_xControl
->copy_iterator(*xSubEntryIter
, *xCurIter
);
809 auto xSubLibIter
= m_xControl
->make_iterator(m_xScratchIter
.get());
810 if (m_xControl
->iter_children(*xSubLibIter
))
811 m_xControl
->copy_iterator(*xLibIter
, *xCurIter
);
817 bCurEntry
= m_xControl
->get_iter_first(*xCurIter
);
823 m_xControl
->set_cursor(*xCurIter
);
826 IMPL_LINK_NOARG(SbTreeListBox
, OpenCurrentHdl
, weld::TreeView
&, bool)
828 bool bValidIter
= m_xControl
->get_cursor(m_xScratchIter
.get());
831 if (!m_xControl
->get_row_expanded(*m_xScratchIter
))
832 m_xControl
->expand_row(*m_xScratchIter
);
834 m_xControl
->collapse_row(*m_xScratchIter
);
836 EntryDescriptor aDesc
= GetEntryDescriptor(m_xScratchIter
.get());
837 switch (aDesc
.GetType())
839 case OBJ_TYPE_METHOD
:
840 case OBJ_TYPE_MODULE
:
841 case OBJ_TYPE_DIALOG
:
842 if (SfxDispatcher
* pDispatcher
= GetDispatcher())
845 SID_BASICIDE_ARG_SBX
, aDesc
.GetDocument(),
846 aDesc
.GetLibName(), aDesc
.GetName(), aDesc
.GetMethodName(),
847 ConvertType(aDesc
.GetType())
849 pDispatcher
->ExecuteList(
850 SID_BASICIDE_SHOWSBX
, SfxCallMode::SYNCHRON
,
862 } // namespace basctl
864 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */