nss: upgrade to release 3.73
[LibreOffice.git] / basctl / source / basicide / bastype2.cxx
blob904ff83076708b273f190fcf263d2eaca5e6d371
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 .
21 #include <basobj.hxx>
22 #include <bastypes.hxx>
23 #include <bastype2.hxx>
24 #include <strings.hrc>
25 #include <bitmaps.hlst>
26 #include <iderid.hxx>
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>
37 #include <memory>
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>
45 namespace basctl
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 )
53 try
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 );
64 if( xNamed.is() )
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;
83 return nType;
86 Entry::~Entry()
87 { }
89 DocumentEntry::DocumentEntry (
90 ScriptDocument const& rDocument,
91 LibraryLocation eLocation,
92 EntryType eType
93 ) :
94 Entry(eType),
95 m_aDocument(rDocument),
96 m_eLocation(eLocation)
98 OSL_ENSURE( m_aDocument.isValid(), "DocumentEntry::DocumentEntry: illegal document!" );
101 DocumentEntry::~DocumentEntry()
104 LibEntry::LibEntry (
105 ScriptDocument const& rDocument,
106 LibraryLocation eLocation,
107 OUString const& rLibName
109 DocumentEntry(rDocument, eLocation, OBJ_TYPE_LIBRARY),
110 m_aLibName(rLibName)
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,
128 EntryType eType
130 m_aDocument(rDocument),
131 m_eLocation(eLocation),
132 m_aLibName(rLibName),
133 m_aLibSubName(rLibSubName),
134 m_aName(rName),
135 m_eType(eType)
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,
147 EntryType eType
149 m_aDocument(rDocument),
150 m_eLocation(eLocation),
151 m_aLibName(rLibName),
152 m_aLibSubName(rLibSubName),
153 m_aName(rName),
154 m_aMethodName(rMethodName),
155 m_eType(eType)
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)
165 , m_aNotifier(*this)
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);
177 while (bValidIter)
179 Entry* pBasicEntry = reinterpret_cast<Entry*>(m_xControl->get_id(*m_xScratchIter).toInt64());
180 delete pBasicEntry;
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() )
189 return;
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
234 if ( bLoaded )
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
244 OUString sId;
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);
247 else
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);
251 if (bLibRootEntry)
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);
259 else
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)
269 // modules
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);
282 else
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);
296 if (!bModuleEntry)
298 AddEntry(aModName, RID_BMP_MODULE, &rLibRootEntry, false, std::make_unique<Entry>(OBJ_TYPE_MODULE), xTreeIter.get());
301 // methods
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);
315 if (!bEntry)
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");
331 // dialogs
332 if ( !(nMode & BrowseMode::Dialogs) )
333 return;
335 Reference< script::XLibraryContainer > xDlgLibContainer( rDocument.getLibraryContainer( E_DIALOGS ) );
337 if ( !(xDlgLibContainer.is() && xDlgLibContainer->hasByName( rLibName ) && xDlgLibContainer->isLibraryLoaded( rLibName )) )
338 return;
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);
354 if (!bDialogEntry)
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);
385 else
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 );
396 if( !xLib.is() )
397 return;
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;
417 break;
418 case script::ModuleType::FORM:
419 eType = OBJ_TYPE_USERFORMS;
420 break;
421 case script::ModuleType::NORMAL:
422 eType = OBJ_TYPE_NORMAL_MODULES;
423 break;
424 case script::ModuleType::CLASS:
425 eType = OBJ_TYPE_CLASS_MODULES;
426 break;
428 if( eType != eCurrentType )
429 continue;
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 )
436 OUString sObjName;
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);
445 if (!bModuleEntry)
447 m_xControl->copy_iterator(rLibSubRootEntry, *xModuleEntry);
448 AddEntry(aEntryName, RID_BMP_MODULE, xModuleEntry.get(), false,
449 std::make_unique<Entry>(OBJ_TYPE_MODULE));
452 // methods
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);
464 if (!bEntry)
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);
481 while (bValidIter)
483 if (rText == m_xControl->get_text(rIter))
484 return true;
485 bValidIter = m_xControl->iter_next_sibling(rIter);
487 return false;
490 void SbTreeListBox::onDocumentCreated( const ScriptDocument& /*_rDocument*/ )
492 UpdateEntries();
495 void SbTreeListBox::onDocumentOpened( const ScriptDocument& /*_rDocument*/ )
497 UpdateEntries();
500 void SbTreeListBox::onDocumentSave( const ScriptDocument& /*_rDocument*/ )
502 // not interested in
505 void SbTreeListBox::onDocumentSaveDone( const ScriptDocument& /*_rDocument*/ )
507 // not interested in
510 void SbTreeListBox::onDocumentSaveAs( const ScriptDocument& /*_rDocument*/ )
512 // not interested in
515 void SbTreeListBox::onDocumentSaveAsDone( const ScriptDocument& /*_rDocument*/ )
517 UpdateEntries();
520 void SbTreeListBox::onDocumentClosed( const ScriptDocument& rDocument )
522 UpdateEntries();
523 // The document is not yet actually deleted, so we need to remove its entry
524 // manually.
525 RemoveEntry(rDocument);
528 void SbTreeListBox::onDocumentTitleChanged( const ScriptDocument& /*_rDocument*/ )
530 // not interested in
533 void SbTreeListBox::onDocumentModeChanged( const ScriptDocument& /*_rDocument*/ )
535 // not interested in
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);
547 while (bValidIter)
549 if (IsValidEntry(*m_xScratchIter))
551 m_xControl->copy_iterator(*m_xScratchIter, *xLastValid);
552 bLastValid = true;
554 else
555 RemoveEntry(*m_xScratchIter);
556 if (bLastValid)
558 m_xControl->copy_iterator(*xLastValid, *m_xScratchIter);
559 bValidIter = m_xControl->iter_next(*m_xScratchIter);
561 else
562 bValidIter = m_xControl->get_iter_first(*m_xScratchIter);
565 ScanAllEntries();
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());
581 delete pBasicEntry;
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);
591 while (bValidIter)
593 if (rDocument == GetEntryDescriptor(m_xScratchIter.get()).GetDocument())
595 RemoveEntry(*m_xScratchIter);
596 break;
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);
605 while (bValidIter)
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))
610 return true;
611 bValidIter = m_xControl->iter_next_sibling(rIter);
613 return false;
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 ) )
633 bProtected = true;
638 return bProtected;
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();
655 if (!pRet)
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;
674 return eType;
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())
686 return OUString();
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;
705 break;
709 catch( const Exception& )
711 DBG_UNHANDLED_EXCEPTION("basctl.basicide");
714 if ( !sFactoryURL.isEmpty() )
716 return SvFileInformationManager::GetFileImageId(INetURLObject(sFactoryURL));
718 else
720 // default icon
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);
744 if (bRootEntry)
746 m_xControl->copy_iterator(*m_xScratchIter, *xCurIter);
747 bCurEntry = true;
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);
754 if (bLibEntry)
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);
763 if (bSubLibEntry)
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);
777 if (bEntry)
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);
786 if (bSubEntry)
788 m_xControl->copy_iterator(*xSubEntryIter, *xCurIter);
790 else
792 m_xControl->copy_iterator(*xCurIter, *xSubEntryIter);
793 if (m_xControl->iter_children(*xSubEntryIter))
794 m_xControl->copy_iterator(*xSubEntryIter, *xCurIter);
798 else
800 auto xSubEntryIter = m_xControl->make_iterator(xCurIter.get());
801 if (m_xControl->iter_children(*xSubEntryIter))
802 m_xControl->copy_iterator(*xSubEntryIter, *xCurIter);
806 else
808 auto xSubLibIter = m_xControl->make_iterator(m_xScratchIter.get());
809 if (m_xControl->iter_children(*xSubLibIter))
810 m_xControl->copy_iterator(*xLibIter, *xCurIter);
814 else
816 bCurEntry = m_xControl->get_iter_first(*xCurIter);
819 if (!bCurEntry)
820 return;
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());
828 if (!bValidIter)
829 return true;
830 if (!m_xControl->get_row_expanded(*m_xScratchIter))
831 m_xControl->expand_row(*m_xScratchIter);
832 else
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())
843 SbxItem aSbxItem(
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,
850 { &aSbxItem }
853 break;
855 default:
856 break;
858 return true;
861 } // namespace basctl
863 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */