1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_basctl.hxx"
26
27
28 #include <ide_pch.hxx>
29
30 #define _SI_NOSBXCONTROLS
31
32 #include <basic/sbx.hxx>
33 #include <bastype2.hxx>
34 #include <basobj.hxx>
35 #include <baside2.hrc>
36 #include <iderid.hxx>
37 #include <bastypes.hxx>
38 #include <basdoc.hxx>
39 #include <com/sun/star/script/XLibraryContainer.hpp>
40 #include <com/sun/star/script/XLibraryContainerPassword.hpp>
41 #include <deque>
42
43 using namespace ::com::sun::star::uno;
44 using namespace ::com::sun::star;
45
46
47 typedef std::deque< SvLBoxEntry* > EntryArray;
48
49
RequestingChilds(SvLBoxEntry * pEntry)50 void __EXPORT BasicTreeListBox::RequestingChilds( SvLBoxEntry* pEntry )
51 {
52 BasicEntryDescriptor aDesc( GetEntryDescriptor( pEntry ) );
53 ScriptDocument aDocument( aDesc.GetDocument() );
54 OSL_ENSURE( aDocument.isAlive(), "BasicTreeListBox::RequestingChilds: invalid document!" );
55 if ( !aDocument.isAlive() )
56 return;
57
58 LibraryLocation eLocation( aDesc.GetLocation() );
59 BasicEntryType eType( aDesc.GetType() );
60
61 if ( eType == OBJ_TYPE_DOCUMENT )
62 {
63 ImpCreateLibEntries( pEntry, aDocument, eLocation );
64 }
65 else if ( eType == OBJ_TYPE_LIBRARY )
66 {
67 String aLibName( aDesc.GetLibName() );
68 ::rtl::OUString aOULibName( aLibName );
69
70 // check password
71 sal_Bool bOK = sal_True;
72 Reference< script::XLibraryContainer > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ) );
73 if ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) )
74 {
75 Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
76 if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aOULibName ) && !xPasswd->isLibraryPasswordVerified( aOULibName ) )
77 {
78 String aPassword;
79 bOK = QueryPassword( xModLibContainer, aLibName, aPassword );
80 }
81 }
82
83 if ( bOK )
84 {
85 // load module library
86 sal_Bool bModLibLoaded = sal_False;
87 if ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) )
88 {
89 if ( !xModLibContainer->isLibraryLoaded( aOULibName ) )
90 {
91 EnterWait();
92 xModLibContainer->loadLibrary( aOULibName );
93 LeaveWait();
94 }
95 bModLibLoaded = xModLibContainer->isLibraryLoaded( aOULibName );
96 }
97
98 // load dialog library
99 sal_Bool bDlgLibLoaded = sal_False;
100 Reference< script::XLibraryContainer > xDlgLibContainer( aDocument.getLibraryContainer( E_DIALOGS ), UNO_QUERY );
101 if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aOULibName ) )
102 {
103 if ( !xDlgLibContainer->isLibraryLoaded( aOULibName ) )
104 {
105 EnterWait();
106 xDlgLibContainer->loadLibrary( aOULibName );
107 LeaveWait();
108 }
109 bDlgLibLoaded = xDlgLibContainer->isLibraryLoaded( aOULibName );
110 }
111
112 if ( bModLibLoaded || bDlgLibLoaded )
113 {
114 // create the sub entries
115 ImpCreateLibSubEntries( pEntry, aDocument, aLibName );
116
117 // exchange image
118 bool bDlgMode = ( nMode & BROWSEMODE_DIALOGS ) && !( nMode & BROWSEMODE_MODULES );
119 Image aImage( IDEResId( bDlgMode ? RID_IMG_DLGLIB : RID_IMG_MODLIB ) );
120 Image aImageHC( IDEResId( bDlgMode ? RID_IMG_DLGLIB_HC : RID_IMG_MODLIB_HC ) );
121 SetEntryBitmaps( pEntry, aImage, aImageHC );
122 }
123 else
124 {
125 DBG_ERROR( "BasicTreeListBox::RequestingChilds: Error loading library!" );
126 }
127 }
128 }
129 else if ( eType == OBJ_TYPE_DOCUMENT_OBJECTS
130 || eType == OBJ_TYPE_USERFORMS
131 || eType == OBJ_TYPE_NORMAL_MODULES
132 || eType == OBJ_TYPE_CLASS_MODULES )
133 {
134 String aLibName( aDesc.GetLibName() );
135 ImpCreateLibSubSubEntriesInVBAMode( pEntry, aDocument, aLibName );
136 }
137 else {
138 DBG_ERROR( "BasicTreeListBox::RequestingChilds: Unknown Type!" );
139 }
140 }
141
ExpandedHdl()142 void __EXPORT BasicTreeListBox::ExpandedHdl()
143 {
144 SvLBoxEntry* pEntry = GetHdlEntry();
145 DBG_ASSERT( pEntry, "Was wurde zugeklappt?" );
146 // Die OnDemand erzeugten Childs loeschen,
147 // SubChilds werden automatisch geloescht.
148 if ( !IsExpanded( pEntry ) && pEntry->HasChildsOnDemand() )
149 {
150 SvLBoxEntry* pChild = FirstChild( pEntry );
151 while ( pChild )
152 {
153 GetModel()->Remove( pChild ); // Ruft auch den DTOR
154 pChild = FirstChild( pEntry );
155 }
156 }
157 }
158
ScanAllEntries()159 void BasicTreeListBox::ScanAllEntries()
160 {
161 ScanEntry( ScriptDocument::getApplicationScriptDocument(), LIBRARY_LOCATION_USER );
162 ScanEntry( ScriptDocument::getApplicationScriptDocument(), LIBRARY_LOCATION_SHARE );
163
164 ScriptDocuments aDocuments( ScriptDocument::getAllScriptDocuments( ScriptDocument::DocumentsSorted ) );
165 for ( ScriptDocuments::const_iterator doc = aDocuments.begin();
166 doc != aDocuments.end();
167 ++doc
168 )
169 {
170 if ( doc->isAlive() )
171 ScanEntry( *doc, LIBRARY_LOCATION_DOCUMENT );
172 }
173 }
174
FindVariable(SvLBoxEntry * pEntry)175 SbxVariable* BasicTreeListBox::FindVariable( SvLBoxEntry* pEntry )
176 {
177 if ( !pEntry )
178 return 0;
179
180 String aLib, aModOrObj, aSubOrPropOrSObj, aPropOrSubInSObj;
181 ScriptDocument aDocument( ScriptDocument::getApplicationScriptDocument() );
182 EntryArray aEntries;
183
184 while ( pEntry )
185 {
186 sal_uInt16 nDepth = GetModel()->GetDepth( pEntry );
187 switch ( nDepth )
188 {
189 case 4:
190 case 3:
191 case 2:
192 case 1:
193 {
194 aEntries.push_front( pEntry );
195 }
196 break;
197 case 0:
198 {
199 aDocument = ((BasicDocumentEntry*)pEntry->GetUserData())->GetDocument();
200 }
201 break;
202 }
203 pEntry = GetParent( pEntry );
204 }
205
206 SbxVariable* pVar = 0;
207 bool bDocumentObjects = false;
208 if ( !aEntries.empty() )
209 {
210 for ( size_t n = 0; n < aEntries.size(); n++ )
211 {
212 SvLBoxEntry* pLE = aEntries[n];
213 DBG_ASSERT( pLE, "Can not find entry in array" );
214 BasicEntry* pBE = (BasicEntry*)pLE->GetUserData();
215 DBG_ASSERT( pBE, "The data in the entry not found!" );
216 String aName( GetEntryText( pLE ) );
217
218 switch ( pBE->GetType() )
219 {
220 case OBJ_TYPE_LIBRARY:
221 {
222 BasicManager* pBasMgr = aDocument.getBasicManager();
223 if ( pBasMgr )
224 pVar = pBasMgr->GetLib( aName );
225 }
226 break;
227 case OBJ_TYPE_MODULE:
228 {
229 DBG_ASSERT( pVar && pVar->IsA( TYPE(StarBASIC) ), "FindVariable: Ungueltiges Basic" );
230 // extract the module name from the string like "Sheet1 (Example1)"
231 if( bDocumentObjects )
232 {
233 sal_uInt16 nIndex = 0;
234 aName = aName.GetToken( 0, ' ', nIndex );
235 }
236 pVar = ((StarBASIC*)pVar)->FindModule( aName );
237 }
238 break;
239 case OBJ_TYPE_METHOD:
240 {
241 DBG_ASSERT( pVar && ( (pVar->IsA( TYPE(SbModule) )) || (pVar->IsA( TYPE(SbxObject) )) ), "FindVariable: Ungueltiges Modul/Objekt" );
242 pVar = ((SbxObject*)pVar)->GetMethods()->Find( aName, SbxCLASS_METHOD );
243 }
244 break;
245 case OBJ_TYPE_DIALOG:
246 {
247 // sbx dialogs removed
248 }
249 break;
250 case OBJ_TYPE_DOCUMENT_OBJECTS:
251 bDocumentObjects = true;
252 case OBJ_TYPE_USERFORMS:
253 case OBJ_TYPE_NORMAL_MODULES:
254 case OBJ_TYPE_CLASS_MODULES:
255 {
256 // skip, to find the child entry.
257 continue;
258 }
259 default:
260 {
261 DBG_ERROR( "FindVariable: Unbekannter Typ!" );
262 pVar = 0;
263 }
264 break;
265 }
266 if ( !pVar )
267 break;
268 }
269 }
270
271 return pVar;
272 }
273
GetEntryDescriptor(SvLBoxEntry * pEntry)274 BasicEntryDescriptor BasicTreeListBox::GetEntryDescriptor( SvLBoxEntry* pEntry )
275 {
276 ScriptDocument aDocument( ScriptDocument::getApplicationScriptDocument() );
277 LibraryLocation eLocation = LIBRARY_LOCATION_UNKNOWN;
278 String aLibName;
279 String aLibSubName;
280 String aName;
281 String aMethodName;
282 BasicEntryType eType = OBJ_TYPE_UNKNOWN;
283
284 if ( !pEntry )
285 return BasicEntryDescriptor( aDocument, eLocation, aLibName, aLibSubName, aName, aMethodName, eType );
286
287 EntryArray aEntries;
288
289 while ( pEntry )
290 {
291 sal_uInt16 nDepth = GetModel()->GetDepth( pEntry );
292 switch ( nDepth )
293 {
294 case 4:
295 case 3:
296 case 2:
297 case 1:
298 {
299 aEntries.push_front( pEntry );
300 }
301 break;
302 case 0:
303 {
304 BasicDocumentEntry* pBasicDocumentEntry = (BasicDocumentEntry*)pEntry->GetUserData();
305 if ( pBasicDocumentEntry )
306 {
307 aDocument = pBasicDocumentEntry->GetDocument();
308 eLocation = pBasicDocumentEntry->GetLocation();
309 eType = OBJ_TYPE_DOCUMENT;
310 }
311 }
312 break;
313 }
314 pEntry = GetParent( pEntry );
315 }
316
317 if ( !aEntries.empty() )
318 {
319 for ( size_t n = 0; n < aEntries.size(); n++ )
320 {
321 SvLBoxEntry* pLE = aEntries[n];
322 DBG_ASSERT( pLE, "Entrie im Array nicht gefunden" );
323 BasicEntry* pBE = (BasicEntry*)pLE->GetUserData();
324 DBG_ASSERT( pBE, "Keine Daten im Eintrag gefunden!" );
325
326 switch ( pBE->GetType() )
327 {
328 case OBJ_TYPE_LIBRARY:
329 {
330 aLibName = GetEntryText( pLE );
331 eType = pBE->GetType();
332 }
333 break;
334 case OBJ_TYPE_MODULE:
335 {
336 aName = GetEntryText( pLE );
337 eType = pBE->GetType();
338 }
339 break;
340 case OBJ_TYPE_METHOD:
341 {
342 aMethodName = GetEntryText( pLE );
343 eType = pBE->GetType();
344 }
345 break;
346 case OBJ_TYPE_DIALOG:
347 {
348 aName = GetEntryText( pLE );
349 eType = pBE->GetType();
350 }
351 break;
352 case OBJ_TYPE_DOCUMENT_OBJECTS:
353 case OBJ_TYPE_USERFORMS:
354 case OBJ_TYPE_NORMAL_MODULES:
355 case OBJ_TYPE_CLASS_MODULES:
356 {
357 aLibSubName = GetEntryText( pLE );
358 eType = pBE->GetType();
359 }
360 break;
361 default:
362 {
363 DBG_ERROR( "GetEntryDescriptor: Unbekannter Typ!" );
364 eType = OBJ_TYPE_UNKNOWN;
365 }
366 break;
367 }
368
369 if ( eType == OBJ_TYPE_UNKNOWN )
370 break;
371 }
372 }
373
374 return BasicEntryDescriptor( aDocument, eLocation, aLibName, aLibSubName, aName, aMethodName, eType );
375 }
376
ConvertType(BasicEntryType eType)377 sal_uInt16 BasicTreeListBox::ConvertType( BasicEntryType eType )
378 {
379 sal_uInt16 nType = OBJ_TYPE_UNKNOWN;
380
381 switch ( eType )
382 {
383 case OBJ_TYPE_DOCUMENT:
384 {
385 nType = BASICIDE_TYPE_SHELL;
386 }
387 break;
388 case OBJ_TYPE_LIBRARY:
389 {
390 nType = BASICIDE_TYPE_LIBRARY;
391 }
392 break;
393 case OBJ_TYPE_MODULE:
394 {
395 nType = BASICIDE_TYPE_MODULE;
396 }
397 break;
398 case OBJ_TYPE_DIALOG:
399 {
400 nType = BASICIDE_TYPE_DIALOG;
401 }
402 break;
403 case OBJ_TYPE_METHOD:
404 {
405 nType = BASICIDE_TYPE_METHOD;
406 }
407 break;
408 default: ;
409 }
410
411 return nType;
412 }
413
IsValidEntry(SvLBoxEntry * pEntry)414 bool BasicTreeListBox::IsValidEntry( SvLBoxEntry* pEntry )
415 {
416 bool bIsValid = false;
417
418 BasicEntryDescriptor aDesc( GetEntryDescriptor( pEntry ) );
419 ScriptDocument aDocument( aDesc.GetDocument() );
420 LibraryLocation eLocation( aDesc.GetLocation() );
421 String aLibName( aDesc.GetLibName() );
422 String aName( aDesc.GetName() );
423 String aMethodName( aDesc.GetMethodName() );
424 BasicEntryType eType( aDesc.GetType() );
425
426 switch ( eType )
427 {
428 case OBJ_TYPE_DOCUMENT:
429 {
430 bIsValid = aDocument.isAlive()
431 && ( aDocument.isApplication()
432 || GetRootEntryName( aDocument, eLocation ) == GetEntryText( pEntry )
433 );
434 }
435 break;
436 case OBJ_TYPE_LIBRARY:
437 {
438 bIsValid = aDocument.hasLibrary( E_SCRIPTS, aLibName ) || aDocument.hasLibrary( E_DIALOGS, aLibName );
439 }
440 break;
441 case OBJ_TYPE_MODULE:
442 {
443 bIsValid = aDocument.hasModule( aLibName, aName );
444 }
445 break;
446 case OBJ_TYPE_DIALOG:
447 {
448 bIsValid = aDocument.hasDialog( aLibName, aName );
449 }
450 break;
451 case OBJ_TYPE_METHOD:
452 {
453 bIsValid = BasicIDE::HasMethod( aDocument, aLibName, aName, aMethodName );
454 }
455 break;
456 case OBJ_TYPE_DOCUMENT_OBJECTS:
457 case OBJ_TYPE_USERFORMS:
458 case OBJ_TYPE_NORMAL_MODULES:
459 case OBJ_TYPE_CLASS_MODULES:
460 {
461 bIsValid = true;
462 }
463 break;
464 default: ;
465 }
466
467 return bIsValid;
468 }
469
FindModule(SvLBoxEntry * pEntry)470 SbModule* BasicTreeListBox::FindModule( SvLBoxEntry* pEntry )
471 {
472 SbxVariable* pVar = FindVariable( pEntry );
473 if ( pVar && pVar->IsA( TYPE(SbModule ) ) )
474 return (SbModule*)pVar;
475 return 0;
476 }
477
FindRootEntry(const ScriptDocument & rDocument,LibraryLocation eLocation)478 SvLBoxEntry* BasicTreeListBox::FindRootEntry( const ScriptDocument& rDocument, LibraryLocation eLocation )
479 {
480 OSL_ENSURE( rDocument.isValid(), "BasicTreeListBox::FindRootEntry: invalid document!" );
481 sal_uLong nRootPos = 0;
482 SvLBoxEntry* pRootEntry = GetEntry( nRootPos );
483 while ( pRootEntry )
484 {
485 DBG_ASSERT( (((BasicEntry*)pRootEntry->GetUserData())->GetType() == OBJ_TYPE_DOCUMENT ), "Kein Shelleintrag?" );
486 BasicDocumentEntry* pBasicDocumentEntry = (BasicDocumentEntry*)pRootEntry->GetUserData();
487 if ( pBasicDocumentEntry && ( pBasicDocumentEntry->GetDocument() == rDocument ) && pBasicDocumentEntry->GetLocation() == eLocation )
488 return pRootEntry;
489 pRootEntry = GetEntry( ++nRootPos );
490 }
491 return 0;
492 }
493
CreateMgrAndLibStr(const String & rMgrName,const String & rLibName)494 String CreateMgrAndLibStr( const String& rMgrName, const String& rLibName )
495 {
496 String aName( '[' );
497 aName += rMgrName;
498 aName += String( RTL_CONSTASCII_USTRINGPARAM( "]." ) );
499 aName += rLibName;
500 return aName;
501 }
502