1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_dbaccess.hxx" 30 31 #ifndef _DBA_COREDATAACCESS_DOCUMENTDEFINITION_HXX_ 32 #include "documentdefinition.hxx" 33 #endif 34 #ifndef DBACCESS_SHARED_DBASTRINGS_HRC 35 #include "dbastrings.hrc" 36 #endif 37 #ifndef DBACORE_SDBCORETOOLS_HXX 38 #include "sdbcoretools.hxx" 39 #endif 40 #ifndef _TOOLS_DEBUG_HXX 41 #include <tools/debug.hxx> 42 #endif 43 #ifndef TOOLS_DIAGNOSE_EX_H 44 #include <tools/diagnose_ex.h> 45 #endif 46 #ifndef _COMPHELPER_PROPERTY_HXX_ 47 #include <comphelper/property.hxx> 48 #endif 49 #ifndef _COMPHELPER_SEQUENCE_HXX_ 50 #include <comphelper/sequence.hxx> 51 #endif 52 #ifndef _COMPHELPER_MEDIADESCRIPTOR_HXX_ 53 #include <comphelper/mediadescriptor.hxx> 54 #endif 55 #ifndef COMPHELPER_NAMEDVALUECOLLECTION_HXX 56 #include <comphelper/namedvaluecollection.hxx> 57 #endif 58 #ifndef _COMPHELPER_CLASSIDS_HXX 59 #include <comphelper/classids.hxx> 60 #endif 61 #include <com/sun/star/frame/XUntitledNumbers.hpp> 62 #ifndef _COM_SUN_STAR_AWT_XTOPWINDOW_HPP_ 63 #include <com/sun/star/awt/XTopWindow.hpp> 64 #endif 65 #ifndef _COM_SUN_STAR_AWT_SIZE_HPP_ 66 #include <com/sun/star/awt/Size.hpp> 67 #endif 68 #ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_ 69 #include <com/sun/star/lang/DisposedException.hpp> 70 #endif 71 #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_ 72 #include <com/sun/star/beans/PropertyAttribute.hpp> 73 #endif 74 #ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_ 75 #include <com/sun/star/frame/XModel.hpp> 76 #endif 77 #include <com/sun/star/frame/XTitle.hpp> 78 #ifndef _COM_SUN_STAR_FRAME_XCONTROLLER_HPP_ 79 #include <com/sun/star/frame/XController.hpp> 80 #endif 81 #ifndef _COM_SUN_STAR_TASK_XJOBEXECUTOR_HPP_ 82 #include <com/sun/star/task/XJobExecutor.hpp> 83 #endif 84 #ifndef _COM_SUN_STAR_FRAME_XDISPATCHPROVIDERINTERCEPTION_HPP_ 85 #include <com/sun/star/frame/XDispatchProviderInterception.hpp> 86 #endif 87 #ifndef _COM_SUN_STAR_FRAME_XFRAMESSUPPLIER_HPP_ 88 #include <com/sun/star/frame/XFramesSupplier.hpp> 89 #endif 90 #ifndef _COM_SUN_STAR_UCB_INSERTCOMMANDARGUMENT_HPP_ 91 #include <com/sun/star/ucb/InsertCommandArgument.hpp> 92 #endif 93 #include <com/sun/star/report/XReportDefinition.hpp> 94 #include <com/sun/star/report/XReportEngine.hpp> 95 #ifndef _COM_SUN_STAR_UCB_OPENMODE_HPP_ 96 #include <com/sun/star/ucb/OpenMode.hpp> 97 #endif 98 #ifndef _COM_SUN_STAR_XEMBEDOBJECTFACTORY_HPP_ 99 #include <com/sun/star/embed/XEmbedObjectFactory.hpp> 100 #endif 101 #ifndef _COM_SUN_STAR_XEMBEDOBJECTCREATOR_HPP_ 102 #include <com/sun/star/embed/XEmbedObjectCreator.hpp> 103 #endif 104 #ifndef _COM_SUN_STAR_EMBED_ASPECTS_HPP_ 105 #include <com/sun/star/embed/Aspects.hpp> 106 #endif 107 #ifndef _UCBHELPER_CANCELCOMMANDEXECUTION_HXX_ 108 #include <ucbhelper/cancelcommandexecution.hxx> 109 #endif 110 #ifndef _COM_SUN_STAR_UCB_UNSUPPORTEDDATASINKEXCEPTION_HPP_ 111 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp> 112 #endif 113 #ifndef _COM_SUN_STAR_UCB_UNSUPPORTEDOPENMODEEXCEPTION_HPP_ 114 #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp> 115 #endif 116 #ifndef _COM_SUN_STAR_ELEMENTMODES_HPP_ 117 #include <com/sun/star/embed/ElementModes.hpp> 118 #endif 119 #ifndef _COM_SUN_STAR_XEMBEDPERSIST_HPP_ 120 #include <com/sun/star/embed/XEmbedPersist.hpp> 121 #endif 122 #ifndef _COM_SUN_STAR_EMBEDSTATES_HPP_ 123 #include <com/sun/star/embed/EmbedStates.hpp> 124 #endif 125 #ifndef _COM_SUN_STAR_XCOMPONENTSUPPLIER_HPP_ 126 #include <com/sun/star/embed/XComponentSupplier.hpp> 127 #endif 128 #ifndef _COM_SUN_STAR_ENTRYINITMODES_HPP_ 129 #include <com/sun/star/embed/EntryInitModes.hpp> 130 #endif 131 #ifndef _COM_SUN_STAR_UCB_MISSINGPROPERTIESEXCEPTION_HPP_ 132 #include <com/sun/star/ucb/MissingPropertiesException.hpp> 133 #endif 134 #ifndef _COM_SUN_STAR_UCB_MISSINGINPUTSTREAMEXCEPTION_HPP_ 135 #include <com/sun/star/ucb/MissingInputStreamException.hpp> 136 #endif 137 #ifndef _COM_SUN_STAR_UCB_OPENCOMMANDARGUMENT2_HPP_ 138 #include <com/sun/star/ucb/OpenCommandArgument2.hpp> 139 #endif 140 #ifndef _COM_SUN_STAR_UTIL_XCLOSEBROADCASTER_HPP_ 141 #include <com/sun/star/util/XCloseBroadcaster.hpp> 142 #endif 143 #ifndef _COM_SUN_STAR_FRAME_XMODULE_HPP_ 144 #include <com/sun/star/frame/XModule.hpp> 145 #endif 146 #ifndef _COM_SUN_STAR_DATATRANSFER_DATAFLAVOR_HPP_ 147 #include <com/sun/star/datatransfer/DataFlavor.hpp> 148 #endif 149 #ifndef _COM_SUN_STAR_DATATRANSFER_XTRANSFERABLE_HPP_ 150 #include <com/sun/star/datatransfer/XTransferable.hpp> 151 #endif 152 #ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_ 153 #include <com/sun/star/container/XNameContainer.hpp> 154 #endif 155 #ifndef _COM_SUN_STAR_XTRANSACTEDOBJECT_HPP_ 156 #include <com/sun/star/embed/XTransactedObject.hpp> 157 #endif 158 #ifndef _COM_SUN_STAR_EMBED_XCOMMONEMBEDPERSIST_HPP_ 159 #include <com/sun/star/embed/XCommonEmbedPersist.hpp> 160 #endif 161 #ifndef DBA_INTERCEPT_HXX 162 #include "intercept.hxx" 163 #endif 164 #ifndef _COM_SUN_STAR_SDB_ERRORCONDITION_HPP_ 165 #include <com/sun/star/sdb/ErrorCondition.hpp> 166 #endif 167 #ifndef _COM_SUN_STAR_SDB_XINTERACTIONDOCUMENTSAVE_HPP_ 168 #include <com/sun/star/sdb/XInteractionDocumentSave.hpp> 169 #endif 170 #ifndef _COM_SUN_STAR_TASK_XINTERACTIONHANDLER_HPP_ 171 #include <com/sun/star/task/XInteractionHandler.hpp> 172 #endif 173 #ifndef _COM_SUN_STAR_SDB_DOCUMENTSAVEREQUEST_HPP_ 174 #include <com/sun/star/sdb/DocumentSaveRequest.hpp> 175 #endif 176 #ifndef _COM_SUN_STAR_DOCUMENT_XDOCUMENTPROPERTIESSUPPLIER_HPP_ 177 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> 178 #endif 179 #ifndef _COM_SUN_STAR_DOCUMENT_MACROEXECMODE_HPP_ 180 #include <com/sun/star/document/MacroExecMode.hpp> 181 #endif 182 #ifndef _COM_SUN_STAR_DRAWING_XDRAWPAGESUPPLIER_HPP_ 183 #include <com/sun/star/drawing/XDrawPageSupplier.hpp> 184 #endif 185 #ifndef _COM_SUN_STAR_CONTAINER_XINDEXCONTAINER_HPP_ 186 #include <com/sun/star/container/XIndexContainer.hpp> 187 #endif 188 #ifndef _COM_SUN_STAR_FORM_XFORMSSUPPLIER_HPP_ 189 #include <com/sun/star/form/XFormsSupplier.hpp> 190 #endif 191 #ifndef _COM_SUN_STAR_FORM_XFORM_HPP_ 192 #include <com/sun/star/form/XForm.hpp> 193 #endif 194 #ifndef _COMPHELPER_INTERACTION_HXX_ 195 #include <comphelper/interaction.hxx> 196 #endif 197 #ifndef _CONNECTIVITY_DBTOOLS_HXX_ 198 #include <connectivity/dbtools.hxx> 199 #endif 200 #ifndef _SV_SVAPP_HXX 201 #include <vcl/svapp.hxx> 202 #endif 203 #ifndef _VOS_MUTEX_HXX_ 204 #include <vos/mutex.hxx> 205 #endif 206 #ifndef _COM_SUN_STAR_VIEW_XVIEWSETTINGSSUPPLIER_HPP_ 207 #include <com/sun/star/view/XViewSettingsSupplier.hpp> 208 #endif 209 #ifndef _DBA_CORE_RESOURCE_HXX_ 210 #include "core_resource.hxx" 211 #endif 212 #ifndef _DBA_CORE_RESOURCE_HRC_ 213 #include "core_resource.hrc" 214 #endif 215 #ifndef _DBA_COREDATAACCESS_DATASOURCE_HXX_ 216 #include "datasource.hxx" 217 #endif 218 #ifndef _COM_SUN_STAR_EMBED_XSTATECHANGEBROADCASTER_HPP_ 219 #include <com/sun/star/embed/XStateChangeBroadcaster.hpp> 220 #endif 221 #ifndef _COM_SUN_STAR_TASK_XINTERACTIONAPPROVE_HPP_ 222 #include <com/sun/star/task/XInteractionApprove.hpp> 223 #endif 224 #ifndef _COM_SUN_STAR_TASK_XINTERACTIONDISAPPROVE_HPP_ 225 #include <com/sun/star/task/XInteractionDisapprove.hpp> 226 #endif 227 #ifndef _COM_SUN_STAR_FRAME_XLAYOUTMANAGER_HPP_ 228 #include <com/sun/star/frame/XLayoutManager.hpp> 229 #endif 230 #ifndef _CPPUHELPER_COMPBASE1_HXX_ 231 #include <cppuhelper/compbase1.hxx> 232 #endif 233 #include <cppuhelper/exc_hlp.hxx> 234 #ifndef _COM_SUN_STAR_FRAME_FRAMESEARCHFLAG_HPP_ 235 #include <com/sun/star/frame/FrameSearchFlag.hpp> 236 #endif 237 #ifndef _COMPHELPER_SEQUENCEASHASHMAP_HXX_ 238 #include <comphelper/sequenceashashmap.hxx> 239 #endif 240 #ifndef _COMPHELPER_MIMECONFIGHELPER_HXX_ 241 #include <comphelper/mimeconfighelper.hxx> 242 #endif 243 #ifndef _COMPHELPER_STORAGEHELPER_HXX 244 #include <comphelper/storagehelper.hxx> 245 #endif 246 #ifndef _COM_SUN_STAR_CONTAINER_XCONTENTENUMERATIONACCESS_HPP_ 247 #include <com/sun/star/container/XContentEnumerationAccess.hpp> 248 #endif 249 #include <com/sun/star/io/WrongFormatException.hpp> 250 #include <com/sun/star/sdb/application/XDatabaseDocumentUI.hpp> 251 #include <com/sun/star/sdb/application/DatabaseObject.hpp> 252 #include <com/sun/star/util/XModifiable2.hpp> 253 254 using namespace ::com::sun::star; 255 using namespace view; 256 using namespace uno; 257 using namespace util; 258 using namespace ucb; 259 using namespace beans; 260 using namespace lang; 261 using namespace awt; 262 using namespace embed; 263 using namespace frame; 264 using namespace document; 265 using namespace sdbc; 266 using namespace sdb; 267 using namespace io; 268 using namespace container; 269 using namespace datatransfer; 270 using namespace task; 271 using namespace form; 272 using namespace drawing; 273 using namespace ::osl; 274 using namespace ::comphelper; 275 using namespace ::cppu; 276 namespace css = ::com::sun::star; 277 278 using sdb::application::XDatabaseDocumentUI; 279 namespace DatabaseObject = sdb::application::DatabaseObject; 280 281 282 #define DEFAULT_WIDTH 10000 283 #define DEFAULT_HEIGHT 7500 284 //............................................................................. 285 namespace dbaccess 286 { 287 //............................................................................. 288 289 typedef ::boost::optional< bool > optional_bool; 290 291 //========================================================================= 292 //= helper 293 //========================================================================= 294 namespace 295 { 296 // -------------------------------------------------------------------- 297 ::rtl::OUString lcl_determineContentType_nothrow( const Reference< XStorage >& _rxContainerStorage, 298 const ::rtl::OUString& _rEntityName ) 299 { 300 ::rtl::OUString sContentType; 301 try 302 { 303 Reference< XStorage > xContainerStorage( _rxContainerStorage, UNO_QUERY_THROW ); 304 ::utl::SharedUNOComponent< XPropertySet > xStorageProps( 305 xContainerStorage->openStorageElement( _rEntityName, ElementModes::READ ), UNO_QUERY_THROW ); 306 OSL_VERIFY( xStorageProps->getPropertyValue( INFO_MEDIATYPE ) >>= sContentType ); 307 } 308 catch( const Exception& ) 309 { 310 DBG_UNHANDLED_EXCEPTION(); 311 } 312 return sContentType; 313 } 314 } 315 316 //================================================================== 317 // OEmbedObjectHolder 318 //================================================================== 319 typedef ::cppu::WeakComponentImplHelper1< embed::XStateChangeListener > TEmbedObjectHolder; 320 class OEmbedObjectHolder : public ::comphelper::OBaseMutex 321 ,public TEmbedObjectHolder 322 { 323 Reference< XEmbeddedObject > m_xBroadCaster; 324 ODocumentDefinition* m_pDefinition; 325 bool m_bInStateChange; 326 bool m_bInChangingState; 327 protected: 328 virtual void SAL_CALL disposing(); 329 public: 330 OEmbedObjectHolder(const Reference< XEmbeddedObject >& _xBroadCaster,ODocumentDefinition* _pDefinition) 331 : TEmbedObjectHolder(m_aMutex) 332 ,m_xBroadCaster(_xBroadCaster) 333 ,m_pDefinition(_pDefinition) 334 ,m_bInStateChange(false) 335 ,m_bInChangingState(false) 336 { 337 osl_incrementInterlockedCount( &m_refCount ); 338 { 339 if ( m_xBroadCaster.is() ) 340 m_xBroadCaster->addStateChangeListener(this); 341 } 342 osl_decrementInterlockedCount( &m_refCount ); 343 } 344 345 virtual void SAL_CALL changingState( const lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState ) throw (embed::WrongStateException, uno::RuntimeException); 346 virtual void SAL_CALL stateChanged( const lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState ) throw (uno::RuntimeException); 347 virtual void SAL_CALL disposing( const lang::EventObject& Source ) throw (uno::RuntimeException); 348 }; 349 //------------------------------------------------------------------ 350 void SAL_CALL OEmbedObjectHolder::disposing() 351 { 352 if ( m_xBroadCaster.is() ) 353 m_xBroadCaster->removeStateChangeListener(this); 354 m_xBroadCaster = NULL; 355 m_pDefinition = NULL; 356 } 357 //------------------------------------------------------------------ 358 void SAL_CALL OEmbedObjectHolder::changingState( const lang::EventObject& /*aEvent*/, ::sal_Int32 nOldState, ::sal_Int32 nNewState ) throw (embed::WrongStateException, uno::RuntimeException) 359 { 360 if ( !m_bInChangingState && nNewState == EmbedStates::RUNNING && nOldState == EmbedStates::ACTIVE && m_pDefinition ) 361 { 362 m_bInChangingState = true; 363 //m_pDefinition->save(sal_False); 364 m_bInChangingState = false; 365 } 366 } 367 //------------------------------------------------------------------ 368 void SAL_CALL OEmbedObjectHolder::stateChanged( const lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState ) throw (uno::RuntimeException) 369 { 370 if ( !m_bInStateChange && nNewState == EmbedStates::RUNNING && nOldState == EmbedStates::ACTIVE && m_pDefinition ) 371 { 372 m_bInStateChange = true; 373 Reference<XInterface> xInt(static_cast< ::cppu::OWeakObject* >(m_pDefinition),UNO_QUERY); 374 { 375 Reference<XEmbeddedObject> xEmbeddedObject(aEvent.Source,UNO_QUERY); 376 if ( xEmbeddedObject.is() ) 377 xEmbeddedObject->changeState(EmbedStates::LOADED); 378 } 379 m_bInStateChange = false; 380 } 381 } 382 //------------------------------------------------------------------ 383 void SAL_CALL OEmbedObjectHolder::disposing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException) 384 { 385 m_xBroadCaster = NULL; 386 } 387 388 //================================================================== 389 // OEmbeddedClientHelper 390 //================================================================== 391 typedef ::cppu::WeakImplHelper1 < XEmbeddedClient 392 > EmbeddedClientHelper_BASE; 393 class OEmbeddedClientHelper : public EmbeddedClientHelper_BASE 394 { 395 ODocumentDefinition* m_pClient; 396 public: 397 OEmbeddedClientHelper(ODocumentDefinition* _pClient) :m_pClient(_pClient) {} 398 399 virtual void SAL_CALL saveObject( ) throw (ObjectSaveVetoException, Exception, RuntimeException) 400 { 401 } 402 virtual void SAL_CALL onShowWindow( sal_Bool /*bVisible*/ ) throw (RuntimeException) 403 { 404 } 405 // XComponentSupplier 406 virtual Reference< util::XCloseable > SAL_CALL getComponent( ) throw (RuntimeException) 407 { 408 return Reference< css::util::XCloseable >(); 409 } 410 411 // XEmbeddedClient 412 virtual void SAL_CALL visibilityChanged( ::sal_Bool /*bVisible*/ ) throw (WrongStateException, RuntimeException) 413 { 414 } 415 inline void resetClient(ODocumentDefinition* _pClient) { m_pClient = _pClient; } 416 }; 417 418 //================================================================== 419 // LockModifiable 420 //================================================================== 421 class LockModifiable 422 { 423 public: 424 LockModifiable( const Reference< XInterface >& i_rModifiable ) 425 :m_xModifiable( i_rModifiable, UNO_QUERY ) 426 { 427 OSL_ENSURE( m_xModifiable.is(), "LockModifiable::LockModifiable: invalid component!" ); 428 if ( m_xModifiable.is() ) 429 { 430 if ( !m_xModifiable->isSetModifiedEnabled() ) 431 { 432 // somebody already locked that, no need to lock it, again, and no need to unlock it later 433 m_xModifiable.clear(); 434 } 435 else 436 { 437 m_xModifiable->disableSetModified(); 438 } 439 } 440 } 441 442 ~LockModifiable() 443 { 444 if ( m_xModifiable.is() ) 445 m_xModifiable->enableSetModified(); 446 } 447 448 private: 449 Reference< XModifiable2 > m_xModifiable; 450 }; 451 452 //================================================================== 453 // LifetimeCoupler 454 //================================================================== 455 typedef ::cppu::WeakImplHelper1 < css::lang::XEventListener 456 > LifetimeCoupler_Base; 457 /** helper class which couples the lifetime of a component to the lifetime 458 of another component 459 460 Instances of this class are constructed with two components. The first is 461 simply held by reference, and thus kept alive. The second one is observed 462 for <code>disposing</code> calls - if they occur, i.e. if the component dies, 463 the reference to the first component is cleared. 464 465 This way, you can ensure that a certain component is kept alive as long 466 as a second component is not disposed. 467 */ 468 class LifetimeCoupler : public LifetimeCoupler_Base 469 { 470 private: 471 Reference< XInterface > m_xClient; 472 473 public: 474 inline static void couple( const Reference< XInterface >& _rxClient, const Reference< XComponent >& _rxActor ) 475 { 476 Reference< css::lang::XEventListener > xEnsureDelete( new LifetimeCoupler( _rxClient, _rxActor ) ); 477 } 478 479 private: 480 inline LifetimeCoupler( const Reference< XInterface >& _rxClient, const Reference< XComponent >& _rxActor ) 481 :m_xClient( _rxClient ) 482 { 483 DBG_ASSERT( _rxActor.is(), "LifetimeCoupler::LifetimeCoupler: this will crash!" ); 484 osl_incrementInterlockedCount( &m_refCount ); 485 { 486 _rxActor->addEventListener( this ); 487 } 488 osl_decrementInterlockedCount( &m_refCount ); 489 DBG_ASSERT( m_refCount, "LifetimeCoupler::LifetimeCoupler: the actor is not holding us by hard ref - this won't work!" ); 490 } 491 492 virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) throw (RuntimeException); 493 protected: 494 }; 495 496 //------------------------------------------------------------------ 497 void SAL_CALL LifetimeCoupler::disposing( const css::lang::EventObject& /*Source*/ ) throw (RuntimeException) 498 { 499 m_xClient.clear(); 500 } 501 502 //================================================================== 503 // ODocumentSaveContinuation 504 //================================================================== 505 class ODocumentSaveContinuation : public OInteraction< XInteractionDocumentSave > 506 { 507 ::rtl::OUString m_sName; 508 Reference<XContent> m_xParentContainer; 509 510 public: 511 ODocumentSaveContinuation() { } 512 513 inline Reference<XContent> getContent() const { return m_xParentContainer; } 514 inline ::rtl::OUString getName() const { return m_sName; } 515 516 // XInteractionDocumentSave 517 virtual void SAL_CALL setName( const ::rtl::OUString& _sName,const Reference<XContent>& _xParent) throw(RuntimeException); 518 }; 519 520 //------------------------------------------------------------------ 521 void SAL_CALL ODocumentSaveContinuation::setName( const ::rtl::OUString& _sName,const Reference<XContent>& _xParent) throw(RuntimeException) 522 { 523 m_sName = _sName; 524 m_xParentContainer = _xParent; 525 } 526 527 // ----------------------------------------------------------------------------- 528 ::rtl::OUString ODocumentDefinition::GetDocumentServiceFromMediaType( const Reference< XStorage >& _rxContainerStorage, 529 const ::rtl::OUString& _rEntityName, const ::comphelper::ComponentContext& _rContext, 530 Sequence< sal_Int8 >& _rClassId ) 531 { 532 return GetDocumentServiceFromMediaType( 533 lcl_determineContentType_nothrow( _rxContainerStorage, _rEntityName ), 534 _rContext, _rClassId ); 535 } 536 537 // ----------------------------------------------------------------------------- 538 ::rtl::OUString ODocumentDefinition::GetDocumentServiceFromMediaType( const ::rtl::OUString& _rMediaType, 539 const ::comphelper::ComponentContext& _rContext, Sequence< sal_Int8 >& _rClassId ) 540 { 541 ::rtl::OUString sResult; 542 try 543 { 544 ::comphelper::MimeConfigurationHelper aConfigHelper( _rContext.getLegacyServiceFactory() ); 545 sResult = aConfigHelper.GetDocServiceNameFromMediaType( _rMediaType ); 546 _rClassId = aConfigHelper.GetSequenceClassIDRepresentation(aConfigHelper.GetExplicitlyRegisteredObjClassID( _rMediaType )); 547 if ( !_rClassId.getLength() && sResult.getLength() ) 548 { 549 Reference< XNameAccess > xObjConfig = aConfigHelper.GetObjConfiguration(); 550 if ( xObjConfig.is() ) 551 { 552 Sequence< ::rtl::OUString > aClassIDs = xObjConfig->getElementNames(); 553 for ( sal_Int32 nInd = 0; nInd < aClassIDs.getLength(); nInd++ ) 554 { 555 Reference< XNameAccess > xObjectProps; 556 ::rtl::OUString aEntryDocName; 557 558 if ( ( xObjConfig->getByName( aClassIDs[nInd] ) >>= xObjectProps ) && xObjectProps.is() 559 && ( xObjectProps->getByName(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ObjectDocumentServiceName")) 560 ) >>= aEntryDocName ) 561 && aEntryDocName.equals( sResult ) ) 562 { 563 _rClassId = aConfigHelper.GetSequenceClassIDRepresentation(aClassIDs[nInd]); 564 break; 565 } 566 } 567 } 568 } 569 #if OSL_DEBUG_LEVEL > 0 570 // alternative, shorter approach 571 const Sequence< NamedValue > aProps( aConfigHelper.GetObjectPropsByMediaType( _rMediaType ) ); 572 const ::comphelper::NamedValueCollection aMediaTypeProps( aProps ); 573 const ::rtl::OUString sAlternativeResult = aMediaTypeProps.getOrDefault( "ObjectDocumentServiceName", ::rtl::OUString() ); 574 OSL_ENSURE( sAlternativeResult == sResult, "ODocumentDefinition::GetDocumentServiceFromMediaType: failed, this approach is *not* equivalent (1)!" ); 575 const Sequence< sal_Int8 > aAlternativeClassID = aMediaTypeProps.getOrDefault( "ClassID", Sequence< sal_Int8 >() ); 576 OSL_ENSURE( aAlternativeClassID == _rClassId, "ODocumentDefinition::GetDocumentServiceFromMediaType: failed, this approach is *not* equivalent (2)!" ); 577 #endif 578 } 579 catch ( Exception& ) 580 { 581 DBG_UNHANDLED_EXCEPTION(); 582 } 583 return sResult; 584 } 585 // ----------------------------------------------------------------------------- 586 //========================================================================== 587 //= ODocumentDefinition 588 //========================================================================== 589 DBG_NAME(ODocumentDefinition) 590 591 //-------------------------------------------------------------------------- 592 ODocumentDefinition::ODocumentDefinition( const Reference< XInterface >& _rxContainer, const Reference< XMultiServiceFactory >& _xORB, 593 const TContentPtr& _pImpl, sal_Bool _bForm ) 594 :OContentHelper(_xORB,_rxContainer,_pImpl) 595 ,OPropertyStateContainer(OContentHelper::rBHelper) 596 ,m_pInterceptor(NULL) 597 ,m_bForm(_bForm) 598 ,m_bOpenInDesign(sal_False) 599 ,m_bInExecute(sal_False) 600 ,m_bRemoveListener(sal_False) 601 ,m_pClientHelper(NULL) 602 { 603 DBG_CTOR(ODocumentDefinition, NULL); 604 registerProperties(); 605 } 606 607 //-------------------------------------------------------------------------- 608 void ODocumentDefinition::initialLoad( const Sequence< sal_Int8 >& i_rClassID, const Sequence< PropertyValue >& i_rCreationArgs, 609 const Reference< XConnection >& i_rConnection ) 610 { 611 OSL_ENSURE( i_rClassID.getLength(), "ODocumentDefinition::initialLoad: illegal class ID!" ); 612 if ( !i_rClassID.getLength() ) 613 return; 614 615 loadEmbeddedObject( i_rConnection, i_rClassID, i_rCreationArgs, false, false ); 616 } 617 618 //-------------------------------------------------------------------------- 619 ODocumentDefinition::~ODocumentDefinition() 620 { 621 DBG_DTOR(ODocumentDefinition, NULL); 622 if ( !OContentHelper::rBHelper.bInDispose && !OContentHelper::rBHelper.bDisposed ) 623 { 624 acquire(); 625 dispose(); 626 } 627 628 if ( m_pInterceptor ) 629 { 630 m_pInterceptor->dispose(); 631 m_pInterceptor->release(); 632 m_pInterceptor = NULL; 633 } 634 } 635 // ----------------------------------------------------------------------------- 636 void ODocumentDefinition::closeObject() 637 { 638 ::osl::MutexGuard aGuard(m_aMutex); 639 if ( m_xEmbeddedObject.is() ) 640 { 641 try 642 { 643 Reference< com::sun::star::util::XCloseable> xCloseable(m_xEmbeddedObject,UNO_QUERY); 644 if ( xCloseable.is() ) 645 xCloseable->close(sal_True); 646 } 647 catch(Exception) 648 { 649 } 650 m_xEmbeddedObject = NULL; 651 if ( m_pClientHelper ) 652 { 653 m_pClientHelper->resetClient(NULL); 654 m_pClientHelper->release(); 655 m_pClientHelper = NULL; 656 } 657 } 658 } 659 // ----------------------------------------------------------------------------- 660 void SAL_CALL ODocumentDefinition::disposing() 661 { 662 OContentHelper::disposing(); 663 ::osl::MutexGuard aGuard(m_aMutex); 664 closeObject(); 665 ::comphelper::disposeComponent(m_xListener); 666 if ( m_bRemoveListener ) 667 { 668 Reference<util::XCloseable> xCloseable(m_pImpl->m_pDataSource->getModel_noCreate(),UNO_QUERY); 669 if ( xCloseable.is() ) 670 xCloseable->removeCloseListener(this); 671 } 672 } 673 // ----------------------------------------------------------------------------- 674 IMPLEMENT_TYPEPROVIDER3(ODocumentDefinition,OContentHelper,OPropertyStateContainer,ODocumentDefinition_Base); 675 IMPLEMENT_FORWARD_XINTERFACE3( ODocumentDefinition,OContentHelper,OPropertyStateContainer,ODocumentDefinition_Base) 676 IMPLEMENT_SERVICE_INFO1(ODocumentDefinition,"com.sun.star.comp.dba.ODocumentDefinition",SERVICE_SDB_DOCUMENTDEFINITION) 677 //-------------------------------------------------------------------------- 678 void ODocumentDefinition::registerProperties() 679 { 680 #define REGISTER_PROPERTY( name, location ) \ 681 registerProperty( PROPERTY_##name, PROPERTY_ID_##name, PropertyAttribute::READONLY, &location, ::getCppuType( &location ) ); 682 683 #define REGISTER_PROPERTY_BV( name, location ) \ 684 registerProperty( PROPERTY_##name, PROPERTY_ID_##name, PropertyAttribute::CONSTRAINED | PropertyAttribute::BOUND | PropertyAttribute::READONLY, &location, ::getCppuType( &location ) ); 685 686 REGISTER_PROPERTY_BV( NAME, m_pImpl->m_aProps.aTitle ); 687 REGISTER_PROPERTY ( AS_TEMPLATE, m_pImpl->m_aProps.bAsTemplate ); 688 REGISTER_PROPERTY ( PERSISTENT_NAME, m_pImpl->m_aProps.sPersistentName ); 689 REGISTER_PROPERTY ( IS_FORM, m_bForm ); 690 } 691 692 // ----------------------------------------------------------------------------- 693 void SAL_CALL ODocumentDefinition::getFastPropertyValue( Any& o_rValue, sal_Int32 i_nHandle ) const 694 { 695 if ( i_nHandle == PROPERTY_ID_PERSISTENT_PATH ) 696 { 697 ::rtl::OUString sPersistentPath; 698 if ( m_pImpl->m_aProps.sPersistentName.getLength() ) 699 { 700 ::rtl::OUStringBuffer aBuffer; 701 aBuffer.append( ODatabaseModelImpl::getObjectContainerStorageName( m_bForm ? ODatabaseModelImpl::E_FORM : ODatabaseModelImpl::E_REPORT ) ); 702 aBuffer.append( sal_Unicode( '/' ) ); 703 aBuffer.append( m_pImpl->m_aProps.sPersistentName ); 704 sPersistentPath = aBuffer.makeStringAndClear(); 705 } 706 o_rValue <<= sPersistentPath; 707 return; 708 } 709 710 OPropertyStateContainer::getFastPropertyValue( o_rValue, i_nHandle ); 711 } 712 713 // ----------------------------------------------------------------------------- 714 Reference< XPropertySetInfo > SAL_CALL ODocumentDefinition::getPropertySetInfo( ) throw(RuntimeException) 715 { 716 Reference<XPropertySetInfo> xInfo( createPropertySetInfo( getInfoHelper() ) ); 717 return xInfo; 718 } 719 720 //-------------------------------------------------------------------------- 721 IPropertyArrayHelper& ODocumentDefinition::getInfoHelper() 722 { 723 return *getArrayHelper(); 724 } 725 726 727 //-------------------------------------------------------------------------- 728 IPropertyArrayHelper* ODocumentDefinition::createArrayHelper( ) const 729 { 730 // properties maintained by our base class (see registerProperties) 731 Sequence< Property > aProps; 732 describeProperties( aProps ); 733 734 // properties not maintained by our base class 735 Sequence< Property > aManualProps( 1 ); 736 aManualProps[0].Name = PROPERTY_PERSISTENT_PATH; 737 aManualProps[0].Handle = PROPERTY_ID_PERSISTENT_PATH; 738 aManualProps[0].Type = ::getCppuType( static_cast< const ::rtl::OUString* >( NULL ) ); 739 aManualProps[0].Attributes = PropertyAttribute::READONLY; 740 741 return new OPropertyArrayHelper( ::comphelper::concatSequences( aProps, aManualProps ) ); 742 } 743 744 // ----------------------------------------------------------------------------- 745 class OExecuteImpl 746 { 747 sal_Bool& m_rbSet; 748 public: 749 OExecuteImpl(sal_Bool& _rbSet) : m_rbSet(_rbSet){ m_rbSet=sal_True; } 750 ~OExecuteImpl(){ m_rbSet = sal_False; } 751 }; 752 753 // ----------------------------------------------------------------------------- 754 namespace 755 { 756 bool lcl_extractOpenMode( const Any& _rValue, sal_Int32& _out_rMode ) 757 { 758 OpenCommandArgument aOpenCommand; 759 if ( _rValue >>= aOpenCommand ) 760 _out_rMode = aOpenCommand.Mode; 761 else 762 { 763 OpenCommandArgument2 aOpenCommand2; 764 if ( _rValue >>= aOpenCommand2 ) 765 _out_rMode = aOpenCommand2.Mode; 766 else 767 return false; 768 } 769 return true; 770 } 771 } 772 773 // ----------------------------------------------------------------------------- 774 void ODocumentDefinition::impl_removeFrameFromDesktop_throw( const ::comphelper::ComponentContext& _rContxt, const Reference< XFrame >& _rxFrame ) 775 { 776 Reference< XFramesSupplier > xDesktop( _rContxt.createComponent( (::rtl::OUString)SERVICE_FRAME_DESKTOP ), UNO_QUERY_THROW ); 777 Reference< XFrames > xFrames( xDesktop->getFrames(), UNO_QUERY_THROW ); 778 xFrames->remove( _rxFrame ); 779 } 780 781 // ----------------------------------------------------------------------------- 782 void ODocumentDefinition::impl_onActivateEmbeddedObject_nothrow( const bool i_bReactivated ) 783 { 784 try 785 { 786 Reference< XModel > xModel( getComponent(), UNO_QUERY ); 787 Reference< XController > xController( xModel.is() ? xModel->getCurrentController() : Reference< XController >() ); 788 if ( !xController.is() ) 789 return; 790 791 if ( !m_xListener.is() ) 792 // it's the first time the embedded object has been activated 793 // create an OEmbedObjectHolder 794 m_xListener = new OEmbedObjectHolder( m_xEmbeddedObject, this ); 795 796 // raise the window to top (especially necessary if this is not the first activation) 797 Reference< XFrame > xFrame( xController->getFrame(), UNO_SET_THROW ); 798 Reference< XTopWindow > xTopWindow( xFrame->getContainerWindow(), UNO_QUERY_THROW ); 799 xTopWindow->toFront(); 800 801 // remove the frame from the desktop's frame collection because we need full control of it. 802 impl_removeFrameFromDesktop_throw( m_aContext, xFrame ); 803 804 // ensure that we ourself are kept alive as long as the embedded object's frame is 805 // opened 806 LifetimeCoupler::couple( *this, xFrame.get() ); 807 808 // init the edit view 809 if ( m_bForm && m_bOpenInDesign && !i_bReactivated ) 810 impl_initFormEditView( xController ); 811 } 812 catch( const RuntimeException& ) 813 { 814 DBG_UNHANDLED_EXCEPTION(); 815 } 816 } 817 818 // ----------------------------------------------------------------------------- 819 namespace 820 { 821 // ========================================================================= 822 // = PreserveVisualAreaSize 823 // ========================================================================= 824 /** stack-guard for preserving the size of the VisArea of an XModel 825 */ 826 class PreserveVisualAreaSize 827 { 828 private: 829 Reference< XVisualObject > m_xVisObject; 830 awt::Size m_aOriginalSize; 831 832 public: 833 inline PreserveVisualAreaSize( const Reference< XModel >& _rxModel ) 834 :m_xVisObject( _rxModel, UNO_QUERY ) 835 { 836 if ( m_xVisObject.is() ) 837 { 838 try 839 { 840 m_aOriginalSize = m_xVisObject->getVisualAreaSize( Aspects::MSOLE_CONTENT ); 841 } 842 catch ( Exception& ) 843 { 844 DBG_ERROR( "PreserveVisualAreaSize::PreserveVisualAreaSize: caught an exception!" ); 845 } 846 } 847 } 848 849 inline ~PreserveVisualAreaSize() 850 { 851 if ( m_xVisObject.is() && m_aOriginalSize.Width && m_aOriginalSize.Height ) 852 { 853 try 854 { 855 m_xVisObject->setVisualAreaSize( Aspects::MSOLE_CONTENT, m_aOriginalSize ); 856 } 857 catch ( Exception& ) 858 { 859 DBG_ERROR( "PreserveVisualAreaSize::~PreserveVisualAreaSize: caught an exception!" ); 860 } 861 } 862 } 863 }; 864 865 // ========================================================================= 866 // = LayoutManagerLock 867 // ========================================================================= 868 /** helper class for stack-usage which during its lifetime locks a layout manager 869 */ 870 class LayoutManagerLock 871 { 872 private: 873 Reference< XLayoutManager > m_xLayoutManager; 874 875 public: 876 inline LayoutManagerLock( const Reference< XController >& _rxController ) 877 { 878 DBG_ASSERT( _rxController.is(), "LayoutManagerLock::LayoutManagerLock: this will crash!" ); 879 Reference< XFrame > xFrame( _rxController->getFrame() ); 880 try 881 { 882 Reference< XPropertySet > xPropSet( xFrame, UNO_QUERY_THROW ); 883 m_xLayoutManager.set( 884 xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ) ) ), 885 UNO_QUERY_THROW ); 886 m_xLayoutManager->lock(); 887 888 } 889 catch( Exception& ) 890 { 891 DBG_ERROR( "LayoutManagerLock::LayoutManagerLock: caught an exception!" ); 892 } 893 } 894 895 inline ~LayoutManagerLock() 896 { 897 try 898 { 899 // unlock the layout manager 900 if ( m_xLayoutManager.is() ) 901 m_xLayoutManager->unlock(); 902 } 903 catch( Exception& ) 904 { 905 DBG_ERROR( "LayoutManagerLock::~LayoutManagerLock: caught an exception!" ); 906 } 907 } 908 }; 909 } 910 911 // ----------------------------------------------------------------------------- 912 void ODocumentDefinition::impl_initFormEditView( const Reference< XController >& _rxController ) 913 { 914 try 915 { 916 Reference< XViewSettingsSupplier > xSettingsSupplier( _rxController, UNO_QUERY_THROW ); 917 Reference< XPropertySet > xViewSettings( xSettingsSupplier->getViewSettings(), UNO_QUERY_THROW ); 918 919 // the below code could indirectly tamper with the "modified" flag of the model, temporarily disable this 920 LockModifiable aLockModify( _rxController->getModel() ); 921 922 // The visual area size can be changed by the setting of the following properties 923 // so it should be restored later 924 PreserveVisualAreaSize aPreserveVisAreaSize( _rxController->getModel() ); 925 926 // Layout manager should not layout while the size is still not restored 927 // so it will stay locked for this time 928 LayoutManagerLock aLockLayout( _rxController ); 929 930 // setting of the visual properties 931 xViewSettings->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowRulers")),makeAny(sal_True)); 932 xViewSettings->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowVertRuler")),makeAny(sal_True)); 933 xViewSettings->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowHoriRuler")),makeAny(sal_True)); 934 xViewSettings->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsRasterVisible")),makeAny(sal_True)); 935 xViewSettings->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsSnapToRaster")),makeAny(sal_True)); 936 xViewSettings->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ShowOnlineLayout")),makeAny(sal_True)); 937 xViewSettings->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RasterSubdivisionX")),makeAny(sal_Int32(5))); 938 xViewSettings->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RasterSubdivisionY")),makeAny(sal_Int32(5))); 939 } 940 catch( const Exception& ) 941 { 942 DBG_UNHANDLED_EXCEPTION(); 943 } 944 } 945 946 // ----------------------------------------------------------------------------- 947 void ODocumentDefinition::impl_showOrHideComponent_throw( const bool i_bShow ) 948 { 949 const sal_Int32 nCurrentState = m_xEmbeddedObject.is() ? m_xEmbeddedObject->getCurrentState() : EmbedStates::LOADED; 950 switch ( nCurrentState ) 951 { 952 default: 953 case EmbedStates::LOADED: 954 throw embed::WrongStateException( ::rtl::OUString(), *this ); 955 956 case EmbedStates::RUNNING: 957 if ( !i_bShow ) 958 // fine, a running (and not yet active) object is never visible 959 return; 960 { 961 LockModifiable aLockModify( impl_getComponent_throw() ); 962 m_xEmbeddedObject->changeState( EmbedStates::ACTIVE ); 963 impl_onActivateEmbeddedObject_nothrow( false ); 964 } 965 break; 966 967 case EmbedStates::ACTIVE: 968 { 969 Reference< XModel > xEmbeddedDoc( impl_getComponent_throw( true ), UNO_QUERY_THROW ); 970 Reference< XController > xEmbeddedController( xEmbeddedDoc->getCurrentController(), UNO_SET_THROW ); 971 Reference< XFrame > xEmbeddedFrame( xEmbeddedController->getFrame(), UNO_SET_THROW ); 972 Reference< XWindow > xEmbeddedWindow( xEmbeddedFrame->getContainerWindow(), UNO_SET_THROW ); 973 xEmbeddedWindow->setVisible( i_bShow ); 974 } 975 break; 976 } 977 } 978 979 // ----------------------------------------------------------------------------- 980 Any ODocumentDefinition::onCommandOpenSomething( const Any& _rOpenArgument, const bool _bActivate, 981 const Reference< XCommandEnvironment >& _rxEnvironment ) 982 { 983 OExecuteImpl aExecuteGuard( m_bInExecute ); 984 985 Reference< XConnection > xConnection; 986 sal_Int32 nOpenMode = OpenMode::DOCUMENT; 987 988 ::comphelper::NamedValueCollection aDocumentArgs; 989 990 // for the document, default to the interaction handler as used for loading the DB doc 991 // This might be overwritten below, when examining _rOpenArgument. 992 const ::comphelper::NamedValueCollection& aDBDocArgs( m_pImpl->m_pDataSource->getMediaDescriptor() ); 993 Reference< XInteractionHandler > xHandler( aDBDocArgs.getOrDefault( "InteractionHandler", Reference< XInteractionHandler >() ) ); 994 if ( xHandler.is() ) 995 aDocumentArgs.put( "InteractionHandler", xHandler ); 996 997 ::boost::optional< sal_Int16 > aDocumentMacroMode; 998 999 if ( !lcl_extractOpenMode( _rOpenArgument, nOpenMode ) ) 1000 { 1001 Sequence< PropertyValue > aArguments; 1002 if ( _rOpenArgument >>= aArguments ) 1003 { 1004 const PropertyValue* pIter = aArguments.getConstArray(); 1005 const PropertyValue* pEnd = pIter + aArguments.getLength(); 1006 for ( ;pIter != pEnd; ++pIter ) 1007 { 1008 if ( pIter->Name == PROPERTY_ACTIVE_CONNECTION ) 1009 { 1010 xConnection.set( pIter->Value, UNO_QUERY ); 1011 continue; 1012 } 1013 1014 if ( lcl_extractOpenMode( pIter->Value, nOpenMode ) ) 1015 continue; 1016 1017 if ( pIter->Name.equalsAscii( "MacroExecutionMode" ) ) 1018 { 1019 sal_Int16 nMacroExecMode( !aDocumentMacroMode ? MacroExecMode::USE_CONFIG : *aDocumentMacroMode ); 1020 OSL_VERIFY( pIter->Value >>= nMacroExecMode ); 1021 aDocumentMacroMode.reset( nMacroExecMode ); 1022 continue; 1023 } 1024 1025 // unknown argument -> pass to the loaded document 1026 aDocumentArgs.put( pIter->Name, pIter->Value ); 1027 } 1028 } 1029 } 1030 1031 bool bExecuteDBDocMacros = m_pImpl->m_pDataSource->checkMacrosOnLoading(); 1032 // Note that this call implies the user might be asked for the macro execution mode. 1033 // Normally, this would happen when the database document is loaded, and subsequent calls 1034 // will simply use the user's decision from this point in time. 1035 // However, it is possible to programmatically load forms/reports, without actually 1036 // loading the database document into a frame. In this case, the user will be asked 1037 // here and now. 1038 // #i87741# / 2008-05-05 / frank.schoenheit@sun.com 1039 1040 // allow the command arguments to downgrade the macro execution mode, but not to upgrade 1041 // it 1042 if ( ( m_pImpl->m_pDataSource->getImposedMacroExecMode() == MacroExecMode::USE_CONFIG ) 1043 && bExecuteDBDocMacros 1044 ) 1045 { 1046 // while loading the whole database document, USE_CONFIG, was passed. 1047 // Additionally, *by now* executing macros from the DB doc is allowed (this is what bExecuteDBDocMacros 1048 // indicates). This means either one of: 1049 // 1. The DB doc or one of the sub docs contained macros and 1050 // 1a. the user explicitly allowed executing them 1051 // 1b. the configuration allows executing them without asking the user 1052 // 2. Neither the DB doc nor the sub docs contained macros, thus macro 1053 // execution was silently enabled, assuming that any macro will be a 1054 // user-created macro 1055 // 1056 // The problem with this: If the to-be-opened sub document has macros embedded in 1057 // the content.xml (which is valid ODF, but normally not produced by OOo itself), 1058 // then this has not been detected while loading the database document - it would 1059 // be too expensive, as it effectively would require loading all forms/reports. 1060 // 1061 // So, in such a case, and with 2. above, we would silently execute those macros, 1062 // regardless of the global security settings - which would be a security issue, of 1063 // course. 1064 if ( m_pImpl->m_pDataSource->determineEmbeddedMacros() == ODatabaseModelImpl::eNoMacros ) 1065 { 1066 // this is case 2. from above 1067 // So, pass a USE_CONFIG to the to-be-loaded document. This means that 1068 // the user will be prompted with a security message upon opening this 1069 // sub document, in case the settings require this, *and* the document 1070 // contains scripts in the content.xml. But this is better than the security 1071 // issue we had before ... 1072 aDocumentMacroMode.reset( MacroExecMode::USE_CONFIG ); 1073 } 1074 } 1075 1076 if ( !aDocumentMacroMode ) 1077 { 1078 // nobody so far felt responsible for setting it 1079 // => use the DBDoc-wide macro exec mode for the document, too 1080 aDocumentMacroMode.reset( bExecuteDBDocMacros ? MacroExecMode::ALWAYS_EXECUTE_NO_WARN : MacroExecMode::NEVER_EXECUTE ); 1081 } 1082 aDocumentArgs.put( "MacroExecutionMode", *aDocumentMacroMode ); 1083 1084 if ( ( nOpenMode == OpenMode::ALL ) 1085 || ( nOpenMode == OpenMode::FOLDERS ) 1086 || ( nOpenMode == OpenMode::DOCUMENTS ) 1087 || ( nOpenMode == OpenMode::DOCUMENT_SHARE_DENY_NONE ) 1088 || ( nOpenMode == OpenMode::DOCUMENT_SHARE_DENY_WRITE ) 1089 ) 1090 { 1091 // not supported 1092 ucbhelper::cancelCommandExecution( 1093 makeAny( UnsupportedOpenModeException( 1094 rtl::OUString(), 1095 static_cast< cppu::OWeakObject * >( this ), 1096 sal_Int16( nOpenMode ) ) ), 1097 _rxEnvironment ); 1098 // Unreachable 1099 DBG_ERROR( "unreachable" ); 1100 } 1101 1102 OSL_ENSURE( m_pImpl->m_aProps.sPersistentName.getLength(), 1103 "ODocumentDefinition::onCommandOpenSomething: no persistent name - cannot load!" ); 1104 if ( !m_pImpl->m_aProps.sPersistentName.getLength() ) 1105 return Any(); 1106 1107 // embedded objects themself do not support the hidden flag. We implement support for 1108 // it by changing the STATE to RUNNING only, instead of ACTIVE. 1109 bool bOpenHidden = aDocumentArgs.getOrDefault( "Hidden", false ); 1110 aDocumentArgs.remove( "Hidden" ); 1111 1112 loadEmbeddedObject( xConnection, Sequence< sal_Int8 >(), aDocumentArgs.getPropertyValues(), false, !m_bOpenInDesign ); 1113 OSL_ENSURE( m_xEmbeddedObject.is(), "ODocumentDefinition::onCommandOpenSomething: what's this?" ); 1114 if ( !m_xEmbeddedObject.is() ) 1115 return Any(); 1116 1117 Reference< XModel > xModel( getComponent(), UNO_QUERY ); 1118 Reference< report::XReportDefinition > xReportDefinition(xModel,UNO_QUERY); 1119 1120 Reference< XModule > xModule( xModel, UNO_QUERY ); 1121 if ( xModule.is() ) 1122 { 1123 if ( m_bForm ) 1124 xModule->setIdentifier( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.FormDesign" ) ) ); 1125 else if ( !xReportDefinition.is() ) 1126 xModule->setIdentifier( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.TextReportDesign" ) ) ); 1127 1128 updateDocumentTitle(); 1129 } 1130 1131 bool bIsAliveNewStyleReport = ( !m_bOpenInDesign && xReportDefinition.is() ); 1132 if ( bIsAliveNewStyleReport ) 1133 { 1134 // we are in ReadOnly mode 1135 // we would like to open the Writer or Calc with the report direct, without design it. 1136 Reference< report::XReportEngine > xReportEngine( m_aContext.createComponent( "com.sun.star.comp.report.OReportEngineJFree" ), UNO_QUERY_THROW ); 1137 1138 xReportEngine->setReportDefinition(xReportDefinition); 1139 xReportEngine->setActiveConnection(m_xLastKnownConnection); 1140 if ( bOpenHidden ) 1141 return makeAny( xReportEngine->createDocumentModel() ); 1142 return makeAny( xReportEngine->createDocumentAlive( NULL ) ); 1143 } 1144 1145 if ( _bActivate && !bOpenHidden ) 1146 { 1147 LockModifiable aLockModify( impl_getComponent_throw() ); 1148 m_xEmbeddedObject->changeState( EmbedStates::ACTIVE ); 1149 impl_onActivateEmbeddedObject_nothrow( false ); 1150 } 1151 else 1152 { 1153 // ensure that we ourself are kept alive as long as the document is open 1154 LifetimeCoupler::couple( *this, xModel.get() ); 1155 } 1156 1157 if ( !m_bForm && m_pImpl->m_aProps.bAsTemplate && !m_bOpenInDesign ) 1158 ODocumentDefinition::fillReportData( m_aContext, getComponent(), xConnection ); 1159 1160 return makeAny( xModel ); 1161 } 1162 1163 // ----------------------------------------------------------------------------- 1164 Any SAL_CALL ODocumentDefinition::execute( const Command& aCommand, sal_Int32 CommandId, const Reference< XCommandEnvironment >& Environment ) throw (Exception, CommandAbortedException, RuntimeException) 1165 { 1166 Any aRet; 1167 1168 sal_Bool bOpen = aCommand.Name.equalsAscii( "open" ); 1169 sal_Bool bOpenInDesign = aCommand.Name.equalsAscii( "openDesign" ); 1170 sal_Bool bOpenForMail = aCommand.Name.equalsAscii( "openForMail" ); 1171 if ( bOpen || bOpenInDesign || bOpenForMail ) 1172 { 1173 // opening the document involves a lot of VCL code, which is not thread-safe, but needs the SolarMutex locked. 1174 // Unfortunately, the DocumentDefinition, as well as the EmbeddedObject implementation, calls into VCL-dependent 1175 // components *without* releasing the own mutex, which is a guaranteed recipe for deadlocks. 1176 // We have control over this implementation here, and in modifying it to release the own mutex before calling into 1177 // the VCL-dependent components is not too difficult (was there, seen it). 1178 // However, we do /not/ have control over the EmbeddedObject implementation, and from a first look, it seems as 1179 // making it release the own mutex before calling SolarMutex-code is ... difficult, at least. 1180 // So, to be on the same side, we lock the SolarMutex here. Yes, it sucks. 1181 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1182 ::osl::ClearableMutexGuard aGuard(m_aMutex); 1183 if ( m_bInExecute ) 1184 return aRet; 1185 1186 bool bActivateObject = true; 1187 if ( bOpenForMail ) 1188 { 1189 OSL_ENSURE( false, "ODocumentDefinition::execute: 'openForMail' should not be used anymore - use the 'Hidden' parameter instead!" ); 1190 bActivateObject = false; 1191 } 1192 1193 // if the object is already opened, do nothing 1194 // #i89509# / 2008-05-22 / frank.schoenheit@sun.com 1195 if ( m_xEmbeddedObject.is() ) 1196 { 1197 sal_Int32 nCurrentState = m_xEmbeddedObject->getCurrentState(); 1198 bool bIsActive = ( nCurrentState == EmbedStates::ACTIVE ); 1199 1200 if ( bIsActive ) 1201 { 1202 // exception: new-style reports always create a new document when "open" is executed 1203 Reference< report::XReportDefinition > xReportDefinition( impl_getComponent_throw( false ), UNO_QUERY ); 1204 bool bIsAliveNewStyleReport = ( xReportDefinition.is() && ( bOpen || bOpenForMail ) ); 1205 1206 if ( !bIsAliveNewStyleReport ) 1207 { 1208 impl_onActivateEmbeddedObject_nothrow( true ); 1209 return makeAny( getComponent() ); 1210 } 1211 } 1212 } 1213 1214 m_bOpenInDesign = bOpenInDesign || bOpenForMail; 1215 return onCommandOpenSomething( aCommand.Argument, bActivateObject, Environment ); 1216 } 1217 1218 ::osl::ClearableMutexGuard aGuard(m_aMutex); 1219 if ( m_bInExecute ) 1220 return aRet; 1221 1222 if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "copyTo" ) ) ) 1223 { 1224 Sequence<Any> aIni; 1225 aCommand.Argument >>= aIni; 1226 if ( aIni.getLength() != 2 ) 1227 { 1228 OSL_ENSURE( sal_False, "Wrong argument type!" ); 1229 ucbhelper::cancelCommandExecution( 1230 makeAny( IllegalArgumentException( 1231 rtl::OUString(), 1232 static_cast< cppu::OWeakObject * >( this ), 1233 -1 ) ), 1234 Environment ); 1235 // Unreachable 1236 } 1237 Reference< XStorage> xDest(aIni[0],UNO_QUERY); 1238 ::rtl::OUString sPersistentName; 1239 aIni[1] >>= sPersistentName; 1240 Reference< XStorage> xStorage = getContainerStorage(); 1241 // ----------------------------------------------------------------------------- 1242 xStorage->copyElementTo(m_pImpl->m_aProps.sPersistentName,xDest,sPersistentName); 1243 } 1244 else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "preview" ) ) ) 1245 { 1246 onCommandPreview(aRet); 1247 } 1248 else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "insert" ) ) ) 1249 { 1250 Sequence<Any> aIni; 1251 aCommand.Argument >>= aIni; 1252 if ( !aIni.getLength() ) 1253 { 1254 OSL_ENSURE( sal_False, "Wrong argument count!" ); 1255 ucbhelper::cancelCommandExecution( 1256 makeAny( IllegalArgumentException( 1257 rtl::OUString(), 1258 static_cast< cppu::OWeakObject * >( this ), 1259 -1 ) ), 1260 Environment ); 1261 // Unreachable 1262 } 1263 ::rtl::OUString sURL; 1264 aIni[0] >>= sURL; 1265 onCommandInsert( sURL, Environment ); 1266 } 1267 else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "getdocumentinfo" ) ) // compatibility 1268 || aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "getDocumentInfo" ) ) 1269 ) 1270 { 1271 onCommandGetDocumentProperties( aRet ); 1272 } 1273 else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "delete" ) ) ) 1274 { 1275 ////////////////////////////////////////////////////////////////// 1276 // delete 1277 ////////////////////////////////////////////////////////////////// 1278 closeObject(); 1279 Reference< XStorage> xStorage = getContainerStorage(); 1280 if ( xStorage.is() ) 1281 xStorage->removeElement(m_pImpl->m_aProps.sPersistentName); 1282 1283 dispose(); 1284 1285 } 1286 else if ( ( aCommand.Name.compareToAscii( "storeOwn" ) == 0 ) // compatibility 1287 || ( aCommand.Name.compareToAscii( "store" ) == 0 ) 1288 ) 1289 { 1290 impl_store_throw(); 1291 } 1292 else if ( ( aCommand.Name.compareToAscii( "shutdown" ) == 0 ) // compatibility 1293 || ( aCommand.Name.compareToAscii( "close" ) == 0 ) 1294 ) 1295 { 1296 aRet <<= impl_close_throw(); 1297 } 1298 else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "show" ) ) ) 1299 { 1300 impl_showOrHideComponent_throw( true ); 1301 } 1302 else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "hide" ) ) ) 1303 { 1304 impl_showOrHideComponent_throw( false ); 1305 } 1306 else 1307 { 1308 aRet = OContentHelper::execute(aCommand,CommandId,Environment); 1309 } 1310 1311 return aRet; 1312 } 1313 // ----------------------------------------------------------------------------- 1314 namespace 1315 { 1316 void lcl_resetChildFormsToEmptyDataSource( const Reference< XIndexAccess>& _rxFormsContainer ) 1317 { 1318 OSL_PRECOND( _rxFormsContainer.is(), "lcl_resetChildFormsToEmptyDataSource: illegal call!" ); 1319 sal_Int32 count = _rxFormsContainer->getCount(); 1320 for ( sal_Int32 i = 0; i < count; ++i ) 1321 { 1322 Reference< XForm > xForm( _rxFormsContainer->getByIndex( i ), UNO_QUERY ); 1323 if ( !xForm.is() ) 1324 continue; 1325 1326 // if the element is a form, reset its DataSourceName property to an empty string 1327 try 1328 { 1329 Reference< XPropertySet > xFormProps( xForm, UNO_QUERY_THROW ); 1330 xFormProps->setPropertyValue( PROPERTY_DATASOURCENAME, makeAny( ::rtl::OUString() ) ); 1331 } 1332 catch( const Exception& ) 1333 { 1334 DBG_UNHANDLED_EXCEPTION(); 1335 } 1336 1337 // if the element is a container itself, step down the component hierarchy 1338 Reference< XIndexAccess > xContainer( xForm, UNO_QUERY ); 1339 if ( xContainer.is() ) 1340 lcl_resetChildFormsToEmptyDataSource( xContainer ); 1341 } 1342 } 1343 1344 void lcl_resetFormsToEmptyDataSource( const Reference< XEmbeddedObject>& _rxEmbeddedObject ) 1345 { 1346 try 1347 { 1348 Reference< XComponentSupplier > xCompProv( _rxEmbeddedObject, UNO_QUERY_THROW ); 1349 Reference< XDrawPageSupplier > xSuppPage( xCompProv->getComponent(), UNO_QUERY_THROW ); 1350 // if this interface does not exist, then either getComponent returned NULL, 1351 // or the document is a multi-page document. The latter is allowed, but currently 1352 // simply not handled by this code, as it would not normally happen. 1353 1354 Reference< XFormsSupplier > xSuppForms( xSuppPage->getDrawPage(), UNO_QUERY_THROW ); 1355 Reference< XIndexAccess > xForms( xSuppForms->getForms(), UNO_QUERY_THROW ); 1356 lcl_resetChildFormsToEmptyDataSource( xForms ); 1357 } 1358 catch( const Exception& ) 1359 { 1360 DBG_UNHANDLED_EXCEPTION(); 1361 } 1362 1363 } 1364 } 1365 // ----------------------------------------------------------------------------- 1366 void ODocumentDefinition::onCommandInsert( const ::rtl::OUString& _sURL, const Reference< XCommandEnvironment >& Environment ) 1367 throw( Exception ) 1368 { 1369 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex ); 1370 1371 // Check, if all required properties were set. 1372 if ( !_sURL.getLength() || m_xEmbeddedObject.is() ) 1373 { 1374 OSL_ENSURE( sal_False, "Content::onCommandInsert - property value missing!" ); 1375 1376 Sequence< rtl::OUString > aProps( 1 ); 1377 aProps[ 0 ] = PROPERTY_URL; 1378 ucbhelper::cancelCommandExecution( 1379 makeAny( MissingPropertiesException( 1380 rtl::OUString(), 1381 static_cast< cppu::OWeakObject * >( this ), 1382 aProps ) ), 1383 Environment ); 1384 // Unreachable 1385 } 1386 1387 1388 if ( !m_xEmbeddedObject.is() ) 1389 { 1390 Reference< XStorage> xStorage = getContainerStorage(); 1391 if ( xStorage.is() ) 1392 { 1393 Reference< XEmbedObjectCreator> xEmbedFactory( m_aContext.createComponent( "com.sun.star.embed.EmbeddedObjectCreator" ), UNO_QUERY ); 1394 if ( xEmbedFactory.is() ) 1395 { 1396 Sequence<PropertyValue> aEmpty,aMediaDesc(1); 1397 aMediaDesc[0].Name = PROPERTY_URL; 1398 aMediaDesc[0].Value <<= _sURL; 1399 m_xEmbeddedObject.set(xEmbedFactory->createInstanceInitFromMediaDescriptor( xStorage 1400 ,m_pImpl->m_aProps.sPersistentName 1401 ,aMediaDesc 1402 ,aEmpty),UNO_QUERY); 1403 1404 lcl_resetFormsToEmptyDataSource( m_xEmbeddedObject ); 1405 // #i57669# / 2005-12-01 / frank.schoenheit@sun.com 1406 1407 Reference<XEmbedPersist> xPersist(m_xEmbeddedObject,UNO_QUERY); 1408 if ( xPersist.is() ) 1409 { 1410 xPersist->storeOwn(); 1411 } 1412 try 1413 { 1414 Reference< com::sun::star::util::XCloseable> xCloseable(m_xEmbeddedObject,UNO_QUERY); 1415 if ( xCloseable.is() ) 1416 xCloseable->close(sal_True); 1417 } 1418 catch(Exception) 1419 { 1420 } 1421 m_xEmbeddedObject = NULL; 1422 } 1423 } 1424 } 1425 1426 // @@@ 1427 // storeData(); 1428 1429 aGuard.clear(); 1430 // inserted(); 1431 } 1432 // ----------------------------------------------------------------------------- 1433 sal_Bool ODocumentDefinition::save(sal_Bool _bApprove) 1434 { 1435 // default handling: instantiate an interaction handler and let it handle the parameter request 1436 if ( !m_bOpenInDesign ) 1437 return sal_False; 1438 try 1439 { 1440 1441 { 1442 ::vos::OGuard aSolarGuard(Application::GetSolarMutex()); 1443 1444 // the request 1445 Reference<XNameAccess> xName(m_xParentContainer,UNO_QUERY); 1446 DocumentSaveRequest aRequest; 1447 aRequest.Name = m_pImpl->m_aProps.aTitle; 1448 if ( !aRequest.Name.getLength() ) 1449 { 1450 if ( m_bForm ) 1451 aRequest.Name = DBACORE_RESSTRING( RID_STR_FORM ); 1452 else 1453 aRequest.Name = DBACORE_RESSTRING( RID_STR_REPORT ); 1454 aRequest.Name = ::dbtools::createUniqueName(xName,aRequest.Name); 1455 } 1456 1457 aRequest.Content.set(m_xParentContainer,UNO_QUERY); 1458 OInteractionRequest* pRequest = new OInteractionRequest(makeAny(aRequest)); 1459 Reference< XInteractionRequest > xRequest(pRequest); 1460 // some knittings 1461 // two continuations allowed: OK and Cancel 1462 ODocumentSaveContinuation* pDocuSave = NULL; 1463 1464 if ( !m_pImpl->m_aProps.aTitle.getLength() ) 1465 { 1466 pDocuSave = new ODocumentSaveContinuation; 1467 pRequest->addContinuation(pDocuSave); 1468 } 1469 OInteraction< XInteractionApprove >* pApprove = NULL; 1470 if ( _bApprove ) 1471 { 1472 pApprove = new OInteraction< XInteractionApprove >; 1473 pRequest->addContinuation(pApprove); 1474 } 1475 1476 OInteraction< XInteractionDisapprove >* pDisApprove = new OInteraction< XInteractionDisapprove >; 1477 pRequest->addContinuation(pDisApprove); 1478 1479 OInteractionAbort* pAbort = new OInteractionAbort; 1480 pRequest->addContinuation(pAbort); 1481 1482 // create the handler, let it handle the request 1483 Reference< XInteractionHandler > xHandler( m_aContext.createComponent( (::rtl::OUString)SERVICE_TASK_INTERACTION_HANDLER ), UNO_QUERY ); 1484 if ( xHandler.is() ) 1485 xHandler->handle(xRequest); 1486 1487 if ( pAbort->wasSelected() ) 1488 return sal_False; 1489 if ( pDisApprove->wasSelected() ) 1490 return sal_True; 1491 if ( pDocuSave && pDocuSave->wasSelected() ) 1492 { 1493 Reference<XNameContainer> xNC( pDocuSave->getContent(), UNO_QUERY_THROW ); 1494 1495 ::osl::ResettableMutexGuard aGuard( m_aMutex ); 1496 NameChangeNotifier aNameChangeAndNotify( *this, pDocuSave->getName(), aGuard ); 1497 m_pImpl->m_aProps.aTitle = pDocuSave->getName(); 1498 1499 Reference< XContent> xContent = this; 1500 xNC->insertByName(pDocuSave->getName(),makeAny(xContent)); 1501 1502 updateDocumentTitle(); 1503 } 1504 } 1505 1506 ::osl::MutexGuard aGuard(m_aMutex); 1507 Reference<XEmbedPersist> xPersist(m_xEmbeddedObject,UNO_QUERY); 1508 if ( xPersist.is() ) 1509 { 1510 xPersist->storeOwn(); 1511 notifyDataSourceModified(); 1512 } 1513 } 1514 catch(Exception&) 1515 { 1516 OSL_ENSURE(0,"ODocumentDefinition::save: caught an Exception (tried to let the InteractionHandler handle it)!"); 1517 } 1518 return sal_True; 1519 } 1520 // ----------------------------------------------------------------------------- 1521 sal_Bool ODocumentDefinition::saveAs() 1522 { 1523 // default handling: instantiate an interaction handler and let it handle the parameter request 1524 if ( !m_bOpenInDesign ) 1525 return sal_False; 1526 1527 { 1528 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex ); 1529 if ( !m_pImpl->m_aProps.aTitle.getLength() ) 1530 { 1531 aGuard.clear(); 1532 return save(sal_False); // (sal_False) : we don't want an approve dialog 1533 } 1534 } 1535 try 1536 { 1537 { 1538 ::vos::OGuard aSolarGuard(Application::GetSolarMutex()); 1539 1540 // the request 1541 Reference<XNameAccess> xName(m_xParentContainer,UNO_QUERY); 1542 DocumentSaveRequest aRequest; 1543 aRequest.Name = m_pImpl->m_aProps.aTitle; 1544 1545 aRequest.Content.set(m_xParentContainer,UNO_QUERY); 1546 OInteractionRequest* pRequest = new OInteractionRequest(makeAny(aRequest)); 1547 Reference< XInteractionRequest > xRequest(pRequest); 1548 // some knittings 1549 // two continuations allowed: OK and Cancel 1550 ODocumentSaveContinuation* pDocuSave = new ODocumentSaveContinuation; 1551 pRequest->addContinuation(pDocuSave); 1552 OInteraction< XInteractionDisapprove >* pDisApprove = new OInteraction< XInteractionDisapprove >; 1553 pRequest->addContinuation(pDisApprove); 1554 OInteractionAbort* pAbort = new OInteractionAbort; 1555 pRequest->addContinuation(pAbort); 1556 1557 // create the handler, let it handle the request 1558 Reference< XInteractionHandler > xHandler(m_aContext.createComponent(::rtl::OUString(SERVICE_TASK_INTERACTION_HANDLER)), UNO_QUERY); 1559 if ( xHandler.is() ) 1560 xHandler->handle(xRequest); 1561 1562 if ( pAbort->wasSelected() ) 1563 return sal_False; 1564 if ( pDisApprove->wasSelected() ) 1565 return sal_True; 1566 if ( pDocuSave->wasSelected() ) 1567 { 1568 ::osl::MutexGuard aGuard(m_aMutex); 1569 Reference<XNameContainer> xNC(pDocuSave->getContent(),UNO_QUERY); 1570 if ( xNC.is() ) 1571 { 1572 if ( m_pImpl->m_aProps.aTitle != pDocuSave->getName() ) 1573 { 1574 try 1575 { 1576 Reference< XStorage> xStorage = getContainerStorage(); 1577 const static ::rtl::OUString sBaseName(RTL_CONSTASCII_USTRINGPARAM("Obj")); 1578 // ----------------------------------------------------------------------------- 1579 Reference<XNameAccess> xElements(xStorage,UNO_QUERY_THROW); 1580 ::rtl::OUString sPersistentName = ::dbtools::createUniqueName(xElements,sBaseName); 1581 xStorage->copyElementTo(m_pImpl->m_aProps.sPersistentName,xStorage,sPersistentName); 1582 1583 ::rtl::OUString sOldName = m_pImpl->m_aProps.aTitle; 1584 rename(pDocuSave->getName()); 1585 updateDocumentTitle(); 1586 1587 Sequence< Any > aArguments(3); 1588 PropertyValue aValue; 1589 // set as folder 1590 aValue.Name = PROPERTY_NAME; 1591 aValue.Value <<= sOldName; 1592 aArguments[0] <<= aValue; 1593 1594 aValue.Name = PROPERTY_PERSISTENT_NAME; 1595 aValue.Value <<= sPersistentName; 1596 aArguments[1] <<= aValue; 1597 1598 aValue.Name = PROPERTY_AS_TEMPLATE; 1599 aValue.Value <<= m_pImpl->m_aProps.bAsTemplate; 1600 aArguments[2] <<= aValue; 1601 1602 Reference< XMultiServiceFactory > xORB( m_xParentContainer, UNO_QUERY_THROW ); 1603 Reference< XInterface > xComponent( xORB->createInstanceWithArguments( SERVICE_SDB_DOCUMENTDEFINITION, aArguments ) ); 1604 Reference< XNameContainer > xNameContainer( m_xParentContainer, UNO_QUERY_THROW ); 1605 xNameContainer->insertByName( sOldName, makeAny( xComponent ) ); 1606 } 1607 catch(Exception&) 1608 { 1609 DBG_UNHANDLED_EXCEPTION(); 1610 } 1611 } 1612 Reference<XEmbedPersist> xPersist(m_xEmbeddedObject,UNO_QUERY); 1613 if ( xPersist.is() ) 1614 { 1615 xPersist->storeOwn(); 1616 notifyDataSourceModified(); 1617 } 1618 } 1619 } 1620 } 1621 1622 1623 } 1624 catch(Exception&) 1625 { 1626 OSL_ENSURE(0,"ODocumentDefinition::save: caught an Exception (tried to let the InteractionHandler handle it)!"); 1627 } 1628 return sal_True; 1629 } 1630 1631 namespace 1632 { 1633 // ......................................................................... 1634 void lcl_putLoadArgs( ::comphelper::NamedValueCollection& _io_rArgs, const optional_bool _bSuppressMacros, const optional_bool _bReadOnly ) 1635 { 1636 if ( !!_bSuppressMacros ) 1637 { 1638 if ( *_bSuppressMacros ) 1639 { 1640 // if we're to suppress macros, do exactly this 1641 _io_rArgs.put( "MacroExecutionMode", MacroExecMode::NEVER_EXECUTE ); 1642 } 1643 else 1644 { 1645 // otherwise, put the setting only if not already present 1646 if ( !_io_rArgs.has( "MacroExecutionMode" ) ) 1647 { 1648 _io_rArgs.put( "MacroExecutionMode", MacroExecMode::USE_CONFIG ); 1649 } 1650 } 1651 } 1652 1653 if ( !!_bReadOnly ) 1654 _io_rArgs.put( "ReadOnly", *_bReadOnly ); 1655 } 1656 } 1657 1658 // ----------------------------------------------------------------------------- 1659 namespace 1660 { 1661 Reference< XFrame > lcl_getDatabaseDocumentFrame( ODatabaseModelImpl& _rImpl ) 1662 { 1663 Reference< XModel > xDatabaseDocumentModel( _rImpl.getModel_noCreate() ); 1664 1665 Reference< XController > xDatabaseDocumentController; 1666 if ( xDatabaseDocumentModel.is() ) 1667 xDatabaseDocumentController = xDatabaseDocumentModel->getCurrentController(); 1668 1669 Reference< XFrame > xFrame; 1670 if ( xDatabaseDocumentController.is() ) 1671 xFrame = xDatabaseDocumentController->getFrame(); 1672 1673 return xFrame; 1674 } 1675 } 1676 1677 // ----------------------------------------------------------------------------- 1678 sal_Bool ODocumentDefinition::objectSupportsEmbeddedScripts() const 1679 { 1680 bool bAllowDocumentMacros = !m_pImpl->m_pDataSource 1681 || ( m_pImpl->m_pDataSource->determineEmbeddedMacros() == ODatabaseModelImpl::eSubDocumentMacros ); 1682 1683 // if *any* of the objects of the database document already has macros, we continue to allow it 1684 // to have them, until the user did a migration. 1685 // If there are no macros, yet, we don't allow to create them 1686 1687 return bAllowDocumentMacros; 1688 } 1689 1690 // ----------------------------------------------------------------------------- 1691 ::rtl::OUString ODocumentDefinition::determineContentType() const 1692 { 1693 return lcl_determineContentType_nothrow( getContainerStorage(), m_pImpl->m_aProps.sPersistentName ); 1694 } 1695 1696 // ----------------------------------------------------------------------------- 1697 void ODocumentDefinition::separateOpenCommandArguments( const Sequence< PropertyValue >& i_rOpenCommandArguments, 1698 ::comphelper::NamedValueCollection& o_rDocumentLoadArgs, ::comphelper::NamedValueCollection& o_rEmbeddedObjectDescriptor ) 1699 { 1700 ::comphelper::NamedValueCollection aOpenCommandArguments( i_rOpenCommandArguments ); 1701 1702 const sal_Char* pObjectDescriptorArgs[] = 1703 { 1704 "RecoveryStorage" 1705 }; 1706 for ( size_t i=0; i < sizeof( pObjectDescriptorArgs ) / sizeof( pObjectDescriptorArgs[0] ); ++i ) 1707 { 1708 if ( aOpenCommandArguments.has( pObjectDescriptorArgs[i] ) ) 1709 { 1710 o_rEmbeddedObjectDescriptor.put( pObjectDescriptorArgs[i], aOpenCommandArguments.get( pObjectDescriptorArgs[i] ) ); 1711 aOpenCommandArguments.remove( pObjectDescriptorArgs[i] ); 1712 } 1713 } 1714 1715 o_rDocumentLoadArgs.merge( aOpenCommandArguments, false ); 1716 } 1717 1718 // ----------------------------------------------------------------------------- 1719 Sequence< PropertyValue > ODocumentDefinition::fillLoadArgs( const Reference< XConnection>& _xConnection, const bool _bSuppressMacros, const bool _bReadOnly, 1720 const Sequence< PropertyValue >& i_rOpenCommandArguments, Sequence< PropertyValue >& _out_rEmbeddedObjectDescriptor ) 1721 { 1722 // ......................................................................... 1723 // (re-)create interceptor, and put it into the descriptor of the embedded object 1724 if ( m_pInterceptor ) 1725 { 1726 m_pInterceptor->dispose(); 1727 m_pInterceptor->release(); 1728 m_pInterceptor = NULL; 1729 } 1730 1731 m_pInterceptor = new OInterceptor( this ,_bReadOnly); 1732 m_pInterceptor->acquire(); 1733 Reference<XDispatchProviderInterceptor> xInterceptor = m_pInterceptor; 1734 1735 ::comphelper::NamedValueCollection aEmbeddedDescriptor; 1736 aEmbeddedDescriptor.put( "OutplaceDispatchInterceptor", xInterceptor ); 1737 1738 // ......................................................................... 1739 ::comphelper::NamedValueCollection aMediaDesc; 1740 separateOpenCommandArguments( i_rOpenCommandArguments, aMediaDesc, aEmbeddedDescriptor ); 1741 1742 // ......................................................................... 1743 // create the OutplaceFrameProperties, and put them into the descriptor of the embedded object 1744 ::comphelper::NamedValueCollection OutplaceFrameProperties; 1745 OutplaceFrameProperties.put( "TopWindow", (sal_Bool)sal_True ); 1746 1747 Reference< XFrame > xParentFrame; 1748 if ( m_pImpl->m_pDataSource ) 1749 xParentFrame = lcl_getDatabaseDocumentFrame( *m_pImpl->m_pDataSource ); 1750 if ( !xParentFrame.is() ) 1751 { // i87957 we need a parent frame 1752 Reference< XComponentLoader > xDesktop( m_aContext.createComponent( (::rtl::OUString)SERVICE_FRAME_DESKTOP ), UNO_QUERY_THROW ); 1753 xParentFrame.set( xDesktop, UNO_QUERY ); 1754 if ( xParentFrame.is() ) 1755 { 1756 Reference<util::XCloseable> xCloseable(m_pImpl->m_pDataSource->getModel_noCreate(),UNO_QUERY); 1757 if ( xCloseable.is() ) 1758 { 1759 xCloseable->addCloseListener(this); 1760 m_bRemoveListener = sal_True; 1761 } 1762 } 1763 } 1764 OSL_ENSURE( xParentFrame.is(), "ODocumentDefinition::fillLoadArgs: no parent frame!" ); 1765 if ( xParentFrame.is() ) 1766 OutplaceFrameProperties.put( "ParentFrame", xParentFrame ); 1767 1768 aEmbeddedDescriptor.put( "OutplaceFrameProperties", OutplaceFrameProperties.getNamedValues() ); 1769 1770 // ......................................................................... 1771 // tell the embedded object to have (or not have) script support 1772 aEmbeddedDescriptor.put( "EmbeddedScriptSupport", (sal_Bool)objectSupportsEmbeddedScripts() ); 1773 1774 // ......................................................................... 1775 // tell the embedded object to not participate in the document recovery game - the DB doc will handle it 1776 aEmbeddedDescriptor.put( "DocumentRecoverySupport", (sal_Bool)sal_False ); 1777 1778 // ......................................................................... 1779 // pass the descriptor of the embedded object to the caller 1780 aEmbeddedDescriptor >>= _out_rEmbeddedObjectDescriptor; 1781 1782 // ......................................................................... 1783 // create the ComponentData, and put it into the document's media descriptor 1784 { 1785 ::comphelper::NamedValueCollection aComponentData; 1786 aComponentData.put( "ActiveConnection", _xConnection ); 1787 aComponentData.put( "ApplyFormDesignMode", !_bReadOnly ); 1788 aMediaDesc.put( "ComponentData", aComponentData.getPropertyValues() ); 1789 } 1790 1791 if ( m_pImpl->m_aProps.aTitle.getLength() ) 1792 aMediaDesc.put( "DocumentTitle", m_pImpl->m_aProps.aTitle ); 1793 1794 aMediaDesc.put( "DocumentBaseURL", m_pImpl->m_pDataSource->getURL() ); 1795 1796 // ......................................................................... 1797 // put the common load arguments into the document's media descriptor 1798 lcl_putLoadArgs( aMediaDesc, optional_bool( _bSuppressMacros ), optional_bool( _bReadOnly ) ); 1799 1800 return aMediaDesc.getPropertyValues(); 1801 } 1802 // ----------------------------------------------------------------------------- 1803 void ODocumentDefinition::loadEmbeddedObject( const Reference< XConnection >& i_rConnection, const Sequence< sal_Int8 >& _aClassID, 1804 const Sequence< PropertyValue >& i_rOpenCommandArguments, const bool _bSuppressMacros, const bool _bReadOnly ) 1805 { 1806 if ( !m_xEmbeddedObject.is() ) 1807 { 1808 Reference< XStorage> xStorage = getContainerStorage(); 1809 if ( xStorage.is() ) 1810 { 1811 Reference< XEmbedObjectFactory> xEmbedFactory( m_aContext.createComponent( "com.sun.star.embed.OOoEmbeddedObjectFactory" ), UNO_QUERY ); 1812 if ( xEmbedFactory.is() ) 1813 { 1814 ::rtl::OUString sDocumentService; 1815 sal_Bool bSetSize = sal_False; 1816 sal_Int32 nEntryConnectionMode = EntryInitModes::DEFAULT_INIT; 1817 Sequence< sal_Int8 > aClassID = _aClassID; 1818 if ( aClassID.getLength() ) 1819 { 1820 nEntryConnectionMode = EntryInitModes::TRUNCATE_INIT; 1821 bSetSize = sal_True; 1822 } 1823 else 1824 { 1825 sDocumentService = GetDocumentServiceFromMediaType( getContentType(), m_aContext, aClassID ); 1826 // check if we are not a form and 1827 // the com.sun.star.report.pentaho.SOReportJobFactory is not present. 1828 if ( !m_bForm && !sDocumentService.equalsAscii("com.sun.star.text.TextDocument")) 1829 { 1830 // we seem to be a "new style" report, check if report extension is present. 1831 Reference< XContentEnumerationAccess > xEnumAccess( m_aContext.getLegacyServiceFactory(), UNO_QUERY ); 1832 const ::rtl::OUString sReportEngineServiceName = ::dbtools::getDefaultReportEngineServiceName(m_aContext.getLegacyServiceFactory()); 1833 Reference< XEnumeration > xEnumDrivers = xEnumAccess->createContentEnumeration(sReportEngineServiceName); 1834 if ( !xEnumDrivers.is() || !xEnumDrivers->hasMoreElements() ) 1835 { 1836 com::sun::star::io::WrongFormatException aWFE; 1837 aWFE.Message = DBACORE_RESSTRING( RID_STR_MISSING_EXTENSION ); 1838 throw aWFE; 1839 } 1840 } 1841 if ( !aClassID.getLength() ) 1842 { 1843 if ( m_bForm ) 1844 aClassID = MimeConfigurationHelper::GetSequenceClassID(SO3_SW_CLASSID); 1845 else 1846 { 1847 aClassID = MimeConfigurationHelper::GetSequenceClassID(SO3_RPT_CLASSID_90); 1848 } 1849 } 1850 } 1851 1852 OSL_ENSURE( aClassID.getLength(),"No Class ID" ); 1853 1854 Sequence< PropertyValue > aEmbeddedObjectDescriptor; 1855 Sequence< PropertyValue > aLoadArgs( fillLoadArgs( 1856 i_rConnection, _bSuppressMacros, _bReadOnly, i_rOpenCommandArguments, aEmbeddedObjectDescriptor ) ); 1857 1858 m_xEmbeddedObject.set(xEmbedFactory->createInstanceUserInit(aClassID 1859 ,sDocumentService 1860 ,xStorage 1861 ,m_pImpl->m_aProps.sPersistentName 1862 ,nEntryConnectionMode 1863 ,aLoadArgs 1864 ,aEmbeddedObjectDescriptor 1865 ),UNO_QUERY); 1866 if ( m_xEmbeddedObject.is() ) 1867 { 1868 if ( !m_pClientHelper ) 1869 { 1870 m_pClientHelper = new OEmbeddedClientHelper(this); 1871 m_pClientHelper->acquire(); 1872 } 1873 Reference<XEmbeddedClient> xClient = m_pClientHelper; 1874 m_xEmbeddedObject->setClientSite(xClient); 1875 m_xEmbeddedObject->changeState(EmbedStates::RUNNING); 1876 if ( bSetSize ) 1877 { 1878 LockModifiable aLockModify( impl_getComponent_throw( false ) ); 1879 1880 awt::Size aSize( DEFAULT_WIDTH, DEFAULT_HEIGHT ); 1881 m_xEmbeddedObject->setVisualAreaSize(Aspects::MSOLE_CONTENT,aSize); 1882 } 1883 } 1884 } 1885 } 1886 } 1887 else 1888 { 1889 sal_Int32 nCurrentState = m_xEmbeddedObject->getCurrentState(); 1890 if ( nCurrentState == EmbedStates::LOADED ) 1891 { 1892 if ( !m_pClientHelper ) 1893 { 1894 m_pClientHelper = new OEmbeddedClientHelper(this); 1895 m_pClientHelper->acquire(); 1896 } 1897 Reference<XEmbeddedClient> xClient = m_pClientHelper; 1898 m_xEmbeddedObject->setClientSite(xClient); 1899 1900 Sequence< PropertyValue > aEmbeddedObjectDescriptor; 1901 Sequence< PropertyValue > aLoadArgs( fillLoadArgs( 1902 i_rConnection, _bSuppressMacros, _bReadOnly, i_rOpenCommandArguments, aEmbeddedObjectDescriptor ) ); 1903 1904 Reference<XCommonEmbedPersist> xCommon(m_xEmbeddedObject,UNO_QUERY); 1905 OSL_ENSURE(xCommon.is(),"unsupported interface!"); 1906 if ( xCommon.is() ) 1907 xCommon->reload( aLoadArgs, aEmbeddedObjectDescriptor ); 1908 m_xEmbeddedObject->changeState(EmbedStates::RUNNING); 1909 } 1910 else 1911 { 1912 OSL_ENSURE( ( nCurrentState == EmbedStates::RUNNING ) || ( nCurrentState == EmbedStates::ACTIVE ), 1913 "ODocumentDefinition::loadEmbeddedObject: unexpected state!" ); 1914 1915 // if the document was already loaded (which means the embedded object is in state RUNNING or ACTIVE), 1916 // then just re-set some model parameters 1917 try 1918 { 1919 // ensure the media descriptor doesn't contain any values which are intended for the 1920 // EmbeddedObjectDescriptor only 1921 ::comphelper::NamedValueCollection aEmbeddedObjectDescriptor; 1922 ::comphelper::NamedValueCollection aNewMediaDesc; 1923 separateOpenCommandArguments( i_rOpenCommandArguments, aNewMediaDesc, aEmbeddedObjectDescriptor ); 1924 1925 // merge the new media descriptor into the existing media descriptor 1926 const Reference< XModel > xModel( getComponent(), UNO_QUERY_THROW ); 1927 const Sequence< PropertyValue > aArgs = xModel->getArgs(); 1928 ::comphelper::NamedValueCollection aExistentMediaDesc( aArgs ); 1929 aExistentMediaDesc.merge( aNewMediaDesc, sal_False ); 1930 1931 lcl_putLoadArgs( aExistentMediaDesc, optional_bool(), optional_bool() ); 1932 // don't put _bSuppressMacros and _bReadOnly here - if the document was already 1933 // loaded, we should not tamper with its settings. 1934 // #i88977# / 2008-05-05 / frank.schoenheit@sun.com 1935 // #i86872# / 2008-03-13 / frank.schoenheit@sun.com 1936 1937 xModel->attachResource( xModel->getURL(), aExistentMediaDesc.getPropertyValues() ); 1938 } 1939 catch( const Exception& ) 1940 { 1941 DBG_UNHANDLED_EXCEPTION(); 1942 } 1943 } 1944 } 1945 1946 // set the OfficeDatabaseDocument instance as parent of the embedded document 1947 // #i40358# / 2005-01-19 / frank.schoenheit@sun.com 1948 Reference< XChild > xDepdendDocAsChild( getComponent(), UNO_QUERY ); 1949 if ( xDepdendDocAsChild.is() ) 1950 { 1951 try 1952 { 1953 if ( !xDepdendDocAsChild->getParent().is() ) 1954 { // first encounter 1955 xDepdendDocAsChild->setParent( getDataSource( m_xParentContainer ) ); 1956 } 1957 } 1958 catch( const Exception& ) 1959 { 1960 DBG_UNHANDLED_EXCEPTION(); 1961 } 1962 } 1963 1964 if ( i_rConnection.is() ) 1965 m_xLastKnownConnection = i_rConnection; 1966 } 1967 1968 // ----------------------------------------------------------------------------- 1969 void ODocumentDefinition::onCommandPreview(Any& _rImage) 1970 { 1971 loadEmbeddedObjectForPreview(); 1972 if ( m_xEmbeddedObject.is() ) 1973 { 1974 try 1975 { 1976 Reference<XTransferable> xTransfer(getComponent(),UNO_QUERY); 1977 if ( xTransfer.is() ) 1978 { 1979 DataFlavor aFlavor; 1980 aFlavor.MimeType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("image/png")); 1981 aFlavor.HumanPresentableName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Portable Network Graphics")); 1982 aFlavor.DataType = ::getCppuType(static_cast< const Sequence < sal_Int8 >* >(NULL)); 1983 1984 _rImage = xTransfer->getTransferData( aFlavor ); 1985 } 1986 } 1987 catch( Exception ) 1988 { 1989 } 1990 } 1991 } 1992 // ----------------------------------------------------------------------------- 1993 void ODocumentDefinition::getPropertyDefaultByHandle( sal_Int32 /*_nHandle*/, Any& _rDefault ) const 1994 { 1995 _rDefault.clear(); 1996 } 1997 // ----------------------------------------------------------------------------- 1998 void ODocumentDefinition::onCommandGetDocumentProperties( Any& _rProps ) 1999 { 2000 loadEmbeddedObjectForPreview(); 2001 if ( m_xEmbeddedObject.is() ) 2002 { 2003 try 2004 { 2005 Reference<XDocumentPropertiesSupplier> xDocSup( 2006 getComponent(), UNO_QUERY ); 2007 if ( xDocSup.is() ) 2008 _rProps <<= xDocSup->getDocumentProperties(); 2009 } 2010 catch( const Exception& ) 2011 { 2012 DBG_UNHANDLED_EXCEPTION(); 2013 } 2014 } 2015 } 2016 // ----------------------------------------------------------------------------- 2017 Reference< util::XCloseable > ODocumentDefinition::impl_getComponent_throw( const bool i_ForceCreate ) 2018 { 2019 OSL_ENSURE(m_xEmbeddedObject.is(),"Illegal call for embeddedObject"); 2020 Reference< util::XCloseable > xComp; 2021 if ( m_xEmbeddedObject.is() ) 2022 { 2023 int nState = m_xEmbeddedObject->getCurrentState(); 2024 if ( ( nState == EmbedStates::LOADED ) && i_ForceCreate ) 2025 { 2026 m_xEmbeddedObject->changeState( EmbedStates::RUNNING ); 2027 nState = m_xEmbeddedObject->getCurrentState(); 2028 OSL_ENSURE( nState == EmbedStates::RUNNING, "ODocumentDefinition::impl_getComponent_throw: could not switch to RUNNING!" ); 2029 } 2030 2031 if ( nState == EmbedStates::ACTIVE || nState == EmbedStates::RUNNING ) 2032 { 2033 Reference<XComponentSupplier> xCompProv(m_xEmbeddedObject,UNO_QUERY); 2034 if ( xCompProv.is() ) 2035 { 2036 xComp = xCompProv->getComponent(); 2037 OSL_ENSURE(xComp.is(),"No valid component"); 2038 } 2039 } 2040 } 2041 return xComp; 2042 } 2043 2044 // ----------------------------------------------------------------------------- 2045 Reference< util::XCloseable > ODocumentDefinition::getComponent() throw (RuntimeException) 2046 { 2047 ::osl::MutexGuard aGuard( m_aMutex ); 2048 return impl_getComponent_throw( true ); 2049 } 2050 2051 // ----------------------------------------------------------------------------- 2052 namespace 2053 { 2054 Reference< XDatabaseDocumentUI > lcl_getDatabaseDocumentUI( ODatabaseModelImpl& _rModelImpl ) 2055 { 2056 Reference< XDatabaseDocumentUI > xUI; 2057 2058 Reference< XModel > xModel( _rModelImpl.getModel_noCreate() ); 2059 if ( xModel.is() ) 2060 xUI.set( xModel->getCurrentController(), UNO_QUERY ); 2061 return xUI; 2062 } 2063 } 2064 2065 // ----------------------------------------------------------------------------- 2066 Reference< XComponent > ODocumentDefinition::impl_openUI_nolck_throw( bool _bForEditing ) 2067 { 2068 ::osl::ClearableMutexGuard aGuard( m_aMutex ); 2069 if ( !m_pImpl || !m_pImpl->m_pDataSource ) 2070 throw DisposedException(); 2071 2072 Reference< XDatabaseDocumentUI > xUI( lcl_getDatabaseDocumentUI( *m_pImpl->m_pDataSource ) ); 2073 if ( !xUI.is() ) 2074 { 2075 // no XDatabaseDocumentUI -> just execute the respective command 2076 m_bOpenInDesign = _bForEditing; 2077 Reference< XComponent > xComponent( onCommandOpenSomething( Any(), true, NULL ), UNO_QUERY ); 2078 OSL_ENSURE( xComponent.is(), "ODocumentDefinition::impl_openUI_nolck_throw: opening the thingie failed." ); 2079 return xComponent; 2080 } 2081 2082 Reference< XComponent > xComponent; 2083 try 2084 { 2085 ::rtl::OUString sName( impl_getHierarchicalName( false ) ); 2086 sal_Int32 nObjectType = m_bForm ? DatabaseObject::FORM : DatabaseObject::REPORT; 2087 aGuard.clear(); 2088 2089 xComponent = xUI->loadComponent( 2090 nObjectType, sName, _bForEditing 2091 ); 2092 } 2093 catch( RuntimeException& ) { throw; } 2094 catch( const Exception& ) 2095 { 2096 throw WrappedTargetException( 2097 ::rtl::OUString(), *this, ::cppu::getCaughtException() ); 2098 } 2099 return xComponent; 2100 } 2101 2102 // ----------------------------------------------------------------------------- 2103 void ODocumentDefinition::impl_store_throw() 2104 { 2105 Reference<XEmbedPersist> xPersist( m_xEmbeddedObject, UNO_QUERY ); 2106 if ( xPersist.is() ) 2107 { 2108 xPersist->storeOwn(); 2109 notifyDataSourceModified(); 2110 } 2111 } 2112 2113 // ----------------------------------------------------------------------------- 2114 bool ODocumentDefinition::impl_close_throw() 2115 { 2116 bool bSuccess = prepareClose(); 2117 if ( bSuccess && m_xEmbeddedObject.is() ) 2118 { 2119 m_xEmbeddedObject->changeState( EmbedStates::LOADED ); 2120 bSuccess = m_xEmbeddedObject->getCurrentState() == EmbedStates::LOADED; 2121 } 2122 return bSuccess; 2123 } 2124 2125 // ----------------------------------------------------------------------------- 2126 Reference< XComponent > SAL_CALL ODocumentDefinition::open( ) throw (WrappedTargetException, RuntimeException) 2127 { 2128 return impl_openUI_nolck_throw( false ); 2129 } 2130 2131 // ----------------------------------------------------------------------------- 2132 Reference< XComponent > SAL_CALL ODocumentDefinition::openDesign( ) throw (WrappedTargetException, RuntimeException) 2133 { 2134 return impl_openUI_nolck_throw( true ); 2135 } 2136 2137 // ----------------------------------------------------------------------------- 2138 void SAL_CALL ODocumentDefinition::store( ) throw (WrappedTargetException, RuntimeException) 2139 { 2140 ::osl::MutexGuard aGuard( m_aMutex ); 2141 try 2142 { 2143 impl_store_throw(); 2144 } 2145 catch( RuntimeException& ) { throw; } 2146 catch( const Exception& ) 2147 { 2148 throw WrappedTargetException( 2149 ::rtl::OUString(), *this, ::cppu::getCaughtException() ); 2150 } 2151 } 2152 2153 // ----------------------------------------------------------------------------- 2154 ::sal_Bool SAL_CALL ODocumentDefinition::close( ) throw (WrappedTargetException, RuntimeException) 2155 { 2156 ::osl::MutexGuard aGuard( m_aMutex ); 2157 2158 sal_Bool bSuccess = sal_False; 2159 try 2160 { 2161 bSuccess = impl_close_throw(); 2162 } 2163 catch( RuntimeException& ) { throw; } 2164 catch( const Exception& ) 2165 { 2166 throw WrappedTargetException( 2167 ::rtl::OUString(), *this, ::cppu::getCaughtException() ); 2168 } 2169 return bSuccess; 2170 } 2171 2172 // ----------------------------------------------------------------------------- 2173 ::rtl::OUString SAL_CALL ODocumentDefinition::getHierarchicalName() throw (RuntimeException) 2174 { 2175 ::osl::MutexGuard aGuard( m_aMutex ); 2176 return impl_getHierarchicalName( false ); 2177 } 2178 2179 // ----------------------------------------------------------------------------- 2180 ::rtl::OUString SAL_CALL ODocumentDefinition::composeHierarchicalName( const ::rtl::OUString& i_rRelativeName ) throw (IllegalArgumentException, NoSupportException, RuntimeException) 2181 { 2182 ::rtl::OUStringBuffer aBuffer; 2183 aBuffer.append( getHierarchicalName() ); 2184 aBuffer.append( sal_Unicode( '/' ) ); 2185 aBuffer.append( i_rRelativeName ); 2186 return aBuffer.makeStringAndClear(); 2187 } 2188 2189 // ----------------------------------------------------------------------------- 2190 void SAL_CALL ODocumentDefinition::rename( const ::rtl::OUString& _rNewName ) throw (SQLException, ElementExistException, RuntimeException) 2191 { 2192 try 2193 { 2194 ::osl::ResettableMutexGuard aGuard(m_aMutex); 2195 if ( _rNewName.equals( m_pImpl->m_aProps.aTitle ) ) 2196 return; 2197 2198 // document definitions are organized in a hierarchical way, so reject names 2199 // which contain a /, as this is reserved for hierarchy level separation 2200 if ( _rNewName.indexOf( '/' ) != -1 ) 2201 m_aErrorHelper.raiseException( ErrorCondition::DB_OBJECT_NAME_WITH_SLASHES, *this ); 2202 2203 NameChangeNotifier aNameChangeAndNotify( *this, _rNewName, aGuard ); 2204 m_pImpl->m_aProps.aTitle = _rNewName; 2205 2206 if ( m_xEmbeddedObject.is() && m_xEmbeddedObject->getCurrentState() == EmbedStates::ACTIVE ) 2207 updateDocumentTitle(); 2208 } 2209 catch(const PropertyVetoException&) 2210 { 2211 throw ElementExistException(_rNewName,*this); 2212 } 2213 } 2214 // ----------------------------------------------------------------------------- 2215 Reference< XStorage> ODocumentDefinition::getContainerStorage() const 2216 { 2217 return m_pImpl->m_pDataSource 2218 ? m_pImpl->m_pDataSource->getStorage( m_bForm ? ODatabaseModelImpl::E_FORM : ODatabaseModelImpl::E_REPORT ) 2219 : Reference< XStorage>(); 2220 } 2221 // ----------------------------------------------------------------------------- 2222 sal_Bool ODocumentDefinition::isModified() 2223 { 2224 osl::ClearableGuard< osl::Mutex > aGuard(m_aMutex); 2225 sal_Bool bRet = sal_False; 2226 if ( m_xEmbeddedObject.is() ) 2227 { 2228 Reference<XModifiable> xModel(getComponent(),UNO_QUERY); 2229 bRet = xModel.is() && xModel->isModified(); 2230 } 2231 return bRet; 2232 } 2233 // ----------------------------------------------------------------------------- 2234 bool ODocumentDefinition::prepareClose() 2235 { 2236 if ( !m_xEmbeddedObject.is() ) 2237 return true; 2238 2239 try 2240 { 2241 // suspend the controller. Embedded objects are not allowed to raise 2242 // own UI at their own discretion, instead, this has always to be triggered 2243 // by the embedding component. Thus, we do the suspend call here. 2244 // #i49370# / 2005-06-09 / frank.schoenheit@sun.com 2245 2246 Reference< util::XCloseable > xComponent( impl_getComponent_throw( false ) ); 2247 if ( !xComponent.is() ) 2248 return true; 2249 2250 Reference< XModel > xModel( xComponent, UNO_QUERY ); 2251 Reference< XController > xController; 2252 if ( xModel.is() ) 2253 xController = xModel->getCurrentController(); 2254 2255 OSL_ENSURE( xController.is() || ( m_xEmbeddedObject->getCurrentState() < EmbedStates::ACTIVE ), 2256 "ODocumentDefinition::prepareClose: no controller!" ); 2257 if ( !xController.is() ) 2258 // document has not yet been activated, i.e. has no UI, yet 2259 return true; 2260 2261 sal_Bool bCouldSuspend = xController->suspend( sal_True ); 2262 if ( !bCouldSuspend ) 2263 // controller vetoed the closing 2264 return false; 2265 2266 if ( isModified() ) 2267 { 2268 Reference< XFrame > xFrame( xController->getFrame() ); 2269 if ( xFrame.is() ) 2270 { 2271 Reference< XTopWindow > xTopWindow( xFrame->getContainerWindow(), UNO_QUERY_THROW ); 2272 xTopWindow->toFront(); 2273 } 2274 if ( !save( sal_True ) ) 2275 { 2276 if ( bCouldSuspend ) 2277 // revert suspension 2278 xController->suspend( sal_False ); 2279 // saving failed or was cancelled 2280 return false; 2281 } 2282 } 2283 } 2284 catch( const Exception& ) 2285 { 2286 DBG_UNHANDLED_EXCEPTION(); 2287 } 2288 2289 return true; 2290 } 2291 // ----------------------------------------------------------------------------- 2292 void ODocumentDefinition::fillReportData( const ::comphelper::ComponentContext& _rContext, 2293 const Reference< util::XCloseable >& _rxComponent, 2294 const Reference< XConnection >& _rxActiveConnection ) 2295 { 2296 Sequence< Any > aArgs(2); 2297 PropertyValue aValue; 2298 aValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TextDocument" ) ); 2299 aValue.Value <<= _rxComponent; 2300 aArgs[0] <<= aValue; 2301 aValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ActiveConnection" ) ); 2302 aValue.Value <<= _rxActiveConnection; 2303 aArgs[1] <<= aValue; 2304 2305 try 2306 { 2307 Reference< XJobExecutor > xExecuteable( 2308 _rContext.createComponentWithArguments( "com.sun.star.wizards.report.CallReportWizard", aArgs ), UNO_QUERY_THROW ); 2309 xExecuteable->trigger( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "fill" ) ) ); 2310 } 2311 catch( const Exception& ) 2312 { 2313 DBG_UNHANDLED_EXCEPTION(); 2314 } 2315 } 2316 // ----------------------------------------------------------------------------- 2317 void ODocumentDefinition::updateDocumentTitle() 2318 { 2319 ::rtl::OUString sName = m_pImpl->m_aProps.aTitle; 2320 if ( m_pImpl->m_pDataSource ) 2321 { 2322 if ( !sName.getLength() ) 2323 { 2324 if ( m_bForm ) 2325 sName = DBACORE_RESSTRING( RID_STR_FORM ); 2326 else 2327 sName = DBACORE_RESSTRING( RID_STR_REPORT ); 2328 Reference< XUntitledNumbers > xUntitledProvider(m_pImpl->m_pDataSource->getModel_noCreate(), UNO_QUERY ); 2329 if ( xUntitledProvider.is() ) 2330 sName += ::rtl::OUString::valueOf( xUntitledProvider->leaseNumber(getComponent()) ); 2331 } 2332 2333 Reference< XTitle > xDatabaseDocumentModel(m_pImpl->m_pDataSource->getModel_noCreate(),uno::UNO_QUERY); 2334 if ( xDatabaseDocumentModel.is() ) 2335 sName = xDatabaseDocumentModel->getTitle() + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" : ")) + sName; 2336 } 2337 Reference< XTitle> xTitle(getComponent(),UNO_QUERY); 2338 if ( xTitle.is() ) 2339 xTitle->setTitle(sName); 2340 } 2341 // ----------------------------------------------------------------------------- 2342 void SAL_CALL ODocumentDefinition::queryClosing( const lang::EventObject& Source, ::sal_Bool GetsOwnership ) throw (util::CloseVetoException, uno::RuntimeException) 2343 { 2344 (void) Source; 2345 (void) GetsOwnership; 2346 try 2347 { 2348 if ( !close() ) 2349 throw util::CloseVetoException(); 2350 } 2351 catch(const lang::WrappedTargetException&) 2352 { 2353 throw util::CloseVetoException(); 2354 } 2355 } 2356 // ----------------------------------------------------------------------------- 2357 void SAL_CALL ODocumentDefinition::notifyClosing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException) 2358 { 2359 } 2360 // ----------------------------------------------------------------------------- 2361 void SAL_CALL ODocumentDefinition::disposing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException) 2362 { 2363 } 2364 2365 // ----------------------------------------------------------------------------- 2366 void ODocumentDefinition::firePropertyChange( sal_Int32 i_nHandle, const Any& i_rNewValue, const Any& i_rOldValue, 2367 sal_Bool i_bVetoable, const NotifierAccess ) 2368 { 2369 fire( &i_nHandle, &i_rNewValue, &i_rOldValue, 1, i_bVetoable ); 2370 } 2371 2372 // ============================================================================= 2373 // NameChangeNotifier 2374 // ============================================================================= 2375 // ----------------------------------------------------------------------------- 2376 NameChangeNotifier::NameChangeNotifier( ODocumentDefinition& i_rDocumentDefinition, const ::rtl::OUString& i_rNewName, 2377 ::osl::ResettableMutexGuard& i_rClearForNotify ) 2378 :m_rDocumentDefinition( i_rDocumentDefinition ) 2379 ,m_aOldValue( makeAny( i_rDocumentDefinition.getCurrentName() ) ) 2380 ,m_aNewValue( makeAny( i_rNewName ) ) 2381 ,m_rClearForNotify( i_rClearForNotify ) 2382 { 2383 impl_fireEvent_throw( sal_True ); 2384 } 2385 2386 // ----------------------------------------------------------------------------- 2387 NameChangeNotifier::~NameChangeNotifier() 2388 { 2389 impl_fireEvent_throw( sal_False ); 2390 } 2391 2392 // ----------------------------------------------------------------------------- 2393 void NameChangeNotifier::impl_fireEvent_throw( const sal_Bool i_bVetoable ) 2394 { 2395 m_rClearForNotify.clear(); 2396 m_rDocumentDefinition.firePropertyChange( 2397 PROPERTY_ID_NAME, m_aNewValue, m_aOldValue, i_bVetoable, ODocumentDefinition::NotifierAccess() ); 2398 m_rClearForNotify.reset(); 2399 } 2400 2401 //........................................................................ 2402 } // namespace dbaccess 2403 //........................................................................ 2404 2405