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 <tools/diagnose_ex.h>
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>
48 using namespace ::com::sun::star::uno
;
49 using namespace ::com::sun::star
;
51 void ModuleInfoHelper::getObjectName( const uno::Reference
< container::XNameContainer
>& rLib
, const OUString
& rModName
, OUString
& rObjName
)
55 uno::Reference
< script::vba::XVBAModuleInfo
> xVBAModuleInfo( rLib
, uno::UNO_QUERY
);
56 if ( xVBAModuleInfo
.is() && xVBAModuleInfo
->hasModuleInfo( rModName
) )
58 script::ModuleInfo aModuleInfo
= xVBAModuleInfo
->getModuleInfo( rModName
);
59 uno::Any
aObject( aModuleInfo
.ModuleObject
);
60 uno::Reference
< lang::XServiceInfo
> xServiceInfo( aObject
, uno::UNO_QUERY
);
61 if( xServiceInfo
.is() && xServiceInfo
->supportsService( "ooo.vba.excel.Worksheet" ) )
63 uno::Reference
< container::XNamed
> xNamed( aObject
, uno::UNO_QUERY
);
65 rObjName
= xNamed
->getName();
69 catch(const uno::Exception
& )
74 sal_Int32
ModuleInfoHelper::getModuleType( const uno::Reference
< container::XNameContainer
>& rLib
, const OUString
& rModName
)
76 sal_Int32 nType
= script::ModuleType::NORMAL
;
77 uno::Reference
< script::vba::XVBAModuleInfo
> xVBAModuleInfo( rLib
, uno::UNO_QUERY
);
78 if ( xVBAModuleInfo
.is() && xVBAModuleInfo
->hasModuleInfo( rModName
) )
80 script::ModuleInfo aModuleInfo
= xVBAModuleInfo
->getModuleInfo( rModName
);
81 nType
= aModuleInfo
.ModuleType
;
89 DocumentEntry::DocumentEntry (
90 ScriptDocument
const& rDocument
,
91 LibraryLocation eLocation
,
95 m_aDocument(rDocument
),
96 m_eLocation(eLocation
)
98 OSL_ENSURE( m_aDocument
.isValid(), "DocumentEntry::DocumentEntry: illegal document!" );
101 DocumentEntry::~DocumentEntry()
105 ScriptDocument
const& rDocument
,
106 LibraryLocation eLocation
,
107 OUString
const& rLibName
109 DocumentEntry(rDocument
, eLocation
, OBJ_TYPE_LIBRARY
),
113 LibEntry::~LibEntry()
116 EntryDescriptor::EntryDescriptor () :
117 m_aDocument(ScriptDocument::getApplicationScriptDocument()),
118 m_eLocation(LIBRARY_LOCATION_UNKNOWN
),
119 m_eType(OBJ_TYPE_UNKNOWN
)
122 EntryDescriptor::EntryDescriptor (
123 ScriptDocument
const& rDocument
,
124 LibraryLocation eLocation
,
125 OUString
const& rLibName
,
126 OUString
const& rLibSubName
,
127 OUString
const& rName
,
130 m_aDocument(rDocument
),
131 m_eLocation(eLocation
),
132 m_aLibName(rLibName
),
133 m_aLibSubName(rLibSubName
),
137 OSL_ENSURE( m_aDocument
.isValid(), "EntryDescriptor::EntryDescriptor: invalid document!" );
140 EntryDescriptor::EntryDescriptor (
141 ScriptDocument
const& rDocument
,
142 LibraryLocation eLocation
,
143 OUString
const& rLibName
,
144 OUString
const& rLibSubName
,
145 OUString
const& rName
,
146 OUString
const& rMethodName
,
149 m_aDocument(rDocument
),
150 m_eLocation(eLocation
),
151 m_aLibName(rLibName
),
152 m_aLibSubName(rLibSubName
),
154 m_aMethodName(rMethodName
),
157 OSL_ENSURE( m_aDocument
.isValid(), "EntryDescriptor::EntryDescriptor: invalid document!" );
160 SbTreeListBox::SbTreeListBox(std::unique_ptr
<weld::TreeView
> xControl
, weld::Window
* pTopLevel
)
161 : m_xControl(std::move(xControl
))
162 , m_xScratchIter(m_xControl
->make_iterator())
163 , m_pTopLevel(pTopLevel
)
164 , m_bFreezeOnFirstAddRemove(false)
167 m_xControl
->connect_row_activated(LINK(this, SbTreeListBox
, OpenCurrentHdl
));
168 m_xControl
->connect_expanding(LINK(this, SbTreeListBox
, RequestingChildrenHdl
));
169 nMode
= BrowseMode::All
; // everything
172 SbTreeListBox::~SbTreeListBox()
174 m_aNotifier
.dispose();
176 bool bValidIter
= m_xControl
->get_iter_first(*m_xScratchIter
);
179 Entry
* pBasicEntry
= reinterpret_cast<Entry
*>(m_xControl
->get_id(*m_xScratchIter
).toInt64());
181 bValidIter
= m_xControl
->iter_next(*m_xScratchIter
);
185 void SbTreeListBox::ScanEntry( const ScriptDocument
& rDocument
, LibraryLocation eLocation
)
187 OSL_ENSURE( rDocument
.isAlive(), "TreeListBox::ScanEntry: illegal document!" );
188 if ( !rDocument
.isAlive() )
191 // can be called multiple times for updating!
193 // actually test if basic's in the tree already?!
194 // level 1: BasicManager (application, document, ...)
195 bool bDocumentRootEntry
= FindRootEntry(rDocument
, eLocation
, *m_xScratchIter
);
196 if (bDocumentRootEntry
&& m_xControl
->get_row_expanded(*m_xScratchIter
))
197 ImpCreateLibEntries(*m_xScratchIter
, rDocument
, eLocation
);
198 if (!bDocumentRootEntry
)
200 OUString
aRootName(GetRootEntryName(rDocument
, eLocation
));
201 OUString
aImage(GetRootEntryBitmaps(rDocument
));
202 AddEntry(aRootName
, aImage
, nullptr, true, std::make_unique
<DocumentEntry
>(rDocument
, eLocation
));
206 void SbTreeListBox::ImpCreateLibEntries(const weld::TreeIter
& rIter
, const ScriptDocument
& rDocument
, LibraryLocation eLocation
)
208 // get a sorted list of library names
209 Sequence
< OUString
> aLibNames( rDocument
.getLibraryNames() );
210 sal_Int32 nLibCount
= aLibNames
.getLength();
211 const OUString
* pLibNames
= aLibNames
.getConstArray();
213 for ( sal_Int32 i
= 0 ; i
< nLibCount
; i
++ )
215 OUString aLibName
= pLibNames
[ i
];
217 if ( eLocation
== rDocument
.getLibraryLocation( aLibName
) )
219 // check, if the module library is loaded
220 bool bModLibLoaded
= false;
221 Reference
< script::XLibraryContainer
> xModLibContainer( rDocument
.getLibraryContainer( E_SCRIPTS
) );
222 if ( xModLibContainer
.is() && xModLibContainer
->hasByName( aLibName
) && xModLibContainer
->isLibraryLoaded( aLibName
) )
223 bModLibLoaded
= true;
225 // check, if the dialog library is loaded
226 bool bDlgLibLoaded
= false;
227 Reference
< script::XLibraryContainer
> xDlgLibContainer( rDocument
.getLibraryContainer( E_DIALOGS
) );
228 if ( xDlgLibContainer
.is() && xDlgLibContainer
->hasByName( aLibName
) && xDlgLibContainer
->isLibraryLoaded( aLibName
) )
229 bDlgLibLoaded
= true;
231 bool bLoaded
= bModLibLoaded
|| bDlgLibLoaded
;
233 // if only one of the libraries is loaded, load also the other
236 if ( xModLibContainer
.is() && xModLibContainer
->hasByName( aLibName
) && !xModLibContainer
->isLibraryLoaded( aLibName
) )
237 xModLibContainer
->loadLibrary( aLibName
);
239 if ( xDlgLibContainer
.is() && xDlgLibContainer
->hasByName( aLibName
) && !xDlgLibContainer
->isLibraryLoaded( aLibName
) )
240 xDlgLibContainer
->loadLibrary( aLibName
);
243 // create tree list box entry
245 if ( ( nMode
& BrowseMode::Dialogs
) && !( nMode
& BrowseMode::Modules
) )
246 sId
= bLoaded
? std::u16string_view(u
"" RID_BMP_DLGLIB
) : std::u16string_view(u
"" RID_BMP_DLGLIBNOTLOADED
);
248 sId
= bLoaded
? OUStringLiteral(u
"" RID_BMP_MODLIB
) : OUStringLiteral(u
"" RID_BMP_MODLIBNOTLOADED
);
249 std::unique_ptr
<weld::TreeIter
> xLibRootEntry(m_xControl
->make_iterator(&rIter
));
250 bool bLibRootEntry
= FindEntry(aLibName
, OBJ_TYPE_LIBRARY
, *xLibRootEntry
);
253 SetEntryBitmaps(*xLibRootEntry
, sId
);
254 bool bRowExpanded
= m_xControl
->get_row_expanded(*xLibRootEntry
);
255 bool bRowExpandAttempted
= !m_xControl
->get_children_on_demand(*xLibRootEntry
);
256 if (bRowExpanded
|| bRowExpandAttempted
)
257 ImpCreateLibSubEntries(*xLibRootEntry
, rDocument
, aLibName
);
261 AddEntry(aLibName
, sId
, &rIter
, true, std::make_unique
<Entry
>(OBJ_TYPE_LIBRARY
));
267 void SbTreeListBox::ImpCreateLibSubEntries(const weld::TreeIter
& rLibRootEntry
, const ScriptDocument
& rDocument
, const OUString
& rLibName
)
270 if ( nMode
& BrowseMode::Modules
)
272 Reference
< script::XLibraryContainer
> xModLibContainer( rDocument
.getLibraryContainer( E_SCRIPTS
) );
274 if ( xModLibContainer
.is() && xModLibContainer
->hasByName( rLibName
) && xModLibContainer
->isLibraryLoaded( rLibName
) )
278 if( rDocument
.isInVBAMode() )
280 ImpCreateLibSubEntriesInVBAMode(rLibRootEntry
, rDocument
, rLibName
);
284 // get a sorted list of module names
285 Sequence
< OUString
> aModNames
= rDocument
.getObjectNames( E_SCRIPTS
, rLibName
);
286 sal_Int32 nModCount
= aModNames
.getLength();
287 const OUString
* pModNames
= aModNames
.getConstArray();
289 auto xTreeIter
= m_xControl
->make_iterator();
291 for ( sal_Int32 i
= 0 ; i
< nModCount
; i
++ )
293 OUString aModName
= pModNames
[ i
];
294 m_xControl
->copy_iterator(rLibRootEntry
, *xTreeIter
);
295 bool bModuleEntry
= FindEntry(aModName
, OBJ_TYPE_MODULE
, *xTreeIter
);
298 AddEntry(aModName
, RID_BMP_MODULE
, &rLibRootEntry
, false, std::make_unique
<Entry
>(OBJ_TYPE_MODULE
), xTreeIter
.get());
302 if ( nMode
& BrowseMode::Subs
)
304 Sequence
< OUString
> aNames
= GetMethodNames( rDocument
, rLibName
, aModName
);
305 sal_Int32 nCount
= aNames
.getLength();
306 const OUString
* pNames
= aNames
.getConstArray();
308 auto xSubTreeIter
= m_xControl
->make_iterator();
310 for ( sal_Int32 j
= 0 ; j
< nCount
; j
++ )
312 OUString aName
= pNames
[ j
];
313 m_xControl
->copy_iterator(*xTreeIter
, *xSubTreeIter
);
314 bool bEntry
= FindEntry(aName
, OBJ_TYPE_METHOD
, *xSubTreeIter
);
317 AddEntry(aName
, RID_BMP_MACRO
, xTreeIter
.get(), false, std::make_unique
<Entry
>(OBJ_TYPE_METHOD
));
324 catch ( const container::NoSuchElementException
& )
326 DBG_UNHANDLED_EXCEPTION("basctl.basicide");
332 if ( !(nMode
& BrowseMode::Dialogs
) )
335 Reference
< script::XLibraryContainer
> xDlgLibContainer( rDocument
.getLibraryContainer( E_DIALOGS
) );
337 if ( !(xDlgLibContainer
.is() && xDlgLibContainer
->hasByName( rLibName
) && xDlgLibContainer
->isLibraryLoaded( rLibName
)) )
342 // get a sorted list of dialog names
343 Sequence
< OUString
> aDlgNames( rDocument
.getObjectNames( E_DIALOGS
, rLibName
) );
344 sal_Int32 nDlgCount
= aDlgNames
.getLength();
345 const OUString
* pDlgNames
= aDlgNames
.getConstArray();
347 auto xTreeIter
= m_xControl
->make_iterator();
349 for ( sal_Int32 i
= 0 ; i
< nDlgCount
; i
++ )
351 OUString aDlgName
= pDlgNames
[ i
];
352 m_xControl
->copy_iterator(rLibRootEntry
, *xTreeIter
);
353 bool bDialogEntry
= FindEntry(aDlgName
, OBJ_TYPE_DIALOG
, *xTreeIter
);
356 AddEntry(aDlgName
, RID_BMP_DIALOG
, &rLibRootEntry
, false, std::make_unique
<Entry
>(OBJ_TYPE_DIALOG
));
360 catch (const container::NoSuchElementException
& )
362 DBG_UNHANDLED_EXCEPTION("basctl.basicide");
366 void SbTreeListBox::ImpCreateLibSubEntriesInVBAMode(const weld::TreeIter
& rLibRootEntry
, const ScriptDocument
& rDocument
, const OUString
& rLibName
)
368 auto const aEntries
= {
369 std::make_pair( OBJ_TYPE_DOCUMENT_OBJECTS
, IDEResId(RID_STR_DOCUMENT_OBJECTS
) ),
370 std::make_pair( OBJ_TYPE_USERFORMS
, IDEResId(RID_STR_USERFORMS
) ),
371 std::make_pair( OBJ_TYPE_NORMAL_MODULES
, IDEResId(RID_STR_NORMAL_MODULES
) ),
372 std::make_pair( OBJ_TYPE_CLASS_MODULES
, IDEResId(RID_STR_CLASS_MODULES
) ) };
373 for( auto const & iter
: aEntries
)
375 EntryType eType
= iter
.first
;
376 OUString
const & aEntryName
= iter
.second
;
377 std::unique_ptr
<weld::TreeIter
> xLibSubRootEntry(m_xControl
->make_iterator(&rLibRootEntry
));
378 bool bLibSubRootEntry
= FindEntry(aEntryName
, eType
, *xLibSubRootEntry
);
379 if (bLibSubRootEntry
)
381 SetEntryBitmaps(*xLibSubRootEntry
, RID_BMP_MODLIB
);
382 if (m_xControl
->get_row_expanded(*xLibSubRootEntry
))
383 ImpCreateLibSubSubEntriesInVBAMode(*xLibSubRootEntry
, rDocument
, rLibName
);
387 m_xControl
->copy_iterator(rLibRootEntry
, *xLibSubRootEntry
);
388 AddEntry(aEntryName
, RID_BMP_MODLIB
, xLibSubRootEntry
.get(), true, std::make_unique
<Entry
>(eType
));
393 void SbTreeListBox::ImpCreateLibSubSubEntriesInVBAMode(const weld::TreeIter
& rLibSubRootEntry
, const ScriptDocument
& rDocument
, const OUString
& rLibName
)
395 uno::Reference
< container::XNameContainer
> xLib
= rDocument
.getOrCreateLibrary( E_SCRIPTS
, rLibName
);
401 // get a sorted list of module names
402 Sequence
< OUString
> aModNames
= rDocument
.getObjectNames( E_SCRIPTS
, rLibName
);
403 sal_Int32 nModCount
= aModNames
.getLength();
404 const OUString
* pModNames
= aModNames
.getConstArray();
406 EntryDescriptor
aDesc(GetEntryDescriptor(&rLibSubRootEntry
));
407 EntryType
eCurrentType(aDesc
.GetType());
409 for ( sal_Int32 i
= 0 ; i
< nModCount
; i
++ )
411 OUString aModName
= pModNames
[ i
];
412 EntryType eType
= OBJ_TYPE_UNKNOWN
;
413 switch( ModuleInfoHelper::getModuleType( xLib
, aModName
) )
415 case script::ModuleType::DOCUMENT
:
416 eType
= OBJ_TYPE_DOCUMENT_OBJECTS
;
418 case script::ModuleType::FORM
:
419 eType
= OBJ_TYPE_USERFORMS
;
421 case script::ModuleType::NORMAL
:
422 eType
= OBJ_TYPE_NORMAL_MODULES
;
424 case script::ModuleType::CLASS
:
425 eType
= OBJ_TYPE_CLASS_MODULES
;
428 if( eType
!= eCurrentType
)
431 // display a nice friendly name in the ObjectModule tab,
432 // combining the objectname and module name, e.g. Sheet1 ( Financials )
433 OUString aEntryName
= aModName
;
434 if( eType
== OBJ_TYPE_DOCUMENT_OBJECTS
)
437 ModuleInfoHelper::getObjectName( xLib
, aModName
, sObjName
);
438 if( !sObjName
.isEmpty() )
440 aEntryName
+= " (" + sObjName
+ ")";
443 std::unique_ptr
<weld::TreeIter
> xModuleEntry(m_xControl
->make_iterator(&rLibSubRootEntry
));
444 bool bModuleEntry
= FindEntry(aEntryName
, OBJ_TYPE_MODULE
, *xModuleEntry
);
447 m_xControl
->copy_iterator(rLibSubRootEntry
, *xModuleEntry
);
448 AddEntry(aEntryName
, RID_BMP_MODULE
, xModuleEntry
.get(), false,
449 std::make_unique
<Entry
>(OBJ_TYPE_MODULE
));
453 if ( nMode
& BrowseMode::Subs
)
455 Sequence
< OUString
> aNames
= GetMethodNames( rDocument
, rLibName
, aModName
);
456 sal_Int32 nCount
= aNames
.getLength();
457 const OUString
* pNames
= aNames
.getConstArray();
459 for ( sal_Int32 j
= 0 ; j
< nCount
; j
++ )
461 OUString aName
= pNames
[ j
];
462 std::unique_ptr
<weld::TreeIter
> xEntry(m_xControl
->make_iterator(xModuleEntry
.get()));
463 bool bEntry
= FindEntry(aName
, OBJ_TYPE_METHOD
, *xEntry
);
466 AddEntry(aName
, RID_BMP_MACRO
, xModuleEntry
.get(), false, std::make_unique
<Entry
>(OBJ_TYPE_METHOD
));
472 catch ( const container::NoSuchElementException
& )
474 DBG_UNHANDLED_EXCEPTION("basctl.basicide");
478 bool SbTreeListBox::ImpFindEntry(weld::TreeIter
& rIter
, const OUString
& rText
)
480 bool bValidIter
= m_xControl
->iter_children(rIter
);
483 if (rText
== m_xControl
->get_text(rIter
))
485 bValidIter
= m_xControl
->iter_next_sibling(rIter
);
490 void SbTreeListBox::onDocumentCreated( const ScriptDocument
& /*_rDocument*/ )
495 void SbTreeListBox::onDocumentOpened( const ScriptDocument
& /*_rDocument*/ )
500 void SbTreeListBox::onDocumentSave( const ScriptDocument
& /*_rDocument*/ )
505 void SbTreeListBox::onDocumentSaveDone( const ScriptDocument
& /*_rDocument*/ )
510 void SbTreeListBox::onDocumentSaveAs( const ScriptDocument
& /*_rDocument*/ )
515 void SbTreeListBox::onDocumentSaveAsDone( const ScriptDocument
& /*_rDocument*/ )
520 void SbTreeListBox::onDocumentClosed( const ScriptDocument
& rDocument
)
523 // The document is not yet actually deleted, so we need to remove its entry
525 RemoveEntry(rDocument
);
528 void SbTreeListBox::onDocumentTitleChanged( const ScriptDocument
& /*_rDocument*/ )
533 void SbTreeListBox::onDocumentModeChanged( const ScriptDocument
& /*_rDocument*/ )
538 void SbTreeListBox::UpdateEntries()
540 bool bValidIter
= m_xControl
->get_selected(m_xScratchIter
.get());
541 EntryDescriptor
aCurDesc(GetEntryDescriptor(bValidIter
? m_xScratchIter
.get() : nullptr));
543 // removing the invalid entries
544 std::unique_ptr
<weld::TreeIter
> xLastValid(m_xControl
->make_iterator(nullptr));
545 bool bLastValid
= false;
546 bValidIter
= m_xControl
->get_iter_first(*m_xScratchIter
);
549 if (IsValidEntry(*m_xScratchIter
))
551 m_xControl
->copy_iterator(*m_xScratchIter
, *xLastValid
);
555 RemoveEntry(*m_xScratchIter
);
558 m_xControl
->copy_iterator(*xLastValid
, *m_xScratchIter
);
559 bValidIter
= m_xControl
->iter_next(*m_xScratchIter
);
562 bValidIter
= m_xControl
->get_iter_first(*m_xScratchIter
);
567 SetCurrentEntry( aCurDesc
);
570 // Removes the entry from the tree.
571 void SbTreeListBox::RemoveEntry(const weld::TreeIter
& rIter
)
573 if (m_bFreezeOnFirstAddRemove
)
575 m_xControl
->freeze();
576 m_bFreezeOnFirstAddRemove
= false;
579 // removing the associated user data
580 Entry
* pBasicEntry
= reinterpret_cast<Entry
*>(m_xControl
->get_id(rIter
).toInt64());
582 // removing the entry
583 m_xControl
->remove(rIter
);
586 // Removes the entry of rDocument.
587 void SbTreeListBox::RemoveEntry (ScriptDocument
const& rDocument
)
589 // finding the entry of rDocument
590 bool bValidIter
= m_xControl
->get_iter_first(*m_xScratchIter
);
593 if (rDocument
== GetEntryDescriptor(m_xScratchIter
.get()).GetDocument())
595 RemoveEntry(*m_xScratchIter
);
598 bValidIter
= m_xControl
->iter_next(*m_xScratchIter
);
602 bool SbTreeListBox::FindEntry(const OUString
& rText
, EntryType eType
, weld::TreeIter
& rIter
)
604 bool bValidIter
= m_xControl
->iter_children(rIter
);
607 Entry
* pBasicEntry
= reinterpret_cast<Entry
*>(m_xControl
->get_id(rIter
).toInt64());
608 assert(pBasicEntry
&& "FindEntry: no Entry ?!");
609 if (pBasicEntry
->GetType() == eType
&& rText
== m_xControl
->get_text(rIter
))
611 bValidIter
= m_xControl
->iter_next_sibling(rIter
);
616 bool SbTreeListBox::IsEntryProtected(const weld::TreeIter
* pEntry
)
618 bool bProtected
= false;
619 if (pEntry
&& m_xControl
->get_iter_depth(*pEntry
) == 1)
621 EntryDescriptor
aDesc(GetEntryDescriptor(pEntry
));
622 const ScriptDocument
& rDocument( aDesc
.GetDocument() );
623 OSL_ENSURE( rDocument
.isAlive(), "TreeListBox::IsEntryProtected: no document, or document is dead!" );
624 if ( rDocument
.isAlive() )
626 const OUString
& aOULibName( aDesc
.GetLibName() );
627 Reference
< script::XLibraryContainer
> xModLibContainer( rDocument
.getLibraryContainer( E_SCRIPTS
) );
628 if ( xModLibContainer
.is() && xModLibContainer
->hasByName( aOULibName
) )
630 Reference
< script::XLibraryContainerPassword
> xPasswd( xModLibContainer
, UNO_QUERY
);
631 if ( xPasswd
.is() && xPasswd
->isLibraryPasswordProtected( aOULibName
) && !xPasswd
->isLibraryPasswordVerified( aOULibName
) )
641 void SbTreeListBox::AddEntry(
642 const OUString
& rText
,
643 const OUString
& rImage
,
644 const weld::TreeIter
* pParent
,
645 bool bChildrenOnDemand
,
646 std::unique_ptr
<Entry
>&& rUserData
,
647 weld::TreeIter
* pRet
)
649 if (m_bFreezeOnFirstAddRemove
)
651 m_xControl
->freeze();
652 m_bFreezeOnFirstAddRemove
= false;
654 std::unique_ptr
<weld::TreeIter
> xScratch
= pRet
? nullptr : m_xControl
->make_iterator();
656 pRet
= xScratch
.get();
657 OUString
sId(OUString::number(reinterpret_cast<sal_uInt64
>(rUserData
.release())));
658 m_xControl
->insert(pParent
, -1, &rText
, &sId
, nullptr, nullptr, bChildrenOnDemand
, pRet
);
659 m_xControl
->set_image(*pRet
, rImage
);
662 void SbTreeListBox::SetEntryBitmaps(const weld::TreeIter
& rIter
, const OUString
& rImage
)
664 m_xControl
->set_image(rIter
, rImage
, -1);
667 LibraryType
SbTreeListBox::GetLibraryType() const
669 LibraryType eType
= LibraryType::All
;
670 if ( ( nMode
& BrowseMode::Modules
) && !( nMode
& BrowseMode::Dialogs
) )
671 eType
= LibraryType::Module
;
672 else if ( !( nMode
& BrowseMode::Modules
) && ( nMode
& BrowseMode::Dialogs
) )
673 eType
= LibraryType::Dialog
;
677 OUString
SbTreeListBox::GetRootEntryName( const ScriptDocument
& rDocument
, LibraryLocation eLocation
) const
679 return rDocument
.getTitle( eLocation
, GetLibraryType() );
682 OUString
SbTreeListBox::GetRootEntryBitmaps(const ScriptDocument
& rDocument
)
684 OSL_ENSURE( rDocument
.isValid(), "TreeListBox::GetRootEntryBitmaps: illegal document!" );
685 if (!rDocument
.isValid())
688 if ( rDocument
.isDocument() )
690 OUString sFactoryURL
;
691 Reference
<uno::XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
692 Reference
< frame::XModuleManager2
> xModuleManager( frame::ModuleManager::create(xContext
) );
695 OUString
sModule( xModuleManager
->identify( rDocument
.getDocument() ) );
696 Sequence
< beans::PropertyValue
> aModuleDescr
;
697 xModuleManager
->getByName( sModule
) >>= aModuleDescr
;
698 sal_Int32 nCount
= aModuleDescr
.getLength();
699 const beans::PropertyValue
* pModuleDescr
= aModuleDescr
.getConstArray();
700 for ( sal_Int32 i
= 0; i
< nCount
; ++i
)
702 if ( pModuleDescr
[ i
].Name
== "ooSetupFactoryEmptyDocumentURL" )
704 pModuleDescr
[ i
].Value
>>= sFactoryURL
;
709 catch( const Exception
& )
711 DBG_UNHANDLED_EXCEPTION("basctl.basicide");
714 if ( !sFactoryURL
.isEmpty() )
716 return SvFileInformationManager::GetFileImageId(INetURLObject(sFactoryURL
));
721 return RID_BMP_DOCUMENT
;
724 return RID_BMP_INSTALLATION
;
727 void SbTreeListBox::SetCurrentEntry (EntryDescriptor
const & rDesc
)
729 bool bCurEntry
= false;
730 auto xCurIter
= m_xControl
->make_iterator();
731 EntryDescriptor aDesc
= rDesc
;
732 if ( aDesc
.GetType() == OBJ_TYPE_UNKNOWN
)
734 aDesc
= EntryDescriptor(
735 ScriptDocument::getApplicationScriptDocument(),
736 LIBRARY_LOCATION_USER
, "Standard",
737 OUString(), ".", OBJ_TYPE_UNKNOWN
740 ScriptDocument aDocument
= aDesc
.GetDocument();
741 OSL_ENSURE( aDocument
.isValid(), "TreeListBox::SetCurrentEntry: invalid document!" );
742 LibraryLocation eLocation
= aDesc
.GetLocation();
743 bool bRootEntry
= FindRootEntry(aDocument
, eLocation
, *m_xScratchIter
);
746 m_xControl
->copy_iterator(*m_xScratchIter
, *xCurIter
);
748 const OUString
& aLibName( aDesc
.GetLibName() );
749 if ( !aLibName
.isEmpty() )
751 m_xControl
->expand_row(*m_xScratchIter
);
752 auto xLibIter
= m_xControl
->make_iterator(m_xScratchIter
.get());
753 bool bLibEntry
= FindEntry(aLibName
, OBJ_TYPE_LIBRARY
, *xLibIter
);
756 m_xControl
->copy_iterator(*xLibIter
, *xCurIter
);
757 const OUString
& aLibSubName( aDesc
.GetLibSubName() );
758 if( !aLibSubName
.isEmpty() )
760 m_xControl
->expand_row(*xLibIter
);
761 auto xSubLibIter
= m_xControl
->make_iterator(xLibIter
.get());
762 bool bSubLibEntry
= ImpFindEntry(*xSubLibIter
, aLibSubName
);
765 m_xControl
->copy_iterator(*xSubLibIter
, *xCurIter
);
768 const OUString
& aName( aDesc
.GetName() );
769 if ( !aName
.isEmpty() )
771 m_xControl
->expand_row(*xCurIter
);
772 EntryType eType
= OBJ_TYPE_MODULE
;
773 if ( aDesc
.GetType() == OBJ_TYPE_DIALOG
)
774 eType
= OBJ_TYPE_DIALOG
;
775 auto xEntryIter
= m_xControl
->make_iterator(xCurIter
.get());
776 bool bEntry
= FindEntry(aName
, eType
, *xEntryIter
);
779 m_xControl
->copy_iterator(*xEntryIter
, *xCurIter
);
780 const OUString
& aMethodName( aDesc
.GetMethodName() );
781 if (!aMethodName
.isEmpty())
783 m_xControl
->expand_row(*xCurIter
);
784 auto xSubEntryIter
= m_xControl
->make_iterator(xCurIter
.get());
785 bool bSubEntry
= FindEntry(aMethodName
, OBJ_TYPE_METHOD
, *xSubEntryIter
);
788 m_xControl
->copy_iterator(*xSubEntryIter
, *xCurIter
);
792 m_xControl
->copy_iterator(*xCurIter
, *xSubEntryIter
);
793 if (m_xControl
->iter_children(*xSubEntryIter
))
794 m_xControl
->copy_iterator(*xSubEntryIter
, *xCurIter
);
800 auto xSubEntryIter
= m_xControl
->make_iterator(xCurIter
.get());
801 if (m_xControl
->iter_children(*xSubEntryIter
))
802 m_xControl
->copy_iterator(*xSubEntryIter
, *xCurIter
);
808 auto xSubLibIter
= m_xControl
->make_iterator(m_xScratchIter
.get());
809 if (m_xControl
->iter_children(*xSubLibIter
))
810 m_xControl
->copy_iterator(*xLibIter
, *xCurIter
);
816 bCurEntry
= m_xControl
->get_iter_first(*xCurIter
);
822 m_xControl
->set_cursor(*xCurIter
);
825 IMPL_LINK_NOARG(SbTreeListBox
, OpenCurrentHdl
, weld::TreeView
&, bool)
827 bool bValidIter
= m_xControl
->get_cursor(m_xScratchIter
.get());
830 if (!m_xControl
->get_row_expanded(*m_xScratchIter
))
831 m_xControl
->expand_row(*m_xScratchIter
);
833 m_xControl
->collapse_row(*m_xScratchIter
);
835 EntryDescriptor aDesc
= GetEntryDescriptor(m_xScratchIter
.get());
836 switch (aDesc
.GetType())
838 case OBJ_TYPE_METHOD
:
839 case OBJ_TYPE_MODULE
:
840 case OBJ_TYPE_DIALOG
:
841 if (SfxDispatcher
* pDispatcher
= GetDispatcher())
844 SID_BASICIDE_ARG_SBX
, aDesc
.GetDocument(),
845 aDesc
.GetLibName(), aDesc
.GetName(), aDesc
.GetMethodName(),
846 ConvertType(aDesc
.GetType())
848 pDispatcher
->ExecuteList(
849 SID_BASICIDE_SHOWSBX
, SfxCallMode::SYNCHRON
,
861 } // namespace basctl
863 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */