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_sfx2.hxx"
26
27 //________________________________________________________________________________________________________
28 // my own includes
29 //________________________________________________________________________________________________________
30
31 #include <sfx2/sfxbasemodel.hxx>
32
33 //________________________________________________________________________________________________________
34 // include of other projects
35 //________________________________________________________________________________________________________
36
37 #include <com/sun/star/task/XInteractionHandler.hpp>
38 #include <com/sun/star/task/ErrorCodeRequest.hpp>
39 #include <com/sun/star/view/XSelectionSupplier.hpp>
40 #include <com/sun/star/view/XPrintJobListener.hpp>
41 #include <com/sun/star/lang/DisposedException.hpp>
42 #include <com/sun/star/lang/IllegalArgumentException.hpp>
43 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
44 #include <com/sun/star/frame/IllegalArgumentIOException.hpp>
45 #include <com/sun/star/frame/XUntitledNumbers.hpp>
46 #include <com/sun/star/frame/UntitledNumbersConst.hpp>
47 #include <com/sun/star/embed/XTransactionBroadcaster.hpp>
48 #include <com/sun/star/embed/XStorage.hpp>
49 #include <com/sun/star/embed/EmbedMapUnits.hpp>
50 #include <com/sun/star/document/XStorageChangeListener.hpp>
51 #include <com/sun/star/document/XActionLockable.hpp>
52 #include <com/sun/star/beans/XPropertySet.hpp>
53 #include <com/sun/star/container/XIndexContainer.hpp>
54 #include <com/sun/star/script/provider/XScriptProviderFactory.hpp>
55 #include <com/sun/star/script/provider/XScriptProvider.hpp>
56 #include <com/sun/star/ui/XUIConfigurationStorage.hpp>
57 #include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
58 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
59 #include <com/sun/star/embed/ElementModes.hpp>
60 #include <com/sun/star/embed/Aspects.hpp>
61 #include <com/sun/star/document/XDocumentProperties.hpp>
62 #include <com/sun/star/frame/XTransientDocumentsDocumentContentFactory.hpp>
63 #include <comphelper/enumhelper.hxx> // can be removed when this is a "real" service
64
65 #include <cppuhelper/interfacecontainer.hxx>
66 #include <cppuhelper/exc_hlp.hxx>
67 #include <comphelper/processfactory.hxx> // can be removed when this is a "real" service
68 #include <comphelper/componentcontext.hxx>
69 #include <comphelper/namedvaluecollection.hxx>
70 #include <svl/itemset.hxx>
71 #include <svl/stritem.hxx>
72 #include <svl/eitem.hxx>
73 #include <svl/intitem.hxx>
74 #include <basic/sbx.hxx>
75 #include <basic/sbuno.hxx>
76 #include <tools/urlobj.hxx>
77 #include <tools/diagnose_ex.h>
78 #include <unotools/tempfile.hxx>
79 #include <vos/mutex.hxx>
80 #include <vcl/salctype.hxx>
81 #include <sot/clsids.hxx>
82 #include <sot/storinfo.hxx>
83 #include <comphelper/storagehelper.hxx>
84 #include <toolkit/helper/vclunohelper.hxx>
85 #include <svtools/transfer.hxx>
86 #include <svtools/ehdl.hxx>
87 #include <svtools/sfxecode.hxx>
88 #include <rtl/logfile.hxx>
89 #include <framework/configimporter.hxx>
90 #include <framework/interaction.hxx>
91 #include <framework/titlehelper.hxx>
92 #include <comphelper/numberedcollection.hxx>
93 #include <unotools/ucbstreamhelper.hxx>
94 #include <unotools/ucbhelper.hxx>
95
96 //________________________________________________________________________________________________________
97 // includes of my own project
98 //________________________________________________________________________________________________________
99
100 #include <sfx2/sfxbasecontroller.hxx>
101 #include "sfx2/viewfac.hxx"
102 #include "workwin.hxx"
103 #include <sfx2/signaturestate.hxx>
104 #include <sfx2/sfxuno.hxx>
105 #include <objshimp.hxx>
106 #include <sfx2/viewfrm.hxx>
107 #include <sfx2/viewsh.hxx>
108 #include <sfx2/docfile.hxx>
109 #include <sfx2/dispatch.hxx>
110 #include <sfx2/request.hxx>
111 #include <sfx2/objuno.hxx>
112 #include <sfx2/printer.hxx>
113 #include <sfx2/basmgr.hxx>
114 #include <sfx2/event.hxx>
115 #include <eventsupplier.hxx>
116 #include <sfx2/evntconf.hxx>
117 #include <sfx2/sfx.hrc>
118 #include <sfx2/app.hxx>
119 #include <sfx2/viewfrm.hxx>
120 #include "appdata.hxx"
121 #include <sfx2/docfac.hxx>
122 #include <sfx2/fcontnr.hxx>
123 #include "sfx2/docstoragemodifylistener.hxx"
124 #include "sfx2/brokenpackageint.hxx"
125 #include "graphhelp.hxx"
126 #include "docundomanager.hxx"
127 #include <sfx2/msgpool.hxx>
128 #include <sfx2/DocumentMetadataAccess.hxx>
129
130 #include <sfx2/sfxresid.hxx>
131
132 //________________________________________________________________________________________________________
133 // const
134 static const ::rtl::OUString SERVICENAME_DESKTOP = ::rtl::OUString::createFromAscii ("com.sun.star.frame.Desktop");
135
136 //________________________________________________________________________________________________________
137 // namespaces
138 //________________________________________________________________________________________________________
139
140 namespace css = ::com::sun::star;
141 using namespace ::com::sun::star;
142 using namespace ::com::sun::star::uno;
143 using ::com::sun::star::beans::PropertyValue;
144 using ::com::sun::star::frame::XFrame;
145 using ::com::sun::star::frame::XController;
146 using ::com::sun::star::frame::XController2;
147 using ::com::sun::star::lang::IllegalArgumentException;
148 using ::com::sun::star::io::IOException;
149 using ::com::sun::star::lang::WrappedTargetException;
150 using ::com::sun::star::uno::Type;
151 using ::com::sun::star::uno::Sequence;
152 using ::com::sun::star::document::XDocumentRecovery;
153 using ::com::sun::star::document::XUndoManager;
154 using ::com::sun::star::document::XUndoAction;
155 using ::com::sun::star::document::UndoFailedException;
156 using ::com::sun::star::frame::XModel;
157
158 /** This Listener is used to get notified when the XDocumentProperties of the
159 XModel change.
160 */
161 class SfxDocInfoListener_Impl : public ::cppu::WeakImplHelper1<
162 ::com::sun::star::util::XModifyListener >
163 {
164
165 public:
166 SfxObjectShell& m_rShell;
167
SfxDocInfoListener_Impl(SfxObjectShell & i_rDoc)168 SfxDocInfoListener_Impl( SfxObjectShell& i_rDoc )
169 : m_rShell(i_rDoc)
170 { };
171
172 ~SfxDocInfoListener_Impl();
173
174 virtual void SAL_CALL disposing( const lang::EventObject& );
175 virtual void SAL_CALL modified( const lang::EventObject& );
176 };
~SfxDocInfoListener_Impl()177 SfxDocInfoListener_Impl::~SfxDocInfoListener_Impl()
178 {
179 }
modified(const lang::EventObject &)180 void SAL_CALL SfxDocInfoListener_Impl::modified( const lang::EventObject& )
181 {
182 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
183
184 // notify changes to the SfxObjectShell
185 m_rShell.FlushDocInfo();
186 }
187
disposing(const lang::EventObject &)188 void SAL_CALL SfxDocInfoListener_Impl::disposing( const lang::EventObject& )
189 {
190 }
191
192 //________________________________________________________________________________________________________
193 // impl. declarations
194 //________________________________________________________________________________________________________
195
196
197 struct IMPL_SfxBaseModel_DataContainer : public ::sfx2::IModifiableDocument
198 {
199 // counter for SfxBaseModel instances created.
200 static sal_Int64 g_nInstanceCounter ;
201 SfxObjectShellRef m_pObjectShell ;
202 ::rtl::OUString m_sURL ;
203 ::rtl::OUString m_sRuntimeUID ;
204 ::rtl::OUString m_aPreusedFilterName;
205 ::cppu::OMultiTypeInterfaceContainerHelper m_aInterfaceContainer ;
206 uno::Reference< uno::XInterface > m_xParent ;
207 uno::Reference< frame::XController > m_xCurrent ;
208 uno::Reference< document::XDocumentInfo > m_xDocumentInfo ;
209 uno::Reference< document::XDocumentProperties > m_xDocumentProperties;
210 uno::Reference< script::XStarBasicAccess > m_xStarBasicAccess ;
211 uno::Reference< container::XNameReplace > m_xEvents ;
212 uno::Sequence< beans::PropertyValue> m_seqArguments ;
213 uno::Sequence< uno::Reference< frame::XController > > m_seqControllers ;
214 uno::Reference< container::XIndexAccess > m_contViewData ;
215 sal_uInt16 m_nControllerLockCount ;
216 sal_Bool m_bClosed ;
217 sal_Bool m_bClosing ;
218 sal_Bool m_bSaving ;
219 sal_Bool m_bSuicide ;
220 sal_Bool m_bInitialized ;
221 sal_Bool m_bExternalTitle ;
222 sal_Bool m_bModifiedSinceLastSave;
223 uno::Reference< com::sun::star::view::XPrintable> m_xPrintable ;
224 uno::Reference< script::provider::XScriptProvider > m_xScriptProvider;
225 uno::Reference< ui::XUIConfigurationManager > m_xUIConfigurationManager;
226 ::rtl::Reference< ::sfx2::DocumentStorageModifyListener > m_pStorageModifyListen;
227 ::rtl::OUString m_sModuleIdentifier;
228 css::uno::Reference< css::frame::XTitle > m_xTitleHelper;
229 css::uno::Reference< css::frame::XUntitledNumbers > m_xNumberedControllers;
230 uno::Reference< rdf::XDocumentMetadataAccess> m_xDocumentMetadata;
231 ::rtl::Reference< ::sfx2::DocumentUndoManager > m_pDocumentUndoManager;
232
233
IMPL_SfxBaseModel_DataContainerIMPL_SfxBaseModel_DataContainer234 IMPL_SfxBaseModel_DataContainer( ::osl::Mutex& rMutex, SfxObjectShell* pObjectShell )
235 : m_pObjectShell ( pObjectShell )
236 , m_aInterfaceContainer ( rMutex )
237 , m_nControllerLockCount ( 0 )
238 , m_bClosed ( sal_False )
239 , m_bClosing ( sal_False )
240 , m_bSaving ( sal_False )
241 , m_bSuicide ( sal_False )
242 , m_bInitialized ( sal_False )
243 , m_bExternalTitle ( sal_False )
244 , m_bModifiedSinceLastSave( sal_False )
245 , m_pStorageModifyListen ( NULL )
246 , m_xTitleHelper ()
247 , m_xNumberedControllers ()
248 , m_xDocumentMetadata () // lazy
249 , m_pDocumentUndoManager ()
250 {
251 // increase global instance counter.
252 ++g_nInstanceCounter;
253 // set own Runtime UID
254 m_sRuntimeUID = rtl::OUString::valueOf( g_nInstanceCounter );
255 }
256
~IMPL_SfxBaseModel_DataContainerIMPL_SfxBaseModel_DataContainer257 virtual ~IMPL_SfxBaseModel_DataContainer()
258 {
259 }
260
261 // ::sfx2::IModifiableDocument
storageIsModifiedIMPL_SfxBaseModel_DataContainer262 virtual void storageIsModified()
263 {
264 if ( m_pObjectShell.Is() && !m_pObjectShell->IsModified() )
265 m_pObjectShell->SetModified( sal_True );
266 }
267
GetDMAIMPL_SfxBaseModel_DataContainer268 uno::Reference<rdf::XDocumentMetadataAccess> GetDMA()
269 {
270 if (!m_xDocumentMetadata.is())
271 {
272 OSL_ENSURE(m_pObjectShell, "GetDMA: no object shell?");
273 if (!m_pObjectShell)
274 {
275 return 0;
276 }
277
278 const uno::Reference<uno::XComponentContext> xContext(
279 ::comphelper::getProcessComponentContext());
280 ::rtl::OUString uri;
281 const uno::Reference<frame::XModel> xModel(
282 m_pObjectShell->GetModel());
283 const uno::Reference<lang::XMultiComponentFactory> xMsf(
284 xContext->getServiceManager());
285 const uno::Reference<frame::
286 XTransientDocumentsDocumentContentFactory> xTDDCF(
287 xMsf->createInstanceWithContext(
288 ::rtl::OUString::createFromAscii( "com.sun.star.frame."
289 "TransientDocumentsDocumentContentFactory"),
290 xContext),
291 uno::UNO_QUERY_THROW);
292 const uno::Reference<ucb::XContent> xContent(
293 xTDDCF->createDocumentContent(xModel) );
294 OSL_ENSURE(xContent.is(), "GetDMA: cannot create DocumentContent");
295 if (!xContent.is())
296 {
297 return 0;
298 }
299 uri = xContent->getIdentifier()->getContentIdentifier();
300 OSL_ENSURE(uri.getLength(), "GetDMA: empty uri?");
301 if (uri.getLength() && !uri.endsWithAsciiL("/", 1))
302 {
303 uri = uri + ::rtl::OUString::createFromAscii("/");
304 }
305
306 m_xDocumentMetadata = new ::sfx2::DocumentMetadataAccess(
307 xContext, *m_pObjectShell, uri);
308 }
309 return m_xDocumentMetadata;
310 }
311
CreateDMAUninitializedIMPL_SfxBaseModel_DataContainer312 uno::Reference<rdf::XDocumentMetadataAccess> CreateDMAUninitialized()
313 {
314 return (m_pObjectShell)
315 ? new ::sfx2::DocumentMetadataAccess(
316 ::comphelper::getProcessComponentContext(), *m_pObjectShell)
317 : 0;
318 }
319 };
320
321 // static member initialization.
322 sal_Int64 IMPL_SfxBaseModel_DataContainer::g_nInstanceCounter = 0;
323
324 // =======================================================================================================
325
326 // Listener that forwards notifications from the PrintHelper to the "real" listeners
327 class SfxPrintHelperListener_Impl : public ::cppu::WeakImplHelper1< ::com::sun::star::view::XPrintJobListener >
328 {
329 public:
330 IMPL_SfxBaseModel_DataContainer* m_pData;
SfxPrintHelperListener_Impl(IMPL_SfxBaseModel_DataContainer * pData)331 SfxPrintHelperListener_Impl( IMPL_SfxBaseModel_DataContainer* pData )
332 : m_pData( pData )
333 {}
334
335 virtual void SAL_CALL disposing( const lang::EventObject& aEvent ) ;
336 virtual void SAL_CALL printJobEvent( const view::PrintJobEvent& rEvent );
337 };
338
disposing(const lang::EventObject &)339 void SAL_CALL SfxPrintHelperListener_Impl::disposing( const lang::EventObject& )
340 {
341 m_pData->m_xPrintable = 0;
342 }
343
printJobEvent(const view::PrintJobEvent & rEvent)344 void SAL_CALL SfxPrintHelperListener_Impl::printJobEvent( const view::PrintJobEvent& rEvent )
345 {
346 ::cppu::OInterfaceContainerHelper* pContainer = m_pData->m_aInterfaceContainer.getContainer( ::getCppuType( ( const uno::Reference< view::XPrintJobListener >*) NULL ) );
347 if ( pContainer!=NULL )
348 {
349 ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
350 while (pIterator.hasMoreElements())
351 ((view::XPrintJobListener*)pIterator.next())->printJobEvent( rEvent );
352 }
353 }
354
355 // SfxOwnFramesLocker ====================================================================================
356 // allows to lock all the frames related to the provided SfxObjectShell
357 class SfxOwnFramesLocker
358 {
359 uno::Sequence< uno::Reference< frame::XFrame > > m_aLockedFrames;
360
361 Window* GetVCLWindow( const uno::Reference< frame::XFrame >& xFrame );
362 public:
363 SfxOwnFramesLocker( SfxObjectShell* ObjechShell );
364 ~SfxOwnFramesLocker();
365 void UnlockFrames();
366 };
367
SfxOwnFramesLocker(SfxObjectShell * pObjectShell)368 SfxOwnFramesLocker::SfxOwnFramesLocker( SfxObjectShell* pObjectShell )
369 {
370 if ( !pObjectShell )
371 return;
372
373 for ( SfxViewFrame *pFrame = SfxViewFrame::GetFirst( pObjectShell );
374 pFrame;
375 pFrame = SfxViewFrame::GetNext( *pFrame, pObjectShell )
376 )
377 {
378 SfxFrame& rSfxFrame = pFrame->GetFrame();
379 try
380 {
381 // get vcl window related to the frame and lock it if it is still not locked
382 uno::Reference< frame::XFrame > xFrame = rSfxFrame.GetFrameInterface();
383 Window* pWindow = GetVCLWindow( xFrame );
384 if ( !pWindow )
385 throw uno::RuntimeException();
386
387 if ( pWindow->IsEnabled() )
388 {
389 pWindow->Disable();
390
391 try
392 {
393 sal_Int32 nLen = m_aLockedFrames.getLength();
394 m_aLockedFrames.realloc( nLen + 1 );
395 m_aLockedFrames[nLen] = xFrame;
396 }
397 catch( uno::Exception& )
398 {
399 pWindow->Enable();
400 throw;
401 }
402 }
403 }
404 catch( uno::Exception& )
405 {
406 OSL_ENSURE( sal_False, "Not possible to lock the frame window!\n" );
407 }
408 }
409 }
410
~SfxOwnFramesLocker()411 SfxOwnFramesLocker::~SfxOwnFramesLocker()
412 {
413 UnlockFrames();
414 }
415
GetVCLWindow(const uno::Reference<frame::XFrame> & xFrame)416 Window* SfxOwnFramesLocker::GetVCLWindow( const uno::Reference< frame::XFrame >& xFrame )
417 {
418 Window* pWindow = NULL;
419
420 if ( xFrame.is() )
421 {
422 uno::Reference< awt::XWindow > xWindow = xFrame->getContainerWindow();
423 if ( xWindow.is() )
424 pWindow = VCLUnoHelper::GetWindow( xWindow );
425 }
426
427 return pWindow;
428 }
429
UnlockFrames()430 void SfxOwnFramesLocker::UnlockFrames()
431 {
432 for ( sal_Int32 nInd = 0; nInd < m_aLockedFrames.getLength(); nInd++ )
433 {
434 try
435 {
436 if ( m_aLockedFrames[nInd].is() )
437 {
438 // get vcl window related to the frame and unlock it
439 Window* pWindow = GetVCLWindow( m_aLockedFrames[nInd] );
440 if ( !pWindow )
441 throw uno::RuntimeException();
442
443 pWindow->Enable();
444
445 m_aLockedFrames[nInd] = uno::Reference< frame::XFrame >();
446 }
447 }
448 catch( uno::Exception& )
449 {
450 OSL_ENSURE( sal_False, "Can't unlock the frame window!\n" );
451 }
452 }
453 }
454
455 // SfxSaveGuard ====================================================================================
456 class SfxSaveGuard
457 {
458 private:
459 uno::Reference< frame::XModel > m_xModel;
460 IMPL_SfxBaseModel_DataContainer* m_pData;
461 SfxOwnFramesLocker* m_pFramesLock;
462
463 public:
464 SfxSaveGuard(const uno::Reference< frame::XModel >& xModel ,
465 IMPL_SfxBaseModel_DataContainer* pData ,
466 sal_Bool bRejectConcurrentSaveRequest);
467 ~SfxSaveGuard();
468 };
469
SfxSaveGuard(const uno::Reference<frame::XModel> & xModel,IMPL_SfxBaseModel_DataContainer * pData,sal_Bool bRejectConcurrentSaveRequest)470 SfxSaveGuard::SfxSaveGuard(const uno::Reference< frame::XModel >& xModel ,
471 IMPL_SfxBaseModel_DataContainer* pData ,
472 sal_Bool bRejectConcurrentSaveRequest)
473 : m_xModel (xModel)
474 , m_pData (pData )
475 , m_pFramesLock(0 )
476 {
477 static ::rtl::OUString MSG_1 = ::rtl::OUString::createFromAscii("Object already disposed." );
478 static ::rtl::OUString MSG_2 = ::rtl::OUString::createFromAscii("Concurrent save requests on the same document are not possible.");
479
480 if ( m_pData->m_bClosed )
481 throw ::com::sun::star::lang::DisposedException(
482 MSG_1,
483 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >());
484
485 if (
486 bRejectConcurrentSaveRequest &&
487 m_pData->m_bSaving
488 )
489 throw ::com::sun::star::io::IOException(
490 MSG_2,
491 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >());
492
493 m_pData->m_bSaving = sal_True;
494 m_pFramesLock = new SfxOwnFramesLocker(m_pData->m_pObjectShell);
495 }
496
~SfxSaveGuard()497 SfxSaveGuard::~SfxSaveGuard()
498 {
499 SfxOwnFramesLocker* pFramesLock = m_pFramesLock;
500 m_pFramesLock = 0;
501 delete pFramesLock;
502
503 m_pData->m_bSaving = sal_False;
504
505 // m_bSuicide was set e.g. in case somewhere tried to close a document, while it was used for
506 // storing at the same time. Further m_bSuicide was set to sal_True only if close(sal_True) was called.
507 // So the owner ship was delegated to the place where a veto exception was thrown.
508 // Now we have to call close() again and delegate the owner ship to the next one, which
509 // can't accept that. Close(sal_False) can't work in this case. Because then the document will may be never closed ...
510
511 if ( m_pData->m_bSuicide )
512 {
513 // Reset this state. In case the new close() request is not accepted by somewhere else ...
514 // it's not a good idea to have two "owners" for close .-)
515 m_pData->m_bSuicide = sal_False;
516 try
517 {
518 uno::Reference< util::XCloseable > xClose(m_xModel, uno::UNO_QUERY);
519 if (xClose.is())
520 xClose->close(sal_True);
521 }
522 catch(const util::CloseVetoException&)
523 {}
524 }
525 }
526
527 // =======================================================================================================
528
529 //________________________________________________________________________________________________________
530 // constructor
531 //________________________________________________________________________________________________________
DBG_NAME(sfx2_SfxBaseModel)532 DBG_NAME(sfx2_SfxBaseModel)
533 SfxBaseModel::SfxBaseModel( SfxObjectShell *pObjectShell )
534 : BaseMutex()
535 , m_pData( new IMPL_SfxBaseModel_DataContainer( m_aMutex, pObjectShell ) )
536 , m_bSupportEmbeddedScripts( pObjectShell && pObjectShell->Get_Impl() ? !pObjectShell->Get_Impl()->m_bNoBasicCapabilities : false )
537 , m_bSupportDocRecovery( pObjectShell && pObjectShell->Get_Impl() ? pObjectShell->Get_Impl()->m_bDocRecoverySupport : false )
538 {
539 DBG_CTOR(sfx2_SfxBaseModel,NULL);
540 if ( pObjectShell != NULL )
541 {
542 StartListening( *pObjectShell ) ;
543 }
544 }
545
546 //________________________________________________________________________________________________________
547 // destructor
548 //________________________________________________________________________________________________________
549
~SfxBaseModel()550 SfxBaseModel::~SfxBaseModel()
551 {
552 DBG_DTOR(sfx2_SfxBaseModel,NULL);
553 }
554
555 //________________________________________________________________________________________________________
556 // XInterface
557 //________________________________________________________________________________________________________
558
queryInterface(const UNOTYPE & rType)559 uno::Any SAL_CALL SfxBaseModel::queryInterface( const UNOTYPE& rType )
560 {
561 if ( ( !m_bSupportEmbeddedScripts && rType.equals( XEMBEDDEDSCRIPTS::static_type() ) )
562 || ( !m_bSupportDocRecovery && rType.equals( XDocumentRecovery::static_type() ) )
563 )
564 return Any();
565
566 return SfxBaseModel_Base::queryInterface( rType );
567 }
568
569 //________________________________________________________________________________________________________
570 // XInterface
571 //________________________________________________________________________________________________________
572
acquire()573 void SAL_CALL SfxBaseModel::acquire() throw( )
574 {
575 // Attention:
576 // Don't use mutex or guard in this method!!! Is a method of XInterface.
577
578 // Forward to baseclass
579 OWeakObject::acquire() ;
580 }
581
582 //________________________________________________________________________________________________________
583 // XInterface
584 //________________________________________________________________________________________________________
585
release()586 void SAL_CALL SfxBaseModel::release() throw( )
587 {
588 // Attention:
589 // Don't use mutex or guard in this method!!! Is a method of XInterface.
590
591 // Forward to baseclass
592 OWeakObject::release() ;
593 }
594
595 //________________________________________________________________________________________________________
596 // XTypeProvider
597 //________________________________________________________________________________________________________
598
599 namespace
600 {
lcl_stripType(Sequence<Type> & io_rTypes,const Type & i_rTypeToStrip)601 void lcl_stripType( Sequence< Type >& io_rTypes, const Type& i_rTypeToStrip )
602 {
603 Sequence< UNOTYPE > aStrippedTypes( io_rTypes.getLength() - 1 );
604 ::std::remove_copy_if(
605 io_rTypes.getConstArray(),
606 io_rTypes.getConstArray() + io_rTypes.getLength(),
607 aStrippedTypes.getArray(),
608 ::std::bind2nd( ::std::equal_to< Type >(), i_rTypeToStrip )
609 );
610 io_rTypes = aStrippedTypes;
611 }
612 }
613
getTypes()614 uno::Sequence< UNOTYPE > SAL_CALL SfxBaseModel::getTypes()
615 {
616 uno::Sequence< UNOTYPE > aTypes( SfxBaseModel_Base::getTypes() );
617
618 if ( !m_bSupportEmbeddedScripts )
619 lcl_stripType( aTypes, XEMBEDDEDSCRIPTS::static_type() );
620
621 if ( !m_bSupportDocRecovery )
622 lcl_stripType( aTypes, XDocumentRecovery::static_type() );
623
624 return aTypes;
625 }
626
627 //________________________________________________________________________________________________________
628 // XTypeProvider
629 //________________________________________________________________________________________________________
630
getImplementationId()631 uno::Sequence< sal_Int8 > SAL_CALL SfxBaseModel::getImplementationId()
632 {
633 // Create one Id for all instances of this class.
634 // Use ethernet address to do this! (sal_True)
635
636 // Optimize this method
637 // We initialize a static variable only one time. And we don't must use a mutex at every call!
638 // For the first call; pID is NULL - for the second call pID is different from NULL!
639 static ::cppu::OImplementationId* pID = NULL ;
640
641 if ( pID == NULL )
642 {
643 // Ready for multithreading; get global mutex for first call of this method only! see before
644 ::osl::MutexGuard aGuard( MUTEX::getGlobalMutex() ) ;
645
646 // Control these pointer again ... it can be, that another instance will be faster then these!
647 if ( pID == NULL )
648 {
649 // Create a new static ID ...
650 static ::cppu::OImplementationId aID( sal_False ) ;
651 // ... and set his address to static pointer!
652 pID = &aID ;
653 }
654 }
655
656 return pID->getImplementationId() ;
657 }
658
659 //________________________________________________________________________________________________________
660 // XStarBasicAccess
661 //________________________________________________________________________________________________________
662
implGetStarBasicAccess(SfxObjectShell * pObjectShell)663 uno::Reference< script::XStarBasicAccess > implGetStarBasicAccess( SfxObjectShell* pObjectShell )
664 {
665 uno::Reference< script::XStarBasicAccess > xRet;
666 if( pObjectShell )
667 {
668 BasicManager* pMgr = pObjectShell->GetBasicManager();
669 xRet = getStarBasicAccess( pMgr );
670 }
671 return xRet;
672 }
673
getLibraryContainer()674 uno::Reference< XNAMECONTAINER > SAL_CALL SfxBaseModel::getLibraryContainer()
675 {
676 SfxModelGuard aGuard( *this );
677
678 uno::Reference< script::XStarBasicAccess >& rxAccess = m_pData->m_xStarBasicAccess;
679 if( !rxAccess.is() && m_pData->m_pObjectShell.Is() )
680 rxAccess = implGetStarBasicAccess( m_pData->m_pObjectShell );
681
682 uno::Reference< XNAMECONTAINER > xRet;
683 if( rxAccess.is() )
684 xRet = rxAccess->getLibraryContainer();
685 return xRet;
686 }
687
688 /**___________________________________________________________________________________________________
689 @seealso XStarBasicAccess
690 */
createLibrary(const::rtl::OUString & LibName,const::rtl::OUString & Password,const::rtl::OUString & ExternalSourceURL,const::rtl::OUString & LinkTargetURL)691 void SAL_CALL SfxBaseModel::createLibrary( const ::rtl::OUString& LibName, const ::rtl::OUString& Password,
692 const ::rtl::OUString& ExternalSourceURL, const ::rtl::OUString& LinkTargetURL )
693 {
694 SfxModelGuard aGuard( *this );
695
696 uno::Reference< script::XStarBasicAccess >& rxAccess = m_pData->m_xStarBasicAccess;
697 if( !rxAccess.is() && m_pData->m_pObjectShell.Is() )
698 rxAccess = implGetStarBasicAccess( m_pData->m_pObjectShell );
699
700 if( rxAccess.is() )
701 rxAccess->createLibrary( LibName, Password, ExternalSourceURL, LinkTargetURL );
702 }
703
704 /**___________________________________________________________________________________________________
705 @seealso XStarBasicAccess
706 */
addModule(const::rtl::OUString & LibraryName,const::rtl::OUString & ModuleName,const::rtl::OUString & Language,const::rtl::OUString & Source)707 void SAL_CALL SfxBaseModel::addModule( const ::rtl::OUString& LibraryName, const ::rtl::OUString& ModuleName,
708 const ::rtl::OUString& Language, const ::rtl::OUString& Source )
709 {
710 SfxModelGuard aGuard( *this );
711
712 uno::Reference< script::XStarBasicAccess >& rxAccess = m_pData->m_xStarBasicAccess;
713 if( !rxAccess.is() && m_pData->m_pObjectShell.Is() )
714 rxAccess = implGetStarBasicAccess( m_pData->m_pObjectShell );
715
716 if( rxAccess.is() )
717 rxAccess->addModule( LibraryName, ModuleName, Language, Source );
718 }
719
720 /**___________________________________________________________________________________________________
721 @seealso XStarBasicAccess
722 */
addDialog(const::rtl::OUString & LibraryName,const::rtl::OUString & DialogName,const::com::sun::star::uno::Sequence<sal_Int8> & Data)723 void SAL_CALL SfxBaseModel::addDialog( const ::rtl::OUString& LibraryName, const ::rtl::OUString& DialogName,
724 const ::com::sun::star::uno::Sequence< sal_Int8 >& Data )
725 {
726 SfxModelGuard aGuard( *this );
727
728 uno::Reference< script::XStarBasicAccess >& rxAccess = m_pData->m_xStarBasicAccess;
729 if( !rxAccess.is() && m_pData->m_pObjectShell.Is() )
730 rxAccess = implGetStarBasicAccess( m_pData->m_pObjectShell );
731
732 if( rxAccess.is() )
733 rxAccess->addDialog( LibraryName, DialogName, Data );
734 }
735
736
737 //________________________________________________________________________________________________________
738 // XChild
739 //________________________________________________________________________________________________________
740
getParent()741 uno::Reference< uno::XInterface > SAL_CALL SfxBaseModel::getParent()
742 {
743 SfxModelGuard aGuard( *this );
744
745 return m_pData->m_xParent;
746 }
747
748 //________________________________________________________________________________________________________
749 // XChild
750 //________________________________________________________________________________________________________
751
setParent(const uno::Reference<uno::XInterface> & Parent)752 void SAL_CALL SfxBaseModel::setParent(const uno::Reference< uno::XInterface >& Parent)
753 {
754 SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
755 m_pData->m_xParent = Parent;
756 }
757
758 //________________________________________________________________________________________________________
759 // XChild
760 //________________________________________________________________________________________________________
761
dispose()762 void SAL_CALL SfxBaseModel::dispose()
763 {
764 SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
765
766 if ( !m_pData->m_bClosed )
767 {
768 // gracefully accept wrong dispose calls instead of close call
769 // and try to make it work (may be really disposed later!)
770 try
771 {
772 close( sal_True );
773 }
774 catch ( com::sun::star::util::CloseVetoException& )
775 {
776 }
777
778 return;
779 }
780
781 if ( m_pData->m_pStorageModifyListen.is() )
782 {
783 m_pData->m_pStorageModifyListen->dispose();
784 m_pData->m_pStorageModifyListen = NULL;
785 }
786
787 if ( m_pData->m_pDocumentUndoManager.is() )
788 {
789 m_pData->m_pDocumentUndoManager->disposing();
790 m_pData->m_pDocumentUndoManager = NULL;
791 }
792
793 lang::EventObject aEvent( (frame::XModel *)this );
794 m_pData->m_aInterfaceContainer.disposeAndClear( aEvent );
795
796 if ( m_pData->m_xDocumentInfo.is() )
797 {
798 // as long as an SfxObjectShell is assigned to an SfxBaseModel it is still existing here
799 // so we can't dispose the shared DocumentInfoObject here
800 // uno::Reference < lang::XComponent > xComp( m_pData->m_xDocumentInfo, uno::UNO_QUERY );
801 // xComp->dispose();
802 m_pData->m_xDocumentInfo = 0;
803 }
804
805 m_pData->m_xDocumentProperties.clear();
806
807 m_pData->m_xDocumentMetadata.clear();
808
809 EndListening( *m_pData->m_pObjectShell );
810
811 m_pData->m_xCurrent = uno::Reference< frame::XController > ();
812 m_pData->m_seqControllers = uno::Sequence< uno::Reference< frame::XController > > () ;
813
814 // m_pData member must be set to zero before 0delete is called to
815 // force disposed exception whenever someone tries to access our
816 // instance while in the dtor.
817 IMPL_SfxBaseModel_DataContainer* pData = m_pData;
818 m_pData = 0;
819 delete pData;
820 }
821
822 //________________________________________________________________________________________________________
823 // XChild
824 //________________________________________________________________________________________________________
825
addEventListener(const uno::Reference<XEVENTLISTENER> & aListener)826 void SAL_CALL SfxBaseModel::addEventListener( const uno::Reference< XEVENTLISTENER >& aListener )
827 {
828 SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
829 m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< XEVENTLISTENER >*)0), aListener );
830 }
831
832 //________________________________________________________________________________________________________
833 // XChild
834 //________________________________________________________________________________________________________
835
removeEventListener(const uno::Reference<XEVENTLISTENER> & aListener)836 void SAL_CALL SfxBaseModel::removeEventListener( const uno::Reference< XEVENTLISTENER >& aListener )
837 {
838 SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
839 m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XEVENTLISTENER >*)0), aListener );
840 }
841
842 //________________________________________________________________________________________________________
843 // document::XDocumentInfoSupplier
844 //________________________________________________________________________________________________________
845
getDocumentInfo()846 uno::Reference< document::XDocumentInfo > SAL_CALL SfxBaseModel::getDocumentInfo()
847 {
848 SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
849 if ( !m_pData->m_xDocumentInfo.is() )
850 {
851 // WARNING: this will only work if (when loading a document) the
852 // document meta-data has already been read and completely written
853 // into the XDocumentProperties at this point
854 // ==> DO NOT call getDocumentInfo before document info has been read!
855 uno::Reference< document::XDocumentInfo > xDocInfo =
856 new SfxDocumentInfoObject;
857 uno::Reference< document::XDocumentProperties > xDocProps =
858 getDocumentProperties();
859 uno::Sequence< uno::Any > args(1);
860 args[0] <<= xDocProps;
861 uno::Reference< lang::XInitialization > xInit(
862 xDocInfo, uno::UNO_QUERY_THROW);
863 try {
864 xInit->initialize(args);
865 ((SfxBaseModel*)this)->m_pData->m_xDocumentInfo = xDocInfo;
866 } catch (uno::RuntimeException &) {
867 throw;
868 } catch (uno::Exception & e) {
869 throw lang::WrappedTargetRuntimeException(::rtl::OUString::createFromAscii(
870 "SfxBaseModel::getDocumentInfo: cannot initialize"), *this,
871 uno::makeAny(e));
872 }
873 try {
874 rtl::OUString aName = rtl::OUString::createFromAscii("MediaType");
875 uno::Reference < beans::XPropertySet > xSet(
876 getDocumentStorage(), uno::UNO_QUERY );
877 uno::Any aMediaType = xSet->getPropertyValue( aName );
878 uno::Reference < beans::XPropertySet > xDocSet(
879 m_pData->m_xDocumentInfo, uno::UNO_QUERY );
880 xDocSet->setPropertyValue( aName, aMediaType );
881 } catch (uno::Exception &) {
882 //ignore
883 }
884 }
885
886 return m_pData->m_xDocumentInfo;
887 }
888
889 // document::XDocumentPropertiesSupplier:
890 uno::Reference< document::XDocumentProperties > SAL_CALL
getDocumentProperties()891 SfxBaseModel::getDocumentProperties()
892 {
893 SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
894 if ( !m_pData->m_xDocumentProperties.is() )
895 {
896 uno::Reference< lang::XInitialization > xDocProps(
897 ::comphelper::getProcessServiceFactory()->createInstance(
898 DEFINE_CONST_UNICODE("com.sun.star.document.DocumentProperties") ),
899 uno::UNO_QUERY_THROW);
900 // xDocProps->initialize(uno::Sequence<uno::Any>());
901 m_pData->m_xDocumentProperties.set(xDocProps, uno::UNO_QUERY_THROW);
902 uno::Reference<util::XModifyBroadcaster> xMB(m_pData->m_xDocumentProperties, uno::UNO_QUERY_THROW);
903 xMB->addModifyListener(new SfxDocInfoListener_Impl(*m_pData->m_pObjectShell));
904 }
905
906 return m_pData->m_xDocumentProperties;
907 }
908
909
910 //________________________________________________________________________________________________________
911 // XEVENTLISTENER
912 //________________________________________________________________________________________________________
913
disposing(const lang::EventObject & aObject)914 void SAL_CALL SfxBaseModel::disposing( const lang::EventObject& aObject )
915 {
916 ::vos::OGuard aGuard( Application::GetSolarMutex() );
917 if ( impl_isDisposed() )
918 return;
919
920 uno::Reference< XMODIFYLISTENER > xMod( aObject.Source, uno::UNO_QUERY );
921 uno::Reference< XEVENTLISTENER > xListener( aObject.Source, uno::UNO_QUERY );
922 uno::Reference< XDOCEVENTLISTENER > xDocListener( aObject.Source, uno::UNO_QUERY );
923
924 if ( xMod.is() )
925 m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XMODIFYLISTENER >*)0), xMod );
926 else if ( xListener.is() )
927 m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XEVENTLISTENER >*)0), xListener );
928 else if ( xDocListener.is() )
929 m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XDOCEVENTLISTENER >*)0), xDocListener );
930 }
931
932 //________________________________________________________________________________________________________
933 // frame::XModel
934 //________________________________________________________________________________________________________
935
attachResource(const::rtl::OUString & rURL,const uno::Sequence<beans::PropertyValue> & rArgs)936 sal_Bool SAL_CALL SfxBaseModel::attachResource( const ::rtl::OUString& rURL ,
937 const uno::Sequence< beans::PropertyValue >& rArgs )
938 {
939 SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
940 if ( rURL.getLength() == 0 && rArgs.getLength() == 1 && rArgs[0].Name.equalsAscii( "SetEmbedded" ) )
941 {
942 // allows to set a windowless document to EMBEDDED state
943 // but _only_ before load() or initNew() methods
944 if ( m_pData->m_pObjectShell.Is() && !m_pData->m_pObjectShell->GetMedium() )
945 {
946 sal_Bool bEmb = sal_Bool();
947 if ( ( rArgs[0].Value >>= bEmb ) && bEmb )
948 m_pData->m_pObjectShell->SetCreateMode_Impl( SFX_CREATE_MODE_EMBEDDED );
949 }
950
951 return sal_True;
952 }
953
954 if ( m_pData->m_pObjectShell.Is() )
955 {
956 m_pData->m_sURL = rURL;
957
958 SfxObjectShell* pObjectShell = m_pData->m_pObjectShell;
959
960 ::comphelper::NamedValueCollection aArgs( rArgs );
961
962 Sequence< sal_Int32 > aWinExtent;
963 if ( ( aArgs.get( "WinExtent" ) >>= aWinExtent )&& ( aWinExtent.getLength() == 4 ) )
964 {
965 Rectangle aVisArea( aWinExtent[0], aWinExtent[1], aWinExtent[2], aWinExtent[3] );
966 aVisArea = OutputDevice::LogicToLogic( aVisArea, MAP_100TH_MM, pObjectShell->GetMapUnit() );
967 pObjectShell->SetVisArea( aVisArea );
968 }
969
970 sal_Bool bBreakMacroSign = sal_False;
971 if ( aArgs.get( "BreakMacroSignature" ) >>= bBreakMacroSign )
972 {
973 pObjectShell->BreakMacroSign_Impl( bBreakMacroSign );
974 }
975
976 aArgs.remove( "WinExtent" );
977 aArgs.remove( "BreakMacroSignature" );
978 aArgs.remove( "Stream" );
979 aArgs.remove( "InputStream" );
980 aArgs.remove( "URL" );
981 aArgs.remove( "Frame" );
982 aArgs.remove( "Password" );
983 aArgs.remove( "EncryptionData" );
984
985 // TODO/LATER: all the parameters that are accepted by ItemSet of the DocShell must be removed here
986
987 m_pData->m_seqArguments = aArgs.getPropertyValues();
988
989 SfxMedium* pMedium = pObjectShell->GetMedium();
990 if ( pMedium )
991 {
992 SfxAllItemSet aSet( pObjectShell->GetPool() );
993 TransformParameters( SID_OPENDOC, rArgs, aSet );
994
995 // the arguments are not allowed to reach the medium
996 aSet.ClearItem( SID_FILE_NAME );
997 aSet.ClearItem( SID_FILLFRAME );
998
999 pMedium->GetItemSet()->Put( aSet );
1000 SFX_ITEMSET_ARG( &aSet, pItem, SfxStringItem, SID_FILTER_NAME, sal_False );
1001 if ( pItem )
1002 pMedium->SetFilter(
1003 pObjectShell->GetFactory().GetFilterContainer()->GetFilter4FilterName( pItem->GetValue() ) );
1004
1005 SFX_ITEMSET_ARG( &aSet, pTitleItem, SfxStringItem, SID_DOCINFO_TITLE, sal_False );
1006 if ( pTitleItem )
1007 {
1008 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pObjectShell );
1009 if ( pFrame )
1010 pFrame->UpdateTitle();
1011 }
1012 }
1013 }
1014
1015 return sal_True ;
1016 }
1017
1018 //________________________________________________________________________________________________________
1019 // frame::XModel
1020 //________________________________________________________________________________________________________
1021
getURL()1022 ::rtl::OUString SAL_CALL SfxBaseModel::getURL()
1023 {
1024 SfxModelGuard aGuard( *this );
1025 return m_pData->m_sURL ;
1026 }
1027
1028 //________________________________________________________________________________________________________
1029 // frame::XModel
1030 //________________________________________________________________________________________________________
1031
getArgs()1032 uno::Sequence< beans::PropertyValue > SAL_CALL SfxBaseModel::getArgs()
1033 {
1034 SfxModelGuard aGuard( *this );
1035 if ( m_pData->m_pObjectShell.Is() )
1036 {
1037 uno::Sequence< beans::PropertyValue > seqArgsNew;
1038 uno::Sequence< beans::PropertyValue > seqArgsOld;
1039 SfxAllItemSet aSet( m_pData->m_pObjectShell->GetPool() );
1040
1041 // we need to know which properties are supported by the transformer
1042 // hopefully it is a temporary solution, I guess nonconvertable properties
1043 // should not be supported so then there will be only ItemSet from medium
1044
1045 TransformItems( SID_OPENDOC, *(m_pData->m_pObjectShell->GetMedium()->GetItemSet()), seqArgsNew );
1046 TransformParameters( SID_OPENDOC, m_pData->m_seqArguments, aSet );
1047 TransformItems( SID_OPENDOC, aSet, seqArgsOld );
1048
1049 sal_Int32 nOrgLength = m_pData->m_seqArguments.getLength();
1050 sal_Int32 nOldLength = seqArgsOld.getLength();
1051 sal_Int32 nNewLength = seqArgsNew.getLength();
1052
1053 // "WinExtent" property should be updated always.
1054 // We can store it now to overwrite an old value
1055 // since it is not from ItemSet
1056 Rectangle aTmpRect = m_pData->m_pObjectShell->GetVisArea( ASPECT_CONTENT );
1057 aTmpRect = OutputDevice::LogicToLogic( aTmpRect, m_pData->m_pObjectShell->GetMapUnit(), MAP_100TH_MM );
1058
1059 Sequence< sal_Int32 > aRectSeq(4);
1060 aRectSeq[0] = aTmpRect.Left();
1061 aRectSeq[1] = aTmpRect.Top();
1062 aRectSeq[2] = aTmpRect.Right();
1063 aRectSeq[3] = aTmpRect.Bottom();
1064
1065 seqArgsNew.realloc( ++nNewLength );
1066 seqArgsNew[ nNewLength - 1 ].Name = ::rtl::OUString::createFromAscii( "WinExtent" );
1067 seqArgsNew[ nNewLength - 1 ].Value <<= aRectSeq;
1068
1069 if ( m_pData->m_aPreusedFilterName.getLength() )
1070 {
1071 seqArgsNew.realloc( ++nNewLength );
1072 seqArgsNew[ nNewLength - 1 ].Name = ::rtl::OUString::createFromAscii( "PreusedFilterName" );
1073 seqArgsNew[ nNewLength - 1 ].Value <<= m_pData->m_aPreusedFilterName;
1074 }
1075
1076 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( m_pData->m_pObjectShell );
1077 if ( pFrame )
1078 {
1079 SvBorder aBorder = pFrame->GetBorderPixelImpl( pFrame->GetViewShell() );
1080
1081 Sequence< sal_Int32 > aBorderSeq(4);
1082 aBorderSeq[0] = aBorder.Left();
1083 aBorderSeq[1] = aBorder.Top();
1084 aBorderSeq[2] = aBorder.Right();
1085 aBorderSeq[3] = aBorder.Bottom();
1086
1087 seqArgsNew.realloc( ++nNewLength );
1088 seqArgsNew[ nNewLength - 1 ].Name = ::rtl::OUString::createFromAscii( "DocumentBorder" );
1089 seqArgsNew[ nNewLength - 1 ].Value <<= aBorderSeq;
1090 }
1091
1092 // only the values that are not supported by the ItemSet must be cached here
1093 uno::Sequence< beans::PropertyValue > aFinalCache;
1094 sal_Int32 nFinalLength = 0;
1095
1096 for ( sal_Int32 nOrg = 0; nOrg < nOrgLength; nOrg++ )
1097 {
1098 sal_Int32 nOldInd = 0;
1099 while ( nOldInd < nOldLength )
1100 {
1101 if ( m_pData->m_seqArguments[nOrg].Name.equals( seqArgsOld[nOldInd].Name ) )
1102 break;
1103 nOldInd++;
1104 }
1105
1106 if ( nOldInd == nOldLength )
1107 {
1108 // the entity with this name should be new for seqArgsNew
1109 // since it is not supported by transformer
1110
1111 seqArgsNew.realloc( ++nNewLength );
1112 seqArgsNew[ nNewLength - 1 ] = m_pData->m_seqArguments[nOrg];
1113
1114 aFinalCache.realloc( ++nFinalLength );
1115 aFinalCache[ nFinalLength - 1 ] = m_pData->m_seqArguments[nOrg];
1116 }
1117 }
1118
1119 m_pData->m_seqArguments = aFinalCache;
1120
1121 return seqArgsNew;
1122 }
1123
1124 return m_pData->m_seqArguments;
1125 }
1126
1127 //________________________________________________________________________________________________________
1128 // frame::XModel
1129 //________________________________________________________________________________________________________
1130
connectController(const uno::Reference<frame::XController> & xController)1131 void SAL_CALL SfxBaseModel::connectController( const uno::Reference< frame::XController >& xController )
1132 {
1133 SfxModelGuard aGuard( *this );
1134 OSL_PRECOND( xController.is(), "SfxBaseModel::connectController: invalid controller!" );
1135 if ( !xController.is() )
1136 return;
1137
1138 sal_uInt32 nOldCount = m_pData->m_seqControllers.getLength();
1139 uno::Sequence< uno::Reference< frame::XController > > aNewSeq( nOldCount + 1 );
1140 for ( sal_uInt32 n = 0; n < nOldCount; n++ )
1141 aNewSeq.getArray()[n] = m_pData->m_seqControllers.getConstArray()[n];
1142 aNewSeq.getArray()[nOldCount] = xController;
1143 m_pData->m_seqControllers = aNewSeq;
1144
1145 if ( m_pData->m_seqControllers.getLength() == 1 )
1146 {
1147 SfxViewFrame* pViewFrame = SfxViewFrame::Get( xController, GetObjectShell() );
1148 ENSURE_OR_THROW( pViewFrame, "SFX document without SFX view!?" );
1149 pViewFrame->UpdateDocument_Impl();
1150 const String sDocumentURL = GetObjectShell()->GetMedium()->GetName();
1151 if ( sDocumentURL.Len() )
1152 SFX_APP()->Broadcast( SfxStringHint( SID_OPENURL, sDocumentURL ) );
1153 }
1154 }
1155
1156 //________________________________________________________________________________________________________
1157 // frame::XModel
1158 //________________________________________________________________________________________________________
1159
disconnectController(const uno::Reference<frame::XController> & xController)1160 void SAL_CALL SfxBaseModel::disconnectController( const uno::Reference< frame::XController >& xController )
1161 {
1162 SfxModelGuard aGuard( *this );
1163
1164 sal_uInt32 nOldCount = m_pData->m_seqControllers.getLength();
1165 if ( !nOldCount )
1166 return;
1167
1168 uno::Sequence< uno::Reference< frame::XController > > aNewSeq( nOldCount - 1 );
1169 for ( sal_uInt32 nOld = 0, nNew = 0; nOld < nOldCount; ++nOld )
1170 {
1171 if ( xController != m_pData->m_seqControllers.getConstArray()[nOld] )
1172 {
1173 aNewSeq.getArray()[nNew] = m_pData->m_seqControllers.getConstArray()[nOld];
1174 ++nNew;
1175 }
1176 }
1177
1178 m_pData->m_seqControllers = aNewSeq;
1179
1180 if ( xController == m_pData->m_xCurrent )
1181 m_pData->m_xCurrent = uno::Reference< frame::XController > ();
1182 }
1183
1184 namespace
1185 {
1186 typedef ::cppu::WeakImplHelper1< XUndoAction > ControllerLockUndoAction_Base;
1187 class ControllerLockUndoAction : public ControllerLockUndoAction_Base
1188 {
1189 public:
ControllerLockUndoAction(const Reference<XModel> & i_model,const bool i_undoIsUnlock)1190 ControllerLockUndoAction( const Reference< XModel >& i_model, const bool i_undoIsUnlock )
1191 :m_xModel( i_model )
1192 ,m_bUndoIsUnlock( i_undoIsUnlock )
1193 {
1194 }
1195
1196 // XUndoAction
1197 virtual ::rtl::OUString SAL_CALL getTitle();
1198 virtual void SAL_CALL undo( );
1199 virtual void SAL_CALL redo( );
1200
1201 private:
1202 const Reference< XModel > m_xModel;
1203 const bool m_bUndoIsUnlock;
1204 };
1205
getTitle()1206 ::rtl::OUString SAL_CALL ControllerLockUndoAction::getTitle()
1207 {
1208 // this action is intended to be used within an UndoContext only, so nobody will ever see this title ...
1209 return ::rtl::OUString();
1210 }
1211
undo()1212 void SAL_CALL ControllerLockUndoAction::undo( )
1213 {
1214 if ( m_bUndoIsUnlock )
1215 m_xModel->unlockControllers();
1216 else
1217 m_xModel->lockControllers();
1218 }
1219
redo()1220 void SAL_CALL ControllerLockUndoAction::redo( )
1221 {
1222 if ( m_bUndoIsUnlock )
1223 m_xModel->lockControllers();
1224 else
1225 m_xModel->unlockControllers();
1226 }
1227 }
1228
1229 //________________________________________________________________________________________________________
1230 // frame::XModel
1231 //________________________________________________________________________________________________________
1232
lockControllers()1233 void SAL_CALL SfxBaseModel::lockControllers()
1234 {
1235 SfxModelGuard aGuard( *this );
1236
1237 ++m_pData->m_nControllerLockCount ;
1238
1239 if ( m_pData->m_pDocumentUndoManager.is()
1240 && m_pData->m_pDocumentUndoManager->isInContext()
1241 && !m_pData->m_pDocumentUndoManager->isLocked()
1242 )
1243 {
1244 m_pData->m_pDocumentUndoManager->addUndoAction( new ControllerLockUndoAction( this, true ) );
1245 }
1246 }
1247
1248 //________________________________________________________________________________________________________
1249 // frame::XModel
1250 //________________________________________________________________________________________________________
1251
unlockControllers()1252 void SAL_CALL SfxBaseModel::unlockControllers()
1253 {
1254 SfxModelGuard aGuard( *this );
1255
1256 --m_pData->m_nControllerLockCount ;
1257
1258 if ( m_pData->m_pDocumentUndoManager.is()
1259 && m_pData->m_pDocumentUndoManager->isInContext()
1260 && !m_pData->m_pDocumentUndoManager->isLocked()
1261 )
1262 {
1263 m_pData->m_pDocumentUndoManager->addUndoAction( new ControllerLockUndoAction( this, false ) );
1264 }
1265 }
1266
1267 //________________________________________________________________________________________________________
1268 // frame::XModel
1269 //________________________________________________________________________________________________________
1270
hasControllersLocked()1271 sal_Bool SAL_CALL SfxBaseModel::hasControllersLocked()
1272 {
1273 SfxModelGuard aGuard( *this );
1274 return ( m_pData->m_nControllerLockCount != 0 ) ;
1275 }
1276
1277 //________________________________________________________________________________________________________
1278 // frame::XModel
1279 //________________________________________________________________________________________________________
1280
getCurrentController()1281 uno::Reference< frame::XController > SAL_CALL SfxBaseModel::getCurrentController()
1282 {
1283 SfxModelGuard aGuard( *this );
1284
1285 // get the last active controller of this model
1286 if ( m_pData->m_xCurrent.is() )
1287 return m_pData->m_xCurrent;
1288
1289 // get the first controller of this model
1290 return m_pData->m_seqControllers.getLength() ? m_pData->m_seqControllers.getConstArray()[0] : m_pData->m_xCurrent;
1291 }
1292
1293 //________________________________________________________________________________________________________
1294 // frame::XModel
1295 //________________________________________________________________________________________________________
1296
setCurrentController(const uno::Reference<frame::XController> & xCurrentController)1297 void SAL_CALL SfxBaseModel::setCurrentController( const uno::Reference< frame::XController >& xCurrentController )
1298 {
1299 SfxModelGuard aGuard( *this );
1300
1301 m_pData->m_xCurrent = xCurrentController;
1302 }
1303
1304 //________________________________________________________________________________________________________
1305 // frame::XModel
1306 //________________________________________________________________________________________________________
1307
getCurrentSelection()1308 uno::Reference< uno::XInterface > SAL_CALL SfxBaseModel::getCurrentSelection()
1309 {
1310 SfxModelGuard aGuard( *this );
1311
1312 uno::Reference< uno::XInterface > xReturn;
1313 uno::Reference< frame::XController > xController = getCurrentController() ;
1314
1315 if ( xController.is() )
1316 {
1317 uno::Reference< view::XSelectionSupplier > xDocView( xController, uno::UNO_QUERY );
1318 if ( xDocView.is() )
1319 {
1320 uno::Any xSel = xDocView->getSelection();
1321 xSel >>= xReturn ;
1322 }
1323 }
1324
1325 return xReturn ;
1326 }
1327
1328 //________________________________________________________________________________________________________
1329 // XModifiable2
1330 //________________________________________________________________________________________________________
1331
disableSetModified()1332 sal_Bool SAL_CALL SfxBaseModel::disableSetModified()
1333 {
1334 SfxModelGuard aGuard( *this );
1335
1336 if ( !m_pData->m_pObjectShell.Is() )
1337 throw uno::RuntimeException();
1338
1339 sal_Bool bResult = m_pData->m_pObjectShell->IsEnableSetModified();
1340 m_pData->m_pObjectShell->EnableSetModified( sal_False );
1341
1342 return bResult;
1343 }
1344
enableSetModified()1345 sal_Bool SAL_CALL SfxBaseModel::enableSetModified()
1346 {
1347 SfxModelGuard aGuard( *this );
1348
1349 if ( !m_pData->m_pObjectShell.Is() )
1350 throw uno::RuntimeException();
1351
1352 sal_Bool bResult = m_pData->m_pObjectShell->IsEnableSetModified();
1353 m_pData->m_pObjectShell->EnableSetModified( sal_True );
1354
1355 return bResult;
1356 }
1357
isSetModifiedEnabled()1358 sal_Bool SAL_CALL SfxBaseModel::isSetModifiedEnabled()
1359 {
1360 SfxModelGuard aGuard( *this );
1361
1362 if ( !m_pData->m_pObjectShell.Is() )
1363 throw uno::RuntimeException();
1364
1365 return m_pData->m_pObjectShell->IsEnableSetModified();
1366 }
1367
1368 //________________________________________________________________________________________________________
1369 // XModifiable
1370 //________________________________________________________________________________________________________
1371
isModified()1372 sal_Bool SAL_CALL SfxBaseModel::isModified()
1373 {
1374 SfxModelGuard aGuard( *this );
1375
1376 return m_pData->m_pObjectShell.Is() ? m_pData->m_pObjectShell->IsModified() : sal_False;
1377 }
1378
1379 //________________________________________________________________________________________________________
1380 // XModifiable
1381 //________________________________________________________________________________________________________
1382
setModified(sal_Bool bModified)1383 void SAL_CALL SfxBaseModel::setModified( sal_Bool bModified )
1384 {
1385 SfxModelGuard aGuard( *this );
1386
1387 if ( m_pData->m_pObjectShell.Is() )
1388 m_pData->m_pObjectShell->SetModified(bModified);
1389 }
1390
1391 //________________________________________________________________________________________________________
1392 // XModifiable
1393 //________________________________________________________________________________________________________
1394
addModifyListener(const uno::Reference<XMODIFYLISTENER> & xListener)1395 void SAL_CALL SfxBaseModel::addModifyListener(const uno::Reference< XMODIFYLISTENER >& xListener)
1396 {
1397 SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
1398
1399 m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< XMODIFYLISTENER >*)0),xListener );
1400 }
1401
1402 //________________________________________________________________________________________________________
1403 // XModifiable
1404 //________________________________________________________________________________________________________
1405
removeModifyListener(const uno::Reference<XMODIFYLISTENER> & xListener)1406 void SAL_CALL SfxBaseModel::removeModifyListener(const uno::Reference< XMODIFYLISTENER >& xListener)
1407 {
1408 SfxModelGuard aGuard( *this );
1409
1410 m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XMODIFYLISTENER >*)0), xListener );
1411 }
1412
1413 //____________________________________________________________________________________________________
1414 // XCloseable
1415 //____________________________________________________________________________________________________
1416
close(sal_Bool bDeliverOwnership)1417 void SAL_CALL SfxBaseModel::close( sal_Bool bDeliverOwnership )
1418 {
1419 static ::rtl::OUString MSG_1 = ::rtl::OUString::createFromAscii("Can't close while saving.");
1420
1421 ::vos::OGuard aGuard( Application::GetSolarMutex() );
1422 if ( impl_isDisposed() || m_pData->m_bClosed || m_pData->m_bClosing )
1423 return;
1424
1425 uno::Reference< uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >(this) );
1426 lang::EventObject aSource (static_cast< ::cppu::OWeakObject*>(this));
1427 ::cppu::OInterfaceContainerHelper* pContainer = m_pData->m_aInterfaceContainer.getContainer( ::getCppuType( ( const uno::Reference< util::XCloseListener >*) NULL ) );
1428 if (pContainer!=NULL)
1429 {
1430 ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
1431 while (pIterator.hasMoreElements())
1432 {
1433 try
1434 {
1435 ((util::XCloseListener*)pIterator.next())->queryClosing( aSource, bDeliverOwnership );
1436 }
1437 catch( uno::RuntimeException& )
1438 {
1439 pIterator.remove();
1440 }
1441 }
1442 }
1443
1444 if ( m_pData->m_bSaving )
1445 {
1446 if (bDeliverOwnership)
1447 m_pData->m_bSuicide = sal_True;
1448 throw util::CloseVetoException(
1449 MSG_1,
1450 static_cast< ::com::sun::star::util::XCloseable* >(this));
1451 }
1452
1453 // no own objections against closing!
1454 m_pData->m_bClosing = sal_True;
1455 pContainer = m_pData->m_aInterfaceContainer.getContainer( ::getCppuType( ( const uno::Reference< util::XCloseListener >*) NULL ) );
1456 if (pContainer!=NULL)
1457 {
1458 ::cppu::OInterfaceIteratorHelper pCloseIterator(*pContainer);
1459 while (pCloseIterator.hasMoreElements())
1460 {
1461 try
1462 {
1463 ((util::XCloseListener*)pCloseIterator.next())->notifyClosing( aSource );
1464 }
1465 catch( uno::RuntimeException& )
1466 {
1467 pCloseIterator.remove();
1468 }
1469 }
1470 }
1471
1472 m_pData->m_bClosed = sal_True;
1473 m_pData->m_bClosing = sal_False;
1474
1475 dispose();
1476 }
1477
1478 //____________________________________________________________________________________________________
1479 // XCloseBroadcaster
1480 //____________________________________________________________________________________________________
1481
addCloseListener(const uno::Reference<XCLOSELISTENER> & xListener)1482 void SAL_CALL SfxBaseModel::addCloseListener( const uno::Reference< XCLOSELISTENER >& xListener )
1483 {
1484 SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
1485
1486 m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< XCLOSELISTENER >*)0), xListener );
1487 }
1488
1489 //____________________________________________________________________________________________________
1490 // XCloseBroadcaster
1491 //____________________________________________________________________________________________________
1492
removeCloseListener(const uno::Reference<XCLOSELISTENER> & xListener)1493 void SAL_CALL SfxBaseModel::removeCloseListener( const uno::Reference< XCLOSELISTENER >& xListener )
1494 {
1495 SfxModelGuard aGuard( *this );
1496
1497 m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XCLOSELISTENER >*)0), xListener );
1498 }
1499
1500 //________________________________________________________________________________________________________
1501 // XPrintable
1502 //________________________________________________________________________________________________________
1503
getPrinter()1504 uno::Sequence< beans::PropertyValue > SAL_CALL SfxBaseModel::getPrinter()
1505 {
1506 SfxModelGuard aGuard( *this );
1507
1508 if ( impl_getPrintHelper() )
1509 return m_pData->m_xPrintable->getPrinter();
1510 else
1511 return uno::Sequence< beans::PropertyValue >();
1512 }
1513
setPrinter(const uno::Sequence<beans::PropertyValue> & rPrinter)1514 void SAL_CALL SfxBaseModel::setPrinter(const uno::Sequence< beans::PropertyValue >& rPrinter)
1515 {
1516 SfxModelGuard aGuard( *this );
1517
1518 if ( impl_getPrintHelper() )
1519 m_pData->m_xPrintable->setPrinter( rPrinter );
1520 }
1521
print(const uno::Sequence<beans::PropertyValue> & rOptions)1522 void SAL_CALL SfxBaseModel::print(const uno::Sequence< beans::PropertyValue >& rOptions)
1523 {
1524 SfxModelGuard aGuard( *this );
1525
1526 if ( impl_getPrintHelper() )
1527 m_pData->m_xPrintable->print( rOptions );
1528 }
1529
1530 //________________________________________________________________________________________________________
1531 // XStorable
1532 //________________________________________________________________________________________________________
1533
hasLocation()1534 sal_Bool SAL_CALL SfxBaseModel::hasLocation()
1535 {
1536 SfxModelGuard aGuard( *this );
1537
1538 return m_pData->m_pObjectShell.Is() ? m_pData->m_pObjectShell->HasName() : sal_False;
1539 }
1540
1541 //________________________________________________________________________________________________________
1542 // XStorable
1543 //________________________________________________________________________________________________________
1544
getLocation()1545 ::rtl::OUString SAL_CALL SfxBaseModel::getLocation()
1546 {
1547 SfxModelGuard aGuard( *this );
1548
1549 if ( m_pData->m_pObjectShell.Is() )
1550 {
1551 // TODO/LATER: is it correct that the shared document returns shared file location?
1552 if ( m_pData->m_pObjectShell->IsDocShared() )
1553 return m_pData->m_pObjectShell->GetSharedFileURL();
1554 else
1555 return ::rtl::OUString(m_pData->m_pObjectShell->GetMedium()->GetName());
1556 }
1557
1558 return m_pData->m_sURL;
1559 }
1560
1561 //________________________________________________________________________________________________________
1562 // XStorable
1563 //________________________________________________________________________________________________________
1564
isReadonly()1565 sal_Bool SAL_CALL SfxBaseModel::isReadonly()
1566 {
1567 SfxModelGuard aGuard( *this );
1568
1569 return m_pData->m_pObjectShell.Is() ? m_pData->m_pObjectShell->IsReadOnly() : sal_True;
1570 }
1571
1572 //________________________________________________________________________________________________________
1573 // XStorable2
1574 //________________________________________________________________________________________________________
1575
storeSelf(const uno::Sequence<beans::PropertyValue> & aSeqArgs)1576 void SAL_CALL SfxBaseModel::storeSelf( const uno::Sequence< beans::PropertyValue >& aSeqArgs )
1577 {
1578 RTL_LOGFILE_PRODUCT_CONTEXT( aPerfLog, "PERFORMANCE - SfxBaseModel::storeSelf" );
1579
1580 SfxModelGuard aGuard( *this );
1581
1582 if ( m_pData->m_pObjectShell.Is() )
1583 {
1584 m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "storeSelf" ) ) );
1585 SfxSaveGuard aSaveGuard(this, m_pData, sal_False);
1586
1587 for ( sal_Int32 nInd = 0; nInd < aSeqArgs.getLength(); nInd++ )
1588 {
1589 // check that only acceptable parameters are provided here
1590 if ( !aSeqArgs[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VersionComment" ) ) )
1591 && !aSeqArgs[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Author" ) ) )
1592 && !aSeqArgs[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InteractionHandler" ) ) )
1593 && !aSeqArgs[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StatusIndicator" ) ) )
1594 && !aSeqArgs[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FailOnWarning" ) ) ) )
1595 {
1596 m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "unexpected parameter for storeSelf, might be no problem if SaveAs is executed." ) ) );
1597 m_pData->m_pObjectShell->StoreLog();
1598
1599 ::rtl::OUString aMessage( RTL_CONSTASCII_USTRINGPARAM( "Unexpected MediaDescriptor parameter: " ) );
1600 aMessage += aSeqArgs[nInd].Name;
1601 throw lang::IllegalArgumentException( aMessage, uno::Reference< uno::XInterface >(), 1 );
1602 }
1603 }
1604
1605 SfxAllItemSet *pParams = new SfxAllItemSet( SFX_APP()->GetPool() );
1606 TransformParameters( SID_SAVEDOC, aSeqArgs, *pParams );
1607
1608 SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_SAVEDOC, GlobalEventConfig::GetEventName(STR_EVENT_SAVEDOC), m_pData->m_pObjectShell ) );
1609
1610 sal_Bool bRet = sal_False;
1611
1612 // TODO/LATER: let the embedded case of saving be handled more careful
1613 if ( m_pData->m_pObjectShell->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
1614 {
1615 // If this is an embedded object that has no URL based location it should be stored to own storage.
1616 // An embedded object can have a location based on URL in case it is a link, then it should be
1617 // stored in normal way.
1618 if ( !hasLocation() || getLocation().compareToAscii( "private:", 8 ) == 0 )
1619 {
1620 // actually in this very rare case only UI parameters have sense
1621 // TODO/LATER: should be done later, after integration of sb19
1622 bRet = m_pData->m_pObjectShell->DoSave()
1623 && m_pData->m_pObjectShell->DoSaveCompleted();
1624 }
1625 else
1626 {
1627 bRet = m_pData->m_pObjectShell->Save_Impl( pParams );
1628 }
1629 }
1630 else
1631 bRet = m_pData->m_pObjectShell->Save_Impl( pParams );
1632
1633 DELETEZ( pParams );
1634
1635 sal_uInt32 nErrCode = m_pData->m_pObjectShell->GetError() ? m_pData->m_pObjectShell->GetError()
1636 : ERRCODE_IO_CANTWRITE;
1637 m_pData->m_pObjectShell->ResetError();
1638
1639 if ( bRet )
1640 {
1641 m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "successful saving." ) ) );
1642 m_pData->m_aPreusedFilterName = GetMediumFilterName_Impl();
1643
1644 SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_SAVEDOCDONE, GlobalEventConfig::GetEventName(STR_EVENT_SAVEDOCDONE), m_pData->m_pObjectShell ) );
1645 }
1646 else
1647 {
1648 m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Storing failed!" ) ) );
1649 m_pData->m_pObjectShell->StoreLog();
1650
1651 // write the contents of the logger to the file
1652 SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_SAVEDOCFAILED, GlobalEventConfig::GetEventName(STR_EVENT_SAVEDOCFAILED), m_pData->m_pObjectShell ) );
1653
1654 throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), nErrCode );
1655 }
1656 }
1657
1658 }
1659
1660 //________________________________________________________________________________________________________
1661 // XStorable
1662 //________________________________________________________________________________________________________
1663
store()1664 void SAL_CALL SfxBaseModel::store()
1665 {
1666 storeSelf( uno::Sequence< beans::PropertyValue >() );
1667 }
1668
1669 //________________________________________________________________________________________________________
1670 // XStorable
1671 //________________________________________________________________________________________________________
1672
storeAsURL(const::rtl::OUString & rURL,const uno::Sequence<beans::PropertyValue> & rArgs)1673 void SAL_CALL SfxBaseModel::storeAsURL( const ::rtl::OUString& rURL ,
1674 const uno::Sequence< beans::PropertyValue >& rArgs )
1675 {
1676 RTL_LOGFILE_PRODUCT_CONTEXT( aPerfLog, "PERFORMANCE - SfxBaseModel::storeAsURL" );
1677
1678 SfxModelGuard aGuard( *this );
1679
1680 if ( m_pData->m_pObjectShell.Is() )
1681 {
1682 m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "storeAsURL" ) ) );
1683 SfxSaveGuard aSaveGuard(this, m_pData, sal_False);
1684
1685 impl_store( rURL, rArgs, sal_False );
1686
1687 uno::Sequence< beans::PropertyValue > aSequence ;
1688 TransformItems( SID_OPENDOC, *m_pData->m_pObjectShell->GetMedium()->GetItemSet(), aSequence );
1689 attachResource( rURL, aSequence );
1690
1691 #if OSL_DEBUG_LEVEL > 0
1692 SFX_ITEMSET_ARG( m_pData->m_pObjectShell->GetMedium()->GetItemSet(), pPasswdItem, SfxStringItem, SID_PASSWORD, sal_False);
1693 OSL_ENSURE( !pPasswdItem, "There should be no Password property in the document MediaDescriptor!" );
1694 #endif
1695 }
1696 }
1697
1698 //________________________________________________________________________________________________________
1699 // XUndoManagerSupplier
1700 //________________________________________________________________________________________________________
getUndoManager()1701 Reference< XUndoManager > SAL_CALL SfxBaseModel::getUndoManager( )
1702 {
1703 SfxModelGuard aGuard( *this );
1704 if ( !m_pData->m_pDocumentUndoManager.is() )
1705 m_pData->m_pDocumentUndoManager.set( new ::sfx2::DocumentUndoManager( *this ) );
1706 return m_pData->m_pDocumentUndoManager.get();
1707 }
1708
1709 //________________________________________________________________________________________________________
1710 // XStorable
1711 //________________________________________________________________________________________________________
1712
storeToURL(const::rtl::OUString & rURL,const uno::Sequence<beans::PropertyValue> & rArgs)1713 void SAL_CALL SfxBaseModel::storeToURL( const ::rtl::OUString& rURL ,
1714 const uno::Sequence< beans::PropertyValue >& rArgs )
1715 {
1716 SfxModelGuard aGuard( *this );
1717
1718 if ( m_pData->m_pObjectShell.Is() )
1719 {
1720 m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "storeToURL" ) ) );
1721 SfxSaveGuard aSaveGuard(this, m_pData, sal_False);
1722 impl_store( rURL, rArgs, sal_True );
1723 }
1724 }
1725
wasModifiedSinceLastSave()1726 ::sal_Bool SAL_CALL SfxBaseModel::wasModifiedSinceLastSave()
1727 {
1728 SfxModelGuard aGuard( *this );
1729 return m_pData->m_bModifiedSinceLastSave;
1730 }
1731
storeToRecoveryFile(const::rtl::OUString & i_TargetLocation,const Sequence<PropertyValue> & i_MediaDescriptor)1732 void SAL_CALL SfxBaseModel::storeToRecoveryFile( const ::rtl::OUString& i_TargetLocation, const Sequence< PropertyValue >& i_MediaDescriptor )
1733 {
1734 SfxModelGuard aGuard( *this );
1735
1736 // delegate
1737 SfxSaveGuard aSaveGuard( this, m_pData, sal_False );
1738 impl_store( i_TargetLocation, i_MediaDescriptor, sal_True );
1739
1740 // no need for subsequent calls to storeToRecoveryFile, unless we're modified, again
1741 m_pData->m_bModifiedSinceLastSave = sal_False;
1742 }
1743
recoverFromFile(const::rtl::OUString & i_SourceLocation,const::rtl::OUString & i_SalvagedFile,const Sequence<PropertyValue> & i_MediaDescriptor)1744 void SAL_CALL SfxBaseModel::recoverFromFile( const ::rtl::OUString& i_SourceLocation, const ::rtl::OUString& i_SalvagedFile, const Sequence< PropertyValue >& i_MediaDescriptor )
1745 {
1746 SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
1747
1748 // delegate to our "load" method
1749 ::comphelper::NamedValueCollection aMediaDescriptor( i_MediaDescriptor );
1750
1751 // our load implementation expects the SalvagedFile to be in the media descriptor
1752 OSL_ENSURE( !aMediaDescriptor.has( "SalvagedFile" ) || ( aMediaDescriptor.getOrDefault( "SalvagedFile", ::rtl::OUString() ) == i_SalvagedFile ),
1753 "SfxBaseModel::recoverFromFile: inconsistent information!" );
1754 aMediaDescriptor.put( "SalvagedFile", i_SalvagedFile );
1755
1756 // similar for the to-be-loaded file
1757 OSL_ENSURE( !aMediaDescriptor.has( "URL" ) || ( aMediaDescriptor.getOrDefault( "URL", ::rtl::OUString() ) == i_SourceLocation ),
1758 "SfxBaseModel::recoverFromFile: inconsistent information!" );
1759 aMediaDescriptor.put( "URL", i_SourceLocation );
1760
1761 load( aMediaDescriptor.getPropertyValues() );
1762
1763 // Note: The XDocumentRecovery interface specification requires us to do an attachResource after loading.
1764 // However, we will not do this here, as we know that our load implementation (respectively some method
1765 // called from there) already did so.
1766 // In particular, the load process might already have modified some elements of the media
1767 // descriptor, for instance the MacroExecMode (in case the user was involved to decide about it), and we do
1768 // not want to overwrite it with the "old" elements passed to this method here.
1769 }
1770
1771 //________________________________________________________________________________________________________
1772 // XLoadable
1773 //________________________________________________________________________________________________________
1774
initNew()1775 void SAL_CALL SfxBaseModel::initNew()
1776 {
1777 SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
1778 if ( IsInitialized() )
1779 throw ::com::sun::star::frame::DoubleInitializationException( ::rtl::OUString(), *this );
1780
1781 // the object shell should exist always
1782 DBG_ASSERT( m_pData->m_pObjectShell.Is(), "Model is useless without an ObjectShell" );
1783 if ( m_pData->m_pObjectShell.Is() )
1784 {
1785 if( m_pData->m_pObjectShell->GetMedium() )
1786 throw DOUBLEINITIALIZATIONEXCEPTION();
1787
1788 sal_Bool bRes = m_pData->m_pObjectShell->DoInitNew( NULL );
1789 sal_uInt32 nErrCode = m_pData->m_pObjectShell->GetError() ?
1790 m_pData->m_pObjectShell->GetError() : ERRCODE_IO_CANTCREATE;
1791 m_pData->m_pObjectShell->ResetError();
1792
1793 if ( !bRes )
1794 throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), nErrCode );
1795 }
1796 }
1797
1798 //________________________________________________________________________________________________________
1799 // XLoadable
1800 //________________________________________________________________________________________________________
1801
load(const uno::Sequence<beans::PropertyValue> & seqArguments)1802 void SAL_CALL SfxBaseModel::load( const uno::Sequence< beans::PropertyValue >& seqArguments )
1803 {
1804 SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
1805 if ( IsInitialized() )
1806 throw ::com::sun::star::frame::DoubleInitializationException( ::rtl::OUString(), *this );
1807
1808 // the object shell should exist always
1809 DBG_ASSERT( m_pData->m_pObjectShell.Is(), "Model is useless without an ObjectShell" );
1810
1811 if ( m_pData->m_pObjectShell.Is() )
1812 {
1813 if( m_pData->m_pObjectShell->GetMedium() )
1814 // if a Medium is present, the document is already initialized
1815 throw DOUBLEINITIALIZATIONEXCEPTION();
1816
1817 SfxMedium* pMedium = new SfxMedium( seqArguments );
1818 String aFilterName;
1819 SFX_ITEMSET_ARG( pMedium->GetItemSet(), pFilterNameItem, SfxStringItem, SID_FILTER_NAME, sal_False );
1820 if( pFilterNameItem )
1821 aFilterName = pFilterNameItem->GetValue();
1822 if( !m_pData->m_pObjectShell->GetFactory().GetFilterContainer()->GetFilter4FilterName( aFilterName ) )
1823 {
1824 // filtername is not valid
1825 delete pMedium;
1826 throw frame::IllegalArgumentIOException();
1827 }
1828
1829 // !TODO: currently not working
1830 //SFX_ITEMSET_ARG( pParams, pFrameItem, SfxFrameItem, SID_DOCFRAME, sal_False );
1831 //if( pFrameItem && pFrameItem->GetFrame() )
1832 //{
1833 // SfxFrame* pFrame = pFrameItem->GetFrame();
1834 // pMedium->SetLoadTargetFrame( pFrame );
1835 //}
1836
1837 SFX_ITEMSET_ARG( pMedium->GetItemSet(), pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, sal_False );
1838 sal_Bool bSalvage = pSalvageItem ? sal_True : sal_False;
1839
1840 // SFX_ITEMSET_ARG( pMedium->GetItemSet(), pTemplateItem, SfxBoolItem, SID_TEMPLATE, sal_False);
1841 // sal_Bool bTemplate = pTemplateItem && pTemplateItem->GetValue();
1842 //
1843 // does already happen in DoLoad call
1844 //m_pData->m_pObjectShell->SetActivateEvent_Impl( bTemplate ? SFX_EVENT_CREATEDOC : SFX_EVENT_OPENDOC );
1845
1846 // load document
1847 sal_uInt32 nError = ERRCODE_NONE;
1848 if ( !m_pData->m_pObjectShell->DoLoad(pMedium) )
1849 nError=ERRCODE_IO_GENERAL;
1850
1851 // QUESTION: if the following happens outside of DoLoad, something important is missing there!
1852 ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler > xHandler = pMedium->GetInteractionHandler();
1853 if( m_pData->m_pObjectShell->GetErrorCode() )
1854 {
1855 nError = m_pData->m_pObjectShell->GetErrorCode();
1856 if ( nError == ERRCODE_IO_BROKENPACKAGE && xHandler.is() )
1857 {
1858 ::rtl::OUString aDocName = pMedium->GetURLObject().getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
1859 SFX_ITEMSET_ARG( pMedium->GetItemSet(), pRepairItem, SfxBoolItem, SID_REPAIRPACKAGE, sal_False );
1860 if ( !pRepairItem || !pRepairItem->GetValue() )
1861 {
1862 RequestPackageReparation aRequest( aDocName );
1863 xHandler->handle( aRequest.GetRequest() );
1864 if( aRequest.isApproved() )
1865 {
1866 // broken package: try second loading and allow repair
1867 pMedium->GetItemSet()->Put( SfxBoolItem( SID_REPAIRPACKAGE, sal_True ) );
1868 pMedium->GetItemSet()->Put( SfxBoolItem( SID_TEMPLATE, sal_True ) );
1869 pMedium->GetItemSet()->Put( SfxStringItem( SID_DOCINFO_TITLE, aDocName ) );
1870
1871 // the error must be reset and the storage must be reopened in new mode
1872 pMedium->ResetError();
1873 pMedium->CloseStorage();
1874 m_pData->m_pObjectShell->PrepareSecondTryLoad_Impl();
1875 if ( !m_pData->m_pObjectShell->DoLoad(pMedium) )
1876 nError=ERRCODE_IO_GENERAL;
1877 nError = m_pData->m_pObjectShell->GetErrorCode();
1878 }
1879 }
1880
1881 if ( nError == ERRCODE_IO_BROKENPACKAGE )
1882 {
1883 // repair either not allowed or not successful
1884 NotifyBrokenPackage aRequest( aDocName );
1885 xHandler->handle( aRequest.GetRequest() );
1886 }
1887 }
1888 }
1889
1890 if( m_pData->m_pObjectShell->IsAbortingImport() )
1891 nError = ERRCODE_ABORT;
1892
1893 if( bSalvage )
1894 {
1895 // file recovery: restore original filter
1896 SFX_ITEMSET_ARG( pMedium->GetItemSet(), pFilterItem, SfxStringItem, SID_FILTER_NAME, sal_False );
1897 SfxFilterMatcher& rMatcher = SFX_APP()->GetFilterMatcher();
1898 const SfxFilter* pSetFilter = rMatcher.GetFilter4FilterName( pFilterItem->GetValue() );
1899 pMedium->SetFilter( pSetFilter );
1900 m_pData->m_pObjectShell->SetModified(sal_True);
1901 }
1902
1903 // TODO/LATER: may be the mode should be retrieved from outside and the preused filter should not be set
1904 if ( m_pData->m_pObjectShell->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
1905 {
1906 SFX_ITEMSET_ARG( pMedium->GetItemSet(), pFilterItem, SfxStringItem, SID_FILTER_NAME, sal_False );
1907 if ( pFilterItem )
1908 m_pData->m_aPreusedFilterName = pFilterItem->GetValue();
1909 }
1910
1911 if ( !nError )
1912 nError = pMedium->GetError();
1913
1914 m_pData->m_pObjectShell->ResetError();
1915
1916 if ( nError )
1917 {
1918 sal_Bool bSilent = sal_False;
1919 SFX_ITEMSET_ARG( pMedium->GetItemSet(), pSilentItem, SfxBoolItem, SID_SILENT, sal_False);
1920 if( pSilentItem )
1921 bSilent = pSilentItem->GetValue();
1922
1923 sal_Bool bWarning = ((nError & ERRCODE_WARNING_MASK) == ERRCODE_WARNING_MASK);
1924 if ( nError != ERRCODE_IO_BROKENPACKAGE && !bSilent )
1925 {
1926 // broken package was handled already
1927 if ( SfxObjectShell::UseInteractionToHandleError( xHandler, nError ) && !bWarning )
1928 {
1929 // abort loading (except for warnings)
1930 nError = ERRCODE_IO_ABORT;
1931 }
1932 }
1933
1934 if ( m_pData->m_pObjectShell->GetMedium() != pMedium )
1935 {
1936 // for whatever reason document now has another medium
1937 DBG_ERROR("Document has rejected the medium?!");
1938 delete pMedium;
1939 }
1940
1941 if ( !bWarning ) // #i30711# don't abort loading if it's only a warning
1942 {
1943 throw task::ErrorCodeIOException( ::rtl::OUString(),
1944 uno::Reference< uno::XInterface >(),
1945 nError ? nError : ERRCODE_IO_CANTREAD );
1946 }
1947 }
1948
1949 sal_Bool bHidden = sal_False;
1950 SFX_ITEMSET_ARG( pMedium->GetItemSet(), pHidItem, SfxBoolItem, SID_HIDDEN, sal_False);
1951 if ( pHidItem )
1952 bHidden = pHidItem->GetValue();
1953
1954 #if OSL_DEBUG_LEVEL > 0
1955 SFX_ITEMSET_ARG( pMedium->GetItemSet(), pPasswdItem, SfxStringItem, SID_PASSWORD, sal_False);
1956 OSL_ENSURE( !pPasswdItem, "There should be no Password property in the document MediaDescriptor!" );
1957 #endif
1958 // !TODO: will be done by Framework!
1959 pMedium->SetUpdatePickList( !bHidden );
1960 }
1961 }
1962
1963 //________________________________________________________________________________________________________
1964 // XTransferable
1965 //________________________________________________________________________________________________________
1966
getTransferData(const DATAFLAVOR & aFlavor)1967 uno::Any SAL_CALL SfxBaseModel::getTransferData( const DATAFLAVOR& aFlavor )
1968 {
1969 SfxModelGuard aGuard( *this );
1970
1971 uno::Any aAny;
1972
1973 if ( m_pData->m_pObjectShell.Is() )
1974 {
1975 if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"" ) )
1976 {
1977 if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
1978 {
1979 TransferableObjectDescriptor aDesc;
1980
1981 aDesc.maClassName = m_pData->m_pObjectShell->GetClassName();
1982 aDesc.maTypeName = aFlavor.HumanPresentableName;
1983
1984 // TODO/LATER: ViewAspect needs to be sal_Int64
1985 aDesc.mnViewAspect = sal::static_int_cast< sal_uInt16 >( embed::Aspects::MSOLE_CONTENT );
1986
1987 //TODO/LATER: status needs to become sal_Int64
1988 aDesc.mnOle2Misc = m_pData->m_pObjectShell->GetMiscStatus();
1989 Size aSize = m_pData->m_pObjectShell->GetVisArea().GetSize();
1990
1991 MapUnit aMapUnit = m_pData->m_pObjectShell->GetMapUnit();
1992 aDesc.maSize = OutputDevice::LogicToLogic( aSize, aMapUnit, MAP_100TH_MM );
1993 aDesc.maDragStartPos = Point();
1994 aDesc.maDisplayName = String();
1995 aDesc.mbCanLink = sal_False;
1996
1997 SvMemoryStream aMemStm( 1024, 1024 );
1998 aMemStm << aDesc;
1999 aAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Tell() );
2000 }
2001 else
2002 throw datatransfer::UnsupportedFlavorException();
2003 }
2004 else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-embed-source;windows_formatname=\"Star EMBS\"" ) )
2005 {
2006 if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
2007 {
2008 try
2009 {
2010 utl::TempFile aTmp;
2011 aTmp.EnableKillingFile( sal_True );
2012 storeToURL( aTmp.GetURL(), uno::Sequence < beans::PropertyValue >() );
2013 SvStream* pStream = aTmp.GetStream( STREAM_READ );
2014 const sal_uInt32 nLen = pStream->Seek( STREAM_SEEK_TO_END );
2015 ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( nLen );
2016 pStream->Seek( STREAM_SEEK_TO_BEGIN );
2017 pStream->Read( aSeq.getArray(), nLen );
2018 delete pStream;
2019 if( aSeq.getLength() )
2020 aAny <<= aSeq;
2021 }
2022 catch ( uno::Exception& )
2023 {
2024 }
2025 }
2026 else
2027 throw datatransfer::UnsupportedFlavorException();
2028 }
2029 else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" ) )
2030 {
2031 if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
2032 {
2033
2034 ::boost::shared_ptr<GDIMetaFile> pMetaFile =
2035 m_pData->m_pObjectShell->GetPreviewMetaFile( sal_True );
2036
2037 if ( pMetaFile )
2038 {
2039 SvMemoryStream aMemStm( 65535, 65535 );
2040 aMemStm.SetVersion( SOFFICE_FILEFORMAT_CURRENT );
2041
2042 pMetaFile->Write( aMemStm );
2043 aAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ),
2044 aMemStm.Seek( STREAM_SEEK_TO_END ) );
2045 }
2046 }
2047 else
2048 throw datatransfer::UnsupportedFlavorException();
2049 }
2050 else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" ) )
2051 {
2052 if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
2053 {
2054 ::boost::shared_ptr<GDIMetaFile> pMetaFile =
2055 m_pData->m_pObjectShell->CreatePreviewMetaFile_Impl( sal_True, sal_True );
2056
2057 if ( pMetaFile )
2058 {
2059 SvMemoryStream aMemStm( 65535, 65535 );
2060 aMemStm.SetVersion( SOFFICE_FILEFORMAT_CURRENT );
2061
2062 pMetaFile->Write( aMemStm );
2063 aAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ),
2064 aMemStm.Seek( STREAM_SEEK_TO_END ) );
2065 }
2066 }
2067 else
2068 throw datatransfer::UnsupportedFlavorException();
2069 }
2070 else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" ) )
2071 {
2072 if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
2073 {
2074 ::boost::shared_ptr<GDIMetaFile> pMetaFile =
2075 m_pData->m_pObjectShell->GetPreviewMetaFile( sal_True );
2076
2077 if ( pMetaFile )
2078 {
2079 ::boost::shared_ptr<SvMemoryStream> pStream(
2080 GraphicHelper::getFormatStrFromGDI_Impl(
2081 pMetaFile.get(), CVT_EMF ) );
2082 if ( pStream )
2083 {
2084 pStream->SetVersion( SOFFICE_FILEFORMAT_CURRENT );
2085 aAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( pStream->GetData() ),
2086 pStream->Seek( STREAM_SEEK_TO_END ) );
2087 }
2088 }
2089 }
2090 else if ( GraphicHelper::supportsMetaFileHandle_Impl()
2091 && aFlavor.DataType == getCppuType( (const sal_uInt64*) 0 ) )
2092 {
2093 ::boost::shared_ptr<GDIMetaFile> pMetaFile =
2094 m_pData->m_pObjectShell->GetPreviewMetaFile( sal_True );
2095
2096 if ( pMetaFile )
2097 {
2098 aAny <<= reinterpret_cast< const sal_uInt64 >(
2099 GraphicHelper::getEnhMetaFileFromGDI_Impl( pMetaFile.get() ) );
2100 }
2101 }
2102 else
2103 throw datatransfer::UnsupportedFlavorException();
2104 }
2105 else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" ) )
2106 {
2107 if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
2108 {
2109 ::boost::shared_ptr<GDIMetaFile> pMetaFile =
2110 m_pData->m_pObjectShell->GetPreviewMetaFile( sal_True );
2111
2112 if ( pMetaFile )
2113 {
2114 ::boost::shared_ptr<SvMemoryStream> pStream(
2115 GraphicHelper::getFormatStrFromGDI_Impl(
2116 pMetaFile.get(), CVT_WMF ) );
2117
2118 if ( pStream )
2119 {
2120 pStream->SetVersion( SOFFICE_FILEFORMAT_CURRENT );
2121 aAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( pStream->GetData() ),
2122 pStream->Seek( STREAM_SEEK_TO_END ) );
2123 }
2124 }
2125 }
2126 else if ( GraphicHelper::supportsMetaFileHandle_Impl()
2127 && aFlavor.DataType == getCppuType( (const sal_uInt64*) 0 ) )
2128 {
2129 // means HGLOBAL handler to memory storage containing METAFILEPICT structure
2130
2131 ::boost::shared_ptr<GDIMetaFile> pMetaFile =
2132 m_pData->m_pObjectShell->GetPreviewMetaFile( sal_True );
2133
2134 if ( pMetaFile )
2135 {
2136 Size aMetaSize = pMetaFile->GetPrefSize();
2137 aAny <<= reinterpret_cast< const sal_uInt64 >(
2138 GraphicHelper::getWinMetaFileFromGDI_Impl(
2139 pMetaFile.get(), aMetaSize ) );
2140 }
2141 }
2142 else
2143 throw datatransfer::UnsupportedFlavorException();
2144 }
2145 else if ( aFlavor.MimeType.equalsAscii( "image/svg+xml" ) )
2146 {
2147 if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
2148 {
2149 ::boost::shared_ptr<GDIMetaFile> pMetaFile =
2150 m_pData->m_pObjectShell->GetPreviewMetaFile( sal_True );
2151
2152 if ( pMetaFile )
2153 {
2154 ::boost::shared_ptr<SvMemoryStream> pStream(
2155 GraphicHelper::getFormatStrFromGDI_Impl(
2156 pMetaFile.get(), CVT_SVG ) );
2157
2158 if ( pStream )
2159 {
2160 pStream->SetVersion( SOFFICE_FILEFORMAT_CURRENT );
2161 aAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( pStream->GetData() ),
2162 pStream->Seek( STREAM_SEEK_TO_END ) );
2163 }
2164 }
2165 }
2166 else
2167 throw datatransfer::UnsupportedFlavorException();
2168 }
2169 else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" ) )
2170 {
2171 if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
2172 {
2173 ::boost::shared_ptr<GDIMetaFile> pMetaFile =
2174 m_pData->m_pObjectShell->GetPreviewMetaFile( sal_True );
2175
2176 if ( pMetaFile )
2177 {
2178 ::boost::shared_ptr<SvMemoryStream> pStream(
2179 GraphicHelper::getFormatStrFromGDI_Impl(
2180 pMetaFile.get(), CVT_BMP ) );
2181
2182 if ( pStream )
2183 {
2184 pStream->SetVersion( SOFFICE_FILEFORMAT_CURRENT );
2185 aAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( pStream->GetData() ),
2186 pStream->Seek( STREAM_SEEK_TO_END ) );
2187 }
2188 }
2189 }
2190 else
2191 throw datatransfer::UnsupportedFlavorException();
2192 }
2193 else if ( aFlavor.MimeType.equalsAscii( "image/png" ) )
2194 {
2195 if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
2196 {
2197 ::boost::shared_ptr<GDIMetaFile> pMetaFile =
2198 m_pData->m_pObjectShell->GetPreviewMetaFile( sal_True );
2199
2200 if ( pMetaFile )
2201 {
2202 ::boost::shared_ptr<SvMemoryStream> pStream(
2203 GraphicHelper::getFormatStrFromGDI_Impl(
2204 pMetaFile.get(), CVT_PNG ) );
2205
2206 if ( pStream )
2207 {
2208 pStream->SetVersion( SOFFICE_FILEFORMAT_CURRENT );
2209 aAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( pStream->GetData() ),
2210 pStream->Seek( STREAM_SEEK_TO_END ) );
2211 }
2212 }
2213 }
2214 else
2215 throw datatransfer::UnsupportedFlavorException();
2216 }
2217 else
2218 throw datatransfer::UnsupportedFlavorException();
2219 }
2220
2221 return aAny;
2222 }
2223
2224 //________________________________________________________________________________________________________
2225 // XTransferable
2226 //________________________________________________________________________________________________________
2227
2228
getTransferDataFlavors()2229 uno::Sequence< DATAFLAVOR > SAL_CALL SfxBaseModel::getTransferDataFlavors()
2230 {
2231 SfxModelGuard aGuard( *this );
2232
2233 sal_Int32 nSuppFlavors = GraphicHelper::supportsMetaFileHandle_Impl() ? 11 : 9;
2234 uno::Sequence< DATAFLAVOR > aFlavorSeq( nSuppFlavors );
2235
2236 aFlavorSeq[0].MimeType =
2237 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" ) );
2238 aFlavorSeq[0].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "GDIMetaFile" ) );
2239 aFlavorSeq[0].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 );
2240
2241 aFlavorSeq[1].MimeType =
2242 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" ) );
2243 aFlavorSeq[1].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "GDIMetaFile" ) );
2244 aFlavorSeq[1].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 );
2245
2246 aFlavorSeq[2].MimeType =
2247 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" ) );
2248 aFlavorSeq[2].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Enhanced Windows MetaFile" ) );
2249 aFlavorSeq[2].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 );
2250
2251 aFlavorSeq[3].MimeType =
2252 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" ) );
2253 aFlavorSeq[3].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Windows MetaFile" ) );
2254 aFlavorSeq[3].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 );
2255
2256 aFlavorSeq[4].MimeType =
2257 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"" ) );
2258 aFlavorSeq[4].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Star Object Descriptor (XML)" ) );
2259 aFlavorSeq[4].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 );
2260
2261 aFlavorSeq[5].MimeType =
2262 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"" ) );
2263 aFlavorSeq[5].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Star Embed Source (XML)" ) );
2264 aFlavorSeq[5].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 );
2265
2266 aFlavorSeq[6].MimeType =
2267 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" ) );
2268 aFlavorSeq[6].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Bitmap" ) );
2269 aFlavorSeq[6].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 );
2270
2271 aFlavorSeq[7].MimeType =
2272 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "image/png" ) );
2273 aFlavorSeq[7].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PNG" ) );
2274 aFlavorSeq[7].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 );
2275
2276 aFlavorSeq[8].MimeType =
2277 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "image/svg+xml" ) );
2278 aFlavorSeq[8].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SVG" ) );
2279 aFlavorSeq[8].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 );
2280
2281 if ( nSuppFlavors == 11 )
2282 {
2283 aFlavorSeq[9].MimeType =
2284 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" ) );
2285 aFlavorSeq[9].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Enhanced Windows MetaFile" ) );
2286 aFlavorSeq[9].DataType = getCppuType( (const sal_uInt64*) 0 );
2287
2288 aFlavorSeq[10].MimeType =
2289 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" ) );
2290 aFlavorSeq[10].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Windows MetaFile" ) );
2291 aFlavorSeq[10].DataType = getCppuType( (const sal_uInt64*) 0 );
2292 }
2293
2294 return aFlavorSeq;
2295 }
2296
2297 //________________________________________________________________________________________________________
2298 // XTransferable
2299 //________________________________________________________________________________________________________
2300
2301
isDataFlavorSupported(const DATAFLAVOR & aFlavor)2302 sal_Bool SAL_CALL SfxBaseModel::isDataFlavorSupported( const DATAFLAVOR& aFlavor )
2303 {
2304 SfxModelGuard aGuard( *this );
2305
2306 if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" ) )
2307 {
2308 if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
2309 return sal_True;
2310 }
2311 else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" ) )
2312 {
2313 if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
2314 return sal_True;
2315 }
2316 else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" ) )
2317 {
2318 if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
2319 return sal_True;
2320 else if ( GraphicHelper::supportsMetaFileHandle_Impl()
2321 && aFlavor.DataType == getCppuType( (const sal_uInt64*) 0 ) )
2322 return sal_True;
2323 }
2324 else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" ) )
2325 {
2326 if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
2327 return sal_True;
2328 else if ( GraphicHelper::supportsMetaFileHandle_Impl()
2329 && aFlavor.DataType == getCppuType( (const sal_uInt64*) 0 ) )
2330 return sal_True;
2331 }
2332 else if ( aFlavor.MimeType.equalsAscii( "image/svg+xml" ) )
2333 {
2334 if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
2335 return sal_True;
2336 }
2337 else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"" ) )
2338 {
2339 if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
2340 return sal_True;
2341 }
2342 else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-embed-source;windows_formatname=\"Star EMBS\"" ) )
2343 {
2344 if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
2345 return sal_True;
2346 }
2347 else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" ) )
2348 {
2349 if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
2350 return sal_True;
2351 }
2352 else if ( aFlavor.MimeType.equalsAscii( "image/png" ) )
2353 {
2354 if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) )
2355 return sal_True;
2356 }
2357
2358 return sal_False;
2359 }
2360
2361
2362 //--------------------------------------------------------------------------------------------------------
2363 // XEventsSupplier
2364 //--------------------------------------------------------------------------------------------------------
2365
getEvents()2366 uno::Reference< container::XNameReplace > SAL_CALL SfxBaseModel::getEvents()
2367 {
2368 SfxModelGuard aGuard( *this );
2369
2370 if ( ! m_pData->m_xEvents.is() )
2371 {
2372 m_pData->m_xEvents = new SfxEvents_Impl( m_pData->m_pObjectShell, this );
2373 }
2374
2375 return m_pData->m_xEvents;
2376 }
2377
2378 //--------------------------------------------------------------------------------------------------------
2379 // XEmbeddedScripts
2380 //--------------------------------------------------------------------------------------------------------
2381
getBasicLibraries()2382 uno::Reference< script::XStorageBasedLibraryContainer > SAL_CALL SfxBaseModel::getBasicLibraries()
2383 {
2384 SfxModelGuard aGuard( *this );
2385
2386 uno::Reference< script::XStorageBasedLibraryContainer > xBasicLibraries;
2387 if ( m_pData->m_pObjectShell )
2388 xBasicLibraries.set( m_pData->m_pObjectShell->GetBasicContainer(), UNO_QUERY_THROW );
2389 return xBasicLibraries;
2390 }
2391
getDialogLibraries()2392 uno::Reference< script::XStorageBasedLibraryContainer > SAL_CALL SfxBaseModel::getDialogLibraries()
2393 {
2394 SfxModelGuard aGuard( *this );
2395
2396 uno::Reference< script::XStorageBasedLibraryContainer > xDialogLibraries;
2397 if ( m_pData->m_pObjectShell )
2398 xDialogLibraries.set( m_pData->m_pObjectShell->GetDialogContainer(), UNO_QUERY_THROW );
2399 return xDialogLibraries;
2400 }
2401
getAllowMacroExecution()2402 ::sal_Bool SAL_CALL SfxBaseModel::getAllowMacroExecution()
2403 {
2404 SfxModelGuard aGuard( *this );
2405
2406 if ( m_pData->m_pObjectShell )
2407 return m_pData->m_pObjectShell->AdjustMacroMode( String(), false );
2408 return sal_False;
2409 }
2410
2411 //--------------------------------------------------------------------------------------------------------
2412 // XScriptInvocationContext
2413 //--------------------------------------------------------------------------------------------------------
2414
getScriptContainer()2415 Reference< document::XEmbeddedScripts > SAL_CALL SfxBaseModel::getScriptContainer()
2416 {
2417 SfxModelGuard aGuard( *this );
2418
2419 Reference< document::XEmbeddedScripts > xDocumentScripts;
2420
2421 try
2422 {
2423 Reference< frame::XModel > xDocument( this );
2424 xDocumentScripts.set( xDocument, uno::UNO_QUERY );
2425 while ( !xDocumentScripts.is() && xDocument.is() )
2426 {
2427 Reference< container::XChild > xDocAsChild( xDocument, uno::UNO_QUERY );
2428 if ( !xDocAsChild.is() )
2429 {
2430 xDocument = NULL;
2431 break;
2432 }
2433
2434 xDocument.set( xDocAsChild->getParent(), uno::UNO_QUERY );
2435 xDocumentScripts.set( xDocument, uno::UNO_QUERY );
2436 }
2437 }
2438 catch( const Exception& )
2439 {
2440 DBG_UNHANDLED_EXCEPTION();
2441 xDocumentScripts = NULL;
2442 }
2443
2444 return xDocumentScripts;
2445 }
2446
2447 //--------------------------------------------------------------------------------------------------------
2448 // XEventBroadcaster
2449 //--------------------------------------------------------------------------------------------------------
2450
addEventListener(const uno::Reference<XDOCEVENTLISTENER> & aListener)2451 void SAL_CALL SfxBaseModel::addEventListener( const uno::Reference< XDOCEVENTLISTENER >& aListener )
2452 {
2453 SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
2454
2455 m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< XDOCEVENTLISTENER >*)0), aListener );
2456 }
2457
2458 //--------------------------------------------------------------------------------------------------------
2459 // XEventBroadcaster
2460 //--------------------------------------------------------------------------------------------------------
2461
removeEventListener(const uno::Reference<XDOCEVENTLISTENER> & aListener)2462 void SAL_CALL SfxBaseModel::removeEventListener( const uno::Reference< XDOCEVENTLISTENER >& aListener )
2463 {
2464 SfxModelGuard aGuard( *this );
2465
2466 m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XDOCEVENTLISTENER >*)0), aListener );
2467 }
2468
2469 //--------------------------------------------------------------------------------------------------------
2470 // XDocumentEventBroadcaster
2471 //--------------------------------------------------------------------------------------------------------
2472 // ---------------------------------
addDocumentEventListener(const uno::Reference<document::XDocumentEventListener> & aListener)2473 void SAL_CALL SfxBaseModel::addDocumentEventListener( const uno::Reference< document::XDocumentEventListener >& aListener )
2474 {
2475 SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
2476 m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< document::XDocumentEventListener >*)0), aListener );
2477 }
2478
2479 // ---------------------------------
removeDocumentEventListener(const uno::Reference<document::XDocumentEventListener> & aListener)2480 void SAL_CALL SfxBaseModel::removeDocumentEventListener( const uno::Reference< document::XDocumentEventListener >& aListener )
2481 {
2482 SfxModelGuard aGuard( *this );
2483 m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< document::XDocumentEventListener >*)0), aListener );
2484 }
2485
2486 // ---------------------------------
notifyDocumentEvent(const::rtl::OUString &,const uno::Reference<frame::XController2> &,const uno::Any &)2487 void SAL_CALL SfxBaseModel::notifyDocumentEvent( const ::rtl::OUString&, const uno::Reference< frame::XController2 >&, const uno::Any& )
2488 {
2489 throw lang::NoSupportException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SfxBaseModel controls all the sent notifications itself!" ) ), uno::Reference< uno::XInterface >() );
2490 }
2491
2492 //________________________________________________________________________________________________________
2493 // SfxListener
2494 //________________________________________________________________________________________________________
2495
addTitle_Impl(Sequence<::com::sun::star::beans::PropertyValue> & rSeq,const::rtl::OUString & rTitle)2496 void addTitle_Impl( Sequence < ::com::sun::star::beans::PropertyValue >& rSeq, const ::rtl::OUString& rTitle )
2497 {
2498 sal_Int32 nCount = rSeq.getLength();
2499 sal_Int32 nArg;
2500
2501 for ( nArg = 0; nArg < nCount; nArg++ )
2502 {
2503 ::com::sun::star::beans::PropertyValue& rProp = rSeq[nArg];
2504 if ( rProp.Name.equalsAscii("Title") )
2505 {
2506 rProp.Value <<= rTitle;
2507 break;
2508 }
2509 }
2510
2511 if ( nArg == nCount )
2512 {
2513 rSeq.realloc( nCount+1 );
2514 rSeq[nCount].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Title") );
2515 rSeq[nCount].Value <<= rTitle;
2516 }
2517 }
2518
NotifyStorageListeners_Impl()2519 void SfxBaseModel::NotifyStorageListeners_Impl()
2520 {
2521 uno::Reference< uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >(this) );
2522
2523 if ( m_pData->m_pObjectShell )
2524 {
2525 ::cppu::OInterfaceContainerHelper* pContainer =
2526 m_pData->m_aInterfaceContainer.getContainer(
2527 ::getCppuType( ( const uno::Reference< document::XStorageChangeListener >*) NULL ) );
2528 if ( pContainer != NULL )
2529 {
2530 uno::Reference< embed::XStorage > xNewStorage = m_pData->m_pObjectShell->GetStorage();
2531 ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
2532 while ( pIterator.hasMoreElements() )
2533 {
2534 try
2535 {
2536 ((document::XStorageChangeListener*)pIterator.next())->notifyStorageChange(
2537 xSelfHold,
2538 xNewStorage );
2539 }
2540 catch( uno::RuntimeException& )
2541 {
2542 pIterator.remove();
2543 }
2544 }
2545 }
2546 }
2547 }
2548
Notify(SfxBroadcaster & rBC,const SfxHint & rHint)2549 void SfxBaseModel::Notify( SfxBroadcaster& rBC ,
2550 const SfxHint& rHint )
2551 {
2552 if ( !m_pData )
2553 return;
2554
2555 if ( &rBC == m_pData->m_pObjectShell )
2556 {
2557 SfxSimpleHint* pSimpleHint = PTR_CAST( SfxSimpleHint, &rHint );
2558 if ( pSimpleHint && pSimpleHint->GetId() == SFX_HINT_DOCCHANGED )
2559 changing();
2560
2561 SfxEventHint* pNamedHint = PTR_CAST( SfxEventHint, &rHint );
2562 if ( pNamedHint )
2563 {
2564
2565 switch ( pNamedHint->GetEventId() )
2566 {
2567 case SFX_EVENT_STORAGECHANGED:
2568 {
2569 // for now this event is sent only on creation of a new storage for new document
2570 // and in case of reload of medium without document reload
2571 // other events are used to detect storage change
2572 // NotifyStorageListeners_Impl();
2573
2574 if ( m_pData->m_xUIConfigurationManager.is()
2575 && m_pData->m_pObjectShell->GetCreateMode() != SFX_CREATE_MODE_EMBEDDED )
2576 {
2577 uno::Reference< XSTORAGE > xConfigStorage;
2578 rtl::OUString aUIConfigFolderName( RTL_CONSTASCII_USTRINGPARAM( "Configurations2" ));
2579
2580 xConfigStorage = getDocumentSubStorage( aUIConfigFolderName, com::sun::star::embed::ElementModes::READWRITE );
2581 if ( !xConfigStorage.is() )
2582 xConfigStorage = getDocumentSubStorage( aUIConfigFolderName, com::sun::star::embed::ElementModes::READ );
2583
2584 if ( xConfigStorage.is() || !m_pData->m_pObjectShell->GetStorage()->hasByName( aUIConfigFolderName ) )
2585 {
2586 // the storage is different, since otherwise it could not be opened, so it must be exchanged
2587 Reference< ui::XUIConfigurationStorage > xUIConfigStorage( m_pData->m_xUIConfigurationManager, uno::UNO_QUERY );
2588 xUIConfigStorage->setStorage( xConfigStorage );
2589 }
2590 else
2591 {
2592 OSL_ENSURE( sal_False, "Unexpected scenario!\n" );
2593 }
2594 }
2595
2596 ListenForStorage_Impl( m_pData->m_pObjectShell->GetStorage() );
2597 }
2598 break;
2599
2600 case SFX_EVENT_LOADFINISHED:
2601 {
2602 impl_getPrintHelper();
2603 ListenForStorage_Impl( m_pData->m_pObjectShell->GetStorage() );
2604 m_pData->m_bModifiedSinceLastSave = sal_False;
2605 }
2606 break;
2607
2608 case SFX_EVENT_SAVEASDOCDONE:
2609 {
2610 m_pData->m_sURL = m_pData->m_pObjectShell->GetMedium()->GetName();
2611
2612 SfxItemSet *pSet = m_pData->m_pObjectShell->GetMedium()->GetItemSet();
2613 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aArgs;
2614 ::rtl::OUString aTitle = m_pData->m_pObjectShell->GetTitle();
2615 TransformItems( SID_SAVEASDOC, *pSet, aArgs );
2616 addTitle_Impl( aArgs, aTitle );
2617 attachResource( m_pData->m_pObjectShell->GetMedium()->GetName(), aArgs );
2618 }
2619 break;
2620
2621 case SFX_EVENT_DOCCREATED:
2622 {
2623 impl_getPrintHelper();
2624 m_pData->m_bModifiedSinceLastSave = sal_False;
2625 }
2626 break;
2627
2628 case SFX_EVENT_MODIFYCHANGED:
2629 {
2630 m_pData->m_bModifiedSinceLastSave = isModified();
2631 }
2632 break;
2633 }
2634
2635
2636 SfxViewEventHint* pViewHint = PTR_CAST( SfxViewEventHint, &rHint );
2637 postEvent_Impl( pNamedHint->GetEventName(), pViewHint ? pViewHint->GetController() : uno::Reference< frame::XController2 >() );
2638 }
2639
2640 if ( pSimpleHint )
2641 {
2642 if ( pSimpleHint->GetId() == SFX_HINT_TITLECHANGED )
2643 {
2644 ::rtl::OUString aTitle = m_pData->m_pObjectShell->GetTitle();
2645 addTitle_Impl( m_pData->m_seqArguments, aTitle );
2646 postEvent_Impl( GlobalEventConfig::GetEventName( STR_EVENT_TITLECHANGED ) );
2647 }
2648 if ( pSimpleHint->GetId() == SFX_HINT_MODECHANGED )
2649 {
2650 postEvent_Impl( GlobalEventConfig::GetEventName( STR_EVENT_MODECHANGED ) );
2651 }
2652 /*
2653 else if ( pSimpleHint->GetId() == SFX_HINT_DYING
2654 || pSimpleHint->GetId() == SFX_HINT_DEINITIALIZING )
2655 {
2656 SfxObjectShellLock pShellLock = m_pData->m_pObjectShellLock;
2657 m_pData->m_pObjectShellLock = SfxObjectShellLock();
2658 }
2659 */
2660 }
2661 }
2662 }
2663
2664 //________________________________________________________________________________________________________
2665 // public impl.
2666 //________________________________________________________________________________________________________
2667
NotifyModifyListeners_Impl() const2668 void SfxBaseModel::NotifyModifyListeners_Impl() const
2669 {
2670 ::cppu::OInterfaceContainerHelper* pIC = m_pData->m_aInterfaceContainer.getContainer( ::getCppuType((const uno::Reference< XMODIFYLISTENER >*)0) );
2671 if ( pIC )
2672 {
2673 lang::EventObject aEvent( (frame::XModel *)this );
2674 pIC->notifyEach( &util::XModifyListener::modified, aEvent );
2675 }
2676
2677 // this notification here is done too generously, we cannot simply assume that we're really modified
2678 // now, but we need to check it ...
2679 m_pData->m_bModifiedSinceLastSave = const_cast< SfxBaseModel* >( this )->isModified();
2680 }
2681
changing()2682 void SfxBaseModel::changing()
2683 {
2684 SfxModelGuard aGuard( *this );
2685
2686 // the notification should not be sent if the document can not be modified
2687 if ( !m_pData->m_pObjectShell.Is() || !m_pData->m_pObjectShell->IsEnableSetModified() )
2688 return;
2689
2690 NotifyModifyListeners_Impl();
2691 }
2692
impl_change()2693 void SfxBaseModel::impl_change()
2694 {
2695 // object already disposed?
2696 if ( impl_isDisposed() )
2697 return;
2698
2699 NotifyModifyListeners_Impl();
2700 }
2701
2702 //________________________________________________________________________________________________________
2703 // public impl.
2704 //________________________________________________________________________________________________________
2705
GetObjectShell() const2706 SfxObjectShell* SfxBaseModel::GetObjectShell() const
2707 {
2708 return m_pData ? (SfxObjectShell*) m_pData->m_pObjectShell : 0;
2709 }
2710
impl_getObjectShell() const2711 SfxObjectShell* SfxBaseModel::impl_getObjectShell() const
2712 {
2713 return m_pData ? (SfxObjectShell*) m_pData->m_pObjectShell : 0;
2714 }
2715
2716 //________________________________________________________________________________________________________
2717 // public impl.
2718 //________________________________________________________________________________________________________
2719
IsInitialized() const2720 sal_Bool SfxBaseModel::IsInitialized() const
2721 {
2722 if ( !m_pData || !m_pData->m_pObjectShell )
2723 {
2724 OSL_ENSURE( false, "SfxBaseModel::IsInitialized: this should have been caught earlier!" );
2725 return sal_False;
2726 }
2727
2728 return m_pData->m_pObjectShell->GetMedium() != NULL;
2729 }
2730
MethodEntryCheck(const bool i_mustBeInitialized) const2731 void SfxBaseModel::MethodEntryCheck( const bool i_mustBeInitialized ) const
2732 {
2733 if ( impl_isDisposed() )
2734 throw ::com::sun::star::lang::DisposedException( ::rtl::OUString(), *const_cast< SfxBaseModel* >( this ) );
2735 if ( i_mustBeInitialized && !IsInitialized() )
2736 throw ::com::sun::star::lang::NotInitializedException( ::rtl::OUString(), *const_cast< SfxBaseModel* >( this ) );
2737 }
2738
impl_isDisposed() const2739 sal_Bool SfxBaseModel::impl_isDisposed() const
2740 {
2741 return ( m_pData == NULL ) ;
2742 }
2743
2744 //________________________________________________________________________________________________________
2745 // private impl.
2746 //________________________________________________________________________________________________________
2747
GetMediumFilterName_Impl()2748 ::rtl::OUString SfxBaseModel::GetMediumFilterName_Impl()
2749 {
2750 const SfxFilter* pFilter = NULL;
2751 SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium();
2752 if ( pMedium )
2753 pFilter = pMedium->GetFilter();
2754
2755 if ( pFilter )
2756 return pFilter->GetName();
2757
2758 return ::rtl::OUString();
2759 }
2760
impl_store(const::rtl::OUString & sURL,const uno::Sequence<beans::PropertyValue> & seqArguments,sal_Bool bSaveTo)2761 void SfxBaseModel::impl_store( const ::rtl::OUString& sURL ,
2762 const uno::Sequence< beans::PropertyValue >& seqArguments ,
2763 sal_Bool bSaveTo )
2764 {
2765 if( !sURL.getLength() )
2766 throw frame::IllegalArgumentIOException();
2767
2768 //sal_Bool aSaveAsTemplate = sal_False;
2769
2770 sal_Bool bSaved = sal_False;
2771 if ( !bSaveTo && m_pData->m_pObjectShell && sURL.getLength()
2772 && sURL.compareToAscii( "private:stream", 14 ) != COMPARE_EQUAL
2773 && ::utl::UCBContentHelper::EqualURLs( getLocation(), sURL ) )
2774 {
2775 // this is the same file URL as the current document location, try to use storeOwn if possible
2776
2777 ::comphelper::SequenceAsHashMap aArgHash( seqArguments );
2778 ::rtl::OUString aFilterString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
2779 ::rtl::OUString aFilterName = aArgHash.getUnpackedValueOrDefault( aFilterString, ::rtl::OUString() );
2780 if ( aFilterName.getLength() )
2781 {
2782 SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium();
2783 if ( pMedium )
2784 {
2785 const SfxFilter* pFilter = pMedium->GetFilter();
2786 if ( pFilter && aFilterName.equals( pFilter->GetFilterName() ) )
2787 {
2788 // 119366 - If the former file saving with password, do not trying in StoreSelf anyway...
2789 bool bFormerPassword = false;
2790 {
2791 uno::Sequence< beans::NamedValue > aOldEncryptionData;
2792 if (GetEncryptionData_Impl( pMedium->GetItemSet(), aOldEncryptionData ))
2793 {
2794 bFormerPassword = true;
2795 }
2796 }
2797 if ( !bFormerPassword )
2798 {
2799 aArgHash.erase( aFilterString );
2800 aArgHash.erase( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ) );
2801
2802 try
2803 {
2804 storeSelf( aArgHash.getAsConstPropertyValueList() );
2805 bSaved = sal_True;
2806 }
2807 catch( const lang::IllegalArgumentException& )
2808 {
2809 // some additional arguments do not allow to use saving, SaveAs should be done
2810 // but only for normal documents, the shared documents would be overwritten in this case
2811 // that would mean an information loss
2812 // TODO/LATER: need a new interaction for this case
2813 if ( m_pData->m_pObjectShell->IsDocShared() )
2814 {
2815 m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't store shared document!" ) ) );
2816 m_pData->m_pObjectShell->StoreLog();
2817
2818 uno::Sequence< beans::NamedValue > aNewEncryptionData = aArgHash.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EncryptionData" ) ), uno::Sequence< beans::NamedValue >() );
2819 if ( !aNewEncryptionData.getLength() )
2820 {
2821 ::rtl::OUString aNewPassword = aArgHash.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Password" ) ), ::rtl::OUString() );
2822 aNewEncryptionData = ::comphelper::OStorageHelper::CreatePackageEncryptionData( aNewPassword );
2823 }
2824
2825 uno::Sequence< beans::NamedValue > aOldEncryptionData;
2826 GetEncryptionData_Impl( pMedium->GetItemSet(), aOldEncryptionData );
2827
2828 if ( !aOldEncryptionData.getLength() && !aNewEncryptionData.getLength() )
2829 throw;
2830 else
2831 {
2832 // if the password is changed a special error should be used in case of shared document
2833 throw task::ErrorCodeIOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can't change password for shared document." ) ), uno::Reference< uno::XInterface >(), ERRCODE_SFX_SHARED_NOPASSWORDCHANGE );
2834 }
2835 }
2836 }
2837 }
2838 }
2839 }
2840 }
2841 }
2842
2843 if ( !bSaved && m_pData->m_pObjectShell )
2844 {
2845 SFX_APP()->NotifyEvent( SfxEventHint( bSaveTo ? SFX_EVENT_SAVETODOC : SFX_EVENT_SAVEASDOC, GlobalEventConfig::GetEventName( bSaveTo ? STR_EVENT_SAVETODOC : STR_EVENT_SAVEASDOC ),
2846 m_pData->m_pObjectShell ) );
2847
2848 SfxAllItemSet *aParams = new SfxAllItemSet( SFX_APP()->GetPool() );
2849 aParams->Put( SfxStringItem( SID_FILE_NAME, String(sURL) ) );
2850 if ( bSaveTo )
2851 aParams->Put( SfxBoolItem( SID_SAVETO, sal_True ) );
2852
2853 TransformParameters( SID_SAVEASDOC, seqArguments, *aParams );
2854
2855 SFX_ITEMSET_ARG( aParams, pCopyStreamItem, SfxBoolItem, SID_COPY_STREAM_IF_POSSIBLE, sal_False );
2856
2857 if ( pCopyStreamItem && pCopyStreamItem->GetValue() && !bSaveTo )
2858 {
2859 m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Misuse of CopyStreamIfPossible!" ) ) );
2860 m_pData->m_pObjectShell->StoreLog();
2861
2862 throw frame::IllegalArgumentIOException(
2863 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("CopyStreamIfPossible parameter is not acceptable for storeAsURL() call!") ),
2864 uno::Reference< uno::XInterface >() );
2865 }
2866
2867 sal_uInt32 nModifyPasswordHash = 0;
2868 uno::Sequence< beans::PropertyValue > aModifyPasswordInfo;
2869 SFX_ITEMSET_ARG( aParams, pModifyPasswordInfoItem, SfxUnoAnyItem, SID_MODIFYPASSWORDINFO, sal_False );
2870 if ( pModifyPasswordInfoItem )
2871 {
2872 // it contains either a simple hash or a set of PropertyValues
2873 // TODO/LATER: the sequence of PropertyValue should replace the hash completely in future
2874 sal_Int32 nMPHTmp = 0;
2875 pModifyPasswordInfoItem->GetValue() >>= nMPHTmp;
2876 nModifyPasswordHash = (sal_uInt32)nMPHTmp;
2877 pModifyPasswordInfoItem->GetValue() >>= aModifyPasswordInfo;
2878 }
2879 aParams->ClearItem( SID_MODIFYPASSWORDINFO );
2880 sal_uInt32 nOldModifyPasswordHash = m_pData->m_pObjectShell->GetModifyPasswordHash();
2881 m_pData->m_pObjectShell->SetModifyPasswordHash( nModifyPasswordHash );
2882 uno::Sequence< beans::PropertyValue > aOldModifyPasswordInfo = m_pData->m_pObjectShell->GetModifyPasswordInfo();
2883 m_pData->m_pObjectShell->SetModifyPasswordInfo( aModifyPasswordInfo );
2884
2885 // since saving a document modifies its DocumentInfo, the current
2886 // DocumentInfo must be saved on "SaveTo", so it can be restored
2887 // after saving
2888 sal_Bool bCopyTo = bSaveTo ||
2889 m_pData->m_pObjectShell->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED;
2890 uno::Reference<document::XDocumentProperties> xOldDocProps;
2891 uno::Reference<document::XDocumentInfo> xOldDocInfo;
2892 if ( bCopyTo )
2893 {
2894 xOldDocProps = getDocumentProperties();
2895 if (m_pData->m_xDocumentInfo.is())
2896 {
2897 xOldDocInfo = getDocumentInfo();
2898 const Reference<util::XCloneable> xCloneable(xOldDocInfo,
2899 UNO_QUERY_THROW);
2900 const Reference<document::XDocumentInfo> xNewDocInfo(
2901 xCloneable->createClone(), UNO_QUERY_THROW);
2902 const Reference<document::XDocumentPropertiesSupplier> xDPS(
2903 xNewDocInfo, UNO_QUERY_THROW);
2904 const Reference<document::XDocumentProperties> xNewDocProps(
2905 xDPS->getDocumentProperties());
2906 m_pData->m_xDocumentProperties = xNewDocProps;
2907 m_pData->m_xDocumentInfo = xNewDocInfo;
2908 }
2909 else // try not to create DocumentInfo if it does not exist...
2910 {
2911 const Reference<util::XCloneable> xCloneable(xOldDocProps,
2912 UNO_QUERY_THROW);
2913 const Reference<document::XDocumentProperties> xNewDocProps(
2914 xCloneable->createClone(), UNO_QUERY_THROW);
2915 m_pData->m_xDocumentProperties = xNewDocProps;
2916 }
2917 }
2918
2919 sal_Bool bRet = m_pData->m_pObjectShell->APISaveAs_Impl( sURL, aParams );
2920
2921 if ( bCopyTo )
2922 {
2923 // restore DocumentInfo if a copy was created
2924 m_pData->m_xDocumentProperties = xOldDocProps;
2925 m_pData->m_xDocumentInfo = xOldDocInfo;
2926 }
2927
2928 uno::Reference < task::XInteractionHandler > xHandler;
2929 SFX_ITEMSET_ARG( aParams, pItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, sal_False);
2930 if ( pItem )
2931 pItem->GetValue() >>= xHandler;
2932
2933 DELETEZ( aParams );
2934
2935 sal_uInt32 nErrCode = m_pData->m_pObjectShell->GetErrorCode();
2936 if ( !bRet && !nErrCode )
2937 {
2938 m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Storing has failed, no error is set!" ) ) );
2939 nErrCode = ERRCODE_IO_CANTWRITE;
2940 }
2941 m_pData->m_pObjectShell->ResetError();
2942
2943 if ( bRet )
2944 {
2945 if ( nErrCode )
2946 {
2947 // must be a warning - use Interactionhandler if possible or abandone
2948 if ( xHandler.is() )
2949 {
2950 // TODO/LATER: a general way to set the error context should be available
2951 SfxErrorContext aEc( ERRCTX_SFX_SAVEASDOC, m_pData->m_pObjectShell->GetTitle() );
2952
2953 ::com::sun::star::task::ErrorCodeRequest aErrorCode;
2954 aErrorCode.ErrCode = nErrCode;
2955 SfxMedium::CallApproveHandler( xHandler, uno::makeAny( aErrorCode ), sal_False );
2956 }
2957 }
2958
2959 m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Storing succeeded!" ) ) );
2960 if ( !bSaveTo )
2961 {
2962 m_pData->m_aPreusedFilterName = GetMediumFilterName_Impl();
2963 m_pData->m_pObjectShell->SetModifyPasswordEntered();
2964
2965 SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_SAVEASDOCDONE, GlobalEventConfig::GetEventName(STR_EVENT_SAVEASDOCDONE), m_pData->m_pObjectShell ) );
2966 }
2967 else
2968 {
2969 m_pData->m_pObjectShell->SetModifyPasswordHash( nOldModifyPasswordHash );
2970 m_pData->m_pObjectShell->SetModifyPasswordInfo( aOldModifyPasswordInfo );
2971
2972 SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_SAVETODOCDONE, GlobalEventConfig::GetEventName(STR_EVENT_SAVETODOCDONE), m_pData->m_pObjectShell ) );
2973 }
2974 }
2975 else
2976 {
2977 // let the logring be stored to the related file
2978 m_pData->m_pObjectShell->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Storing failed!" ) ) );
2979 m_pData->m_pObjectShell->StoreLog();
2980
2981 m_pData->m_pObjectShell->SetModifyPasswordHash( nOldModifyPasswordHash );
2982 m_pData->m_pObjectShell->SetModifyPasswordInfo( aOldModifyPasswordInfo );
2983
2984
2985 SFX_APP()->NotifyEvent( SfxEventHint( bSaveTo ? SFX_EVENT_SAVETODOCFAILED : SFX_EVENT_SAVEASDOCFAILED, GlobalEventConfig::GetEventName( bSaveTo ? STR_EVENT_SAVETODOCFAILED : STR_EVENT_SAVEASDOCFAILED),
2986 m_pData->m_pObjectShell ) );
2987
2988 throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), nErrCode );
2989 }
2990 }
2991 }
2992
2993 //********************************************************************************************************
2994 namespace {
2995 template< typename ListenerT, typename EventT >
2996 class NotifySingleListenerIgnoreRE
2997 {
2998 private:
2999 typedef void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& );
3000 NotificationMethod m_pMethod;
3001 const EventT& m_rEvent;
3002 public:
NotifySingleListenerIgnoreRE(NotificationMethod method,const EventT & event)3003 NotifySingleListenerIgnoreRE( NotificationMethod method, const EventT& event ) : m_pMethod( method ), m_rEvent( event ) { }
3004
operator ()(const uno::Reference<ListenerT> & listener) const3005 void operator()( const uno::Reference<ListenerT>& listener ) const
3006 {
3007 try
3008 {
3009 (listener.get()->*m_pMethod)( m_rEvent );
3010 }
3011 catch( uno::RuntimeException& )
3012 {
3013 // this exception is ignored to avoid problems with invalid listeners, the listener should be probably thrown away in future
3014 }
3015 }
3016 };
3017 } // anonymous namespace
3018
postEvent_Impl(const::rtl::OUString & aName,const uno::Reference<frame::XController2> & xController)3019 void SfxBaseModel::postEvent_Impl( const ::rtl::OUString& aName, const uno::Reference< frame::XController2 >& xController )
3020 {
3021 // object already disposed?
3022 if ( impl_isDisposed() )
3023 return;
3024
3025 DBG_ASSERT( aName.getLength(), "Empty event name!" );
3026 if (!aName.getLength())
3027 return;
3028
3029 ::cppu::OInterfaceContainerHelper* pIC =
3030 m_pData->m_aInterfaceContainer.getContainer( ::getCppuType( (const uno::Reference< document::XDocumentEventListener >*)0 ) );
3031 if ( pIC )
3032 {
3033 #ifdef DBG_UTIL
3034 ByteString aTmp( "SfxDocumentEvent: " );
3035 aTmp += ByteString( String(aName), RTL_TEXTENCODING_UTF8 );
3036 DBG_TRACE( aTmp.GetBuffer() );
3037 #endif
3038
3039 document::DocumentEvent aDocumentEvent( (frame::XModel*)this, aName, xController, uno::Any() );
3040
3041 pIC->forEach< document::XDocumentEventListener, NotifySingleListenerIgnoreRE< document::XDocumentEventListener, document::DocumentEvent > >(
3042 NotifySingleListenerIgnoreRE< document::XDocumentEventListener, document::DocumentEvent >(
3043 &document::XDocumentEventListener::documentEventOccured,
3044 aDocumentEvent ) );
3045 }
3046
3047 pIC = m_pData->m_aInterfaceContainer.getContainer( ::getCppuType( (const uno::Reference< document::XEventListener >*)0 ) );
3048 if ( pIC )
3049 {
3050 #ifdef DBG_UTIL
3051 ByteString aTmp( "SfxEvent: " );
3052 aTmp += ByteString( String(aName), RTL_TEXTENCODING_UTF8 );
3053 DBG_TRACE( aTmp.GetBuffer() );
3054 #endif
3055
3056 document::EventObject aEvent( (frame::XModel*)this, aName );
3057
3058 pIC->forEach< document::XEventListener, NotifySingleListenerIgnoreRE< document::XEventListener, document::EventObject > >(
3059 NotifySingleListenerIgnoreRE< document::XEventListener, document::EventObject >(
3060 &document::XEventListener::notifyEvent,
3061 aEvent ) );
3062 }
3063
3064 }
3065
getViewData()3066 uno::Reference < container::XIndexAccess > SAL_CALL SfxBaseModel::getViewData()
3067 {
3068 SfxModelGuard aGuard( *this );
3069
3070 if ( m_pData->m_pObjectShell.Is() && !m_pData->m_contViewData.is() )
3071 {
3072 SfxViewFrame *pActFrame = SfxViewFrame::Current();
3073 if ( !pActFrame || pActFrame->GetObjectShell() != m_pData->m_pObjectShell )
3074 pActFrame = SfxViewFrame::GetFirst( m_pData->m_pObjectShell );
3075
3076 if ( !pActFrame || !pActFrame->GetViewShell() )
3077 // currently no frame for this document at all or View is under construction
3078 return uno::Reference < container::XIndexAccess >();
3079
3080 m_pData->m_contViewData = Reference < container::XIndexAccess >(
3081 ::comphelper::getProcessServiceFactory()->createInstance(
3082 DEFINE_CONST_UNICODE("com.sun.star.document.IndexedPropertyValues") ),
3083 uno::UNO_QUERY );
3084
3085 if ( !m_pData->m_contViewData.is() )
3086 {
3087 // error: no container class available!
3088 return uno::Reference < container::XIndexAccess >();
3089 }
3090
3091 uno::Reference < container::XIndexContainer > xCont( m_pData->m_contViewData, uno::UNO_QUERY );
3092 sal_Int32 nCount = 0;
3093 uno::Sequence < beans::PropertyValue > aSeq;
3094 ::com::sun::star::uno::Any aAny;
3095 for ( SfxViewFrame *pFrame = SfxViewFrame::GetFirst( m_pData->m_pObjectShell ); pFrame;
3096 pFrame = SfxViewFrame::GetNext( *pFrame, m_pData->m_pObjectShell ) )
3097 {
3098 sal_Bool bIsActive = ( pFrame == pActFrame );
3099 pFrame->GetViewShell()->WriteUserDataSequence( aSeq );
3100 aAny <<= aSeq;
3101 xCont->insertByIndex( bIsActive ? 0 : nCount, aAny );
3102 nCount++;
3103 }
3104 }
3105
3106 return m_pData->m_contViewData;
3107 }
3108
setViewData(const uno::Reference<container::XIndexAccess> & aData)3109 void SAL_CALL SfxBaseModel::setViewData( const uno::Reference < container::XIndexAccess >& aData )
3110 {
3111 SfxModelGuard aGuard( *this );
3112
3113 m_pData->m_contViewData = aData;
3114 }
3115
3116 /** calls all XEventListeners */
notifyEvent(const::com::sun::star::document::EventObject & aEvent) const3117 void SfxBaseModel::notifyEvent( const ::com::sun::star::document::EventObject& aEvent ) const
3118 {
3119 // object already disposed?
3120 if ( impl_isDisposed() )
3121 return;
3122
3123 ::cppu::OInterfaceContainerHelper* pIC = m_pData->m_aInterfaceContainer.getContainer(
3124 ::getCppuType((const uno::Reference< XDOCEVENTLISTENER >*)0) );
3125 if( pIC )
3126
3127 {
3128 ::cppu::OInterfaceIteratorHelper aIt( *pIC );
3129 while( aIt.hasMoreElements() )
3130 {
3131 try
3132 {
3133 ((XDOCEVENTLISTENER *)aIt.next())->notifyEvent( aEvent );
3134 }
3135 catch( uno::RuntimeException& )
3136 {
3137 aIt.remove();
3138 }
3139 }
3140 }
3141 }
3142
3143 /** returns true if someone added a XEventListener to this XEventBroadcaster */
hasEventListeners() const3144 sal_Bool SfxBaseModel::hasEventListeners() const
3145 {
3146 return !impl_isDisposed() && (NULL != m_pData->m_aInterfaceContainer.getContainer( ::getCppuType((const uno::Reference< XDOCEVENTLISTENER >*)0) ) );
3147 }
3148
addPrintJobListener(const uno::Reference<view::XPrintJobListener> & xListener)3149 void SAL_CALL SfxBaseModel::addPrintJobListener( const uno::Reference< view::XPrintJobListener >& xListener )
3150 {
3151 SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
3152
3153 if ( impl_getPrintHelper() )
3154 {
3155 uno::Reference < view::XPrintJobBroadcaster > xPJB( m_pData->m_xPrintable, uno::UNO_QUERY );
3156 if ( xPJB.is() )
3157 xPJB->addPrintJobListener( xListener );
3158 }
3159 // else
3160 // m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< view::XPrintJobListener >*)0), xListener );
3161 }
3162
removePrintJobListener(const uno::Reference<view::XPrintJobListener> & xListener)3163 void SAL_CALL SfxBaseModel::removePrintJobListener( const uno::Reference< view::XPrintJobListener >& xListener )
3164 {
3165 SfxModelGuard aGuard( *this );
3166
3167 if ( impl_getPrintHelper() )
3168 {
3169 uno::Reference < view::XPrintJobBroadcaster > xPJB( m_pData->m_xPrintable, uno::UNO_QUERY );
3170 if ( xPJB.is() )
3171 xPJB->removePrintJobListener( xListener );
3172 }
3173 // else
3174 // m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< view::XPrintJobListener >*)0), xListener );
3175 }
3176
3177 // simple declaration of class SvObject is enough
3178 // the corresponding <so3/iface.hxx> cannon be included because it provides
3179 // declaration of class SvBorder that conflicts with ../../inc/viewfrm.hxx
3180 class SvObject;
getSomething(const::com::sun::star::uno::Sequence<sal_Int8> & aIdentifier)3181 sal_Int64 SAL_CALL SfxBaseModel::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier )
3182 {
3183 ::vos::OGuard aGuard( Application::GetSolarMutex() );
3184 if ( GetObjectShell() )
3185 {
3186 SvGlobalName aName( aIdentifier );
3187 if ( aName == SvGlobalName( SO3_GLOBAL_CLASSID ) )
3188 return (sal_Int64)(sal_IntPtr)(SvObject*)GetObjectShell();
3189 else if ( aName == SvGlobalName( SFX_GLOBAL_CLASSID ) )
3190 return (sal_Int64)(sal_IntPtr)(SfxObjectShell*)GetObjectShell();
3191 }
3192
3193 return 0;
3194 }
3195
3196 //____________________________________________________________________________________________________
3197 // XDocumentSubStorageSupplier
3198 //____________________________________________________________________________________________________
3199
ListenForStorage_Impl(const uno::Reference<embed::XStorage> & xStorage)3200 void SfxBaseModel::ListenForStorage_Impl( const uno::Reference< embed::XStorage >& xStorage )
3201 {
3202 uno::Reference< util::XModifiable > xModifiable( xStorage, uno::UNO_QUERY );
3203 if ( xModifiable.is() )
3204 {
3205 if ( !m_pData->m_pStorageModifyListen.is() )
3206 {
3207 m_pData->m_pStorageModifyListen = new ::sfx2::DocumentStorageModifyListener( *m_pData, Application::GetSolarMutex() );
3208 }
3209
3210 // no need to deregister the listening for old storage since it should be disposed automatically
3211 xModifiable->addModifyListener( m_pData->m_pStorageModifyListen.get() );
3212 }
3213 }
3214
getDocumentSubStorage(const::rtl::OUString & aStorageName,sal_Int32 nMode)3215 uno::Reference< XSTORAGE > SAL_CALL SfxBaseModel::getDocumentSubStorage( const ::rtl::OUString& aStorageName, sal_Int32 nMode )
3216 {
3217 SfxModelGuard aGuard( *this );
3218
3219 uno::Reference< XSTORAGE > xResult;
3220 if ( m_pData->m_pObjectShell.Is() )
3221 {
3222 uno::Reference< embed::XStorage > xStorage = m_pData->m_pObjectShell->GetStorage();
3223 if ( xStorage.is() )
3224 {
3225 try
3226 {
3227 xResult = xStorage->openStorageElement( aStorageName, nMode );
3228 }
3229 catch ( uno::Exception& )
3230 {
3231 }
3232 }
3233 }
3234
3235 return xResult;
3236 }
3237
getDocumentSubStoragesNames()3238 Sequence< ::rtl::OUString > SAL_CALL SfxBaseModel::getDocumentSubStoragesNames()
3239 {
3240 SfxModelGuard aGuard( *this );
3241
3242 Sequence< ::rtl::OUString > aResult;
3243 sal_Int32 nResultSize = 0;
3244 sal_Bool bSuccess = sal_False;
3245 if ( m_pData->m_pObjectShell.Is() )
3246 {
3247 uno::Reference < embed::XStorage > xStorage = m_pData->m_pObjectShell->GetStorage();
3248 uno::Reference < container::XNameAccess > xAccess( xStorage, uno::UNO_QUERY );
3249 if ( xAccess.is() )
3250 {
3251 Sequence< ::rtl::OUString > aTemp = xAccess->getElementNames();
3252 for ( sal_Int32 n = 0; n < aTemp.getLength(); n++ )
3253 {
3254 if ( xStorage->isStorageElement( aTemp[n] ) )
3255 {
3256 aResult.realloc( ++nResultSize );
3257 aResult[ nResultSize - 1 ] = aTemp[n];
3258 }
3259 }
3260
3261 bSuccess = sal_True;
3262 }
3263 }
3264
3265 if ( !bSuccess )
3266 throw io::IOException();
3267
3268 return aResult;
3269 }
3270
3271 //____________________________________________________________________________________________________
3272 // XScriptProviderSupplier
3273 //____________________________________________________________________________________________________
3274
3275
getScriptProvider()3276 uno::Reference< script::provider::XScriptProvider > SAL_CALL SfxBaseModel::getScriptProvider()
3277 {
3278 SfxModelGuard aGuard( *this );
3279
3280 uno::Reference< script::provider::XScriptProvider > xScriptProvider;
3281
3282 ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
3283 Reference< script::provider::XScriptProviderFactory > xScriptProviderFactory(
3284 aContext.getSingleton( "com.sun.star.script.provider.theMasterScriptProviderFactory" ), uno::UNO_QUERY_THROW );
3285
3286 try
3287 {
3288 Reference< XScriptInvocationContext > xScriptContext( this );
3289 xScriptProvider.set( xScriptProviderFactory->createScriptProvider( makeAny( xScriptContext ) ), uno::UNO_SET_THROW );
3290 }
3291 catch( const uno::RuntimeException& )
3292 {
3293 throw;
3294 }
3295 catch( const lang::IllegalArgumentException& )
3296 {
3297 throw lang::WrappedTargetRuntimeException(
3298 ::rtl::OUString(),
3299 *this,
3300 ::cppu::getCaughtException()
3301 );
3302 }
3303
3304 return xScriptProvider;
3305 }
3306
3307 //____________________________________________________________________________________________________
3308 // XUIConfigurationManagerSupplier
3309 //____________________________________________________________________________________________________
3310
getRuntimeUID() const3311 rtl::OUString SfxBaseModel::getRuntimeUID() const
3312 {
3313 OSL_ENSURE( m_pData->m_sRuntimeUID.getLength() > 0,
3314 "SfxBaseModel::getRuntimeUID - ID is empty!" );
3315 return m_pData->m_sRuntimeUID;
3316 }
3317
hasValidSignatures() const3318 sal_Bool SfxBaseModel::hasValidSignatures() const
3319 {
3320 ::vos::OGuard aGuard( Application::GetSolarMutex() );
3321 if ( m_pData->m_pObjectShell.Is() )
3322 return ( m_pData->m_pObjectShell->ImplGetSignatureState( sal_False ) == SIGNATURESTATE_SIGNATURES_OK );
3323 return sal_False;
3324 }
3325
GetCommandFromSequence(rtl::OUString & rCommand,sal_Int32 & nIndex,const uno::Sequence<beans::PropertyValue> & rSeqPropValue)3326 static void GetCommandFromSequence( rtl::OUString& rCommand, sal_Int32& nIndex, const uno::Sequence< beans::PropertyValue >& rSeqPropValue )
3327 {
3328 rtl::OUString aCommand;
3329 nIndex = -1;
3330
3331 for ( sal_Int32 i = 0; i < rSeqPropValue.getLength(); i++ )
3332 {
3333 if ( rSeqPropValue[i].Name.equalsAsciiL( "Command", 7 ))
3334 {
3335 rSeqPropValue[i].Value >>= rCommand;
3336 nIndex = i;
3337 return;
3338 }
3339 }
3340 }
3341
ConvertSlotsToCommands(SfxObjectShell * pDoc,uno::Reference<container::XIndexContainer> & rToolbarDefinition)3342 static void ConvertSlotsToCommands( SfxObjectShell* pDoc, uno::Reference< container::XIndexContainer >& rToolbarDefinition )
3343 {
3344 if ( pDoc )
3345 {
3346 Any aAny;
3347 SfxModule* pModule( pDoc->GetFactory().GetModule() );
3348 rtl::OUString aSlotCmd( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
3349 rtl::OUString aUnoCmd( RTL_CONSTASCII_USTRINGPARAM( ".uno:" ));
3350 uno::Sequence< beans::PropertyValue > aSeqPropValue;
3351
3352 for ( sal_Int32 i = 0; i < rToolbarDefinition->getCount(); i++ )
3353 {
3354 sal_Int32 nIndex( -1 );
3355 rtl::OUString aCommand;
3356
3357 if ( rToolbarDefinition->getByIndex( i ) >>= aSeqPropValue )
3358 {
3359 GetCommandFromSequence( aCommand, nIndex, aSeqPropValue );
3360 if ( nIndex >= 0 && ( aCommand.indexOf( aSlotCmd ) == 0 ))
3361 {
3362 rtl::OUString aSlot( aCommand.copy( 5 ));
3363
3364 // We have to replace the old "slot-Command" with our new ".uno:-Command"
3365 const SfxSlot* pSlot = pModule->GetSlotPool()->GetSlot( sal_uInt16( aSlot.toInt32() ));
3366 if ( pSlot )
3367 {
3368 rtl::OUStringBuffer aStrBuf( aUnoCmd );
3369 aStrBuf.appendAscii( pSlot->GetUnoName() );
3370
3371 aCommand = aStrBuf.makeStringAndClear();
3372 aSeqPropValue[nIndex].Value <<= aCommand;
3373 rToolbarDefinition->replaceByIndex( i, Any( aSeqPropValue ));
3374 }
3375 }
3376 }
3377 }
3378 }
3379 }
3380
getUIConfigurationManager()3381 uno::Reference< ui::XUIConfigurationManager > SAL_CALL SfxBaseModel::getUIConfigurationManager()
3382 {
3383 SfxModelGuard aGuard( *this );
3384
3385 if ( !m_pData->m_xUIConfigurationManager.is() )
3386 {
3387 uno::Reference< ui::XUIConfigurationManager > xNewUIConfMan(
3388 ::comphelper::getProcessServiceFactory()->createInstance(
3389 ::rtl::OUString::createFromAscii( "com.sun.star.ui.UIConfigurationManager" )),
3390 uno::UNO_QUERY );
3391
3392 Reference< ui::XUIConfigurationStorage > xUIConfigStorage( xNewUIConfMan, uno::UNO_QUERY );
3393 if ( xUIConfigStorage.is() )
3394 {
3395 uno::Reference< XSTORAGE > xConfigStorage;
3396
3397 rtl::OUString aUIConfigFolderName( RTL_CONSTASCII_USTRINGPARAM( "Configurations2" ));
3398 // First try to open with READWRITE and then READ
3399 xConfigStorage = getDocumentSubStorage( aUIConfigFolderName, embed::ElementModes::READWRITE );
3400 if ( xConfigStorage.is() )
3401 {
3402 rtl::OUString aMediaTypeProp( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ));
3403 rtl::OUString aUIConfigMediaType(
3404 RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.xml.ui.configuration" ) );
3405 rtl::OUString aMediaType;
3406 uno::Reference< beans::XPropertySet > xPropSet( xConfigStorage, uno::UNO_QUERY );
3407 Any a = xPropSet->getPropertyValue( aMediaTypeProp );
3408 if ( !( a >>= aMediaType ) || ( aMediaType.getLength() == 0 ))
3409 {
3410 a <<= aUIConfigMediaType;
3411 xPropSet->setPropertyValue( aMediaTypeProp, a );
3412 }
3413 }
3414 else
3415 xConfigStorage = getDocumentSubStorage( aUIConfigFolderName, embed::ElementModes::READ );
3416
3417 // initialize ui configuration manager with document substorage
3418 xUIConfigStorage->setStorage( xConfigStorage );
3419
3420 // embedded objects did not support local configuration data until OOo 3.0, so there's nothing to
3421 // migrate
3422 if ( m_pData->m_pObjectShell->GetCreateMode() != SFX_CREATE_MODE_EMBEDDED )
3423 {
3424 // Import old UI configuration from OOo 1.x
3425 uno::Reference< XSTORAGE > xOOo1ConfigStorage;
3426 rtl::OUString aOOo1UIConfigFolderName( RTL_CONSTASCII_USTRINGPARAM( "Configurations" ));
3427
3428 // Try to open with READ
3429 xOOo1ConfigStorage = getDocumentSubStorage( aOOo1UIConfigFolderName, embed::ElementModes::READ );
3430 if ( xOOo1ConfigStorage.is() )
3431 {
3432 uno::Reference< lang::XMultiServiceFactory > xServiceMgr( ::comphelper::getProcessServiceFactory() );
3433 uno::Sequence< uno::Reference< container::XIndexContainer > > rToolbars;
3434
3435 sal_Bool bImported = framework::UIConfigurationImporterOOo1x::ImportCustomToolbars(
3436 xNewUIConfMan, rToolbars, xServiceMgr, xOOo1ConfigStorage );
3437 if ( bImported )
3438 {
3439 SfxObjectShell* pObjShell = SfxBaseModel::GetObjectShell();
3440
3441 char aNum[] = "private:resource/toolbar/custom_OOo1x_0";
3442 char aTitle[] = "Toolbar 0";
3443 sal_Int32 nNumIndex = strlen( aNum )-1;
3444 sal_Int32 nTitleIndex = strlen( aTitle )-1;
3445 for ( sal_Int32 i = 0; i < rToolbars.getLength(); i++ )
3446 {
3447 aNum[nNumIndex]++;
3448 aTitle[nTitleIndex]++;
3449
3450 rtl::OUString aCustomTbxName( RTL_CONSTASCII_USTRINGPARAM( aNum ));
3451 rtl::OUString aCustomTbxTitle( RTL_CONSTASCII_USTRINGPARAM( aTitle ));
3452
3453 uno::Reference< container::XIndexContainer > xToolbar = rToolbars[i];
3454 ConvertSlotsToCommands( pObjShell, xToolbar );
3455 if ( !xNewUIConfMan->hasSettings( aCustomTbxName ))
3456 {
3457 // Set UIName for the toolbar with container property
3458 uno::Reference< beans::XPropertySet > xPropSet( xToolbar, UNO_QUERY );
3459 if ( xPropSet.is() )
3460 {
3461 try
3462 {
3463 rtl::OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( "UIName" ));
3464 Any aAny( aCustomTbxTitle );
3465 xPropSet->setPropertyValue( aPropName, aAny );
3466 }
3467 catch ( beans::UnknownPropertyException& )
3468 {
3469 }
3470 }
3471
3472 uno::Reference< container::XIndexAccess > xToolbarData( xToolbar, uno::UNO_QUERY );
3473 xNewUIConfMan->insertSettings( aCustomTbxName, xToolbarData );
3474 uno::Reference< ui::XUIConfigurationPersistence > xPersist( xNewUIConfMan, uno::UNO_QUERY );
3475 xPersist->store();
3476 }
3477 }
3478 }
3479 }
3480 }
3481 }
3482
3483 m_pData->m_xUIConfigurationManager = xNewUIConfMan;
3484 }
3485
3486 return m_pData->m_xUIConfigurationManager;
3487 }
3488
3489 //____________________________________________________________________________________________________
3490 // XVisualObject
3491 //____________________________________________________________________________________________________
3492
setVisualAreaSize(sal_Int64 nAspect,const awt::Size & aSize)3493 void SAL_CALL SfxBaseModel::setVisualAreaSize( sal_Int64 nAspect, const awt::Size& aSize )
3494 {
3495 SfxModelGuard aGuard( *this );
3496
3497 if ( !m_pData->m_pObjectShell.Is() )
3498 throw uno::Exception(); // TODO: error handling
3499
3500 SfxViewFrame* pViewFrm = SfxViewFrame::GetFirst( m_pData->m_pObjectShell, sal_False );
3501 if ( pViewFrm && m_pData->m_pObjectShell->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED && !pViewFrm->GetFrame().IsInPlace() )
3502 {
3503 Window* pWindow = VCLUnoHelper::GetWindow( pViewFrm->GetFrame().GetFrameInterface()->getContainerWindow() );
3504 Size aWinSize = pWindow->GetSizePixel();
3505 awt::Size aCurrent = getVisualAreaSize( nAspect );
3506 Size aDiff( aSize.Width-aCurrent.Width, aSize.Height-aCurrent.Height );
3507 Size aWrongDiff = OutputDevice::LogicToLogic( aDiff , m_pData->m_pObjectShell->GetMapUnit(), pWindow->GetMapMode() );
3508 aDiff = pViewFrm->GetViewShell()->GetWindow()->LogicToPixel( aDiff );
3509 aWinSize.Width() += aDiff.Width();
3510 aWinSize.Height() += aDiff.Height();
3511 pWindow->SetSizePixel( aWinSize );
3512 }
3513 else
3514 {
3515 Rectangle aTmpRect = m_pData->m_pObjectShell->GetVisArea( ASPECT_CONTENT );
3516 aTmpRect.SetSize( Size( aSize.Width, aSize.Height ) );
3517 m_pData->m_pObjectShell->SetVisArea( aTmpRect );
3518 }
3519 }
3520
getVisualAreaSize(sal_Int64)3521 awt::Size SAL_CALL SfxBaseModel::getVisualAreaSize( sal_Int64 /*nAspect*/ )
3522 {
3523 SfxModelGuard aGuard( *this );
3524
3525 if ( !m_pData->m_pObjectShell.Is() )
3526 throw uno::Exception(); // TODO: error handling
3527
3528 Rectangle aTmpRect = m_pData->m_pObjectShell->GetVisArea( ASPECT_CONTENT );
3529
3530 #if 0
3531 Window* pWindow = NULL;
3532 SfxViewFrame* pViewFrm = m_pData->m_pObjectShell.Is() ?
3533 SfxViewFrame::GetFirst( m_pData->m_pObjectShell, 0, sal_False ) : 0;
3534
3535 if ( pWindow )
3536 {
3537 MapMode aInternalMapMode( pViewFrm->GetWindow().GetMapMode() );
3538 MapMode aExternalMapMode( m_pData->m_pObjectShell->GetMapUnit() );
3539
3540 aTmpRect = OutputDevice::LogicToLogic( aTmpRect, aInternalMapMode, aExternalMapMode );
3541 }
3542 #endif
3543
3544 return awt::Size( aTmpRect.GetWidth(), aTmpRect.GetHeight() );
3545 }
3546
3547
getMapUnit(sal_Int64)3548 sal_Int32 SAL_CALL SfxBaseModel::getMapUnit( sal_Int64 /*nAspect*/ )
3549 {
3550 SfxModelGuard aGuard( *this );
3551
3552 if ( !m_pData->m_pObjectShell.Is() )
3553 throw uno::Exception(); // TODO: error handling
3554
3555 return VCLUnoHelper::VCL2UnoEmbedMapUnit( m_pData->m_pObjectShell->GetMapUnit() );
3556 }
3557
getPreferredVisualRepresentation(::sal_Int64)3558 embed::VisualRepresentation SAL_CALL SfxBaseModel::getPreferredVisualRepresentation( ::sal_Int64 /*nAspect*/ )
3559 {
3560 SfxModelGuard aGuard( *this );
3561
3562 datatransfer::DataFlavor aDataFlavor(
3563 ::rtl::OUString::createFromAscii( "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" ),
3564 ::rtl::OUString::createFromAscii( "GDIMetaFile" ),
3565 ::getCppuType( (const uno::Sequence< sal_Int8 >*) NULL ) );
3566
3567 embed::VisualRepresentation aVisualRepresentation;
3568 aVisualRepresentation.Data = getTransferData( aDataFlavor );
3569 aVisualRepresentation.Flavor = aDataFlavor;
3570
3571 return aVisualRepresentation;
3572 }
3573
3574 //____________________________________________________________________________________________________
3575 // XStorageBasedDocument
3576 //____________________________________________________________________________________________________
3577
loadFromStorage(const uno::Reference<XSTORAGE> & xStorage,const uno::Sequence<beans::PropertyValue> & aMediaDescriptor)3578 void SAL_CALL SfxBaseModel::loadFromStorage( const uno::Reference< XSTORAGE >& xStorage,
3579 const uno::Sequence< beans::PropertyValue >& aMediaDescriptor )
3580 {
3581 SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
3582 if ( IsInitialized() )
3583 throw ::com::sun::star::frame::DoubleInitializationException( ::rtl::OUString(), *this );
3584
3585 // after i36090 is fixed the pool from object shell can be used
3586 // SfxAllItemSet aSet( m_pData->m_pObjectShell->GetPool() );
3587 SfxAllItemSet aSet( SFX_APP()->GetPool() );
3588
3589 // the BaseURL is part of the ItemSet
3590 SfxMedium* pMedium = new SfxMedium( xStorage, String() );
3591 TransformParameters( SID_OPENDOC, aMediaDescriptor, aSet );
3592 pMedium->GetItemSet()->Put( aSet );
3593
3594 // allow to use an interactionhandler (if there is one)
3595 pMedium->UseInteractionHandler( sal_True );
3596
3597 SFX_ITEMSET_ARG( &aSet, pTemplateItem, SfxBoolItem, SID_TEMPLATE, sal_False);
3598 sal_Bool bTemplate = pTemplateItem && pTemplateItem->GetValue();
3599 m_pData->m_pObjectShell->SetActivateEvent_Impl( bTemplate ? SFX_EVENT_CREATEDOC : SFX_EVENT_OPENDOC );
3600 m_pData->m_pObjectShell->Get_Impl()->bOwnsStorage = sal_False;
3601
3602 // load document
3603 if ( !m_pData->m_pObjectShell->DoLoad(pMedium) )
3604 {
3605 sal_uInt32 nError = m_pData->m_pObjectShell->GetErrorCode();
3606 throw task::ErrorCodeIOException( ::rtl::OUString(),
3607 uno::Reference< uno::XInterface >(),
3608 nError ? nError : ERRCODE_IO_CANTREAD );
3609 }
3610 }
3611
storeToStorage(const uno::Reference<XSTORAGE> & xStorage,const uno::Sequence<beans::PropertyValue> & aMediaDescriptor)3612 void SAL_CALL SfxBaseModel::storeToStorage( const uno::Reference< XSTORAGE >& xStorage,
3613 const uno::Sequence< beans::PropertyValue >& aMediaDescriptor )
3614 {
3615 SfxModelGuard aGuard( *this );
3616
3617 uno::Reference< XSTORAGE > xResult;
3618 if ( !m_pData->m_pObjectShell.Is() )
3619 throw IOEXCEPTION(); // TODO:
3620
3621 SfxAllItemSet aSet( m_pData->m_pObjectShell->GetPool() );
3622 TransformParameters( SID_SAVEASDOC, aMediaDescriptor, aSet );
3623
3624 // TODO/LATER: may be a special URL "private:storage" should be used
3625 SFX_ITEMSET_ARG( &aSet, pItem, SfxStringItem, SID_FILTER_NAME, sal_False );
3626 sal_Int32 nVersion = SOFFICE_FILEFORMAT_CURRENT;
3627 if( pItem )
3628 {
3629 String aFilterName = pItem->GetValue();
3630 const SfxFilter* pFilter = SFX_APP()->GetFilterMatcher().GetFilter4FilterName( aFilterName );
3631 if ( pFilter && pFilter->UsesStorage() )
3632 nVersion = pFilter->GetVersion();
3633 }
3634
3635 sal_Bool bSuccess = sal_False;
3636 if ( xStorage == m_pData->m_pObjectShell->GetStorage() )
3637 {
3638 // storing to the own storage
3639 bSuccess = m_pData->m_pObjectShell->DoSave();
3640 }
3641 else
3642 {
3643 // TODO/LATER: if the provided storage has some data inside the storing might fail, probably the storage must be truncated
3644 // TODO/LATER: is it possible to have a template here?
3645 m_pData->m_pObjectShell->SetupStorage( xStorage, nVersion, sal_False );
3646
3647 // BaseURL is part of the ItemSet
3648 SfxMedium aMedium( xStorage, String(), &aSet );
3649 aMedium.CanDisposeStorage_Impl( sal_False );
3650 if ( aMedium.GetFilter() )
3651 {
3652 // storing without a valid filter will often crash
3653 bSuccess = m_pData->m_pObjectShell->DoSaveObjectAs( aMedium, sal_True );
3654 m_pData->m_pObjectShell->DoSaveCompleted( NULL );
3655 }
3656 }
3657
3658 sal_uInt32 nError = m_pData->m_pObjectShell->GetErrorCode();
3659 m_pData->m_pObjectShell->ResetError();
3660
3661 // the warnings are currently not transported
3662 if ( !bSuccess )
3663 {
3664 throw task::ErrorCodeIOException( ::rtl::OUString(),
3665 uno::Reference< uno::XInterface >(),
3666 nError ? nError : ERRCODE_IO_GENERAL );
3667 }
3668 }
3669
switchToStorage(const uno::Reference<XSTORAGE> & xStorage)3670 void SAL_CALL SfxBaseModel::switchToStorage( const uno::Reference< XSTORAGE >& xStorage )
3671 {
3672 SfxModelGuard aGuard( *this );
3673
3674 uno::Reference< XSTORAGE > xResult;
3675 if ( !m_pData->m_pObjectShell.Is() )
3676 throw IOEXCEPTION(); // TODO:
3677
3678 // the persistence should be switched only if the storage is different
3679 if ( xStorage != m_pData->m_pObjectShell->GetStorage()
3680 && !m_pData->m_pObjectShell->SwitchPersistance( xStorage ) )
3681 {
3682 sal_uInt32 nError = m_pData->m_pObjectShell->GetErrorCode();
3683 throw task::ErrorCodeIOException( ::rtl::OUString(),
3684 uno::Reference< uno::XInterface >(),
3685 nError ? nError : ERRCODE_IO_GENERAL );
3686 }
3687
3688 m_pData->m_pObjectShell->Get_Impl()->bOwnsStorage = sal_False;
3689 }
3690
getDocumentStorage()3691 uno::Reference< XSTORAGE > SAL_CALL SfxBaseModel::getDocumentStorage()
3692 {
3693 SfxModelGuard aGuard( *this );
3694
3695 uno::Reference< XSTORAGE > xResult;
3696 if ( !m_pData->m_pObjectShell.Is() )
3697 throw IOEXCEPTION(); // TODO
3698
3699 return m_pData->m_pObjectShell->GetStorage();
3700 }
3701
addStorageChangeListener(const uno::Reference<document::XStorageChangeListener> & xListener)3702 void SAL_CALL SfxBaseModel::addStorageChangeListener(
3703 const uno::Reference< document::XStorageChangeListener >& xListener )
3704 {
3705 SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
3706
3707 m_pData->m_aInterfaceContainer.addInterface(
3708 ::getCppuType((const uno::Reference< document::XStorageChangeListener >*)0), xListener );
3709 }
3710
removeStorageChangeListener(const uno::Reference<document::XStorageChangeListener> & xListener)3711 void SAL_CALL SfxBaseModel::removeStorageChangeListener(
3712 const uno::Reference< document::XStorageChangeListener >& xListener )
3713 {
3714 SfxModelGuard aGuard( *this );
3715
3716 m_pData->m_aInterfaceContainer.removeInterface(
3717 ::getCppuType((const uno::Reference< document::XStorageChangeListener >*)0), xListener );
3718 }
3719
3720 #include "printhelper.hxx"
impl_getPrintHelper()3721 bool SfxBaseModel::impl_getPrintHelper()
3722 {
3723 if ( m_pData->m_xPrintable.is() )
3724 return true;
3725 m_pData->m_xPrintable = new SfxPrintHelper();
3726 uno::Reference < lang::XInitialization > xInit( m_pData->m_xPrintable, uno::UNO_QUERY );
3727 uno::Sequence < uno::Any > aValues(1);
3728 aValues[0] <<= uno::Reference < frame::XModel > (static_cast< frame::XModel* >(this), uno::UNO_QUERY );
3729 xInit->initialize( aValues );
3730 uno::Reference < view::XPrintJobBroadcaster > xBrd( m_pData->m_xPrintable, uno::UNO_QUERY );
3731 xBrd->addPrintJobListener( new SfxPrintHelperListener_Impl( m_pData ) );
3732 return true;
3733 }
3734
3735 //=============================================================================
3736 // css.frame.XModule
setIdentifier(const::rtl::OUString & Identifier)3737 void SAL_CALL SfxBaseModel::setIdentifier(const ::rtl::OUString& Identifier)
3738 {
3739 SfxModelGuard aGuard( *this );
3740 m_pData->m_sModuleIdentifier = Identifier;
3741 }
3742
3743 //=============================================================================
3744 // css.frame.XModule
getIdentifier()3745 ::rtl::OUString SAL_CALL SfxBaseModel::getIdentifier()
3746 {
3747 SfxModelGuard aGuard( *this );
3748 if (m_pData->m_sModuleIdentifier.getLength() > 0)
3749 return m_pData->m_sModuleIdentifier;
3750 if (m_pData->m_pObjectShell)
3751 return m_pData->m_pObjectShell->GetFactory().GetDocumentServiceName();
3752 return ::rtl::OUString();
3753 }
3754
3755 //=============================================================================
impl_getTitleHelper()3756 css::uno::Reference< css::frame::XTitle > SfxBaseModel::impl_getTitleHelper ()
3757 {
3758 SfxModelGuard aGuard( *this );
3759
3760 if ( ! m_pData->m_xTitleHelper.is ())
3761 {
3762 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory ();
3763 css::uno::Reference< css::frame::XUntitledNumbers > xDesktop(xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY_THROW);
3764 css::uno::Reference< css::frame::XModel > xThis (static_cast< css::frame::XModel* >(this), css::uno::UNO_QUERY_THROW);
3765
3766 ::framework::TitleHelper* pHelper = new ::framework::TitleHelper(xSMGR);
3767 m_pData->m_xTitleHelper = css::uno::Reference< css::frame::XTitle >(static_cast< ::cppu::OWeakObject* >(pHelper), css::uno::UNO_QUERY_THROW);
3768 pHelper->setOwner (xThis );
3769 pHelper->connectWithUntitledNumbers (xDesktop);
3770 }
3771
3772 return m_pData->m_xTitleHelper;
3773 }
3774
3775 //=============================================================================
impl_getUntitledHelper()3776 css::uno::Reference< css::frame::XUntitledNumbers > SfxBaseModel::impl_getUntitledHelper ()
3777 {
3778 SfxModelGuard aGuard( *this );
3779
3780 if ( ! m_pData->m_xNumberedControllers.is ())
3781 {
3782 css::uno::Reference< css::frame::XModel > xThis (static_cast< css::frame::XModel* >(this), css::uno::UNO_QUERY_THROW);
3783 ::comphelper::NumberedCollection* pHelper = new ::comphelper::NumberedCollection();
3784
3785 m_pData->m_xNumberedControllers = css::uno::Reference< css::frame::XUntitledNumbers >(static_cast< ::cppu::OWeakObject* >(pHelper), css::uno::UNO_QUERY_THROW);
3786
3787 pHelper->setOwner (xThis);
3788 pHelper->setUntitledPrefix (::rtl::OUString::createFromAscii(" : "));
3789 }
3790
3791 return m_pData->m_xNumberedControllers;
3792 }
3793
3794 //=============================================================================
3795 // css.frame.XTitle
getTitle()3796 ::rtl::OUString SAL_CALL SfxBaseModel::getTitle()
3797 {
3798 // SYNCHRONIZED ->
3799 SfxModelGuard aGuard( *this );
3800
3801 ::rtl::OUString aResult = impl_getTitleHelper()->getTitle ();
3802 if ( !m_pData->m_bExternalTitle && m_pData->m_pObjectShell )
3803 {
3804 SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium();
3805 if ( pMedium )
3806 {
3807 SFX_ITEMSET_ARG( pMedium->GetItemSet(), pRepairedDocItem, SfxBoolItem, SID_REPAIRPACKAGE, sal_False );
3808 if ( pRepairedDocItem && pRepairedDocItem->GetValue() )
3809 aResult += String( SfxResId(STR_REPAIREDDOCUMENT) );
3810 }
3811
3812 if ( m_pData->m_pObjectShell->IsReadOnlyUI() || (pMedium && pMedium->IsReadOnly()) )
3813 aResult += ::rtl::OUString( String( SfxResId(STR_READONLY) ) );
3814 else if ( m_pData->m_pObjectShell->IsDocShared() )
3815 aResult += ::rtl::OUString( String( SfxResId(STR_SHARED) ) );
3816
3817 if ( m_pData->m_pObjectShell->GetDocumentSignatureState() == SIGNATURESTATE_SIGNATURES_OK )
3818 aResult += String( SfxResId( RID_XMLSEC_DOCUMENTSIGNED ) );
3819 }
3820
3821 return aResult;
3822 }
3823
3824 //=============================================================================
3825 // css.frame.XTitle
setTitle(const::rtl::OUString & sTitle)3826 void SAL_CALL SfxBaseModel::setTitle( const ::rtl::OUString& sTitle )
3827 {
3828 // SYNCHRONIZED ->
3829 SfxModelGuard aGuard( *this );
3830
3831 impl_getTitleHelper()->setTitle (sTitle);
3832 m_pData->m_bExternalTitle = sal_True;
3833 }
3834
3835 //=============================================================================
3836 // css.frame.XTitleChangeBroadcaster
addTitleChangeListener(const css::uno::Reference<css::frame::XTitleChangeListener> & xListener)3837 void SAL_CALL SfxBaseModel::addTitleChangeListener( const css::uno::Reference< css::frame::XTitleChangeListener >& xListener )
3838 {
3839 // SYNCHRONIZED ->
3840 SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING );
3841
3842 css::uno::Reference< css::frame::XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper(), css::uno::UNO_QUERY);
3843 if (xBroadcaster.is ())
3844 xBroadcaster->addTitleChangeListener (xListener);
3845 }
3846
3847 //=============================================================================
3848 // css.frame.XTitleChangeBroadcaster
removeTitleChangeListener(const css::uno::Reference<css::frame::XTitleChangeListener> & xListener)3849 void SAL_CALL SfxBaseModel::removeTitleChangeListener( const css::uno::Reference< css::frame::XTitleChangeListener >& xListener )
3850 {
3851 // SYNCHRONIZED ->
3852 SfxModelGuard aGuard( *this );
3853
3854 css::uno::Reference< css::frame::XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper(), css::uno::UNO_QUERY);
3855 if (xBroadcaster.is ())
3856 xBroadcaster->removeTitleChangeListener (xListener);
3857 }
3858
3859 //=============================================================================
3860 // css.frame.XUntitledNumbers
leaseNumber(const css::uno::Reference<css::uno::XInterface> & xComponent)3861 ::sal_Int32 SAL_CALL SfxBaseModel::leaseNumber( const css::uno::Reference< css::uno::XInterface >& xComponent )
3862 {
3863 SfxModelGuard aGuard( *this );
3864
3865 return impl_getUntitledHelper ()->leaseNumber (xComponent);
3866 }
3867
3868 //=============================================================================
3869 // css.frame.XUntitledNumbers
releaseNumber(::sal_Int32 nNumber)3870 void SAL_CALL SfxBaseModel::releaseNumber( ::sal_Int32 nNumber )
3871 {
3872 SfxModelGuard aGuard( *this );
3873 impl_getUntitledHelper ()->releaseNumber (nNumber);
3874 }
3875
3876 //=============================================================================
3877 // css.frame.XUntitledNumbers
releaseNumberForComponent(const css::uno::Reference<css::uno::XInterface> & xComponent)3878 void SAL_CALL SfxBaseModel::releaseNumberForComponent( const css::uno::Reference< css::uno::XInterface >& xComponent )
3879 {
3880 SfxModelGuard aGuard( *this );
3881 impl_getUntitledHelper ()->releaseNumberForComponent (xComponent);
3882 }
3883
3884 //=============================================================================
3885 // css.frame.XUntitledNumbers
getUntitledPrefix()3886 ::rtl::OUString SAL_CALL SfxBaseModel::getUntitledPrefix()
3887 {
3888 SfxModelGuard aGuard( *this );
3889 return impl_getUntitledHelper ()->getUntitledPrefix ();
3890 }
3891
3892 //=============================================================================
3893 // css::frame::XModel2
getControllers()3894 css::uno::Reference< css::container::XEnumeration > SAL_CALL SfxBaseModel::getControllers()
3895 {
3896 SfxModelGuard aGuard( *this );
3897
3898 sal_Int32 c = m_pData->m_seqControllers.getLength();
3899 sal_Int32 i = 0;
3900 css::uno::Sequence< css::uno::Any > lEnum(c);
3901 for (i=0; i<c; ++i)
3902 lEnum[i] <<= m_pData->m_seqControllers[i];
3903
3904 ::comphelper::OAnyEnumeration* pEnum = new ::comphelper::OAnyEnumeration(lEnum);
3905 css::uno::Reference< css::container::XEnumeration > xEnum(static_cast< css::container::XEnumeration* >(pEnum), css::uno::UNO_QUERY_THROW);
3906 return xEnum;
3907 }
3908
3909 //=============================================================================
3910 // css::frame::XModel2
getAvailableViewControllerNames()3911 css::uno::Sequence< ::rtl::OUString > SAL_CALL SfxBaseModel::getAvailableViewControllerNames()
3912 {
3913 SfxModelGuard aGuard( *this );
3914
3915 const SfxObjectFactory& rDocumentFactory = GetObjectShell()->GetFactory();
3916 const sal_Int32 nViewFactoryCount = rDocumentFactory.GetViewFactoryCount();
3917
3918 Sequence< ::rtl::OUString > aViewNames( nViewFactoryCount );
3919 for ( sal_Int32 nViewNo = 0; nViewNo < nViewFactoryCount; ++nViewNo )
3920 aViewNames[nViewNo] = rDocumentFactory.GetViewFactory( nViewNo ).GetAPIViewName();
3921 return aViewNames;
3922 }
3923
3924 //=============================================================================
3925 // css::frame::XModel2
createDefaultViewController(const css::uno::Reference<css::frame::XFrame> & i_rFrame)3926 css::uno::Reference< css::frame::XController2 > SAL_CALL SfxBaseModel::createDefaultViewController( const css::uno::Reference< css::frame::XFrame >& i_rFrame )
3927 {
3928 SfxModelGuard aGuard( *this );
3929
3930 const SfxObjectFactory& rDocumentFactory = GetObjectShell()->GetFactory();
3931 const ::rtl::OUString sDefaultViewName = rDocumentFactory.GetViewFactory( 0 ).GetAPIViewName();
3932
3933 aGuard.clear();
3934
3935 return createViewController( sDefaultViewName, Sequence< PropertyValue >(), i_rFrame );
3936 }
3937
3938 //=============================================================================
3939 namespace sfx { namespace intern {
3940
3941 /** a class which, in its dtor, cleans up various objects (well, at the moment only the frame) collected during
3942 the creation of a document view, unless the creation was successful.
3943 */
3944 class SAL_DLLPRIVATE ViewCreationGuard
3945 {
3946 public:
ViewCreationGuard()3947 ViewCreationGuard()
3948 :m_bSuccess( false )
3949 {
3950 }
3951
~ViewCreationGuard()3952 ~ViewCreationGuard()
3953 {
3954 if ( !m_bSuccess )
3955 impl_closeAll();
3956 }
3957
takeFrameOwnership(SfxFrame * i_pFrame)3958 void takeFrameOwnership( SfxFrame* i_pFrame )
3959 {
3960 OSL_PRECOND( !m_aWeakFrame, "ViewCreationGuard::takeFrameOwnership: already have a frame!" );
3961 OSL_PRECOND( i_pFrame != NULL, "ViewCreationGuard::takeFrameOwnership: invalid frame!" );
3962 m_aWeakFrame = i_pFrame;
3963 }
3964
releaseAll()3965 void releaseAll()
3966 {
3967 m_bSuccess = true;
3968 }
3969
3970 private:
impl_closeAll()3971 void impl_closeAll()
3972 {
3973 if ( m_aWeakFrame && !m_aWeakFrame->GetCurrentDocument() )
3974 {
3975 m_aWeakFrame->SetFrameInterface_Impl( NULL );
3976 m_aWeakFrame->DoClose();
3977 }
3978 }
3979
3980 private:
3981 bool m_bSuccess;
3982 SfxFrameWeak m_aWeakFrame;
3983 };
3984 } }
3985
3986 //=============================================================================
FindOrCreateViewFrame_Impl(const Reference<XFrame> & i_rFrame,::sfx::intern::ViewCreationGuard & i_rGuard) const3987 SfxViewFrame* SfxBaseModel::FindOrCreateViewFrame_Impl( const Reference< XFrame >& i_rFrame, ::sfx::intern::ViewCreationGuard& i_rGuard ) const
3988 {
3989 SfxViewFrame* pViewFrame = NULL;
3990 for ( pViewFrame = SfxViewFrame::GetFirst( GetObjectShell(), sal_False );
3991 pViewFrame;
3992 pViewFrame= SfxViewFrame::GetNext( *pViewFrame, GetObjectShell(), sal_False )
3993 )
3994 {
3995 if ( pViewFrame->GetFrame().GetFrameInterface() == i_rFrame )
3996 break;
3997 }
3998 if ( !pViewFrame )
3999 {
4000 #if OSL_DEBUG_LEVEL > 0
4001 for ( SfxFrame* pCheckFrame = SfxFrame::GetFirst();
4002 pCheckFrame;
4003 pCheckFrame = SfxFrame::GetNext( *pCheckFrame )
4004 )
4005 {
4006 if ( pCheckFrame->GetFrameInterface() == i_rFrame )
4007 {
4008 if ( ( pCheckFrame->GetCurrentViewFrame() != NULL )
4009 || ( pCheckFrame->GetCurrentDocument() != NULL )
4010 )
4011 // Note that it is perfectly letgitimate that during loading into an XFrame which already contains
4012 // a document, there exist two SfxFrame instances bound to this XFrame - the old one, which will be
4013 // destroyed later, and the new one, which we're going to create
4014 continue;
4015
4016 OSL_ENSURE( false, "SfxBaseModel::FindOrCreateViewFrame_Impl: there already is an SfxFrame for the given XFrame, but no view in it!" );
4017 // nowadays, we're the only instance allowed to create an SfxFrame for an XFrame, so this case here should not happen
4018 break;
4019 }
4020 }
4021 #endif
4022
4023 SfxFrame* pTargetFrame = SfxFrame::Create( i_rFrame );
4024 ENSURE_OR_THROW( pTargetFrame, "could not create an SfxFrame" );
4025 i_rGuard.takeFrameOwnership( pTargetFrame );
4026
4027 // prepare it
4028 pTargetFrame->PrepareForDoc_Impl( *GetObjectShell() );
4029
4030 // create view frame
4031 pViewFrame = new SfxViewFrame( *pTargetFrame, GetObjectShell() );
4032 }
4033 return pViewFrame;
4034 }
4035
4036 //=============================================================================
4037 // css::frame::XModel2
createViewController(const::rtl::OUString & i_rViewName,const Sequence<PropertyValue> & i_rArguments,const Reference<XFrame> & i_rFrame)4038 css::uno::Reference< css::frame::XController2 > SAL_CALL SfxBaseModel::createViewController(
4039 const ::rtl::OUString& i_rViewName, const Sequence< PropertyValue >& i_rArguments, const Reference< XFrame >& i_rFrame )
4040 {
4041 SfxModelGuard aGuard( *this );
4042
4043 if ( !i_rFrame.is() )
4044 throw css::lang::IllegalArgumentException( ::rtl::OUString(), *this, 3 );
4045
4046 // find the proper SFX view factory
4047 SfxViewFactory* pViewFactory = GetObjectShell()->GetFactory().GetViewFactoryByViewName( i_rViewName );
4048 if ( !pViewFactory )
4049 throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
4050
4051 // determine previous shell (used in some special cases)
4052 Reference< XController > xPreviousController( i_rFrame->getController() );
4053 const Reference< XModel > xMe( this );
4054 if ( ( xPreviousController.is() )
4055 && ( xMe != xPreviousController->getModel() )
4056 )
4057 {
4058 xPreviousController.clear();
4059 }
4060 SfxViewShell* pOldViewShell = SfxViewShell::Get( xPreviousController );
4061 OSL_ENSURE( !xPreviousController.is() || ( pOldViewShell != NULL ),
4062 "SfxBaseModel::createViewController: invalid old controller!" );
4063
4064 // a guard which will clean up in case of failure
4065 ::sfx::intern::ViewCreationGuard aViewCreationGuard;
4066
4067 // determine the ViewFrame belonging to the given XFrame
4068 SfxViewFrame* pViewFrame = FindOrCreateViewFrame_Impl( i_rFrame, aViewCreationGuard );
4069 OSL_POSTCOND( pViewFrame, "SfxBaseModel::createViewController: no frame?" );
4070
4071 // delegate to SFX' view factory
4072 pViewFrame->GetBindings().ENTERREGISTRATIONS();
4073 SfxViewShell* pViewShell = pViewFactory->CreateInstance( pViewFrame, pOldViewShell );
4074 pViewFrame->GetBindings().LEAVEREGISTRATIONS();
4075 ENSURE_OR_THROW( pViewShell, "invalid view shell provided by factory" );
4076
4077 // by setting the ViewShell it is prevented that disposing the Controller will destroy this ViewFrame also
4078 pViewFrame->GetDispatcher()->SetDisableFlags( 0 );
4079 pViewFrame->SetViewShell_Impl( pViewShell );
4080
4081 // remember ViewID
4082 pViewFrame->SetCurViewId_Impl( pViewFactory->GetOrdinal() );
4083
4084 // ensure a default controller, if the view shell did not provide an own implementation
4085 if ( !pViewShell->GetController().is() )
4086 pViewShell->SetController( new SfxBaseController( pViewShell ) );
4087
4088 // pass the creation arguments to the controller
4089 SfxBaseController* pBaseController = pViewShell->GetBaseController_Impl();
4090 ENSURE_OR_THROW( pBaseController, "invalid controller implementation!" );
4091 pBaseController->SetCreationArguments_Impl( i_rArguments );
4092
4093 // some initial view settings, coming from our most recent attachResource call
4094 ::comphelper::NamedValueCollection aDocumentLoadArgs( getArgs() );
4095 if ( aDocumentLoadArgs.getOrDefault( "ViewOnly", false ) )
4096 pViewFrame->GetFrame().SetMenuBarOn_Impl( sal_False );
4097
4098 const sal_Int16 nPluginMode = aDocumentLoadArgs.getOrDefault( "PluginMode", sal_Int16( 0 ) );
4099 if ( nPluginMode == 1 )
4100 {
4101 pViewFrame->ForceOuterResize_Impl( sal_False );
4102 pViewFrame->GetBindings().HidePopups( sal_True );
4103
4104 SfxFrame& rFrame = pViewFrame->GetFrame();
4105 // MBA: layoutmanager of inplace frame starts locked and invisible
4106 rFrame.GetWorkWindow_Impl()->MakeVisible_Impl( sal_False );
4107 rFrame.GetWorkWindow_Impl()->Lock_Impl( sal_True );
4108
4109 rFrame.GetWindow().SetBorderStyle( WINDOW_BORDER_NOBORDER );
4110 pViewFrame->GetWindow().SetBorderStyle( WINDOW_BORDER_NOBORDER );
4111 }
4112
4113 // tell the guard we were successful
4114 aViewCreationGuard.releaseAll();
4115
4116 // outta gere
4117 return pBaseController;
4118 }
4119
4120 //=============================================================================
4121 // RDF DocumentMetadataAccess
4122
4123 // ::com::sun::star::rdf::XRepositorySupplier:
4124 uno::Reference< rdf::XRepository > SAL_CALL
getRDFRepository()4125 SfxBaseModel::getRDFRepository()
4126 {
4127 SfxModelGuard aGuard( *this );
4128
4129 const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4130 if (!xDMA.is()) {
4131 throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
4132 "model has no document metadata"), *this );
4133 }
4134
4135 return xDMA->getRDFRepository();
4136 }
4137
4138 // ::com::sun::star::rdf::XNode:
4139 ::rtl::OUString SAL_CALL
getStringValue()4140 SfxBaseModel::getStringValue()
4141 {
4142 SfxModelGuard aGuard( *this );
4143
4144 const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4145 if (!xDMA.is()) {
4146 throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
4147 "model has no document metadata"), *this );
4148 }
4149
4150 return xDMA->getStringValue();
4151 }
4152
4153 // ::com::sun::star::rdf::XURI:
4154 ::rtl::OUString SAL_CALL
getNamespace()4155 SfxBaseModel::getNamespace()
4156 {
4157 SfxModelGuard aGuard( *this );
4158
4159 const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4160 if (!xDMA.is()) {
4161 throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
4162 "model has no document metadata"), *this );
4163 }
4164
4165 return xDMA->getNamespace();
4166 }
4167
4168 ::rtl::OUString SAL_CALL
getLocalName()4169 SfxBaseModel::getLocalName()
4170 {
4171 SfxModelGuard aGuard( *this );
4172
4173 const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4174 if (!xDMA.is()) {
4175 throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
4176 "model has no document metadata"), *this );
4177 }
4178
4179 return xDMA->getLocalName();
4180 }
4181
4182 // ::com::sun::star::rdf::XDocumentMetadataAccess:
4183 uno::Reference< rdf::XMetadatable > SAL_CALL
getElementByMetadataReference(const::com::sun::star::beans::StringPair & i_rReference)4184 SfxBaseModel::getElementByMetadataReference(
4185 const ::com::sun::star::beans::StringPair & i_rReference)
4186 {
4187 SfxModelGuard aGuard( *this );
4188
4189 const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4190 if (!xDMA.is()) {
4191 throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
4192 "model has no document metadata"), *this );
4193 }
4194
4195 return xDMA->getElementByMetadataReference(i_rReference);
4196 }
4197
4198 uno::Reference< rdf::XMetadatable > SAL_CALL
getElementByURI(const uno::Reference<rdf::XURI> & i_xURI)4199 SfxBaseModel::getElementByURI(const uno::Reference< rdf::XURI > & i_xURI)
4200 {
4201 SfxModelGuard aGuard( *this );
4202
4203 const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4204 if (!xDMA.is()) {
4205 throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
4206 "model has no document metadata"), *this );
4207 }
4208
4209 return xDMA->getElementByURI(i_xURI);
4210 }
4211
4212 uno::Sequence< uno::Reference< rdf::XURI > > SAL_CALL
getMetadataGraphsWithType(const uno::Reference<rdf::XURI> & i_xType)4213 SfxBaseModel::getMetadataGraphsWithType(
4214 const uno::Reference<rdf::XURI> & i_xType)
4215 {
4216 SfxModelGuard aGuard( *this );
4217
4218 const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4219 if (!xDMA.is()) {
4220 throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
4221 "model has no document metadata"), *this );
4222 }
4223
4224 return xDMA->getMetadataGraphsWithType(i_xType);
4225 }
4226
4227 uno::Reference<rdf::XURI> SAL_CALL
addMetadataFile(const::rtl::OUString & i_rFileName,const uno::Sequence<uno::Reference<rdf::XURI>> & i_rTypes)4228 SfxBaseModel::addMetadataFile(const ::rtl::OUString & i_rFileName,
4229 const uno::Sequence < uno::Reference< rdf::XURI > > & i_rTypes)
4230 {
4231 SfxModelGuard aGuard( *this );
4232
4233 const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4234 if (!xDMA.is()) {
4235 throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
4236 "model has no document metadata"), *this );
4237 }
4238
4239 return xDMA->addMetadataFile(i_rFileName, i_rTypes);
4240 }
4241
4242 uno::Reference<rdf::XURI> SAL_CALL
importMetadataFile(::sal_Int16 i_Format,const uno::Reference<io::XInputStream> & i_xInStream,const::rtl::OUString & i_rFileName,const uno::Reference<rdf::XURI> & i_xBaseURI,const uno::Sequence<uno::Reference<rdf::XURI>> & i_rTypes)4243 SfxBaseModel::importMetadataFile(::sal_Int16 i_Format,
4244 const uno::Reference< io::XInputStream > & i_xInStream,
4245 const ::rtl::OUString & i_rFileName,
4246 const uno::Reference< rdf::XURI > & i_xBaseURI,
4247 const uno::Sequence < uno::Reference< rdf::XURI > > & i_rTypes)
4248 {
4249 SfxModelGuard aGuard( *this );
4250
4251 const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4252 if (!xDMA.is()) {
4253 throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
4254 "model has no document metadata"), *this );
4255 }
4256
4257 return xDMA->importMetadataFile(i_Format,
4258 i_xInStream, i_rFileName, i_xBaseURI, i_rTypes);
4259 }
4260
4261 void SAL_CALL
removeMetadataFile(const uno::Reference<rdf::XURI> & i_xGraphName)4262 SfxBaseModel::removeMetadataFile(
4263 const uno::Reference< rdf::XURI > & i_xGraphName)
4264 {
4265 SfxModelGuard aGuard( *this );
4266
4267 const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4268 if (!xDMA.is()) {
4269 throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
4270 "model has no document metadata"), *this );
4271 }
4272
4273 return xDMA->removeMetadataFile(i_xGraphName);
4274 }
4275
4276 void SAL_CALL
addContentOrStylesFile(const::rtl::OUString & i_rFileName)4277 SfxBaseModel::addContentOrStylesFile(const ::rtl::OUString & i_rFileName)
4278 {
4279 SfxModelGuard aGuard( *this );
4280
4281 const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4282 if (!xDMA.is()) {
4283 throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
4284 "model has no document metadata"), *this );
4285 }
4286
4287 return xDMA->addContentOrStylesFile(i_rFileName);
4288 }
4289
4290 void SAL_CALL
removeContentOrStylesFile(const::rtl::OUString & i_rFileName)4291 SfxBaseModel::removeContentOrStylesFile(const ::rtl::OUString & i_rFileName)
4292 {
4293 SfxModelGuard aGuard( *this );
4294
4295 const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4296 if (!xDMA.is()) {
4297 throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
4298 "model has no document metadata"), *this );
4299 }
4300
4301 return xDMA->removeContentOrStylesFile(i_rFileName);
4302 }
4303
4304 void SAL_CALL
loadMetadataFromStorage(uno::Reference<embed::XStorage> const & i_xStorage,uno::Reference<rdf::XURI> const & i_xBaseURI,uno::Reference<task::XInteractionHandler> const & i_xHandler)4305 SfxBaseModel::loadMetadataFromStorage(
4306 uno::Reference< embed::XStorage > const & i_xStorage,
4307 uno::Reference<rdf::XURI> const & i_xBaseURI,
4308 uno::Reference<task::XInteractionHandler> const & i_xHandler)
4309 {
4310 SfxModelGuard aGuard( *this );
4311
4312 const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(
4313 m_pData->CreateDMAUninitialized());
4314 if (!xDMA.is()) {
4315 throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
4316 "model has no document metadata"), *this );
4317 }
4318
4319 try {
4320 xDMA->loadMetadataFromStorage(i_xStorage, i_xBaseURI, i_xHandler);
4321 } catch (lang::IllegalArgumentException &) {
4322 throw; // not initialized
4323 } catch (uno::Exception &) {
4324 // UGLY: if it's a RuntimeException, we can't be sure DMA is initialized
4325 m_pData->m_xDocumentMetadata = xDMA;
4326 throw;
4327 }
4328 m_pData->m_xDocumentMetadata = xDMA;
4329
4330 }
4331
4332 void SAL_CALL
storeMetadataToStorage(uno::Reference<embed::XStorage> const & i_xStorage)4333 SfxBaseModel::storeMetadataToStorage(
4334 uno::Reference< embed::XStorage > const & i_xStorage)
4335 {
4336 SfxModelGuard aGuard( *this );
4337
4338 const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4339 if (!xDMA.is()) {
4340 throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
4341 "model has no document metadata"), *this );
4342 }
4343
4344 return xDMA->storeMetadataToStorage(i_xStorage);
4345 }
4346
4347 void SAL_CALL
loadMetadataFromMedium(const uno::Sequence<beans::PropertyValue> & i_rMedium)4348 SfxBaseModel::loadMetadataFromMedium(
4349 const uno::Sequence< beans::PropertyValue > & i_rMedium)
4350 {
4351 SfxModelGuard aGuard( *this );
4352
4353 const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(
4354 m_pData->CreateDMAUninitialized());
4355 if (!xDMA.is()) {
4356 throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
4357 "model has no document metadata"), *this );
4358 }
4359
4360 try {
4361 xDMA->loadMetadataFromMedium(i_rMedium);
4362 } catch (lang::IllegalArgumentException &) {
4363 throw; // not initialized
4364 } catch (uno::Exception &) {
4365 // UGLY: if it's a RuntimeException, we can't be sure DMA is initialized
4366 m_pData->m_xDocumentMetadata = xDMA;
4367 throw;
4368 }
4369 m_pData->m_xDocumentMetadata = xDMA;
4370 }
4371
4372 void SAL_CALL
storeMetadataToMedium(const uno::Sequence<beans::PropertyValue> & i_rMedium)4373 SfxBaseModel::storeMetadataToMedium(
4374 const uno::Sequence< beans::PropertyValue > & i_rMedium)
4375 {
4376 SfxModelGuard aGuard( *this );
4377
4378 const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA());
4379 if (!xDMA.is()) {
4380 throw uno::RuntimeException( ::rtl::OUString::createFromAscii(
4381 "model has no document metadata"), *this );
4382 }
4383
4384 return xDMA->storeMetadataToMedium(i_rMedium);
4385 }
4386
4387 // =====================================================================================================================
4388 // = SfxModelSubComponent
4389 // =====================================================================================================================
4390
~SfxModelSubComponent()4391 SfxModelSubComponent::~SfxModelSubComponent()
4392 {
4393 }
4394
disposing()4395 void SfxModelSubComponent::disposing()
4396 {
4397 // nothing to do here
4398 }
4399