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 <memory> 21 #include <scriptdocument.hxx> 22 #include <basobj.hxx> 23 #include <strings.hrc> 24 #include <iderid.hxx> 25 #include <dlgeddef.hxx> 26 #include <doceventnotifier.hxx> 27 #include "documentenumeration.hxx" 28 29 #include <com/sun/star/ucb/ContentCreationException.hpp> 30 #include <com/sun/star/uri/UriReferenceFactory.hpp> 31 #include <com/sun/star/util/theMacroExpander.hpp> 32 #include <com/sun/star/frame/XStorable.hpp> 33 #include <com/sun/star/frame/FrameSearchFlag.hpp> 34 #include <com/sun/star/frame/XDispatchProvider.hpp> 35 #include <com/sun/star/awt/XWindow2.hpp> 36 #include <com/sun/star/beans/XPropertySet.hpp> 37 #include <com/sun/star/document/XEmbeddedScripts.hpp> 38 #include <com/sun/star/script/vba/XVBACompatibility.hpp> 39 #include <com/sun/star/script/vba/XVBAModuleInfo.hpp> 40 #include <com/sun/star/script/ModuleInfo.hpp> 41 #include <com/sun/star/script/ModuleType.hpp> 42 43 #include <sfx2/app.hxx> 44 #include <sfx2/objsh.hxx> 45 #include <sfx2/bindings.hxx> 46 #include <sfx2/docfile.hxx> 47 48 #include <basic/basicmanagerrepository.hxx> 49 50 #include <xmlscript/xmldlg_imexp.hxx> 51 52 #include <i18nlangtag/languagetag.hxx> 53 54 #include <tools/diagnose_ex.h> 55 #include <tools/debug.hxx> 56 57 #include <comphelper/documentinfo.hxx> 58 #include <comphelper/processfactory.hxx> 59 #include <comphelper/propertysequence.hxx> 60 #include <comphelper/string.hxx> 61 62 #include <vcl/svapp.hxx> 63 #include <vcl/settings.hxx> 64 65 #include <osl/file.hxx> 66 #include <rtl/uri.hxx> 67 #include <set> 68 69 70 namespace basctl 71 { 72 using ::com::sun::star::uno::Sequence; 73 using ::com::sun::star::uno::Reference; 74 using ::com::sun::star::frame::XModel; 75 using ::com::sun::star::beans::XPropertySet; 76 using ::com::sun::star::script::XLibraryContainer; 77 using ::com::sun::star::uno::UNO_QUERY_THROW; 78 using ::com::sun::star::uno::UNO_SET_THROW; 79 using ::com::sun::star::uno::Exception; 80 using ::com::sun::star::container::XNameContainer; 81 using ::com::sun::star::container::NoSuchElementException; 82 using ::com::sun::star::uno::UNO_QUERY; 83 using ::com::sun::star::task::XStatusIndicator; 84 using ::com::sun::star::uno::Any; 85 using ::com::sun::star::script::XLibraryContainer2; 86 using ::com::sun::star::uri::UriReferenceFactory; 87 using ::com::sun::star::uri::XUriReferenceFactory; 88 using ::com::sun::star::uri::XUriReference; 89 using ::com::sun::star::uno::XComponentContext; 90 using ::com::sun::star::util::XMacroExpander; 91 using ::com::sun::star::util::theMacroExpander; 92 using ::com::sun::star::io::XInputStreamProvider; 93 using ::com::sun::star::uno::Any; 94 using ::com::sun::star::io::XInputStream; 95 using ::com::sun::star::frame::XStorable; 96 using ::com::sun::star::util::XModifiable; 97 using ::com::sun::star::frame::XController; 98 using ::com::sun::star::frame::XFrame; 99 using ::com::sun::star::util::URL; 100 using ::com::sun::star::frame::XDispatchProvider; 101 using ::com::sun::star::frame::XDispatch; 102 using ::com::sun::star::beans::PropertyValue; 103 using ::com::sun::star::awt::XWindow2; 104 using ::com::sun::star::document::XEmbeddedScripts; 105 using ::com::sun::star::script::ModuleInfo; 106 using ::com::sun::star::script::vba::XVBACompatibility; 107 using ::com::sun::star::script::vba::XVBAModuleInfo; 108 109 namespace FrameSearchFlag = ::com::sun::star::frame::FrameSearchFlag; 110 111 112 namespace 113 { 114 class FilterDocuments : public docs::IDocumentDescriptorFilter 115 { 116 public: FilterDocuments(bool _bFilterInvisible)117 explicit FilterDocuments(bool _bFilterInvisible) 118 : m_bFilterInvisible(_bFilterInvisible) 119 { 120 } 121 ~FilterDocuments()122 virtual ~FilterDocuments() {} 123 124 virtual bool includeDocument( const docs::DocumentDescriptor& _rDocument ) const override; 125 126 private: 127 static bool impl_isDocumentVisible_nothrow( const docs::DocumentDescriptor& _rDocument ); 128 129 private: 130 bool m_bFilterInvisible; 131 }; 132 impl_isDocumentVisible_nothrow(const docs::DocumentDescriptor & _rDocument)133 bool FilterDocuments::impl_isDocumentVisible_nothrow( const docs::DocumentDescriptor& _rDocument ) 134 { 135 try 136 { 137 for (auto const& controller : _rDocument.aControllers) 138 { 139 Reference< XFrame > xFrame( controller->getFrame(), UNO_SET_THROW ); 140 Reference< XWindow2 > xContainer( xFrame->getContainerWindow(), UNO_QUERY_THROW ); 141 if ( xContainer->isVisible() ) 142 return true; 143 } 144 } 145 catch( const Exception& ) 146 { 147 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 148 } 149 return false; 150 } 151 includeDocument(const docs::DocumentDescriptor & _rDocument) const152 bool FilterDocuments::includeDocument( const docs::DocumentDescriptor& _rDocument ) const 153 { 154 Reference< XEmbeddedScripts > xScripts( _rDocument.xModel, UNO_QUERY ); 155 if ( !xScripts.is() ) 156 return false; 157 return !m_bFilterInvisible || impl_isDocumentVisible_nothrow( _rDocument ); 158 } 159 lcl_getAllModels_throw(docs::Documents & _out_rModels,bool _bVisibleOnly)160 void lcl_getAllModels_throw( docs::Documents& _out_rModels, bool _bVisibleOnly ) 161 { 162 _out_rModels.clear(); 163 164 FilterDocuments aFilter( _bVisibleOnly ); 165 docs::DocumentEnumeration aEnum( 166 comphelper::getProcessComponentContext(), &aFilter ); 167 168 aEnum.getDocuments( _out_rModels ); 169 } 170 } 171 172 class ScriptDocument::Impl : public DocumentEventListener 173 { 174 private: 175 bool m_bIsApplication; 176 bool m_bValid; 177 bool m_bDocumentClosed; 178 Reference< XModel > m_xDocument; 179 Reference< XModifiable > m_xDocModify; 180 Reference< XEmbeddedScripts > m_xScriptAccess; 181 std::unique_ptr< DocumentEventNotifier > m_pDocListener; 182 183 public: 184 Impl (); 185 explicit Impl(Reference<XModel> const& rxDocument); 186 virtual ~Impl() override; 187 188 /** determines whether the instance refers to a valid "document" with script and 189 dialog libraries 190 */ isValid() const191 bool isValid() const { return m_bValid; } 192 /** determines whether the instance refers to a non-closed document 193 */ isAlive() const194 bool isAlive() const { return m_bValid && ( m_bIsApplication || !m_bDocumentClosed ); } 195 /// determines whether the "document" refers to the application in real isApplication() const196 bool isApplication() const { return m_bValid && m_bIsApplication; } 197 /// determines whether the document refers to a real document (instead of the application) isDocument() const198 bool isDocument() const { return m_bValid && !m_bIsApplication; } 199 200 /** invalidates the instance 201 */ 202 void invalidate(); 203 204 const Reference< XModel >& getDocumentRef() const205 getDocumentRef() const { return m_xDocument; } 206 207 /// returns a library container belonging to the document 208 Reference< XLibraryContainer > 209 getLibraryContainer( LibraryContainerType _eType ) const; 210 211 /// determines whether a given library is part of the shared installation 212 bool isLibraryShared( const OUString& _rLibName, LibraryContainerType _eType ); 213 214 /** returns the current frame of the document 215 216 To be called for documents only, not for the application. 217 218 If <FALSE/> is returned, an assertion will be raised in non-product builds. 219 */ 220 bool getCurrentFrame( Reference< XFrame >& _out_rxFrame ) const; 221 222 // versions with the same signature/semantics as in ScriptDocument itself 223 bool isReadOnly() const; 224 bool isInVBAMode() const; 225 BasicManager* 226 getBasicManager() const; 227 Reference< XModel > 228 getDocument() const; 229 void setDocumentModified() const; 230 bool isDocumentModified() const; 231 void saveDocument( const Reference< XStatusIndicator >& _rxStatusIndicator ) const; 232 233 OUString getTitle() const; 234 OUString getURL() const; 235 236 bool allowMacros() const; 237 238 Reference< XNameContainer > 239 getLibrary( LibraryContainerType _eType, const OUString& _rLibName, bool _bLoadLibrary ) const; 240 bool hasLibrary( LibraryContainerType _eType, const OUString& _rLibName ) const; 241 Reference< XNameContainer > 242 getOrCreateLibrary( LibraryContainerType _eType, const OUString& _rLibName ) const; 243 244 void loadLibraryIfExists( LibraryContainerType _eType, const OUString& _rLibrary ); 245 246 bool removeModuleOrDialog( LibraryContainerType _eType, const OUString& _rLibName, const OUString& _rModuleName ); 247 bool hasModuleOrDialog( LibraryContainerType _eType, const OUString& _rLibName, const OUString& _rModName ) const; 248 bool getModuleOrDialog( LibraryContainerType _eType, const OUString& _rLibName, const OUString& _rObjectName, Any& _out_rModuleOrDialog ); 249 bool renameModuleOrDialog( LibraryContainerType _eType, const OUString& _rLibName, const OUString& _rOldName, const OUString& _rNewName, const Reference< XNameContainer >& _rxExistingDialogModel ); 250 bool createModule( const OUString& _rLibName, const OUString& _rModName, bool _bCreateMain, OUString& _out_rNewModuleCode ) const; 251 bool insertModuleOrDialog( LibraryContainerType _eType, const OUString& _rObjectName, const OUString& _rModName, const Any& _rElement ) const; 252 bool updateModule( const OUString& _rLibName, const OUString& _rModName, const OUString& _rModuleCode ) const; 253 bool createDialog( const OUString& _rLibName, const OUString& _rDialogName, Reference< XInputStreamProvider >& _out_rDialogProvider ) const; 254 255 protected: 256 // DocumentEventListener 257 virtual void onDocumentCreated( const ScriptDocument& _rDocument ) override; 258 virtual void onDocumentOpened( const ScriptDocument& _rDocument ) override; 259 virtual void onDocumentSave( const ScriptDocument& _rDocument ) override; 260 virtual void onDocumentSaveDone( const ScriptDocument& _rDocument ) override; 261 virtual void onDocumentSaveAs( const ScriptDocument& _rDocument ) override; 262 virtual void onDocumentSaveAsDone( const ScriptDocument& _rDocument ) override; 263 virtual void onDocumentClosed( const ScriptDocument& _rDocument ) override; 264 virtual void onDocumentTitleChanged( const ScriptDocument& _rDocument ) override; 265 virtual void onDocumentModeChanged( const ScriptDocument& _rDocument ) override; 266 267 private: 268 bool impl_initDocument_nothrow( const Reference< XModel >& _rxModel ); 269 }; 270 271 Impl()272 ScriptDocument::Impl::Impl() 273 :m_bIsApplication( true ) 274 ,m_bValid( true ) 275 ,m_bDocumentClosed( false ) 276 { 277 } 278 Impl(const Reference<XModel> & _rxDocument)279 ScriptDocument::Impl::Impl( const Reference< XModel >& _rxDocument ) 280 :m_bIsApplication( false ) 281 ,m_bValid( false ) 282 ,m_bDocumentClosed( false ) 283 { 284 if ( _rxDocument.is() ) 285 impl_initDocument_nothrow( _rxDocument ); 286 } 287 ~Impl()288 ScriptDocument::Impl::~Impl() 289 { 290 invalidate(); 291 } 292 invalidate()293 void ScriptDocument::Impl::invalidate() 294 { 295 m_bIsApplication = false; 296 m_bValid = false; 297 m_bDocumentClosed = false; 298 299 m_xDocument.clear(); 300 m_xDocModify.clear(); 301 m_xScriptAccess.clear(); 302 303 if (m_pDocListener) 304 m_pDocListener->dispose(); 305 } 306 impl_initDocument_nothrow(const Reference<XModel> & _rxModel)307 bool ScriptDocument::Impl::impl_initDocument_nothrow( const Reference< XModel >& _rxModel ) 308 { 309 try 310 { 311 m_xDocument.set ( _rxModel, UNO_SET_THROW ); 312 m_xDocModify.set ( _rxModel, UNO_QUERY_THROW ); 313 m_xScriptAccess.set ( _rxModel, UNO_QUERY ); 314 315 m_bValid = m_xScriptAccess.is(); 316 317 if ( m_bValid ) 318 m_pDocListener.reset( new DocumentEventNotifier( *this, _rxModel ) ); 319 } 320 catch( const Exception& ) 321 { 322 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 323 m_bValid = false; 324 } 325 326 if ( !m_bValid ) 327 { 328 invalidate(); 329 } 330 331 return m_bValid; 332 } 333 getLibraryContainer(LibraryContainerType _eType) const334 Reference< XLibraryContainer > ScriptDocument::Impl::getLibraryContainer( LibraryContainerType _eType ) const 335 { 336 OSL_ENSURE( isValid(), "ScriptDocument::Impl::getLibraryContainer: invalid!" ); 337 338 Reference< XLibraryContainer > xContainer; 339 if ( !isValid() ) 340 return xContainer; 341 342 try 343 { 344 if ( isApplication() ) 345 xContainer.set( _eType == E_SCRIPTS ? SfxGetpApp()->GetBasicContainer() : SfxGetpApp()->GetDialogContainer(), UNO_QUERY_THROW ); 346 else 347 { 348 xContainer.set( 349 _eType == E_SCRIPTS ? m_xScriptAccess->getBasicLibraries() : m_xScriptAccess->getDialogLibraries(), 350 UNO_QUERY_THROW ); 351 } 352 } 353 catch( const Exception& ) 354 { 355 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 356 } 357 return xContainer; 358 } 359 isReadOnly() const360 bool ScriptDocument::Impl::isReadOnly() const 361 { 362 OSL_ENSURE( isValid(), "ScriptDocument::Impl::isReadOnly: invalid state!" ); 363 OSL_ENSURE( !isApplication(), "ScriptDocument::Impl::isReadOnly: not allowed to be called for the application!" ); 364 365 bool bIsReadOnly = true; 366 if ( isValid() && !isApplication() ) 367 { 368 try 369 { 370 // note that XStorable is required by the OfficeDocument service 371 Reference< XStorable > xDocStorable( m_xDocument, UNO_QUERY_THROW ); 372 bIsReadOnly = xDocStorable->isReadonly(); 373 } 374 catch( const Exception& ) 375 { 376 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 377 } 378 } 379 return bIsReadOnly; 380 } 381 isInVBAMode() const382 bool ScriptDocument::Impl::isInVBAMode() const 383 { 384 bool bResult = false; 385 if ( !isApplication() ) 386 { 387 Reference< XVBACompatibility > xVBACompat( getLibraryContainer( E_SCRIPTS ), UNO_QUERY ); 388 if ( xVBACompat.is() ) 389 bResult = xVBACompat->getVBACompatibilityMode(); 390 } 391 return bResult; 392 } 393 getBasicManager() const394 BasicManager* ScriptDocument::Impl::getBasicManager() const 395 { 396 try 397 { 398 OSL_ENSURE( isValid(), "ScriptDocument::Impl::getBasicManager: invalid state!" ); 399 if ( !isValid() ) 400 return nullptr; 401 402 if ( isApplication() ) 403 return SfxApplication::GetBasicManager(); 404 405 return ::basic::BasicManagerRepository::getDocumentBasicManager( m_xDocument ); 406 } 407 catch (const css::ucb::ContentCreationException&) 408 { 409 TOOLS_WARN_EXCEPTION( "basctl.basicide", "ScriptDocument::getBasicManager" ); 410 } 411 return nullptr; 412 } 413 getDocument() const414 Reference< XModel > ScriptDocument::Impl::getDocument() const 415 { 416 OSL_ENSURE( isValid(), "ScriptDocument::Impl::getDocument: invalid state!" ); 417 OSL_ENSURE( isDocument(), "ScriptDocument::Impl::getDocument: for documents only!" ); 418 if ( !isValid() || !isDocument() ) 419 return nullptr; 420 421 return m_xDocument; 422 } 423 424 getLibrary(LibraryContainerType _eType,const OUString & _rLibName,bool _bLoadLibrary) const425 Reference< XNameContainer > ScriptDocument::Impl::getLibrary( LibraryContainerType _eType, const OUString& _rLibName, bool _bLoadLibrary ) const 426 { 427 OSL_ENSURE( isValid(), "ScriptDocument::Impl::getLibrary: invalid state!" ); 428 429 Reference< XNameContainer > xContainer; 430 try 431 { 432 Reference< XLibraryContainer > xLibContainer = getLibraryContainer( _eType ); 433 if ( isValid() && xLibContainer.is() ) 434 xContainer.set( xLibContainer->getByName( _rLibName ), UNO_QUERY_THROW ); 435 436 if ( !xContainer.is() ) 437 throw NoSuchElementException(); 438 439 // load library 440 if ( _bLoadLibrary && !xLibContainer->isLibraryLoaded( _rLibName ) ) 441 xLibContainer->loadLibrary( _rLibName ); 442 } 443 catch( const NoSuchElementException& ) 444 { 445 throw; // allowed to leave 446 } 447 catch( const Exception& ) 448 { 449 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 450 } 451 452 return xContainer; 453 } 454 455 hasLibrary(LibraryContainerType _eType,const OUString & _rLibName) const456 bool ScriptDocument::Impl::hasLibrary( LibraryContainerType _eType, const OUString& _rLibName ) const 457 { 458 bool bHas = false; 459 try 460 { 461 Reference< XLibraryContainer > xLibContainer = getLibraryContainer( _eType ); 462 bHas = xLibContainer.is() && xLibContainer->hasByName( _rLibName ); 463 } 464 catch( const Exception& ) 465 { 466 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 467 } 468 return bHas; 469 } 470 471 getOrCreateLibrary(LibraryContainerType _eType,const OUString & _rLibName) const472 Reference< XNameContainer > ScriptDocument::Impl::getOrCreateLibrary( LibraryContainerType _eType, const OUString& _rLibName ) const 473 { 474 Reference< XNameContainer > xLibrary; 475 try 476 { 477 Reference< XLibraryContainer > xLibContainer( getLibraryContainer( _eType ), UNO_SET_THROW ); 478 if ( xLibContainer->hasByName( _rLibName ) ) 479 xLibrary.set( xLibContainer->getByName( _rLibName ), UNO_QUERY_THROW ); 480 else 481 xLibrary.set( xLibContainer->createLibrary( _rLibName ), UNO_SET_THROW ); 482 483 if ( !xLibContainer->isLibraryLoaded( _rLibName ) ) 484 xLibContainer->loadLibrary( _rLibName ); 485 } 486 catch( const Exception& ) 487 { 488 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 489 } 490 return xLibrary; 491 } 492 493 loadLibraryIfExists(LibraryContainerType _eType,const OUString & _rLibrary)494 void ScriptDocument::Impl::loadLibraryIfExists( LibraryContainerType _eType, const OUString& _rLibrary ) 495 { 496 try 497 { 498 Reference< XLibraryContainer > xLibContainer( getLibraryContainer( _eType ) ); 499 if ( xLibContainer.is() && xLibContainer->hasByName( _rLibrary ) && !xLibContainer->isLibraryLoaded( _rLibrary ) ) 500 xLibContainer->loadLibrary( _rLibrary ); 501 } 502 catch( const Exception& ) 503 { 504 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 505 } 506 } 507 508 removeModuleOrDialog(LibraryContainerType _eType,const OUString & _rLibName,const OUString & _rModuleName)509 bool ScriptDocument::Impl::removeModuleOrDialog( LibraryContainerType _eType, const OUString& _rLibName, const OUString& _rModuleName ) 510 { 511 OSL_ENSURE( isValid(), "ScriptDocument::Impl::removeModuleOrDialog: invalid!" ); 512 if ( isValid() ) 513 { 514 try 515 { 516 Reference< XNameContainer > xLib( getLibrary( _eType, _rLibName, true ) ); 517 if ( xLib.is() ) 518 { 519 xLib->removeByName( _rModuleName ); 520 Reference< XVBAModuleInfo > xVBAModuleInfo(xLib, UNO_QUERY); 521 if(xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo(_rModuleName)) 522 xVBAModuleInfo->removeModuleInfo(_rModuleName); 523 return true; 524 } 525 } 526 catch( const Exception& ) 527 { 528 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 529 } 530 } 531 return false; 532 } 533 534 hasModuleOrDialog(LibraryContainerType _eType,const OUString & _rLibName,const OUString & _rModName) const535 bool ScriptDocument::Impl::hasModuleOrDialog( LibraryContainerType _eType, const OUString& _rLibName, const OUString& _rModName ) const 536 { 537 OSL_ENSURE( isValid(), "ScriptDocument::Impl::hasModuleOrDialog: invalid!" ); 538 if ( !isValid() ) 539 return false; 540 541 try 542 { 543 Reference< XNameContainer > xLib( getLibrary( _eType, _rLibName, true ) ); 544 if ( xLib.is() ) 545 return xLib->hasByName( _rModName ); 546 } 547 catch( const Exception& ) 548 { 549 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 550 } 551 return false; 552 } 553 554 getModuleOrDialog(LibraryContainerType _eType,const OUString & _rLibName,const OUString & _rObjectName,Any & _out_rModuleOrDialog)555 bool ScriptDocument::Impl::getModuleOrDialog( LibraryContainerType _eType, const OUString& _rLibName, const OUString& _rObjectName, Any& _out_rModuleOrDialog ) 556 { 557 OSL_ENSURE( isValid(), "ScriptDocument::Impl::getModuleOrDialog: invalid!" ); 558 if ( !isValid() ) 559 return false; 560 561 _out_rModuleOrDialog.clear(); 562 try 563 { 564 Reference< XNameContainer > xLib( getLibrary( _eType, _rLibName, true ), UNO_SET_THROW ); 565 if ( xLib->hasByName( _rObjectName ) ) 566 { 567 _out_rModuleOrDialog = xLib->getByName( _rObjectName ); 568 return true; 569 } 570 } 571 catch( const Exception& ) 572 { 573 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 574 } 575 return false; 576 } 577 578 renameModuleOrDialog(LibraryContainerType _eType,const OUString & _rLibName,const OUString & _rOldName,const OUString & _rNewName,const Reference<XNameContainer> & _rxExistingDialogModel)579 bool ScriptDocument::Impl::renameModuleOrDialog( LibraryContainerType _eType, const OUString& _rLibName, 580 const OUString& _rOldName, const OUString& _rNewName, const Reference< XNameContainer >& _rxExistingDialogModel ) 581 { 582 OSL_ENSURE( isValid(), "ScriptDocument::Impl::renameModuleOrDialog: invalid!" ); 583 if ( !isValid() ) 584 return false; 585 586 try 587 { 588 Reference< XNameContainer > xLib( getLibrary( _eType, _rLibName, true ), UNO_SET_THROW ); 589 590 // get element 591 Any aElement( xLib->getByName( _rOldName ) ); 592 593 // remove element from container 594 xLib->removeByName( _rOldName ); 595 596 // if it's a dialog, import and export, to reflect the new name 597 if ( _eType == E_DIALOGS ) 598 { 599 // create dialog model 600 Reference< XComponentContext > aContext( 601 comphelper::getProcessComponentContext() ); 602 Reference< XNameContainer > xDialogModel; 603 if ( _rxExistingDialogModel.is() ) 604 xDialogModel = _rxExistingDialogModel; 605 else 606 xDialogModel.set( 607 ( aContext->getServiceManager()-> 608 createInstanceWithContext( 609 "com.sun.star.awt.UnoControlDialogModel", 610 aContext ) ), 611 UNO_QUERY_THROW ); 612 613 // import dialog model 614 Reference< XInputStreamProvider > xISP( aElement, UNO_QUERY_THROW ); 615 if ( !_rxExistingDialogModel.is() ) 616 { 617 Reference< XInputStream > xInput( xISP->createInputStream(), UNO_SET_THROW ); 618 ::xmlscript::importDialogModel( xInput, xDialogModel, aContext, isDocument() ? getDocument() : Reference< XModel >() ); 619 } 620 621 // set new name as property 622 Reference< XPropertySet > xDlgPSet( xDialogModel, UNO_QUERY_THROW ); 623 xDlgPSet->setPropertyValue( DLGED_PROP_NAME, Any( _rNewName ) ); 624 625 // export dialog model 626 xISP = ::xmlscript::exportDialogModel( xDialogModel, aContext, isDocument() ? getDocument() : Reference< XModel >() ); 627 aElement <<= xISP; 628 } 629 630 // insert element by new name in container 631 if ( _eType == E_SCRIPTS ) 632 { 633 Reference< XVBAModuleInfo > xVBAModuleInfo( xLib, UNO_QUERY ); 634 if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( _rOldName ) ) 635 { 636 ModuleInfo sModuleInfo = xVBAModuleInfo->getModuleInfo( _rOldName ); 637 xVBAModuleInfo->removeModuleInfo( _rOldName ); 638 xVBAModuleInfo->insertModuleInfo( _rNewName, sModuleInfo ); 639 } 640 } 641 xLib->insertByName( _rNewName, aElement ); 642 return true; 643 } 644 catch( const Exception& ) 645 { 646 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 647 } 648 return false; 649 } 650 651 createModule(const OUString & _rLibName,const OUString & _rModName,bool _bCreateMain,OUString & _out_rNewModuleCode) const652 bool ScriptDocument::Impl::createModule( const OUString& _rLibName, const OUString& _rModName, bool _bCreateMain, OUString& _out_rNewModuleCode ) const 653 { 654 _out_rNewModuleCode.clear(); 655 try 656 { 657 Reference< XNameContainer > xLib( getLibrary( E_SCRIPTS, _rLibName, true ) ); 658 if ( !xLib.is() || xLib->hasByName( _rModName ) ) 659 return false; 660 661 // create new module 662 _out_rNewModuleCode = "REM ***** BASIC *****\n\n" ; 663 if ( _bCreateMain ) 664 _out_rNewModuleCode += "Sub Main\n\nEnd Sub\n" ; 665 666 Reference< XVBAModuleInfo > xVBAModuleInfo(xLib, UNO_QUERY); 667 if (xVBAModuleInfo.is()) 668 { 669 css::script::ModuleInfo aModuleInfo; 670 aModuleInfo.ModuleType = css::script::ModuleType::NORMAL; 671 xVBAModuleInfo->insertModuleInfo(_rModName, aModuleInfo); 672 } 673 674 // insert module into library 675 xLib->insertByName( _rModName, Any( _out_rNewModuleCode ) ); 676 } 677 catch( const Exception& ) 678 { 679 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 680 return false; 681 } 682 683 return true; 684 } 685 686 insertModuleOrDialog(LibraryContainerType _eType,const OUString & _rLibName,const OUString & _rObjectName,const Any & _rElement) const687 bool ScriptDocument::Impl::insertModuleOrDialog( LibraryContainerType _eType, const OUString& _rLibName, const OUString& _rObjectName, const Any& _rElement ) const 688 { 689 try 690 { 691 Reference< XNameContainer > xLib( getOrCreateLibrary( _eType, _rLibName ), UNO_SET_THROW ); 692 if ( xLib->hasByName( _rObjectName ) ) 693 return false; 694 695 xLib->insertByName( _rObjectName, _rElement ); 696 return true; 697 } 698 catch( const Exception& ) 699 { 700 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 701 } 702 return false; 703 } 704 705 updateModule(const OUString & _rLibName,const OUString & _rModName,const OUString & _rModuleCode) const706 bool ScriptDocument::Impl::updateModule( const OUString& _rLibName, const OUString& _rModName, const OUString& _rModuleCode ) const 707 { 708 try 709 { 710 Reference< XNameContainer > xLib( getOrCreateLibrary( E_SCRIPTS, _rLibName ), UNO_SET_THROW ); 711 if ( !xLib->hasByName( _rModName ) ) 712 return false; 713 xLib->replaceByName( _rModName, Any( _rModuleCode ) ); 714 return true; 715 } 716 catch( const Exception& ) 717 { 718 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 719 } 720 return false; 721 } 722 723 createDialog(const OUString & _rLibName,const OUString & _rDialogName,Reference<XInputStreamProvider> & _out_rDialogProvider) const724 bool ScriptDocument::Impl::createDialog( const OUString& _rLibName, const OUString& _rDialogName, Reference< XInputStreamProvider >& _out_rDialogProvider ) const 725 { 726 try 727 { 728 Reference< XNameContainer > xLib( getLibrary( E_DIALOGS, _rLibName, true ), UNO_SET_THROW ); 729 730 // create dialog 731 _out_rDialogProvider.clear(); 732 if ( xLib->hasByName( _rDialogName ) ) 733 return false; 734 735 // create new dialog model 736 Reference< XComponentContext > aContext( 737 comphelper::getProcessComponentContext() ); 738 Reference< XNameContainer > xDialogModel( 739 aContext->getServiceManager()->createInstanceWithContext( 740 "com.sun.star.awt.UnoControlDialogModel", aContext ), 741 UNO_QUERY_THROW ); 742 743 // set name property 744 Reference< XPropertySet > xDlgPSet( xDialogModel, UNO_QUERY_THROW ); 745 xDlgPSet->setPropertyValue( DLGED_PROP_NAME, Any( _rDialogName ) ); 746 747 // export dialog model 748 _out_rDialogProvider = ::xmlscript::exportDialogModel( xDialogModel, aContext, isDocument() ? getDocument() : Reference< XModel >() ); 749 750 // insert dialog into library 751 xLib->insertByName( _rDialogName, Any( _out_rDialogProvider ) ); 752 } 753 catch( const Exception& ) 754 { 755 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 756 } 757 758 return _out_rDialogProvider.is(); 759 } 760 761 setDocumentModified() const762 void ScriptDocument::Impl::setDocumentModified() const 763 { 764 OSL_ENSURE( isValid() && isDocument(), "ScriptDocument::Impl::setDocumentModified: only to be called for real documents!" ); 765 if ( isValid() && isDocument() ) 766 { 767 try 768 { 769 m_xDocModify->setModified( true ); 770 } 771 catch( const Exception& ) 772 { 773 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 774 } 775 } 776 } 777 778 isDocumentModified() const779 bool ScriptDocument::Impl::isDocumentModified() const 780 { 781 OSL_ENSURE( isValid() && isDocument(), "ScriptDocument::Impl::isDocumentModified: only to be called for real documents!" ); 782 bool bIsModified = false; 783 if ( isValid() && isDocument() ) 784 { 785 try 786 { 787 bIsModified = m_xDocModify->isModified(); 788 } 789 catch( const Exception& ) 790 { 791 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 792 } 793 } 794 return bIsModified; 795 } 796 797 saveDocument(const Reference<XStatusIndicator> & _rxStatusIndicator) const798 void ScriptDocument::Impl::saveDocument( const Reference< XStatusIndicator >& _rxStatusIndicator ) const 799 { 800 Reference< XFrame > xFrame; 801 if ( !getCurrentFrame( xFrame ) ) 802 return; 803 804 Sequence< PropertyValue > aArgs; 805 if ( _rxStatusIndicator.is() ) 806 { 807 aArgs = ::comphelper::InitPropertySequence({ 808 { "StatusIndicator", Any(_rxStatusIndicator) } 809 }); 810 } 811 812 try 813 { 814 URL aURL; 815 aURL.Complete = ".uno:Save" ; 816 aURL.Main = aURL.Complete; 817 aURL.Protocol = ".uno:" ; 818 aURL.Path = "Save" ; 819 820 Reference< XDispatchProvider > xDispProv( xFrame, UNO_QUERY_THROW ); 821 Reference< XDispatch > xDispatch( 822 xDispProv->queryDispatch( aURL, "_self", FrameSearchFlag::AUTO ), 823 UNO_SET_THROW ); 824 825 xDispatch->dispatch( aURL, aArgs ); 826 } 827 catch( const Exception& ) 828 { 829 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 830 } 831 } 832 833 getTitle() const834 OUString ScriptDocument::Impl::getTitle() const 835 { 836 OSL_PRECOND( isValid() && isDocument(), "ScriptDocument::Impl::getTitle: for documents only!" ); 837 838 OUString sTitle; 839 if ( isValid() && isDocument() ) 840 { 841 sTitle = ::comphelper::DocumentInfo::getDocumentTitle( m_xDocument ); 842 } 843 return sTitle; 844 } 845 846 getURL() const847 OUString ScriptDocument::Impl::getURL() const 848 { 849 OSL_PRECOND( isValid() && isDocument(), "ScriptDocument::Impl::getURL: for documents only!" ); 850 851 OUString sURL; 852 if ( isValid() && isDocument() ) 853 { 854 try 855 { 856 sURL = m_xDocument->getURL(); 857 } 858 catch( const Exception& ) 859 { 860 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 861 } 862 } 863 return sURL; 864 } 865 866 allowMacros() const867 bool ScriptDocument::Impl::allowMacros() const 868 { 869 OSL_ENSURE( isValid() && isDocument(), "ScriptDocument::Impl::allowMacros: for documents only!" ); 870 bool bAllow = false; 871 if ( isValid() && isDocument() ) 872 { 873 try 874 { 875 bAllow = m_xScriptAccess->getAllowMacroExecution(); 876 } 877 catch( const Exception& ) 878 { 879 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 880 } 881 } 882 return bAllow; 883 } 884 885 getCurrentFrame(Reference<XFrame> & _out_rxFrame) const886 bool ScriptDocument::Impl::getCurrentFrame( Reference< XFrame >& _out_rxFrame ) const 887 { 888 _out_rxFrame.clear(); 889 OSL_PRECOND( isValid() && isDocument(), "ScriptDocument::Impl::getCurrentFrame: documents only!" ); 890 if ( !isValid() || !isDocument() ) 891 return false; 892 893 try 894 { 895 Reference< XModel > xDocument( m_xDocument, UNO_SET_THROW ); 896 Reference< XController > xController( xDocument->getCurrentController(), UNO_SET_THROW ); 897 _out_rxFrame.set( xController->getFrame(), UNO_SET_THROW ); 898 } 899 catch( const Exception& ) 900 { 901 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 902 } 903 904 return _out_rxFrame.is(); 905 } 906 907 isLibraryShared(const OUString & _rLibName,LibraryContainerType _eType)908 bool ScriptDocument::Impl::isLibraryShared( const OUString& _rLibName, LibraryContainerType _eType ) 909 { 910 bool bIsShared = false; 911 try 912 { 913 Reference< XLibraryContainer2 > xLibContainer( getLibraryContainer( _eType ), UNO_QUERY_THROW ); 914 915 if ( !xLibContainer->hasByName( _rLibName ) || !xLibContainer->isLibraryLink( _rLibName ) ) 916 return false; 917 OUString aFileURL; 918 Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() ); 919 Reference< XUriReferenceFactory > xUriFac = UriReferenceFactory::create(xContext); 920 921 OUString aLinkURL( xLibContainer->getLibraryLinkURL( _rLibName ) ); 922 Reference< XUriReference > xUriRef( xUriFac->parse( aLinkURL ), UNO_SET_THROW ); 923 924 OUString aScheme = xUriRef->getScheme(); 925 if ( aScheme.equalsIgnoreAsciiCase("file") ) 926 { 927 aFileURL = aLinkURL; 928 } 929 else if ( aScheme.equalsIgnoreAsciiCase("vnd.sun.star.pkg") ) 930 { 931 OUString aAuthority = xUriRef->getAuthority(); 932 if ( aAuthority.matchIgnoreAsciiCase("vnd.sun.star.expand:") ) 933 { 934 OUString aDecodedURL( aAuthority.copy( sizeof ( "vnd.sun.star.expand:" ) - 1 ) ); 935 aDecodedURL = ::rtl::Uri::decode( aDecodedURL, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 ); 936 Reference< XMacroExpander > xMacroExpander = theMacroExpander::get(xContext); 937 aFileURL = xMacroExpander->expandMacros( aDecodedURL ); 938 } 939 } 940 941 if ( !aFileURL.isEmpty() ) 942 { 943 ::osl::DirectoryItem aFileItem; 944 ::osl::FileStatus aFileStatus( osl_FileStatus_Mask_FileURL ); 945 OSL_VERIFY( ::osl::DirectoryItem::get( aFileURL, aFileItem ) == ::osl::FileBase::E_None ); 946 OSL_VERIFY( aFileItem.getFileStatus( aFileStatus ) == ::osl::FileBase::E_None ); 947 OUString aCanonicalFileURL( aFileStatus.getFileURL() ); 948 949 if( aCanonicalFileURL.indexOf( "share/basic" ) >= 0 || 950 aCanonicalFileURL.indexOf( "share/uno_packages" ) >= 0 || 951 aCanonicalFileURL.indexOf( "share/extensions" ) >= 0 ) 952 bIsShared = true; 953 } 954 } 955 catch( const Exception& ) 956 { 957 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 958 } 959 960 return bIsShared; 961 } 962 963 onDocumentCreated(const ScriptDocument &)964 void ScriptDocument::Impl::onDocumentCreated( const ScriptDocument& /*_rDocument*/ ) 965 { 966 // not interested in 967 } 968 onDocumentOpened(const ScriptDocument &)969 void ScriptDocument::Impl::onDocumentOpened( const ScriptDocument& /*_rDocument*/ ) 970 { 971 // not interested in 972 } 973 onDocumentSave(const ScriptDocument &)974 void ScriptDocument::Impl::onDocumentSave( const ScriptDocument& /*_rDocument*/ ) 975 { 976 // not interested in 977 } 978 onDocumentSaveDone(const ScriptDocument &)979 void ScriptDocument::Impl::onDocumentSaveDone( const ScriptDocument& /*_rDocument*/ ) 980 { 981 // not interested in 982 } 983 onDocumentSaveAs(const ScriptDocument &)984 void ScriptDocument::Impl::onDocumentSaveAs( const ScriptDocument& /*_rDocument*/ ) 985 { 986 // not interested in 987 } 988 onDocumentSaveAsDone(const ScriptDocument &)989 void ScriptDocument::Impl::onDocumentSaveAsDone( const ScriptDocument& /*_rDocument*/ ) 990 { 991 // not interested in 992 } 993 onDocumentClosed(const ScriptDocument & _rDocument)994 void ScriptDocument::Impl::onDocumentClosed( const ScriptDocument& _rDocument ) 995 { 996 DBG_TESTSOLARMUTEX(); 997 OSL_PRECOND( isValid(), "ScriptDocument::Impl::onDocumentClosed: should not be listening if I'm not valid!" ); 998 999 bool bMyDocument = m_xDocument == _rDocument.getDocument(); 1000 OSL_PRECOND( bMyDocument, "ScriptDocument::Impl::onDocumentClosed: didn't want to know *this*!" ); 1001 if ( bMyDocument ) 1002 { 1003 m_bDocumentClosed = true; 1004 } 1005 } 1006 1007 onDocumentTitleChanged(const ScriptDocument &)1008 void ScriptDocument::Impl::onDocumentTitleChanged( const ScriptDocument& /*_rDocument*/ ) 1009 { 1010 // not interested in 1011 } 1012 onDocumentModeChanged(const ScriptDocument &)1013 void ScriptDocument::Impl::onDocumentModeChanged( const ScriptDocument& /*_rDocument*/ ) 1014 { 1015 // not interested in 1016 } 1017 1018 ScriptDocument()1019 ScriptDocument::ScriptDocument() 1020 :m_pImpl(std::make_shared<Impl>()) 1021 { } 1022 1023 ScriptDocument(ScriptDocument::SpecialDocument _eType)1024 ScriptDocument::ScriptDocument( ScriptDocument::SpecialDocument _eType ) 1025 :m_pImpl( std::make_shared<Impl>( Reference< XModel >() ) ) 1026 { 1027 OSL_ENSURE( _eType == NoDocument, "ScriptDocument::ScriptDocument: unknown SpecialDocument type!" ); 1028 } 1029 1030 ScriptDocument(const Reference<XModel> & _rxDocument)1031 ScriptDocument::ScriptDocument( const Reference< XModel >& _rxDocument ) 1032 :m_pImpl( std::make_shared<Impl>( _rxDocument ) ) 1033 { 1034 OSL_ENSURE( _rxDocument.is(), "ScriptDocument::ScriptDocument: document must not be NULL!" ); 1035 // a NULL document results in an uninitialized instance, and for this 1036 // purpose, there is a dedicated constructor 1037 } 1038 1039 getApplicationScriptDocument()1040 const ScriptDocument& ScriptDocument::getApplicationScriptDocument() 1041 { 1042 static ScriptDocument s_aApplicationScripts; 1043 return s_aApplicationScripts; 1044 } 1045 1046 getDocumentForBasicManager(const BasicManager * _pManager)1047 ScriptDocument ScriptDocument::getDocumentForBasicManager( const BasicManager* _pManager ) 1048 { 1049 if ( _pManager == SfxApplication::GetBasicManager() ) 1050 return getApplicationScriptDocument(); 1051 1052 docs::Documents aDocuments; 1053 lcl_getAllModels_throw( aDocuments, false ); 1054 1055 for (auto const& doc : aDocuments) 1056 { 1057 const BasicManager* pDocBasicManager = ::basic::BasicManagerRepository::getDocumentBasicManager( doc.xModel ); 1058 if ( ( pDocBasicManager != SfxApplication::GetBasicManager() ) 1059 && ( pDocBasicManager == _pManager ) 1060 ) 1061 { 1062 return ScriptDocument( doc.xModel ); 1063 } 1064 } 1065 1066 OSL_FAIL( "ScriptDocument::getDocumentForBasicManager: did not find a document for this manager!" ); 1067 return ScriptDocument( NoDocument ); 1068 } 1069 1070 getDocumentWithURLOrCaption(std::u16string_view _rUrlOrCaption)1071 ScriptDocument ScriptDocument::getDocumentWithURLOrCaption( std::u16string_view _rUrlOrCaption ) 1072 { 1073 ScriptDocument aDocument( getApplicationScriptDocument() ); 1074 if ( _rUrlOrCaption.empty() ) 1075 return aDocument; 1076 1077 docs::Documents aDocuments; 1078 lcl_getAllModels_throw( aDocuments, false ); 1079 1080 for (auto const& doc : aDocuments) 1081 { 1082 const ScriptDocument aCheck( doc.xModel ); 1083 if ( _rUrlOrCaption == aCheck.getTitle() 1084 || _rUrlOrCaption == aCheck.m_pImpl->getURL() 1085 ) 1086 { 1087 aDocument = aCheck; 1088 break; 1089 } 1090 } 1091 1092 return aDocument; 1093 } 1094 getAllScriptDocuments(ScriptDocument::ScriptDocumentList _eListType)1095 ScriptDocuments ScriptDocument::getAllScriptDocuments( ScriptDocument::ScriptDocumentList _eListType ) 1096 { 1097 ScriptDocuments aScriptDocs; 1098 1099 // include application? 1100 if ( _eListType == AllWithApplication ) 1101 aScriptDocs.push_back( getApplicationScriptDocument() ); 1102 1103 // obtain documents 1104 try 1105 { 1106 docs::Documents aDocuments; 1107 lcl_getAllModels_throw( aDocuments, true /* exclude invisible */ ); 1108 1109 for (auto const& doc : aDocuments) 1110 { 1111 // exclude documents without script/library containers 1112 ScriptDocument aDoc( doc.xModel ); 1113 if ( !aDoc.isValid() ) 1114 continue; 1115 1116 aScriptDocs.push_back( aDoc ); 1117 } 1118 } 1119 catch( const Exception& ) 1120 { 1121 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 1122 } 1123 1124 // sort document list by doc title? 1125 if ( _eListType == DocumentsSorted ) 1126 { 1127 auto const sort = comphelper::string::NaturalStringSorter( 1128 comphelper::getProcessComponentContext(), 1129 Application::GetSettings().GetUILanguageTag().getLocale()); 1130 std::sort(aScriptDocs.begin(), aScriptDocs.end(), 1131 [&sort](const ScriptDocument& rLHS, const ScriptDocument& rRHS) { 1132 return sort.compare(rLHS.getTitle(), rRHS.getTitle()) < 0; 1133 }); 1134 } 1135 1136 return aScriptDocs; 1137 } 1138 1139 operator ==(const ScriptDocument & _rhs) const1140 bool ScriptDocument::operator==( const ScriptDocument& _rhs ) const 1141 { 1142 return m_pImpl->getDocumentRef() == _rhs.m_pImpl->getDocumentRef(); 1143 } 1144 1145 hashCode() const1146 sal_Int32 ScriptDocument::hashCode() const 1147 { 1148 return sal::static_int_cast<sal_Int32>(reinterpret_cast< sal_IntPtr >( m_pImpl->getDocumentRef().get() )); 1149 } 1150 1151 isValid() const1152 bool ScriptDocument::isValid() const 1153 { 1154 return m_pImpl->isValid(); 1155 } 1156 1157 isAlive() const1158 bool ScriptDocument::isAlive() const 1159 { 1160 return m_pImpl->isAlive(); 1161 } 1162 1163 getLibraryContainer(LibraryContainerType _eType) const1164 Reference< XLibraryContainer > ScriptDocument::getLibraryContainer( LibraryContainerType _eType ) const 1165 { 1166 return m_pImpl->getLibraryContainer( _eType ); 1167 } 1168 1169 getLibrary(LibraryContainerType _eType,const OUString & _rLibName,bool _bLoadLibrary) const1170 Reference< XNameContainer > ScriptDocument::getLibrary( LibraryContainerType _eType, const OUString& _rLibName, bool _bLoadLibrary ) const 1171 { 1172 return m_pImpl->getLibrary( _eType, _rLibName, _bLoadLibrary ); 1173 } 1174 1175 hasLibrary(LibraryContainerType _eType,const OUString & _rLibName) const1176 bool ScriptDocument::hasLibrary( LibraryContainerType _eType, const OUString& _rLibName ) const 1177 { 1178 return m_pImpl->hasLibrary( _eType, _rLibName ); 1179 } 1180 1181 getOrCreateLibrary(LibraryContainerType _eType,const OUString & _rLibName) const1182 Reference< XNameContainer > ScriptDocument::getOrCreateLibrary( LibraryContainerType _eType, const OUString& _rLibName ) const 1183 { 1184 return m_pImpl->getOrCreateLibrary( _eType, _rLibName ); 1185 } 1186 1187 loadLibraryIfExists(LibraryContainerType _eType,const OUString & _rLibrary)1188 void ScriptDocument::loadLibraryIfExists( LibraryContainerType _eType, const OUString& _rLibrary ) 1189 { 1190 m_pImpl->loadLibraryIfExists( _eType, _rLibrary ); 1191 } 1192 1193 getObjectNames(LibraryContainerType _eType,const OUString & _rLibName) const1194 Sequence< OUString > ScriptDocument::getObjectNames( LibraryContainerType _eType, const OUString& _rLibName ) const 1195 { 1196 Sequence< OUString > aModuleNames; 1197 1198 try 1199 { 1200 if ( hasLibrary( _eType, _rLibName ) ) 1201 { 1202 Reference< XNameContainer > xLib( getLibrary( _eType, _rLibName, false ) ); 1203 if ( xLib.is() ) 1204 aModuleNames = xLib->getElementNames(); 1205 } 1206 } 1207 catch( const Exception& ) 1208 { 1209 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 1210 } 1211 1212 // sort 1213 auto const sort = comphelper::string::NaturalStringSorter( 1214 comphelper::getProcessComponentContext(), 1215 Application::GetSettings().GetUILanguageTag().getLocale()); 1216 std::sort(aModuleNames.begin(), aModuleNames.end(), 1217 [&sort](const OUString& rLHS, const OUString& rRHS) { 1218 return sort.compare(rLHS, rRHS) < 0; 1219 }); 1220 return aModuleNames; 1221 } 1222 1223 createObjectName(LibraryContainerType _eType,const OUString & _rLibName) const1224 OUString ScriptDocument::createObjectName( LibraryContainerType _eType, const OUString& _rLibName ) const 1225 { 1226 OUString aObjectName; 1227 1228 OUString aBaseName = _eType == E_SCRIPTS ? OUString("Module") : OUString("Dialog"); 1229 1230 Sequence< OUString > aUsedNames( getObjectNames( _eType, _rLibName ) ); 1231 std::set< OUString > aUsedNamesCheck( aUsedNames.begin(), aUsedNames.end() ); 1232 1233 bool bValid = false; 1234 sal_Int32 i = 1; 1235 while ( !bValid ) 1236 { 1237 aObjectName = aBaseName 1238 + OUString::number( i ); 1239 1240 if ( aUsedNamesCheck.find( aObjectName ) == aUsedNamesCheck.end() ) 1241 bValid = true; 1242 1243 ++i; 1244 } 1245 1246 return aObjectName; 1247 } 1248 1249 getLibraryNames() const1250 Sequence< OUString > ScriptDocument::getLibraryNames() const 1251 { 1252 return GetMergedLibraryNames( getLibraryContainer( E_SCRIPTS ), getLibraryContainer( E_DIALOGS ) ); 1253 } 1254 1255 isReadOnly() const1256 bool ScriptDocument::isReadOnly() const 1257 { 1258 return m_pImpl->isReadOnly(); 1259 } 1260 1261 isApplication() const1262 bool ScriptDocument::isApplication() const 1263 { 1264 return m_pImpl->isApplication(); 1265 } 1266 isInVBAMode() const1267 bool ScriptDocument::isInVBAMode() const 1268 { 1269 return m_pImpl->isInVBAMode(); 1270 } 1271 1272 getBasicManager() const1273 BasicManager* ScriptDocument::getBasicManager() const 1274 { 1275 return m_pImpl->getBasicManager(); 1276 } 1277 1278 getDocument() const1279 Reference< XModel > ScriptDocument::getDocument() const 1280 { 1281 return m_pImpl->getDocument(); 1282 } 1283 1284 getDocumentOrNull() const1285 Reference< XModel > ScriptDocument::getDocumentOrNull() const 1286 { 1287 if ( isDocument() ) 1288 return m_pImpl->getDocument(); 1289 return nullptr; 1290 } 1291 1292 removeModule(const OUString & _rLibName,const OUString & _rModuleName) const1293 bool ScriptDocument::removeModule( const OUString& _rLibName, const OUString& _rModuleName ) const 1294 { 1295 return m_pImpl->removeModuleOrDialog( E_SCRIPTS, _rLibName, _rModuleName ); 1296 } 1297 1298 hasModule(const OUString & _rLibName,const OUString & _rModuleName) const1299 bool ScriptDocument::hasModule( const OUString& _rLibName, const OUString& _rModuleName ) const 1300 { 1301 return m_pImpl->hasModuleOrDialog( E_SCRIPTS, _rLibName, _rModuleName ); 1302 } 1303 1304 getModule(const OUString & _rLibName,const OUString & _rModName,OUString & _out_rModuleSource) const1305 bool ScriptDocument::getModule( const OUString& _rLibName, const OUString& _rModName, OUString& _out_rModuleSource ) const 1306 { 1307 Any aCode; 1308 if ( !m_pImpl->getModuleOrDialog( E_SCRIPTS, _rLibName, _rModName, aCode ) ) 1309 return false; 1310 OSL_VERIFY( aCode >>= _out_rModuleSource ); 1311 return true; 1312 } 1313 1314 renameModule(const OUString & _rLibName,const OUString & _rOldName,const OUString & _rNewName) const1315 bool ScriptDocument::renameModule( const OUString& _rLibName, const OUString& _rOldName, const OUString& _rNewName ) const 1316 { 1317 return m_pImpl->renameModuleOrDialog( E_SCRIPTS, _rLibName, _rOldName, _rNewName, nullptr ); 1318 } 1319 1320 createModule(const OUString & _rLibName,const OUString & _rModName,bool _bCreateMain,OUString & _out_rNewModuleCode) const1321 bool ScriptDocument::createModule( const OUString& _rLibName, const OUString& _rModName, bool _bCreateMain, OUString& _out_rNewModuleCode ) const 1322 { 1323 if ( !m_pImpl->createModule( _rLibName, _rModName, _bCreateMain, _out_rNewModuleCode ) ) 1324 return false; 1325 1326 // doc shell modified 1327 MarkDocumentModified( *const_cast< ScriptDocument* >( this ) ); // here? 1328 return true; 1329 } 1330 1331 insertModule(const OUString & _rLibName,const OUString & _rModName,const OUString & _rModuleCode) const1332 bool ScriptDocument::insertModule( const OUString& _rLibName, const OUString& _rModName, const OUString& _rModuleCode ) const 1333 { 1334 return m_pImpl->insertModuleOrDialog( E_SCRIPTS, _rLibName, _rModName, Any( _rModuleCode ) ); 1335 } 1336 1337 updateModule(const OUString & _rLibName,const OUString & _rModName,const OUString & _rModuleCode) const1338 bool ScriptDocument::updateModule( const OUString& _rLibName, const OUString& _rModName, const OUString& _rModuleCode ) const 1339 { 1340 return m_pImpl->updateModule( _rLibName, _rModName, _rModuleCode ); 1341 } 1342 1343 removeDialog(const OUString & _rLibName,const OUString & _rDialogName) const1344 bool ScriptDocument::removeDialog( const OUString& _rLibName, const OUString& _rDialogName ) const 1345 { 1346 return m_pImpl->removeModuleOrDialog( E_DIALOGS, _rLibName, _rDialogName ); 1347 } 1348 1349 hasDialog(const OUString & _rLibName,const OUString & _rDialogName) const1350 bool ScriptDocument::hasDialog( const OUString& _rLibName, const OUString& _rDialogName ) const 1351 { 1352 return m_pImpl->hasModuleOrDialog( E_DIALOGS, _rLibName, _rDialogName ); 1353 } 1354 1355 getDialog(const OUString & _rLibName,const OUString & _rDialogName,Reference<XInputStreamProvider> & _out_rDialogProvider) const1356 bool ScriptDocument::getDialog( const OUString& _rLibName, const OUString& _rDialogName, Reference< XInputStreamProvider >& _out_rDialogProvider ) const 1357 { 1358 Any aCode; 1359 if ( !m_pImpl->getModuleOrDialog( E_DIALOGS, _rLibName, _rDialogName, aCode ) ) 1360 return false; 1361 OSL_VERIFY( aCode >>= _out_rDialogProvider ); 1362 return _out_rDialogProvider.is(); 1363 } 1364 1365 renameDialog(const OUString & _rLibName,const OUString & _rOldName,const OUString & _rNewName,const Reference<XNameContainer> & _rxExistingDialogModel) const1366 bool ScriptDocument::renameDialog( const OUString& _rLibName, const OUString& _rOldName, const OUString& _rNewName, const Reference< XNameContainer >& _rxExistingDialogModel ) const 1367 { 1368 return m_pImpl->renameModuleOrDialog( E_DIALOGS, _rLibName, _rOldName, _rNewName, _rxExistingDialogModel ); 1369 } 1370 1371 createDialog(const OUString & _rLibName,const OUString & _rDialogName,Reference<XInputStreamProvider> & _out_rDialogProvider) const1372 bool ScriptDocument::createDialog( const OUString& _rLibName, const OUString& _rDialogName, Reference< XInputStreamProvider >& _out_rDialogProvider ) const 1373 { 1374 if ( !m_pImpl->createDialog( _rLibName, _rDialogName, _out_rDialogProvider ) ) 1375 return false; 1376 1377 MarkDocumentModified( *const_cast< ScriptDocument* >( this ) ); // here? 1378 return true; 1379 } 1380 1381 insertDialog(const OUString & _rLibName,const OUString & _rDialogName,const Reference<XInputStreamProvider> & _rxDialogProvider) const1382 bool ScriptDocument::insertDialog( const OUString& _rLibName, const OUString& _rDialogName, const Reference< XInputStreamProvider >& _rxDialogProvider ) const 1383 { 1384 return m_pImpl->insertModuleOrDialog( E_DIALOGS, _rLibName, _rDialogName, Any( _rxDialogProvider ) ); 1385 } 1386 1387 setDocumentModified() const1388 void ScriptDocument::setDocumentModified() const 1389 { 1390 m_pImpl->setDocumentModified(); 1391 } 1392 1393 isDocumentModified() const1394 bool ScriptDocument::isDocumentModified() const 1395 { 1396 return m_pImpl->isDocumentModified(); 1397 } 1398 1399 saveDocument(const Reference<XStatusIndicator> & _rxStatusIndicator) const1400 void ScriptDocument::saveDocument( const Reference< XStatusIndicator >& _rxStatusIndicator ) const 1401 { 1402 m_pImpl->saveDocument( _rxStatusIndicator ); 1403 } 1404 1405 getLibraryLocation(const OUString & _rLibName) const1406 LibraryLocation ScriptDocument::getLibraryLocation( const OUString& _rLibName ) const 1407 { 1408 LibraryLocation eLocation = LIBRARY_LOCATION_UNKNOWN; 1409 if ( !_rLibName.isEmpty() ) 1410 { 1411 if ( isDocument() ) 1412 { 1413 eLocation = LIBRARY_LOCATION_DOCUMENT; 1414 } 1415 else 1416 { 1417 if ( ( hasLibrary( E_SCRIPTS, _rLibName ) && !m_pImpl->isLibraryShared( _rLibName, E_SCRIPTS ) ) 1418 || ( hasLibrary( E_DIALOGS, _rLibName ) && !m_pImpl->isLibraryShared( _rLibName, E_DIALOGS ) ) 1419 ) 1420 { 1421 eLocation = LIBRARY_LOCATION_USER; 1422 } 1423 else 1424 { 1425 eLocation = LIBRARY_LOCATION_SHARE; 1426 } 1427 } 1428 } 1429 1430 return eLocation; 1431 } 1432 1433 getTitle(LibraryLocation _eLocation,LibraryType _eType) const1434 OUString ScriptDocument::getTitle( LibraryLocation _eLocation, LibraryType _eType ) const 1435 { 1436 OUString aTitle; 1437 1438 switch ( _eLocation ) 1439 { 1440 case LIBRARY_LOCATION_USER: 1441 { 1442 switch ( _eType ) 1443 { 1444 case LibraryType::Module: aTitle = IDEResId(RID_STR_USERMACROS); break; 1445 case LibraryType::Dialog: aTitle = IDEResId(RID_STR_USERDIALOGS); break; 1446 case LibraryType::All: aTitle = IDEResId(RID_STR_USERMACROSDIALOGS); break; 1447 default: 1448 break; 1449 } 1450 } 1451 break; 1452 case LIBRARY_LOCATION_SHARE: 1453 { 1454 switch ( _eType ) 1455 { 1456 case LibraryType::Module: aTitle = IDEResId(RID_STR_SHAREMACROS); break; 1457 case LibraryType::Dialog: aTitle = IDEResId(RID_STR_SHAREDIALOGS); break; 1458 case LibraryType::All: aTitle = IDEResId(RID_STR_SHAREMACROSDIALOGS); break; 1459 default: 1460 break; 1461 } 1462 } 1463 break; 1464 case LIBRARY_LOCATION_DOCUMENT: 1465 aTitle = getTitle(); 1466 break; 1467 default: 1468 break; 1469 } 1470 1471 return aTitle; 1472 } 1473 1474 getTitle() const1475 OUString ScriptDocument::getTitle() const 1476 { 1477 return m_pImpl->getTitle(); 1478 } 1479 1480 isActive() const1481 bool ScriptDocument::isActive() const 1482 { 1483 bool bIsActive( false ); 1484 try 1485 { 1486 Reference< XFrame > xFrame; 1487 if ( m_pImpl->getCurrentFrame( xFrame ) ) 1488 bIsActive = xFrame->isActive(); 1489 } 1490 catch( const Exception& ) 1491 { 1492 DBG_UNHANDLED_EXCEPTION("basctl.basicide"); 1493 } 1494 return bIsActive; 1495 } 1496 1497 allowMacros() const1498 bool ScriptDocument::allowMacros() const 1499 { 1500 return m_pImpl->allowMacros(); 1501 } 1502 1503 } // namespace basctl 1504 1505 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 1506