tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / basctl / source / basicide / bastype2.cxx
blob75d21f3c41c1427bb682f0929e375affd11dc244
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 <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>
35 #include <svl/itemset.hxx>
37 #include <initializer_list>
38 #include <memory>
39 #include <string_view>
41 #include <com/sun/star/script/ModuleType.hpp>
42 #include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
43 #include <com/sun/star/lang/XServiceInfo.hpp>
44 #include <com/sun/star/container/XNamed.hpp>
45 #include <utility>
47 namespace basctl
50 using namespace ::com::sun::star::uno;
51 using namespace ::com::sun::star;
53 void ModuleInfoHelper::getObjectName( const uno::Reference< container::XNameContainer >& rLib, const OUString& rModName, OUString& rObjName )
55 try
57 uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( rLib, uno::UNO_QUERY );
58 if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( rModName ) )
60 script::ModuleInfo aModuleInfo = xVBAModuleInfo->getModuleInfo( rModName );
61 uno::Any aObject( aModuleInfo.ModuleObject );
62 uno::Reference< lang::XServiceInfo > xServiceInfo( aObject, uno::UNO_QUERY );
63 if( xServiceInfo.is() && xServiceInfo->supportsService( u"ooo.vba.excel.Worksheet"_ustr ) )
65 uno::Reference< container::XNamed > xNamed( aObject, uno::UNO_QUERY );
66 if( xNamed.is() )
67 rObjName = xNamed->getName();
71 catch(const uno::Exception& )
76 sal_Int32 ModuleInfoHelper::getModuleType( const uno::Reference< container::XNameContainer >& rLib, const OUString& rModName )
78 sal_Int32 nType = script::ModuleType::NORMAL;
79 uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( rLib, uno::UNO_QUERY );
80 if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( rModName ) )
82 script::ModuleInfo aModuleInfo = xVBAModuleInfo->getModuleInfo( rModName );
83 nType = aModuleInfo.ModuleType;
85 return nType;
88 Entry::~Entry()
89 { }
91 DocumentEntry::DocumentEntry (
92 ScriptDocument aDocument,
93 LibraryLocation eLocation,
94 EntryType eType
95 ) :
96 Entry(eType),
97 m_aDocument(std::move(aDocument)),
98 m_eLocation(eLocation)
100 OSL_ENSURE( m_aDocument.isValid(), "DocumentEntry::DocumentEntry: illegal document!" );
103 DocumentEntry::~DocumentEntry()
106 LibEntry::LibEntry (
107 ScriptDocument const& rDocument,
108 LibraryLocation eLocation,
109 OUString aLibName
111 DocumentEntry(rDocument, eLocation, OBJ_TYPE_LIBRARY),
112 m_aLibName(std::move(aLibName))
115 LibEntry::~LibEntry()
118 EntryDescriptor::EntryDescriptor () :
119 m_aDocument(ScriptDocument::getApplicationScriptDocument()),
120 m_eLocation(LIBRARY_LOCATION_UNKNOWN),
121 m_eType(OBJ_TYPE_UNKNOWN)
124 EntryDescriptor::EntryDescriptor (
125 ScriptDocument aDocument,
126 LibraryLocation eLocation,
127 OUString aLibName,
128 OUString aLibSubName,
129 OUString aName,
130 EntryType eType
132 m_aDocument(std::move(aDocument)),
133 m_eLocation(eLocation),
134 m_aLibName(std::move(aLibName)),
135 m_aLibSubName(std::move(aLibSubName)),
136 m_aName(std::move(aName)),
137 m_eType(eType)
139 OSL_ENSURE( m_aDocument.isValid(), "EntryDescriptor::EntryDescriptor: invalid document!" );
142 EntryDescriptor::EntryDescriptor (
143 ScriptDocument aDocument,
144 LibraryLocation eLocation,
145 OUString aLibName,
146 OUString aLibSubName,
147 OUString aName,
148 OUString aMethodName,
149 EntryType eType
151 m_aDocument(std::move(aDocument)),
152 m_eLocation(eLocation),
153 m_aLibName(std::move(aLibName)),
154 m_aLibSubName(std::move(aLibSubName)),
155 m_aName(std::move(aName)),
156 m_aMethodName(std::move(aMethodName)),
157 m_eType(eType)
159 OSL_ENSURE( m_aDocument.isValid(), "EntryDescriptor::EntryDescriptor: invalid document!" );
162 SbTreeListBox::SbTreeListBox(std::unique_ptr<weld::TreeView> xControl, weld::Window* pTopLevel)
163 : m_xControl(std::move(xControl))
164 , m_xScratchIter(m_xControl->make_iterator())
165 , m_pTopLevel(pTopLevel)
166 , m_bFreezeOnFirstAddRemove(false)
167 , m_aNotifier(*this)
169 m_xControl->connect_row_activated(LINK(this, SbTreeListBox, OpenCurrentHdl));
170 m_xControl->connect_expanding(LINK(this, SbTreeListBox, RequestingChildrenHdl));
171 nMode = BrowseMode::All; // everything
174 SbTreeListBox::~SbTreeListBox()
176 m_aNotifier.dispose();
178 bool bValidIter = m_xControl->get_iter_first(*m_xScratchIter);
179 while (bValidIter)
181 Entry* pBasicEntry = weld::fromId<Entry*>(m_xControl->get_id(*m_xScratchIter));
182 delete pBasicEntry;
183 bValidIter = m_xControl->iter_next(*m_xScratchIter);
187 void SbTreeListBox::ScanEntry( const ScriptDocument& rDocument, LibraryLocation eLocation )
189 OSL_ENSURE( rDocument.isAlive(), "TreeListBox::ScanEntry: illegal document!" );
190 if ( !rDocument.isAlive() )
191 return;
193 // can be called multiple times for updating!
195 // actually test if basic's in the tree already?!
196 // level 1: BasicManager (application, document, ...)
197 bool bDocumentRootEntry = FindRootEntry(rDocument, eLocation, *m_xScratchIter);
198 if (bDocumentRootEntry && m_xControl->get_row_expanded(*m_xScratchIter))
199 ImpCreateLibEntries(*m_xScratchIter, rDocument, eLocation);
200 if (!bDocumentRootEntry)
202 OUString aRootName(GetRootEntryName(rDocument, eLocation));
203 OUString aImage(GetRootEntryBitmaps(rDocument));
204 AddEntry(aRootName, aImage, nullptr, true, std::make_unique<DocumentEntry>(rDocument, eLocation));
208 void SbTreeListBox::ImpCreateLibEntries(const weld::TreeIter& rIter, const ScriptDocument& rDocument, LibraryLocation eLocation)
210 // get a sorted list of library names
211 for (auto& aLibName : rDocument.getLibraryNames())
213 if ( eLocation == rDocument.getLibraryLocation( aLibName ) )
215 // check, if the module library is loaded
216 bool bModLibLoaded = false;
217 Reference< script::XLibraryContainer > xModLibContainer( rDocument.getLibraryContainer( E_SCRIPTS ) );
218 if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && xModLibContainer->isLibraryLoaded( aLibName ) )
219 bModLibLoaded = true;
221 // check, if the dialog library is loaded
222 bool bDlgLibLoaded = false;
223 Reference< script::XLibraryContainer > xDlgLibContainer( rDocument.getLibraryContainer( E_DIALOGS ) );
224 if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && xDlgLibContainer->isLibraryLoaded( aLibName ) )
225 bDlgLibLoaded = true;
227 bool bLoaded = bModLibLoaded || bDlgLibLoaded;
229 // if only one of the libraries is loaded, load also the other
230 if ( bLoaded )
232 if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) && !xModLibContainer->isLibraryLoaded( aLibName ) )
233 xModLibContainer->loadLibrary( aLibName );
235 if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) && !xDlgLibContainer->isLibraryLoaded( aLibName ) )
236 xDlgLibContainer->loadLibrary( aLibName );
239 // create tree list box entry
240 OUString sId;
241 if ( ( nMode & BrowseMode::Dialogs ) && !( nMode & BrowseMode::Modules ) )
242 sId = bLoaded ? RID_BMP_DLGLIB : RID_BMP_DLGLIBNOTLOADED;
243 else
244 sId = bLoaded ? RID_BMP_MODLIB : RID_BMP_MODLIBNOTLOADED;
245 std::unique_ptr<weld::TreeIter> xLibRootEntry(m_xControl->make_iterator(&rIter));
246 bool bLibRootEntry = FindEntry(aLibName, OBJ_TYPE_LIBRARY, *xLibRootEntry);
247 if (bLibRootEntry)
249 SetEntryBitmaps(*xLibRootEntry, sId);
250 bool bRowExpanded = m_xControl->get_row_expanded(*xLibRootEntry);
251 bool bRowExpandAttempted = !m_xControl->get_children_on_demand(*xLibRootEntry);
252 if (bRowExpanded || bRowExpandAttempted)
253 ImpCreateLibSubEntries(*xLibRootEntry, rDocument, aLibName);
255 else
257 AddEntry(aLibName, sId, &rIter, true, std::make_unique<Entry>(OBJ_TYPE_LIBRARY));
263 void SbTreeListBox::ImpCreateLibSubEntries(const weld::TreeIter& rLibRootEntry, const ScriptDocument& rDocument, const OUString& rLibName)
265 // modules
266 if ( nMode & BrowseMode::Modules )
268 Reference< script::XLibraryContainer > xModLibContainer( rDocument.getLibraryContainer( E_SCRIPTS ) );
270 if ( xModLibContainer.is() && xModLibContainer->hasByName( rLibName ) && xModLibContainer->isLibraryLoaded( rLibName ) )
274 if( rDocument.isInVBAMode() )
276 ImpCreateLibSubEntriesInVBAMode(rLibRootEntry, rDocument, rLibName);
278 else
280 // get a sorted list of module names
281 auto xTreeIter = m_xControl->make_iterator();
283 for (auto& aModName : rDocument.getObjectNames(E_SCRIPTS, rLibName))
285 m_xControl->copy_iterator(rLibRootEntry, *xTreeIter);
286 bool bModuleEntry = FindEntry(aModName, OBJ_TYPE_MODULE, *xTreeIter);
287 if (!bModuleEntry)
289 AddEntry(aModName, RID_BMP_MODULE, &rLibRootEntry, false, std::make_unique<Entry>(OBJ_TYPE_MODULE), xTreeIter.get());
292 // methods
293 if ( nMode & BrowseMode::Subs )
295 auto xSubTreeIter = m_xControl->make_iterator();
297 for (auto& aName : GetMethodNames(rDocument, rLibName, aModName))
299 m_xControl->copy_iterator(*xTreeIter, *xSubTreeIter);
300 bool bEntry = FindEntry(aName, OBJ_TYPE_METHOD, *xSubTreeIter);
301 if (!bEntry)
303 AddEntry(aName, RID_BMP_MACRO, xTreeIter.get(), false, std::make_unique<Entry>(OBJ_TYPE_METHOD));
310 catch ( const container::NoSuchElementException& )
312 DBG_UNHANDLED_EXCEPTION("basctl.basicide");
317 // dialogs
318 if ( !(nMode & BrowseMode::Dialogs) )
319 return;
321 Reference< script::XLibraryContainer > xDlgLibContainer( rDocument.getLibraryContainer( E_DIALOGS ) );
323 if ( !(xDlgLibContainer.is() && xDlgLibContainer->hasByName( rLibName ) && xDlgLibContainer->isLibraryLoaded( rLibName )) )
324 return;
328 // get a sorted list of dialog names
329 auto xTreeIter = m_xControl->make_iterator();
331 for (auto& aDlgName : rDocument.getObjectNames(E_DIALOGS, rLibName))
333 m_xControl->copy_iterator(rLibRootEntry, *xTreeIter);
334 bool bDialogEntry = FindEntry(aDlgName, OBJ_TYPE_DIALOG, *xTreeIter);
335 if (!bDialogEntry)
337 AddEntry(aDlgName, RID_BMP_DIALOG, &rLibRootEntry, false, std::make_unique<Entry>(OBJ_TYPE_DIALOG));
341 catch (const container::NoSuchElementException& )
343 DBG_UNHANDLED_EXCEPTION("basctl.basicide");
347 void SbTreeListBox::ImpCreateLibSubEntriesInVBAMode(const weld::TreeIter& rLibRootEntry, const ScriptDocument& rDocument, const OUString& rLibName )
349 auto const aEntries = {
350 std::make_pair( OBJ_TYPE_DOCUMENT_OBJECTS, IDEResId(RID_STR_DOCUMENT_OBJECTS) ),
351 std::make_pair( OBJ_TYPE_USERFORMS, IDEResId(RID_STR_USERFORMS) ),
352 std::make_pair( OBJ_TYPE_NORMAL_MODULES, IDEResId(RID_STR_NORMAL_MODULES) ),
353 std::make_pair( OBJ_TYPE_CLASS_MODULES, IDEResId(RID_STR_CLASS_MODULES) ) };
354 for( auto const & iter: aEntries )
356 EntryType eType = iter.first;
357 OUString const & aEntryName = iter.second;
358 std::unique_ptr<weld::TreeIter> xLibSubRootEntry(m_xControl->make_iterator(&rLibRootEntry));
359 bool bLibSubRootEntry = FindEntry(aEntryName, eType, *xLibSubRootEntry);
360 if (bLibSubRootEntry)
362 SetEntryBitmaps(*xLibSubRootEntry, RID_BMP_MODLIB);
363 if (m_xControl->get_row_expanded(*xLibSubRootEntry))
364 ImpCreateLibSubSubEntriesInVBAMode(*xLibSubRootEntry, rDocument, rLibName);
366 else
368 m_xControl->copy_iterator(rLibRootEntry, *xLibSubRootEntry);
369 AddEntry(aEntryName, RID_BMP_MODLIB, xLibSubRootEntry.get(), true, std::make_unique<Entry>(eType));
374 void SbTreeListBox::ImpCreateLibSubSubEntriesInVBAMode(const weld::TreeIter& rLibSubRootEntry, const ScriptDocument& rDocument, const OUString& rLibName)
376 uno::Reference< container::XNameContainer > xLib = rDocument.getOrCreateLibrary( E_SCRIPTS, rLibName );
377 if( !xLib.is() )
378 return;
382 // get a sorted list of module names
383 EntryDescriptor aDesc(GetEntryDescriptor(&rLibSubRootEntry));
384 EntryType eCurrentType(aDesc.GetType());
386 for (auto& aModName : rDocument.getObjectNames(E_SCRIPTS, rLibName))
388 EntryType eType = OBJ_TYPE_UNKNOWN;
389 switch( ModuleInfoHelper::getModuleType( xLib, aModName ) )
391 case script::ModuleType::DOCUMENT:
392 eType = OBJ_TYPE_DOCUMENT_OBJECTS;
393 break;
394 case script::ModuleType::FORM:
395 eType = OBJ_TYPE_USERFORMS;
396 break;
397 case script::ModuleType::NORMAL:
398 eType = OBJ_TYPE_NORMAL_MODULES;
399 break;
400 case script::ModuleType::CLASS:
401 eType = OBJ_TYPE_CLASS_MODULES;
402 break;
404 if( eType != eCurrentType )
405 continue;
407 // display a nice friendly name in the ObjectModule tab,
408 // combining the objectname and module name, e.g. Sheet1 ( Financials )
409 OUString aEntryName = aModName;
410 if( eType == OBJ_TYPE_DOCUMENT_OBJECTS )
412 OUString sObjName;
413 ModuleInfoHelper::getObjectName( xLib, aModName, sObjName );
414 if( !sObjName.isEmpty() )
416 aEntryName += " (" + sObjName + ")";
419 std::unique_ptr<weld::TreeIter> xModuleEntry(m_xControl->make_iterator(&rLibSubRootEntry));
420 bool bModuleEntry = FindEntry(aEntryName, OBJ_TYPE_MODULE, *xModuleEntry);
421 if (!bModuleEntry)
423 m_xControl->copy_iterator(rLibSubRootEntry, *xModuleEntry);
424 AddEntry(aEntryName, RID_BMP_MODULE, xModuleEntry.get(), false,
425 std::make_unique<Entry>(OBJ_TYPE_MODULE));
428 // methods
429 if ( nMode & BrowseMode::Subs )
431 for (auto& aName : GetMethodNames(rDocument, rLibName, aModName))
433 std::unique_ptr<weld::TreeIter> xEntry(m_xControl->make_iterator(xModuleEntry.get()));
434 bool bEntry = FindEntry(aName, OBJ_TYPE_METHOD, *xEntry);
435 if (!bEntry)
437 AddEntry(aName, RID_BMP_MACRO, xModuleEntry.get(), false, std::make_unique<Entry>(OBJ_TYPE_METHOD));
443 catch ( const container::NoSuchElementException& )
445 DBG_UNHANDLED_EXCEPTION("basctl.basicide");
449 bool SbTreeListBox::ImpFindEntry(weld::TreeIter& rIter, std::u16string_view rText)
451 bool bValidIter = m_xControl->iter_children(rIter);
452 while (bValidIter)
454 if (rText == m_xControl->get_text(rIter))
455 return true;
456 bValidIter = m_xControl->iter_next_sibling(rIter);
458 return false;
461 void SbTreeListBox::onDocumentCreated( const ScriptDocument& /*_rDocument*/ )
463 UpdateEntries();
466 void SbTreeListBox::onDocumentOpened( const ScriptDocument& /*_rDocument*/ )
468 UpdateEntries();
471 void SbTreeListBox::onDocumentSave( const ScriptDocument& /*_rDocument*/ )
473 // not interested in
476 void SbTreeListBox::onDocumentSaveDone( const ScriptDocument& /*_rDocument*/ )
478 // not interested in
481 void SbTreeListBox::onDocumentSaveAs( const ScriptDocument& /*_rDocument*/ )
483 // not interested in
486 void SbTreeListBox::onDocumentSaveAsDone( const ScriptDocument& /*_rDocument*/ )
488 UpdateEntries();
491 void SbTreeListBox::onDocumentClosed( const ScriptDocument& rDocument )
493 UpdateEntries();
494 // The document is not yet actually deleted, so we need to remove its entry
495 // manually.
496 RemoveEntry(rDocument);
499 void SbTreeListBox::onDocumentTitleChanged( const ScriptDocument& /*_rDocument*/ )
501 // not interested in
504 void SbTreeListBox::onDocumentModeChanged( const ScriptDocument& /*_rDocument*/ )
506 // not interested in
509 void SbTreeListBox::UpdateEntries()
511 bool bValidIter = m_xControl->get_selected(m_xScratchIter.get());
512 EntryDescriptor aCurDesc(GetEntryDescriptor(bValidIter ? m_xScratchIter.get() : nullptr));
514 // removing the invalid entries
515 std::unique_ptr<weld::TreeIter> xLastValid(m_xControl->make_iterator(nullptr));
516 bool bLastValid = false;
517 bValidIter = m_xControl->get_iter_first(*m_xScratchIter);
518 while (bValidIter)
520 if (IsValidEntry(*m_xScratchIter))
522 m_xControl->copy_iterator(*m_xScratchIter, *xLastValid);
523 bLastValid = true;
525 else
526 RemoveEntry(*m_xScratchIter);
527 if (bLastValid)
529 m_xControl->copy_iterator(*xLastValid, *m_xScratchIter);
530 bValidIter = m_xControl->iter_next(*m_xScratchIter);
532 else
533 bValidIter = m_xControl->get_iter_first(*m_xScratchIter);
536 ScanAllEntries();
538 SetCurrentEntry( aCurDesc );
541 // Removes the entry from the tree.
542 void SbTreeListBox::RemoveEntry(const weld::TreeIter& rIter)
544 if (m_bFreezeOnFirstAddRemove)
546 m_xControl->freeze();
547 m_bFreezeOnFirstAddRemove = false;
550 // removing the associated user data
551 Entry* pBasicEntry = weld::fromId<Entry*>(m_xControl->get_id(rIter));
552 delete pBasicEntry;
553 // removing the entry
554 m_xControl->remove(rIter);
557 // Removes the entry of rDocument.
558 void SbTreeListBox::RemoveEntry (ScriptDocument const& rDocument)
560 // finding the entry of rDocument
561 bool bValidIter = m_xControl->get_iter_first(*m_xScratchIter);
562 while (bValidIter)
564 if (rDocument == GetEntryDescriptor(m_xScratchIter.get()).GetDocument())
566 RemoveEntry(*m_xScratchIter);
567 break;
569 bValidIter = m_xControl->iter_next(*m_xScratchIter);
573 bool SbTreeListBox::FindEntry(std::u16string_view rText, EntryType eType, weld::TreeIter& rIter)
575 bool bValidIter = m_xControl->iter_children(rIter);
576 while (bValidIter)
578 Entry* pBasicEntry = weld::fromId<Entry*>(m_xControl->get_id(rIter));
579 assert(pBasicEntry && "FindEntry: no Entry ?!");
580 if (pBasicEntry->GetType() == eType && rText == m_xControl->get_text(rIter))
581 return true;
582 bValidIter = m_xControl->iter_next_sibling(rIter);
584 return false;
587 bool SbTreeListBox::IsEntryProtected(const weld::TreeIter* pEntry)
589 bool bProtected = false;
590 if (pEntry && m_xControl->get_iter_depth(*pEntry) == 1)
592 EntryDescriptor aDesc(GetEntryDescriptor(pEntry));
593 const ScriptDocument& rDocument( aDesc.GetDocument() );
594 OSL_ENSURE( rDocument.isAlive(), "TreeListBox::IsEntryProtected: no document, or document is dead!" );
595 if ( rDocument.isAlive() )
597 const OUString& aOULibName( aDesc.GetLibName() );
598 Reference< script::XLibraryContainer > xModLibContainer( rDocument.getLibraryContainer( E_SCRIPTS ) );
599 if ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) )
601 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
602 if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aOULibName ) && !xPasswd->isLibraryPasswordVerified( aOULibName ) )
604 bProtected = true;
609 return bProtected;
612 void SbTreeListBox::AddEntry(
613 const OUString& rText,
614 const OUString& rImage,
615 const weld::TreeIter* pParent,
616 bool bChildrenOnDemand,
617 std::unique_ptr<Entry>&& rUserData,
618 weld::TreeIter* pRet)
620 if (m_bFreezeOnFirstAddRemove)
622 m_xControl->freeze();
623 m_bFreezeOnFirstAddRemove= false;
625 std::unique_ptr<weld::TreeIter> xScratch = pRet ? nullptr : m_xControl->make_iterator();
626 if (!pRet)
627 pRet = xScratch.get();
628 OUString sId(weld::toId(rUserData.release()));
629 m_xControl->insert(pParent, -1, &rText, &sId, nullptr, nullptr, bChildrenOnDemand, pRet);
630 m_xControl->set_image(*pRet, rImage);
633 void SbTreeListBox::SetEntryBitmaps(const weld::TreeIter& rIter, const OUString& rImage)
635 m_xControl->set_image(rIter, rImage, -1);
638 LibraryType SbTreeListBox::GetLibraryType() const
640 LibraryType eType = LibraryType::All;
641 if ( ( nMode & BrowseMode::Modules ) && !( nMode & BrowseMode::Dialogs ) )
642 eType = LibraryType::Module;
643 else if ( !( nMode & BrowseMode::Modules ) && ( nMode & BrowseMode::Dialogs ) )
644 eType = LibraryType::Dialog;
645 return eType;
648 OUString SbTreeListBox::GetRootEntryName( const ScriptDocument& rDocument, LibraryLocation eLocation ) const
650 return rDocument.getTitle( eLocation, GetLibraryType() );
653 OUString SbTreeListBox::GetRootEntryBitmaps(const ScriptDocument& rDocument)
655 OSL_ENSURE( rDocument.isValid(), "TreeListBox::GetRootEntryBitmaps: illegal document!" );
656 if (!rDocument.isValid())
657 return OUString();
659 if ( rDocument.isDocument() )
661 OUString sFactoryURL;
662 const Reference<uno::XComponentContext>& xContext( ::comphelper::getProcessComponentContext() );
663 Reference< frame::XModuleManager2 > xModuleManager( frame::ModuleManager::create(xContext) );
666 OUString sModule( xModuleManager->identify( rDocument.getDocument() ) );
667 Sequence< beans::PropertyValue > aModuleDescr;
668 xModuleManager->getByName( sModule ) >>= aModuleDescr;
669 for (auto& rModuleDescr : aModuleDescr)
671 if (rModuleDescr.Name == "ooSetupFactoryEmptyDocumentURL")
673 rModuleDescr.Value >>= sFactoryURL;
674 break;
678 catch( const Exception& )
680 DBG_UNHANDLED_EXCEPTION("basctl.basicide");
683 if ( !sFactoryURL.isEmpty() )
685 return SvFileInformationManager::GetFileImageId(INetURLObject(sFactoryURL));
687 else
689 // default icon
690 return RID_BMP_DOCUMENT;
693 return RID_BMP_INSTALLATION;
696 void SbTreeListBox::SetCurrentEntry (EntryDescriptor const & rDesc)
698 bool bCurEntry = false;
699 auto xCurIter = m_xControl->make_iterator();
700 EntryDescriptor aDesc = rDesc;
701 if ( aDesc.GetType() == OBJ_TYPE_UNKNOWN )
703 aDesc = EntryDescriptor(
704 ScriptDocument::getApplicationScriptDocument(),
705 LIBRARY_LOCATION_USER, u"Standard"_ustr,
706 OUString(), u"."_ustr, OBJ_TYPE_UNKNOWN
709 ScriptDocument aDocument = aDesc.GetDocument();
710 OSL_ENSURE( aDocument.isValid(), "TreeListBox::SetCurrentEntry: invalid document!" );
711 LibraryLocation eLocation = aDesc.GetLocation();
712 bool bRootEntry = FindRootEntry(aDocument, eLocation, *m_xScratchIter);
713 if (bRootEntry)
715 m_xControl->copy_iterator(*m_xScratchIter, *xCurIter);
716 bCurEntry = true;
717 const OUString& aLibName( aDesc.GetLibName() );
718 if ( !aLibName.isEmpty() )
720 m_xControl->expand_row(*m_xScratchIter);
721 auto xLibIter = m_xControl->make_iterator(m_xScratchIter.get());
722 bool bLibEntry = FindEntry(aLibName, OBJ_TYPE_LIBRARY, *xLibIter);
723 if (bLibEntry)
725 m_xControl->copy_iterator(*xLibIter, *xCurIter);
726 const OUString& aLibSubName( aDesc.GetLibSubName() );
727 if( !aLibSubName.isEmpty() )
729 m_xControl->expand_row(*xLibIter);
730 auto xSubLibIter = m_xControl->make_iterator(xLibIter.get());
731 bool bSubLibEntry = ImpFindEntry(*xSubLibIter, aLibSubName);
732 if (bSubLibEntry)
734 m_xControl->copy_iterator(*xSubLibIter, *xCurIter);
737 const OUString& aName( aDesc.GetName() );
738 if ( !aName.isEmpty() )
740 m_xControl->expand_row(*xCurIter);
741 EntryType eType = OBJ_TYPE_MODULE;
742 if ( aDesc.GetType() == OBJ_TYPE_DIALOG )
743 eType = OBJ_TYPE_DIALOG;
744 auto xEntryIter = m_xControl->make_iterator(xCurIter.get());
745 bool bEntry = FindEntry(aName, eType, *xEntryIter);
746 if (bEntry)
748 m_xControl->copy_iterator(*xEntryIter, *xCurIter);
749 const OUString& aMethodName( aDesc.GetMethodName() );
750 if (!aMethodName.isEmpty())
752 m_xControl->expand_row(*xCurIter);
753 auto xSubEntryIter = m_xControl->make_iterator(xCurIter.get());
754 bool bSubEntry = FindEntry(aMethodName, OBJ_TYPE_METHOD, *xSubEntryIter);
755 if (bSubEntry)
757 m_xControl->copy_iterator(*xSubEntryIter, *xCurIter);
759 else
761 m_xControl->copy_iterator(*xCurIter, *xSubEntryIter);
762 if (m_xControl->iter_children(*xSubEntryIter))
763 m_xControl->copy_iterator(*xSubEntryIter, *xCurIter);
767 else
769 auto xSubEntryIter = m_xControl->make_iterator(xCurIter.get());
770 if (m_xControl->iter_children(*xSubEntryIter))
771 m_xControl->copy_iterator(*xSubEntryIter, *xCurIter);
775 else
777 auto xSubLibIter = m_xControl->make_iterator(m_xScratchIter.get());
778 if (m_xControl->iter_children(*xSubLibIter))
779 m_xControl->copy_iterator(*xLibIter, *xCurIter);
783 else
785 bCurEntry = m_xControl->get_iter_first(*xCurIter);
788 if (!bCurEntry)
789 return;
791 m_xControl->set_cursor(*xCurIter);
794 IMPL_LINK_NOARG(SbTreeListBox, OpenCurrentHdl, weld::TreeView&, bool)
796 bool bValidIter = m_xControl->get_cursor(m_xScratchIter.get());
797 if (!bValidIter)
798 return true;
799 if (!m_xControl->get_row_expanded(*m_xScratchIter))
800 m_xControl->expand_row(*m_xScratchIter);
801 else
802 m_xControl->collapse_row(*m_xScratchIter);
804 EntryDescriptor aDesc = GetEntryDescriptor(m_xScratchIter.get());
805 switch (aDesc.GetType())
807 case OBJ_TYPE_METHOD:
808 case OBJ_TYPE_MODULE:
809 case OBJ_TYPE_DIALOG:
810 if (SfxDispatcher* pDispatcher = GetDispatcher())
812 SbxItem aSbxItem(
813 SID_BASICIDE_ARG_SBX, aDesc.GetDocument(),
814 aDesc.GetLibName(), aDesc.GetName(), aDesc.GetMethodName(),
815 ConvertType(aDesc.GetType())
817 pDispatcher->ExecuteList(
818 SID_BASICIDE_SHOWSBX, SfxCallMode::SYNCHRON,
819 { &aSbxItem }
822 break;
824 default:
825 break;
827 return true;
830 } // namespace basctl
832 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */