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