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