xref: /trunk/main/sfx2/source/doc/sfxbasemodel.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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