Version 6.1.0.2, tag libreoffice-6.1.0.2
[LibreOffice.git] / basctl / source / basicide / bastype3.cxx
blob2b8e3f79d8e31126e9cd22b42ce0c1a58101303a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <basic/basmgr.hxx>
21 #include <basic/sbmod.hxx>
22 #include <bastype2.hxx>
23 #include <bitmaps.hlst>
24 #include <bastypes.hxx>
25 #include <com/sun/star/script/XLibraryContainer.hpp>
26 #include <com/sun/star/script/XLibraryContainerPassword.hpp>
27 #include <deque>
28 #include <sfx2/docfac.hxx>
29 #include <svtools/treelistentry.hxx>
31 namespace basctl
34 using namespace ::com::sun::star::uno;
35 using namespace ::com::sun::star;
38 typedef std::deque< SvTreeListEntry* > EntryArray;
41 void TreeListBox::RequestingChildren( SvTreeListEntry* pEntry )
43 EntryDescriptor aDesc = GetEntryDescriptor(pEntry);
44 ScriptDocument aDocument = aDesc.GetDocument();
45 OSL_ENSURE( aDocument.isAlive(), "basctl::TreeListBox::RequestingChildren: invalid document!" );
46 if ( !aDocument.isAlive() )
47 return;
49 LibraryLocation eLocation = aDesc.GetLocation();
50 EntryType eType = aDesc.GetType();
52 if ( eType == OBJ_TYPE_DOCUMENT )
54 ImpCreateLibEntries( pEntry, aDocument, eLocation );
56 else if ( eType == OBJ_TYPE_LIBRARY )
58 OUString aOULibName( aDesc.GetLibName() );
60 // check password
61 bool bOK = true;
62 Reference< script::XLibraryContainer > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ) );
63 if ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) )
65 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
66 if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aOULibName ) && !xPasswd->isLibraryPasswordVerified( aOULibName ) )
68 OUString aPassword;
69 bOK = QueryPassword( xModLibContainer, aOULibName, aPassword );
73 if ( bOK )
75 // load module library
76 bool bModLibLoaded = false;
77 if ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) )
79 if ( !xModLibContainer->isLibraryLoaded( aOULibName ) )
81 EnterWait();
82 xModLibContainer->loadLibrary( aOULibName );
83 LeaveWait();
85 bModLibLoaded = xModLibContainer->isLibraryLoaded( aOULibName );
88 // load dialog library
89 bool bDlgLibLoaded = false;
90 Reference< script::XLibraryContainer > xDlgLibContainer( aDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
91 if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aOULibName ) )
93 if ( !xDlgLibContainer->isLibraryLoaded( aOULibName ) )
95 EnterWait();
96 xDlgLibContainer->loadLibrary( aOULibName );
97 LeaveWait();
99 bDlgLibLoaded = xDlgLibContainer->isLibraryLoaded( aOULibName );
102 if ( bModLibLoaded || bDlgLibLoaded )
104 // create the sub entries
105 ImpCreateLibSubEntries( pEntry, aDocument, aOULibName );
107 // exchange image
108 const bool bDlgMode = (nMode & BrowseMode::Dialogs) && !(nMode & BrowseMode::Modules);
109 Image aImage(BitmapEx(bDlgMode ? OUStringLiteral(RID_BMP_DLGLIB) : OUStringLiteral(RID_BMP_MODLIB)));
110 SetEntryBitmaps( pEntry, aImage );
112 else
114 OSL_FAIL( "basctl::TreeListBox::RequestingChildren: Error loading library!" );
118 else if ( eType == OBJ_TYPE_DOCUMENT_OBJECTS
119 || eType == OBJ_TYPE_USERFORMS
120 || eType == OBJ_TYPE_NORMAL_MODULES
121 || eType == OBJ_TYPE_CLASS_MODULES )
123 OUString aLibName( aDesc.GetLibName() );
124 ImpCreateLibSubSubEntriesInVBAMode( pEntry, aDocument, aLibName );
126 else {
127 OSL_FAIL( "basctl::TreeListBox::RequestingChildren: Unknown Type!" );
131 void TreeListBox::ExpandedHdl()
133 SvTreeListEntry* pEntry = GetHdlEntry();
134 assert(pEntry && "What was collapsed?");
135 if ( !IsExpanded( pEntry ) && pEntry->HasChildrenOnDemand() )
137 SvTreeListEntry* pChild = FirstChild( pEntry );
138 while ( pChild )
140 GetModel()->Remove( pChild ); // does also call the DTOR
141 pChild = FirstChild( pEntry );
146 void TreeListBox::ScanAllEntries()
148 ScanEntry( ScriptDocument::getApplicationScriptDocument(), LIBRARY_LOCATION_USER );
149 ScanEntry( ScriptDocument::getApplicationScriptDocument(), LIBRARY_LOCATION_SHARE );
151 ScriptDocuments aDocuments( ScriptDocument::getAllScriptDocuments( ScriptDocument::DocumentsSorted ) );
152 for (auto const& doc : aDocuments)
154 if ( doc.isAlive() )
155 ScanEntry(doc, LIBRARY_LOCATION_DOCUMENT);
159 SbxVariable* TreeListBox::FindVariable( SvTreeListEntry* pEntry )
161 if ( !pEntry )
162 return nullptr;
164 ScriptDocument aDocument( ScriptDocument::getApplicationScriptDocument() );
165 EntryArray aEntries;
167 while ( pEntry )
169 sal_uInt16 nDepth = GetModel()->GetDepth( pEntry );
170 switch ( nDepth )
172 case 4:
173 case 3:
174 case 2:
175 case 1:
177 aEntries.push_front( pEntry );
179 break;
180 case 0:
182 aDocument = static_cast<DocumentEntry*>(pEntry->GetUserData())->GetDocument();
184 break;
186 pEntry = GetParent( pEntry );
189 SbxVariable* pVar = nullptr;
190 if ( !aEntries.empty() )
192 bool bDocumentObjects = false;
193 for (SvTreeListEntry* pLE : aEntries)
195 assert(pLE && "Can not find entry in array");
196 Entry* pBE = static_cast<Entry*>(pLE->GetUserData());
197 assert(pBE && "The data in the entry not found!");
198 OUString aName( GetEntryText( pLE ) );
200 switch ( pBE->GetType() )
202 case OBJ_TYPE_LIBRARY:
203 if (BasicManager* pBasMgr = aDocument.getBasicManager())
204 pVar = pBasMgr->GetLib( aName );
205 break;
206 case OBJ_TYPE_MODULE:
207 DBG_ASSERT(dynamic_cast<StarBASIC*>(pVar), "FindVariable: invalid Basic");
208 if(!pVar)
210 break;
212 // extract the module name from the string like "Sheet1 (Example1)"
213 if( bDocumentObjects )
215 sal_Int32 nIndex = 0;
216 aName = aName.getToken( 0, ' ', nIndex );
218 pVar = static_cast<StarBASIC*>(pVar)->FindModule( aName );
219 break;
220 case OBJ_TYPE_METHOD:
221 DBG_ASSERT(dynamic_cast<SbxObject*>(pVar), "FindVariable: invalid module/object");
222 if(!pVar)
224 break;
226 pVar = static_cast<SbxObject*>(pVar)->GetMethods()->Find(aName, SbxClassType::Method);
227 break;
228 case OBJ_TYPE_DIALOG:
229 // sbx dialogs removed
230 break;
231 case OBJ_TYPE_DOCUMENT_OBJECTS:
232 bDocumentObjects = true;
233 SAL_FALLTHROUGH;
234 case OBJ_TYPE_USERFORMS:
235 case OBJ_TYPE_NORMAL_MODULES:
236 case OBJ_TYPE_CLASS_MODULES:
237 // skip, to find the child entry.
238 continue;
239 default:
240 OSL_FAIL( "FindVariable: unknown type" );
241 pVar = nullptr;
242 break;
244 if ( !pVar )
245 break;
249 return pVar;
252 EntryDescriptor TreeListBox::GetEntryDescriptor( SvTreeListEntry* pEntry )
254 ScriptDocument aDocument( ScriptDocument::getApplicationScriptDocument() );
255 LibraryLocation eLocation = LIBRARY_LOCATION_UNKNOWN;
256 OUString aLibName;
257 OUString aLibSubName;
258 OUString aName;
259 OUString aMethodName;
260 EntryType eType = OBJ_TYPE_UNKNOWN;
262 if ( !pEntry )
263 return EntryDescriptor( aDocument, eLocation, aLibName, aLibSubName, aName, aMethodName, eType );
265 EntryArray aEntries;
267 while ( pEntry )
269 sal_uInt16 nDepth = GetModel()->GetDepth( pEntry );
270 switch ( nDepth )
272 case 4:
273 case 3:
274 case 2:
275 case 1:
277 aEntries.push_front( pEntry );
279 break;
280 case 0:
282 if (DocumentEntry* pDocumentEntry = static_cast<DocumentEntry*>(pEntry->GetUserData()))
284 aDocument = pDocumentEntry->GetDocument();
285 eLocation = pDocumentEntry->GetLocation();
286 eType = OBJ_TYPE_DOCUMENT;
289 break;
291 pEntry = GetParent( pEntry );
294 if ( !aEntries.empty() )
296 for (SvTreeListEntry* pLE : aEntries)
298 assert(pLE && "Entry not found in array");
299 Entry* pBE = static_cast<Entry*>(pLE->GetUserData());
300 assert(pBE && "No data found in entry!");
302 switch ( pBE->GetType() )
304 case OBJ_TYPE_LIBRARY:
306 aLibName = GetEntryText( pLE );
307 eType = pBE->GetType();
309 break;
310 case OBJ_TYPE_MODULE:
312 aName = GetEntryText( pLE );
313 eType = pBE->GetType();
315 break;
316 case OBJ_TYPE_METHOD:
318 aMethodName = GetEntryText( pLE );
319 eType = pBE->GetType();
321 break;
322 case OBJ_TYPE_DIALOG:
324 aName = GetEntryText( pLE );
325 eType = pBE->GetType();
327 break;
328 case OBJ_TYPE_DOCUMENT_OBJECTS:
329 case OBJ_TYPE_USERFORMS:
330 case OBJ_TYPE_NORMAL_MODULES:
331 case OBJ_TYPE_CLASS_MODULES:
333 aLibSubName = GetEntryText( pLE );
334 eType = pBE->GetType();
336 break;
337 default:
339 OSL_FAIL( "GetEntryDescriptor: unknown type" );
340 eType = OBJ_TYPE_UNKNOWN;
342 break;
345 if ( eType == OBJ_TYPE_UNKNOWN )
346 break;
350 return EntryDescriptor( aDocument, eLocation, aLibName, aLibSubName, aName, aMethodName, eType );
353 ItemType TreeListBox::ConvertType (EntryType eType)
355 switch (eType)
357 case OBJ_TYPE_DOCUMENT: return TYPE_SHELL;
358 case OBJ_TYPE_LIBRARY: return TYPE_LIBRARY;
359 case OBJ_TYPE_MODULE: return TYPE_MODULE;
360 case OBJ_TYPE_DIALOG: return TYPE_DIALOG;
361 case OBJ_TYPE_METHOD: return TYPE_METHOD;
362 default:
363 return static_cast<ItemType>(OBJ_TYPE_UNKNOWN);
367 bool TreeListBox::IsValidEntry( SvTreeListEntry* pEntry )
369 bool bIsValid = false;
371 EntryDescriptor aDesc( GetEntryDescriptor( pEntry ) );
372 ScriptDocument aDocument( aDesc.GetDocument() );
373 LibraryLocation eLocation( aDesc.GetLocation() );
374 OUString aLibName( aDesc.GetLibName() );
375 OUString aName( aDesc.GetName() );
376 OUString aMethodName( aDesc.GetMethodName() );
377 EntryType eType( aDesc.GetType() );
379 switch ( eType )
381 case OBJ_TYPE_DOCUMENT:
383 bIsValid = aDocument.isAlive()
384 && (aDocument.isApplication()
385 || GetRootEntryName(aDocument, eLocation) == GetEntryText(pEntry));
387 break;
388 case OBJ_TYPE_LIBRARY:
390 bIsValid = aDocument.hasLibrary( E_SCRIPTS, aLibName ) || aDocument.hasLibrary( E_DIALOGS, aLibName );
392 break;
393 case OBJ_TYPE_MODULE:
395 bIsValid = aDocument.hasModule( aLibName, aName );
397 break;
398 case OBJ_TYPE_DIALOG:
400 bIsValid = aDocument.hasDialog( aLibName, aName );
402 break;
403 case OBJ_TYPE_METHOD:
405 bIsValid = HasMethod( aDocument, aLibName, aName, aMethodName );
407 break;
408 case OBJ_TYPE_DOCUMENT_OBJECTS:
409 case OBJ_TYPE_USERFORMS:
410 case OBJ_TYPE_NORMAL_MODULES:
411 case OBJ_TYPE_CLASS_MODULES:
413 bIsValid = true;
415 break;
416 default: ;
419 return bIsValid;
422 SbModule* TreeListBox::FindModule( SvTreeListEntry* pEntry )
424 return dynamic_cast<SbModule*>(FindVariable(pEntry));
427 SvTreeListEntry* TreeListBox::FindRootEntry( const ScriptDocument& rDocument, LibraryLocation eLocation )
429 OSL_ENSURE( rDocument.isValid(), "basctl::TreeListBox::FindRootEntry: invalid document!" );
430 sal_uLong nRootPos = 0;
431 SvTreeListEntry* pRootEntry = GetEntry( nRootPos );
432 while ( pRootEntry )
434 DBG_ASSERT( static_cast<Entry*>(pRootEntry->GetUserData())->GetType() == OBJ_TYPE_DOCUMENT, "No shell entry?" );
435 DocumentEntry* pBDEntry = static_cast<DocumentEntry*>(pRootEntry->GetUserData());
436 if (pBDEntry && pBDEntry->GetDocument() == rDocument && pBDEntry->GetLocation() == eLocation)
437 return pRootEntry;
438 pRootEntry = GetEntry( ++nRootPos );
440 return nullptr;
443 OUString CreateMgrAndLibStr( const OUString& rMgrName, const OUString& rLibName )
445 return "[" + rMgrName + "]." + rLibName;
449 } // namespace basctl
451 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */