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