Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <vcl/bitmap.hxx>
21 : #include <vcl/builder.hxx>
22 :
23 : #include "basidesh.hxx"
24 : #include "iderdll.hxx"
25 : #include "iderdll2.hxx"
26 : #include <basidesh.hrc>
27 : #include <bastypes.hxx>
28 : #include <bastype2.hxx>
29 : #include <basobj.hxx>
30 : #include <baside2.hrc>
31 : #include <iderid.hxx>
32 : #include <tools/urlobj.hxx>
33 : #include <tools/diagnose_ex.h>
34 : #include <basic/sbx.hxx>
35 : #include <svtools/imagemgr.hxx>
36 : #include <svtools/treelistentry.hxx>
37 : #include <com/sun/star/script/XLibraryContainer.hpp>
38 : #include <com/sun/star/script/XLibraryContainerPassword.hpp>
39 : #include <com/sun/star/frame/ModuleManager.hpp>
40 : #include <comphelper/processfactory.hxx>
41 : #include <sfx2/dispatch.hxx>
42 :
43 : #include <cassert>
44 : #include <memory>
45 :
46 : #include <com/sun/star/script/ModuleType.hpp>
47 : #include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
48 : #include <com/sun/star/container/XNameContainer.hpp>
49 : #include <com/sun/star/lang/XServiceInfo.hpp>
50 : #include <com/sun/star/container/XNamed.hpp>
51 :
52 : namespace basctl
53 : {
54 :
55 : using namespace ::com::sun::star::uno;
56 : using namespace ::com::sun::star;
57 :
58 0 : void ModuleInfoHelper::getObjectName( const uno::Reference< container::XNameContainer >& rLib, const OUString& rModName, OUString& rObjName )
59 : {
60 : try
61 : {
62 0 : uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( rLib, uno::UNO_QUERY );
63 0 : if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( rModName ) )
64 : {
65 0 : script::ModuleInfo aModuleInfo = xVBAModuleInfo->getModuleInfo( rModName );
66 0 : uno::Any aObject( aModuleInfo.ModuleObject );
67 0 : uno::Reference< lang::XServiceInfo > xServiceInfo( aObject, uno::UNO_QUERY );
68 0 : if( xServiceInfo.is() && xServiceInfo->supportsService( "ooo.vba.excel.Worksheet" ) )
69 : {
70 0 : uno::Reference< container::XNamed > xNamed( aObject, uno::UNO_QUERY );
71 0 : if( xNamed.is() )
72 0 : rObjName = xNamed->getName();
73 0 : }
74 0 : }
75 : }
76 0 : catch(const uno::Exception& )
77 : {
78 : }
79 0 : }
80 :
81 0 : sal_Int32 ModuleInfoHelper::getModuleType( const uno::Reference< container::XNameContainer >& rLib, const OUString& rModName )
82 : {
83 0 : sal_Int32 nType = script::ModuleType::NORMAL;
84 0 : uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( rLib, uno::UNO_QUERY );
85 0 : if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( rModName ) )
86 : {
87 0 : script::ModuleInfo aModuleInfo = xVBAModuleInfo->getModuleInfo( rModName );
88 0 : nType = aModuleInfo.ModuleType;
89 : }
90 0 : return nType;
91 : }
92 :
93 0 : Entry::~Entry()
94 0 : { }
95 :
96 0 : DocumentEntry::DocumentEntry (
97 : ScriptDocument const& rDocument,
98 : LibraryLocation eLocation,
99 : EntryType eType
100 : ) :
101 : Entry(eType),
102 : m_aDocument(rDocument),
103 0 : m_eLocation(eLocation)
104 : {
105 : OSL_ENSURE( m_aDocument.isValid(), "DocumentEntry::DocumentEntry: illegal document!" );
106 0 : }
107 :
108 0 : DocumentEntry::~DocumentEntry()
109 0 : { }
110 :
111 0 : LibEntry::LibEntry (
112 : ScriptDocument const& rDocument,
113 : LibraryLocation eLocation,
114 : OUString const& rLibName,
115 : EntryType eType
116 : ) :
117 : DocumentEntry(rDocument, eLocation, eType),
118 0 : m_aLibName(rLibName)
119 0 : { }
120 :
121 0 : LibEntry::~LibEntry()
122 0 : { }
123 :
124 0 : EntryDescriptor::EntryDescriptor () :
125 0 : m_aDocument(ScriptDocument::getApplicationScriptDocument()),
126 : m_eLocation(LIBRARY_LOCATION_UNKNOWN),
127 0 : m_eType(OBJ_TYPE_UNKNOWN)
128 0 : { }
129 :
130 0 : EntryDescriptor::EntryDescriptor (
131 : ScriptDocument const& rDocument,
132 : LibraryLocation eLocation,
133 : OUString const& rLibName,
134 : OUString const& rLibSubName,
135 : OUString const& rName,
136 : EntryType eType
137 : ) :
138 : m_aDocument(rDocument),
139 : m_eLocation(eLocation),
140 : m_aLibName(rLibName),
141 : m_aLibSubName(rLibSubName),
142 : m_aName(rName),
143 0 : m_eType(eType)
144 : {
145 : OSL_ENSURE( m_aDocument.isValid(), "EntryDescriptor::EntryDescriptor: invalid document!" );
146 0 : }
147 :
148 0 : EntryDescriptor::EntryDescriptor (
149 : ScriptDocument const& rDocument,
150 : LibraryLocation eLocation,
151 : OUString const& rLibName,
152 : OUString const& rLibSubName,
153 : OUString const& rName,
154 : OUString const& rMethodName,
155 : EntryType eType
156 : ) :
157 : m_aDocument(rDocument),
158 : m_eLocation(eLocation),
159 : m_aLibName(rLibName),
160 : m_aLibSubName(rLibSubName),
161 : m_aName(rName),
162 : m_aMethodName(rMethodName),
163 0 : m_eType(eType)
164 : {
165 : OSL_ENSURE( m_aDocument.isValid(), "EntryDescriptor::EntryDescriptor: invalid document!" );
166 0 : }
167 :
168 0 : EntryDescriptor::~EntryDescriptor()
169 0 : { }
170 :
171 0 : bool EntryDescriptor::operator == (EntryDescriptor const& rDesc) const
172 : {
173 : return
174 0 : m_aDocument == rDesc.m_aDocument &&
175 0 : m_eLocation == rDesc.m_eLocation &&
176 0 : m_aLibName == rDesc.m_aLibName &&
177 0 : m_aLibSubName == rDesc.m_aLibSubName &&
178 0 : m_aName == rDesc.m_aName &&
179 0 : m_aMethodName == rDesc.m_aMethodName &&
180 0 : m_eType == rDesc.m_eType;
181 : }
182 :
183 :
184 : // TreeListBox
185 :
186 :
187 :
188 0 : TreeListBox::TreeListBox (vcl::Window* pParent, ResId const& rRes)
189 0 : : SvTreeListBox( pParent, IDEResId( sal::static_int_cast<sal_uInt16>( rRes.GetId() ) ) )
190 0 : , m_aNotifier( *this )
191 : {
192 0 : Init();
193 0 : }
194 :
195 0 : TreeListBox::TreeListBox (vcl::Window* pParent, WinBits nStyle)
196 : : SvTreeListBox(pParent, nStyle)
197 0 : , m_aNotifier( *this )
198 : {
199 0 : Init();
200 0 : }
201 :
202 0 : void TreeListBox::Init()
203 : {
204 0 : SetNodeDefaultImages();
205 0 : SetSelectionMode( SINGLE_SELECTION );
206 0 : nMode = 0xFF; // everything
207 0 : }
208 :
209 0 : extern "C" SAL_DLLPUBLIC_EXPORT vcl::Window* SAL_CALL makeTreeListBox(vcl::Window *pParent, VclBuilder::stringmap &rMap)
210 : {
211 0 : WinBits nWinBits = WB_TABSTOP;
212 0 : OString sBorder = VclBuilder::extractCustomProperty(rMap);
213 0 : if (!sBorder.isEmpty())
214 0 : nWinBits |= WB_BORDER;
215 0 : return new TreeListBox(pParent, nWinBits);
216 : }
217 :
218 0 : TreeListBox::~TreeListBox ()
219 : {
220 0 : m_aNotifier.dispose();
221 :
222 : // destroy user data
223 0 : SvTreeListEntry* pEntry = First();
224 0 : while ( pEntry )
225 : {
226 0 : delete static_cast<Entry*>(pEntry->GetUserData());
227 0 : pEntry = Next( pEntry );
228 : }
229 0 : }
230 :
231 0 : void TreeListBox::ScanEntry( const ScriptDocument& rDocument, LibraryLocation eLocation )
232 : {
233 : OSL_ENSURE( rDocument.isAlive(), "TreeListBox::ScanEntry: illegal document!" );
234 0 : if ( !rDocument.isAlive() )
235 0 : return;
236 :
237 : // can be called multiple times for updating!
238 :
239 : // actually test if basic's in the tree already?!
240 0 : SetUpdateMode(false);
241 :
242 : // level 1: BasicManager (application, document, ...)
243 0 : SvTreeListEntry* pDocumentRootEntry = FindRootEntry( rDocument, eLocation );
244 0 : if ( pDocumentRootEntry && IsExpanded( pDocumentRootEntry ) )
245 0 : ImpCreateLibEntries( pDocumentRootEntry, rDocument, eLocation );
246 0 : if ( !pDocumentRootEntry )
247 : {
248 0 : OUString aRootName( GetRootEntryName( rDocument, eLocation ) );
249 0 : Image aImage;
250 0 : GetRootEntryBitmaps( rDocument, aImage );
251 0 : std::unique_ptr<Entry> e(new DocumentEntry(rDocument, eLocation));
252 : AddEntry(
253 : aRootName,
254 : aImage,
255 0 : 0, true, &e);
256 : }
257 :
258 0 : SetUpdateMode(true);
259 : }
260 :
261 0 : void TreeListBox::ImpCreateLibEntries( SvTreeListEntry* pDocumentRootEntry, const ScriptDocument& rDocument, LibraryLocation eLocation )
262 : {
263 : // get a sorted list of library names
264 0 : Sequence< OUString > aLibNames( rDocument.getLibraryNames() );
265 0 : sal_Int32 nLibCount = aLibNames.getLength();
266 0 : const OUString* pLibNames = aLibNames.getConstArray();
267 :
268 0 : for ( sal_Int32 i = 0 ; i < nLibCount ; i++ )
269 : {
270 0 : OUString aLibName = pLibNames[ i ];
271 :
272 0 : if ( eLocation == rDocument.getLibraryLocation( aLibName ) )
273 : {
274 : // check, if the module library is loaded
275 0 : bool bModLibLoaded = false;
276 0 : OUString aOULibName( aLibName );
277 0 : Reference< script::XLibraryContainer > xModLibContainer( rDocument.getLibraryContainer( E_SCRIPTS ) );
278 0 : if ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) && xModLibContainer->isLibraryLoaded( aOULibName ) )
279 0 : bModLibLoaded = true;
280 :
281 : // check, if the dialog library is loaded
282 0 : bool bDlgLibLoaded = false;
283 0 : Reference< script::XLibraryContainer > xDlgLibContainer( rDocument.getLibraryContainer( E_DIALOGS ) );
284 0 : if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aOULibName ) && xDlgLibContainer->isLibraryLoaded( aOULibName ) )
285 0 : bDlgLibLoaded = true;
286 :
287 0 : bool bLoaded = bModLibLoaded || bDlgLibLoaded;
288 :
289 : // if only one of the libraries is loaded, load also the other
290 0 : if ( bLoaded )
291 : {
292 0 : if ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) && !xModLibContainer->isLibraryLoaded( aOULibName ) )
293 0 : xModLibContainer->loadLibrary( aOULibName );
294 :
295 0 : if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aOULibName ) && !xDlgLibContainer->isLibraryLoaded( aOULibName ) )
296 0 : xDlgLibContainer->loadLibrary( aOULibName );
297 : }
298 :
299 : // create tree list box entry
300 : sal_uInt16 nId;
301 0 : if ( ( nMode & BROWSEMODE_DIALOGS ) && !( nMode & BROWSEMODE_MODULES ) )
302 0 : nId = bLoaded ? RID_IMG_DLGLIB : RID_IMG_DLGLIBNOTLOADED;
303 : else
304 0 : nId = bLoaded ? RID_IMG_MODLIB : RID_IMG_MODLIBNOTLOADED;
305 0 : SvTreeListEntry* pLibRootEntry = FindEntry( pDocumentRootEntry, aLibName, OBJ_TYPE_LIBRARY );
306 0 : if ( pLibRootEntry )
307 : {
308 0 : SetEntryBitmaps( pLibRootEntry, Image( IDEResId( nId ) ) );
309 0 : if ( IsExpanded( pLibRootEntry ) )
310 0 : ImpCreateLibSubEntries( pLibRootEntry, rDocument, aLibName );
311 : }
312 : else
313 : {
314 0 : std::unique_ptr<Entry> e(new Entry(OBJ_TYPE_LIBRARY));
315 : AddEntry(
316 : aLibName,
317 : Image( IDEResId( nId ) ),
318 0 : pDocumentRootEntry, true, &e);
319 0 : }
320 : }
321 0 : }
322 0 : }
323 :
324 0 : void TreeListBox::ImpCreateLibSubEntries( SvTreeListEntry* pLibRootEntry, const ScriptDocument& rDocument, const OUString& rLibName )
325 : {
326 : // modules
327 0 : if ( nMode & BROWSEMODE_MODULES )
328 : {
329 0 : Reference< script::XLibraryContainer > xModLibContainer( rDocument.getLibraryContainer( E_SCRIPTS ) );
330 :
331 0 : if ( xModLibContainer.is() && xModLibContainer->hasByName( rLibName ) && xModLibContainer->isLibraryLoaded( rLibName ) )
332 : {
333 : try
334 : {
335 0 : if( rDocument.isInVBAMode() )
336 0 : ImpCreateLibSubEntriesInVBAMode( pLibRootEntry, rDocument, rLibName );
337 : else
338 : {
339 : // get a sorted list of module names
340 0 : Sequence< OUString > aModNames = rDocument.getObjectNames( E_SCRIPTS, rLibName );
341 0 : sal_Int32 nModCount = aModNames.getLength();
342 0 : const OUString* pModNames = aModNames.getConstArray();
343 :
344 0 : for ( sal_Int32 i = 0 ; i < nModCount ; i++ )
345 : {
346 0 : OUString aModName = pModNames[ i ];
347 0 : SvTreeListEntry* pModuleEntry = FindEntry( pLibRootEntry, aModName, OBJ_TYPE_MODULE );
348 0 : if ( !pModuleEntry )
349 : {
350 0 : std::unique_ptr<Entry> e(new Entry(OBJ_TYPE_MODULE));
351 : pModuleEntry = AddEntry(
352 : aModName,
353 : Image( IDEResId( RID_IMG_MODULE ) ),
354 0 : pLibRootEntry, false, &e);
355 : }
356 :
357 : // methods
358 0 : if ( nMode & BROWSEMODE_SUBS )
359 : {
360 0 : Sequence< OUString > aNames = GetMethodNames( rDocument, rLibName, aModName );
361 0 : sal_Int32 nCount = aNames.getLength();
362 0 : const OUString* pNames = aNames.getConstArray();
363 :
364 0 : for ( sal_Int32 j = 0 ; j < nCount ; j++ )
365 : {
366 0 : OUString aName = pNames[ j ];
367 0 : SvTreeListEntry* pEntry = FindEntry( pModuleEntry, aName, OBJ_TYPE_METHOD );
368 0 : if ( !pEntry )
369 : {
370 : std::unique_ptr<Entry> e(
371 0 : new Entry(OBJ_TYPE_METHOD));
372 : pEntry = AddEntry(
373 : aName,
374 : Image( IDEResId( RID_IMG_MACRO ) ),
375 0 : pModuleEntry, false, &e);
376 : }
377 0 : }
378 : }
379 0 : }
380 : }
381 : }
382 0 : catch ( const container::NoSuchElementException& )
383 : {
384 : DBG_UNHANDLED_EXCEPTION();
385 : }
386 0 : }
387 : }
388 :
389 : // dialogs
390 0 : if ( nMode & BROWSEMODE_DIALOGS )
391 : {
392 0 : Reference< script::XLibraryContainer > xDlgLibContainer( rDocument.getLibraryContainer( E_DIALOGS ) );
393 :
394 0 : if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( rLibName ) && xDlgLibContainer->isLibraryLoaded( rLibName ) )
395 : {
396 : try
397 : {
398 : // get a sorted list of dialog names
399 0 : Sequence< OUString > aDlgNames( rDocument.getObjectNames( E_DIALOGS, rLibName ) );
400 0 : sal_Int32 nDlgCount = aDlgNames.getLength();
401 0 : const OUString* pDlgNames = aDlgNames.getConstArray();
402 :
403 0 : for ( sal_Int32 i = 0 ; i < nDlgCount ; i++ )
404 : {
405 0 : OUString aDlgName = pDlgNames[ i ];
406 0 : SvTreeListEntry* pDialogEntry = FindEntry( pLibRootEntry, aDlgName, OBJ_TYPE_DIALOG );
407 0 : if ( !pDialogEntry )
408 : {
409 0 : std::unique_ptr<Entry> e(new Entry(OBJ_TYPE_DIALOG));
410 : pDialogEntry = AddEntry(
411 : aDlgName,
412 : Image( IDEResId( RID_IMG_DIALOG ) ),
413 0 : pLibRootEntry, false, &e);
414 : }
415 0 : }
416 : }
417 0 : catch (const container::NoSuchElementException& )
418 : {
419 : DBG_UNHANDLED_EXCEPTION();
420 : }
421 0 : }
422 : }
423 0 : }
424 :
425 0 : void TreeListBox::ImpCreateLibSubEntriesInVBAMode( SvTreeListEntry* pLibRootEntry, const ScriptDocument& rDocument, const OUString& rLibName )
426 : {
427 :
428 0 : std::vector<std::pair<EntryType, OUString> > aEntries;
429 0 : aEntries.push_back( ::std::make_pair( OBJ_TYPE_DOCUMENT_OBJECTS, IDE_RESSTR(RID_STR_DOCUMENT_OBJECTS) ) );
430 0 : aEntries.push_back( ::std::make_pair( OBJ_TYPE_USERFORMS, IDE_RESSTR(RID_STR_USERFORMS) ) );
431 0 : aEntries.push_back( ::std::make_pair( OBJ_TYPE_NORMAL_MODULES, IDE_RESSTR(RID_STR_NORMAL_MODULES) ) );
432 0 : aEntries.push_back( ::std::make_pair( OBJ_TYPE_CLASS_MODULES, IDE_RESSTR(RID_STR_CLASS_MODULES) ) );
433 :
434 0 : std::vector<std::pair<EntryType, OUString> >::iterator iter;
435 0 : for( iter = aEntries.begin(); iter != aEntries.end(); ++iter )
436 : {
437 0 : EntryType eType = iter->first;
438 0 : OUString aEntryName = iter->second;
439 0 : SvTreeListEntry* pLibSubRootEntry = FindEntry( pLibRootEntry, aEntryName, eType );
440 0 : if( pLibSubRootEntry )
441 : {
442 0 : SetEntryBitmaps( pLibSubRootEntry, Image( IDEResId( RID_IMG_MODLIB ) ) );
443 0 : if ( IsExpanded( pLibSubRootEntry ) )
444 0 : ImpCreateLibSubSubEntriesInVBAMode( pLibSubRootEntry, rDocument, rLibName );
445 : }
446 : else
447 : {
448 0 : std::unique_ptr<Entry> e(new Entry(eType));
449 : AddEntry(
450 : aEntryName,
451 : Image( IDEResId( RID_IMG_MODLIB ) ),
452 0 : pLibRootEntry, true, &e);
453 : }
454 0 : }
455 0 : }
456 :
457 0 : void TreeListBox::ImpCreateLibSubSubEntriesInVBAMode( SvTreeListEntry* pLibSubRootEntry, const ScriptDocument& rDocument, const OUString& rLibName )
458 : {
459 0 : uno::Reference< container::XNameContainer > xLib = rDocument.getOrCreateLibrary( E_SCRIPTS, rLibName );
460 0 : if( !xLib.is() )
461 0 : return;
462 :
463 : try
464 : {
465 : // get a sorted list of module names
466 0 : Sequence< OUString > aModNames = rDocument.getObjectNames( E_SCRIPTS, rLibName );
467 0 : sal_Int32 nModCount = aModNames.getLength();
468 0 : const OUString* pModNames = aModNames.getConstArray();
469 :
470 0 : EntryDescriptor aDesc( GetEntryDescriptor( pLibSubRootEntry ) );
471 0 : EntryType eCurrentType( aDesc.GetType() );
472 :
473 0 : for ( sal_Int32 i = 0 ; i < nModCount ; i++ )
474 : {
475 0 : OUString aModName = pModNames[ i ];
476 0 : EntryType eType = OBJ_TYPE_UNKNOWN;
477 0 : switch( ModuleInfoHelper::getModuleType( xLib, aModName ) )
478 : {
479 : case script::ModuleType::DOCUMENT:
480 0 : eType = OBJ_TYPE_DOCUMENT_OBJECTS;
481 0 : break;
482 : case script::ModuleType::FORM:
483 0 : eType = OBJ_TYPE_USERFORMS;
484 0 : break;
485 : case script::ModuleType::NORMAL:
486 0 : eType = OBJ_TYPE_NORMAL_MODULES;
487 0 : break;
488 : case script::ModuleType::CLASS:
489 0 : eType = OBJ_TYPE_CLASS_MODULES;
490 0 : break;
491 : }
492 0 : if( eType != eCurrentType )
493 0 : continue;
494 :
495 : // display a nice friendly name in the ObjectModule tab,
496 : // combining the objectname and module name, e.g. Sheet1 ( Financials )
497 0 : OUString aEntryName = aModName;
498 0 : if( eType == OBJ_TYPE_DOCUMENT_OBJECTS )
499 : {
500 0 : OUString sObjName;
501 0 : ModuleInfoHelper::getObjectName( xLib, aModName, sObjName );
502 0 : if( !sObjName.isEmpty() )
503 : {
504 0 : aEntryName += " (" + sObjName + ")";
505 0 : }
506 : }
507 0 : SvTreeListEntry* pModuleEntry = FindEntry( pLibSubRootEntry, aEntryName, OBJ_TYPE_MODULE );
508 0 : if ( !pModuleEntry )
509 : {
510 0 : std::unique_ptr<Entry> e(new Entry(OBJ_TYPE_MODULE));
511 : pModuleEntry = AddEntry(
512 : aEntryName,
513 : Image( IDEResId( RID_IMG_MODULE ) ),
514 0 : pLibSubRootEntry, false, &e);
515 : }
516 :
517 : // methods
518 0 : if ( nMode & BROWSEMODE_SUBS )
519 : {
520 0 : Sequence< OUString > aNames = GetMethodNames( rDocument, rLibName, aModName );
521 0 : sal_Int32 nCount = aNames.getLength();
522 0 : const OUString* pNames = aNames.getConstArray();
523 :
524 0 : for ( sal_Int32 j = 0 ; j < nCount ; j++ )
525 : {
526 0 : OUString aName = pNames[ j ];
527 0 : SvTreeListEntry* pEntry = FindEntry( pModuleEntry, aName, OBJ_TYPE_METHOD );
528 0 : if ( !pEntry )
529 : {
530 0 : std::unique_ptr<Entry> e(new Entry(OBJ_TYPE_METHOD));
531 : pEntry = AddEntry(
532 : aName,
533 : Image( IDEResId( RID_IMG_MACRO ) ),
534 0 : pModuleEntry, false, &e);
535 : }
536 0 : }
537 : }
538 0 : }
539 : }
540 0 : catch ( const container::NoSuchElementException& )
541 : {
542 : DBG_UNHANDLED_EXCEPTION();
543 0 : }
544 : }
545 :
546 0 : SvTreeListEntry* TreeListBox::ImpFindEntry( SvTreeListEntry* pParent, const OUString& rText )
547 : {
548 0 : sal_uLong nRootPos = 0;
549 0 : SvTreeListEntry* pEntry = pParent ? FirstChild( pParent ) : GetEntry( nRootPos );
550 0 : while ( pEntry )
551 : {
552 0 : if ( rText.equals(GetEntryText( pEntry )) )
553 0 : return pEntry;
554 :
555 0 : pEntry = pParent ? NextSibling( pEntry ) : GetEntry( ++nRootPos );
556 : }
557 0 : return 0;
558 : }
559 :
560 0 : void TreeListBox::onDocumentCreated( const ScriptDocument& /*_rDocument*/ )
561 : {
562 0 : UpdateEntries();
563 0 : }
564 :
565 0 : void TreeListBox::onDocumentOpened( const ScriptDocument& /*_rDocument*/ )
566 : {
567 0 : UpdateEntries();
568 0 : }
569 :
570 0 : void TreeListBox::onDocumentSave( const ScriptDocument& /*_rDocument*/ )
571 : {
572 : // not interested in
573 0 : }
574 :
575 0 : void TreeListBox::onDocumentSaveDone( const ScriptDocument& /*_rDocument*/ )
576 : {
577 : // not interested in
578 0 : }
579 :
580 0 : void TreeListBox::onDocumentSaveAs( const ScriptDocument& /*_rDocument*/ )
581 : {
582 : // not interested in
583 0 : }
584 :
585 0 : void TreeListBox::onDocumentSaveAsDone( const ScriptDocument& /*_rDocument*/ )
586 : {
587 0 : UpdateEntries();
588 0 : }
589 :
590 0 : void TreeListBox::onDocumentClosed( const ScriptDocument& rDocument )
591 : {
592 0 : UpdateEntries();
593 : // The document is not yet actually deleted, so we need to remove its entry
594 : // manually.
595 0 : RemoveEntry(rDocument);
596 0 : }
597 :
598 0 : void TreeListBox::onDocumentTitleChanged( const ScriptDocument& /*_rDocument*/ )
599 : {
600 : // not interested in
601 0 : }
602 :
603 0 : void TreeListBox::onDocumentModeChanged( const ScriptDocument& /*_rDocument*/ )
604 : {
605 : // not interested in
606 0 : }
607 :
608 0 : void TreeListBox::UpdateEntries()
609 : {
610 0 : EntryDescriptor aCurDesc( GetEntryDescriptor( FirstSelected() ) );
611 :
612 : // removing the invalid entries
613 0 : SvTreeListEntry* pLastValid = 0;
614 0 : SvTreeListEntry* pEntry = First();
615 0 : while ( pEntry )
616 : {
617 0 : if ( IsValidEntry( pEntry ) )
618 0 : pLastValid = pEntry;
619 : else
620 0 : RemoveEntry(pEntry);
621 0 : pEntry = pLastValid ? Next( pLastValid ) : First();
622 : }
623 :
624 0 : ScanAllEntries();
625 :
626 0 : SetCurrentEntry( aCurDesc );
627 0 : }
628 :
629 : // Removes the entry from the tree.
630 0 : void TreeListBox::RemoveEntry (SvTreeListEntry* pEntry)
631 : {
632 : // removing the associated user data
633 0 : delete static_cast<Entry*>(pEntry->GetUserData());
634 : // removing the entry
635 0 : GetModel()->Remove( pEntry );
636 0 : }
637 :
638 : // Removes the entry of rDocument.
639 0 : void TreeListBox::RemoveEntry (ScriptDocument const& rDocument)
640 : {
641 : // finding the entry of rDocument
642 0 : for (SvTreeListEntry* pEntry = First(); pEntry; pEntry = Next(pEntry))
643 0 : if (rDocument == GetEntryDescriptor(pEntry).GetDocument())
644 : {
645 0 : RemoveEntry(pEntry);
646 0 : break;
647 : }
648 0 : }
649 :
650 0 : SvTreeListEntry* TreeListBox::CloneEntry( SvTreeListEntry* pSource )
651 : {
652 0 : SvTreeListEntry* pNew = SvTreeListBox::CloneEntry( pSource );
653 0 : Entry* pUser = static_cast<Entry*>(pSource->GetUserData());
654 :
655 : DBG_ASSERT( pUser, "User-Daten?!" );
656 : DBG_ASSERT( pUser->GetType() != OBJ_TYPE_DOCUMENT, "TreeListBox::CloneEntry: document?!" );
657 :
658 0 : Entry* pNewUser = new Entry( *pUser );
659 0 : pNew->SetUserData( pNewUser );
660 0 : return pNew;
661 : }
662 :
663 0 : SvTreeListEntry* TreeListBox::FindEntry( SvTreeListEntry* pParent, const OUString& rText, EntryType eType )
664 : {
665 0 : sal_uLong nRootPos = 0;
666 0 : SvTreeListEntry* pEntry = pParent ? FirstChild( pParent ) : GetEntry( nRootPos );
667 0 : while ( pEntry )
668 : {
669 0 : Entry* pBasicEntry = static_cast<Entry*>(pEntry->GetUserData());
670 : DBG_ASSERT( pBasicEntry, "FindEntry: no Entry ?!" );
671 0 : if ( ( pBasicEntry->GetType() == eType ) && ( rText.equals(GetEntryText( pEntry )) ) )
672 0 : return pEntry;
673 :
674 0 : pEntry = pParent ? NextSibling( pEntry ) : GetEntry( ++nRootPos );
675 : }
676 0 : return 0;
677 : }
678 :
679 0 : bool TreeListBox::ExpandingHdl()
680 : {
681 : // expanding or collapsing?
682 0 : bool bOK = true;
683 0 : if ( GetModel()->GetDepth( GetHdlEntry() ) == 1 )
684 : {
685 0 : SvTreeListEntry* pCurEntry = GetCurEntry();
686 0 : EntryDescriptor aDesc( GetEntryDescriptor( pCurEntry ) );
687 0 : ScriptDocument aDocument( aDesc.GetDocument() );
688 : OSL_ENSURE( aDocument.isAlive(), "TreeListBox::ExpandingHdl: no document, or document is dead!" );
689 0 : if ( aDocument.isAlive() )
690 : {
691 0 : OUString aLibName( aDesc.GetLibName() );
692 0 : OUString aLibSubName( aDesc.GetLibSubName() );
693 0 : OUString aName( aDesc.GetName() );
694 0 : OUString aMethodName( aDesc.GetMethodName() );
695 :
696 0 : if ( !aLibName.isEmpty() && aLibSubName.isEmpty() && aName.isEmpty() && aMethodName.isEmpty() )
697 : {
698 : // check password, if library is password protected and not verified
699 0 : Reference< script::XLibraryContainer > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ) );
700 0 : if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) )
701 : {
702 0 : Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
703 0 : if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aLibName ) && !xPasswd->isLibraryPasswordVerified( aLibName ) )
704 : {
705 0 : OUString aPassword;
706 0 : bOK = QueryPassword( xModLibContainer, aLibName, aPassword );
707 0 : }
708 0 : }
709 0 : }
710 0 : }
711 : }
712 0 : return bOK;
713 : }
714 :
715 0 : bool TreeListBox::IsEntryProtected( SvTreeListEntry* pEntry )
716 : {
717 0 : bool bProtected = false;
718 0 : if ( pEntry && ( GetModel()->GetDepth( pEntry ) == 1 ) )
719 : {
720 0 : EntryDescriptor aDesc( GetEntryDescriptor( pEntry ) );
721 0 : ScriptDocument aDocument( aDesc.GetDocument() );
722 : OSL_ENSURE( aDocument.isAlive(), "TreeListBox::IsEntryProtected: no document, or document is dead!" );
723 0 : if ( aDocument.isAlive() )
724 : {
725 0 : OUString aOULibName( aDesc.GetLibName() );
726 0 : Reference< script::XLibraryContainer > xModLibContainer( aDocument.getLibraryContainer( E_SCRIPTS ) );
727 0 : if ( xModLibContainer.is() && xModLibContainer->hasByName( aOULibName ) )
728 : {
729 0 : Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
730 0 : if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aOULibName ) && !xPasswd->isLibraryPasswordVerified( aOULibName ) )
731 : {
732 0 : bProtected = true;
733 0 : }
734 0 : }
735 0 : }
736 : }
737 0 : return bProtected;
738 : }
739 :
740 0 : SvTreeListEntry* TreeListBox::AddEntry(
741 : OUString const& rText,
742 : const Image& rImage,
743 : SvTreeListEntry* pParent,
744 : bool bChildrenOnDemand,
745 : std::unique_ptr<Entry> * aUserData
746 : )
747 : {
748 : assert(aUserData != 0);
749 : SvTreeListEntry* p = InsertEntry(
750 : rText, rImage, rImage, pParent, bChildrenOnDemand, TREELIST_APPEND,
751 0 : aUserData->get()
752 0 : );
753 0 : aUserData->release();
754 0 : return p;
755 : }
756 :
757 0 : void TreeListBox::SetEntryBitmaps( SvTreeListEntry * pEntry, const Image& rImage )
758 : {
759 0 : SetExpandedEntryBmp( pEntry, rImage );
760 0 : SetCollapsedEntryBmp( pEntry, rImage );
761 0 : }
762 :
763 0 : LibraryType TreeListBox::GetLibraryType() const
764 : {
765 0 : LibraryType eType = LIBRARY_TYPE_ALL;
766 0 : if ( ( nMode & BROWSEMODE_MODULES ) && !( nMode & BROWSEMODE_DIALOGS ) )
767 0 : eType = LIBRARY_TYPE_MODULE;
768 0 : else if ( !( nMode & BROWSEMODE_MODULES ) && ( nMode & BROWSEMODE_DIALOGS ) )
769 0 : eType = LIBRARY_TYPE_DIALOG;
770 0 : return eType;
771 : }
772 :
773 0 : OUString TreeListBox::GetRootEntryName( const ScriptDocument& rDocument, LibraryLocation eLocation ) const
774 : {
775 0 : return rDocument.getTitle( eLocation, GetLibraryType() );
776 : }
777 :
778 0 : void TreeListBox::GetRootEntryBitmaps( const ScriptDocument& rDocument, Image& rImage )
779 : {
780 : OSL_ENSURE( rDocument.isValid(), "TreeListBox::GetRootEntryBitmaps: illegal document!" );
781 0 : if ( !rDocument.isValid() )
782 0 : return;
783 :
784 0 : if ( rDocument.isDocument() )
785 : {
786 0 : OUString sFactoryURL;
787 0 : Reference<uno::XComponentContext> xContext( ::comphelper::getProcessComponentContext() );
788 0 : Reference< frame::XModuleManager2 > xModuleManager( frame::ModuleManager::create(xContext) );
789 : try
790 : {
791 0 : OUString sModule( xModuleManager->identify( rDocument.getDocument() ) );
792 0 : Reference< container::XNameAccess > xModuleConfig( xModuleManager, UNO_QUERY );
793 0 : if ( xModuleConfig.is() )
794 : {
795 0 : Sequence< beans::PropertyValue > aModuleDescr;
796 0 : xModuleConfig->getByName( sModule ) >>= aModuleDescr;
797 0 : sal_Int32 nCount = aModuleDescr.getLength();
798 0 : const beans::PropertyValue* pModuleDescr = aModuleDescr.getConstArray();
799 0 : for ( sal_Int32 i = 0; i < nCount; ++i )
800 : {
801 0 : if ( pModuleDescr[ i ].Name == "ooSetupFactoryEmptyDocumentURL" )
802 : {
803 0 : pModuleDescr[ i ].Value >>= sFactoryURL;
804 0 : break;
805 : }
806 0 : }
807 0 : }
808 : }
809 0 : catch( const Exception& )
810 : {
811 : DBG_UNHANDLED_EXCEPTION();
812 : }
813 :
814 0 : if ( !sFactoryURL.isEmpty() )
815 : {
816 0 : rImage = SvFileInformationManager::GetFileImage( INetURLObject( sFactoryURL ), false );
817 : }
818 : else
819 : {
820 : // default icon
821 0 : rImage = Image( IDEResId( RID_IMG_DOCUMENT ) );
822 0 : }
823 : }
824 : else
825 : {
826 0 : rImage = Image( IDEResId( RID_IMG_INSTALLATION ) );
827 : }
828 : }
829 :
830 0 : void TreeListBox::SetCurrentEntry (EntryDescriptor& rDesc)
831 : {
832 0 : SvTreeListEntry* pCurEntry = 0;
833 0 : EntryDescriptor aDesc = rDesc;
834 0 : if ( aDesc.GetType() == OBJ_TYPE_UNKNOWN )
835 : {
836 0 : aDesc = EntryDescriptor(
837 0 : ScriptDocument::getApplicationScriptDocument(),
838 : LIBRARY_LOCATION_USER, "Standard",
839 : OUString(), ".", OBJ_TYPE_UNKNOWN
840 0 : );
841 : }
842 0 : ScriptDocument aDocument = aDesc.GetDocument();
843 : OSL_ENSURE( aDocument.isValid(), "TreeListBox::SetCurrentEntry: invalid document!" );
844 0 : LibraryLocation eLocation = aDesc.GetLocation();
845 0 : SvTreeListEntry* pRootEntry = FindRootEntry( aDocument, eLocation );
846 0 : if ( pRootEntry )
847 : {
848 0 : pCurEntry = pRootEntry;
849 0 : OUString aLibName( aDesc.GetLibName() );
850 0 : if ( !aLibName.isEmpty() )
851 : {
852 0 : Expand( pRootEntry );
853 0 : SvTreeListEntry* pLibEntry = FindEntry( pRootEntry, aLibName, OBJ_TYPE_LIBRARY );
854 0 : if ( pLibEntry )
855 : {
856 0 : pCurEntry = pLibEntry;
857 0 : OUString aLibSubName( aDesc.GetLibSubName() );
858 0 : if( !aLibSubName.isEmpty() )
859 : {
860 0 : Expand( pLibEntry );
861 0 : SvTreeListEntry* pLibSubEntry = ImpFindEntry( pLibEntry, aLibSubName );
862 0 : if( pLibSubEntry )
863 : {
864 0 : pCurEntry = pLibSubEntry;
865 : }
866 : }
867 0 : OUString aName( aDesc.GetName() );
868 0 : if ( !aName.isEmpty() )
869 : {
870 0 : Expand( pCurEntry );
871 0 : EntryType eType = OBJ_TYPE_MODULE;
872 0 : if ( aDesc.GetType() == OBJ_TYPE_DIALOG )
873 0 : eType = OBJ_TYPE_DIALOG;
874 0 : SvTreeListEntry* pEntry = FindEntry( pCurEntry, aName, eType );
875 0 : if ( pEntry )
876 : {
877 0 : pCurEntry = pEntry;
878 0 : OUString aMethodName( aDesc.GetMethodName() );
879 0 : if ( !aMethodName.isEmpty() )
880 : {
881 0 : Expand( pEntry );
882 0 : SvTreeListEntry* pSubEntry = FindEntry( pEntry, aMethodName, OBJ_TYPE_METHOD );
883 0 : if ( pSubEntry )
884 : {
885 0 : pCurEntry = pSubEntry;
886 : }
887 : else
888 : {
889 0 : pSubEntry = FirstChild( pEntry );
890 0 : if ( pSubEntry )
891 0 : pCurEntry = pSubEntry;
892 : }
893 0 : }
894 : }
895 : else
896 : {
897 0 : pEntry = FirstChild( pLibEntry );
898 0 : if ( pEntry )
899 0 : pCurEntry = pEntry;
900 : }
901 0 : }
902 : }
903 : else
904 : {
905 0 : pLibEntry = FirstChild( pRootEntry );
906 0 : if ( pLibEntry )
907 0 : pCurEntry = pLibEntry;
908 : }
909 0 : }
910 : }
911 : else
912 : {
913 0 : pRootEntry = First();
914 0 : if ( pRootEntry )
915 0 : pCurEntry = pRootEntry;
916 : }
917 :
918 0 : SetCurEntry( pCurEntry );
919 0 : }
920 :
921 0 : void TreeListBox::MouseButtonDown( const MouseEvent& rMEvt )
922 : {
923 0 : SvTreeListBox::MouseButtonDown( rMEvt );
924 0 : if ( rMEvt.IsLeft() && ( rMEvt.GetClicks() == 2 ) )
925 : {
926 0 : OpenCurrent();
927 : }
928 0 : }
929 :
930 0 : void TreeListBox::KeyInput( const KeyEvent& rEvt )
931 : {
932 0 : if ( rEvt.GetKeyCode() == KEY_RETURN && OpenCurrent() )
933 : {
934 0 : return;
935 : }
936 0 : SvTreeListBox::KeyInput( rEvt );
937 : }
938 :
939 0 : bool TreeListBox::OpenCurrent()
940 : {
941 0 : EntryDescriptor aDesc = GetEntryDescriptor(GetCurEntry());
942 0 : switch (aDesc.GetType())
943 : {
944 : case OBJ_TYPE_METHOD:
945 : case OBJ_TYPE_MODULE:
946 : case OBJ_TYPE_DIALOG:
947 0 : if (SfxDispatcher* pDispatcher = GetDispatcher())
948 : {
949 : SbxItem aSbxItem(
950 0 : SID_BASICIDE_ARG_SBX, aDesc.GetDocument(),
951 0 : aDesc.GetLibName(), aDesc.GetName(), aDesc.GetMethodName(),
952 : ConvertType(aDesc.GetType())
953 0 : );
954 : pDispatcher->Execute(
955 : SID_BASICIDE_SHOWSBX,
956 : SfxCallMode::SYNCHRON, &aSbxItem, 0L
957 0 : );
958 0 : return true;
959 : }
960 0 : break;
961 :
962 : default:
963 0 : break;
964 : }
965 0 : return false;
966 : }
967 :
968 0 : } // namespace basctl
969 :
970 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|