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 #include "arrdecl.hxx"
28 #include <map>
29
30 #include <cppuhelper/implbase1.hxx>
31
32 #include <com/sun/star/util/XCloseable.hpp>
33 #include <com/sun/star/frame/XComponentLoader.hpp>
34 #include <com/sun/star/util/XCloseBroadcaster.hpp>
35 #include <com/sun/star/util/XCloseListener.hpp>
36 #include <com/sun/star/util/XModifyBroadcaster.hpp>
37 #include <com/sun/star/beans/XPropertySet.hpp>
38 #include <com/sun/star/frame/XTitle.hpp>
39 #include <vos/mutex.hxx>
40
41 #include <tools/resary.hxx>
42 #include <vcl/msgbox.hxx>
43 #include <vcl/wrkwin.hxx>
44 #include <vcl/svapp.hxx>
45 #include <svl/eitem.hxx>
46 #include <tools/rtti.hxx>
47 #include <svl/lstner.hxx>
48 #include <sfx2/sfxhelp.hxx>
49 #include <basic/sbstar.hxx>
50 #include <svl/stritem.hxx>
51 #include <basic/sbx.hxx>
52 #include <unotools/eventcfg.hxx>
53
54 #include <sfx2/objsh.hxx>
55 #include <sfx2/signaturestate.hxx>
56 #include <sfx2/sfxmodelfactory.hxx>
57
58 #include <basic/sbuno.hxx>
59 #include <svtools/sfxecode.hxx>
60 #include <svtools/ehdl.hxx>
61 #include <unotools/printwarningoptions.hxx>
62 #include <comphelper/processfactory.hxx>
63
64 #include <com/sun/star/document/XStorageBasedDocument.hpp>
65 #include <com/sun/star/script/DocumentDialogLibraryContainer.hpp>
66 #include <com/sun/star/script/DocumentScriptLibraryContainer.hpp>
67 #include <com/sun/star/document/XEmbeddedScripts.hpp>
68 #include <com/sun/star/document/XScriptInvocationContext.hpp>
69
70 #include <svl/urihelper.hxx>
71 #include <unotools/pathoptions.hxx>
72 #include <svl/sharecontrolfile.hxx>
73 #include <unotools/localfilehelper.hxx>
74 #include <unotools/ucbhelper.hxx>
75 #include <svtools/asynclink.hxx>
76 #include <tools/diagnose_ex.h>
77 #include <sot/clsids.hxx>
78
79 #include <sfx2/app.hxx>
80 #include <sfx2/docfac.hxx>
81 #include <sfx2/docfile.hxx>
82 #include <sfx2/event.hxx>
83 #include <sfx2/dispatch.hxx>
84 #include <sfx2/viewsh.hxx>
85 #include <sfx2/viewfrm.hxx>
86 #include "sfx2/sfxresid.hxx"
87 #include "objshimp.hxx"
88 #include "appbas.hxx"
89 #include "sfxtypes.hxx"
90 #include <sfx2/evntconf.hxx>
91 #include <sfx2/request.hxx>
92 #include "doc.hrc"
93 #include "sfxlocal.hrc"
94 #include "appdata.hxx"
95 #include <sfx2/appuno.hxx>
96 #include <sfx2/sfxsids.hrc>
97 #include "sfx2/basmgr.hxx"
98 #include "sfx2/QuerySaveDocument.hxx"
99 #include "helpid.hrc"
100 #include <sfx2/msg.hxx>
101 #include "appbaslib.hxx"
102 #include <sfx2/sfxbasemodel.hxx>
103
104 #include <basic/basicmanagerrepository.hxx>
105
106 using namespace ::com::sun::star;
107 using namespace ::com::sun::star::uno;
108 using namespace ::com::sun::star::script;
109 using namespace ::com::sun::star::frame;
110 using namespace ::com::sun::star::document;
111
112 using ::basic::BasicManagerRepository;
113 #include <uno/mapping.hxx>
114
115 //====================================================================
116
117 DBG_NAME(SfxObjectShell)
118
119 #define DocumentInfo
120 #include "sfxslots.hxx"
121
122 namespace {
123
124 static WeakReference< XInterface > s_xCurrentComponent;
125
126 // remember all registered components for VBA compatibility, to be able to remove them on disposing the model
127 typedef ::std::map< XInterface*, ::rtl::OString > VBAConstantNameMap;
128 static VBAConstantNameMap s_aRegisteredVBAConstants;
129
lclGetVBAGlobalConstName(const Reference<XInterface> & rxComponent)130 ::rtl::OString lclGetVBAGlobalConstName( const Reference< XInterface >& rxComponent )
131 {
132 OSL_ENSURE( rxComponent.is(), "lclGetVBAGlobalConstName - missing component" );
133
134 VBAConstantNameMap::iterator aIt = s_aRegisteredVBAConstants.find( rxComponent.get() );
135 if( aIt != s_aRegisteredVBAConstants.end() )
136 return aIt->second;
137
138 uno::Reference< beans::XPropertySet > xProps( rxComponent, uno::UNO_QUERY );
139 if( xProps.is() ) try
140 {
141 ::rtl::OUString aConstName;
142 xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VBAGlobalConstantName" ) ) ) >>= aConstName;
143 return ::rtl::OUStringToOString( aConstName, RTL_TEXTENCODING_ASCII_US );
144 }
145 catch( uno::Exception& ) // not supported
146 {
147 }
148 return ::rtl::OString();
149 }
150
151 } // namespace
152
153 //=========================================================================
154
155
156 //=========================================================================
157
158 class SfxModelListener_Impl : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XCloseListener >
159 {
160 SfxObjectShell* mpDoc;
161 public:
SfxModelListener_Impl(SfxObjectShell * pDoc)162 SfxModelListener_Impl( SfxObjectShell* pDoc ) : mpDoc(pDoc) {};
163 virtual void SAL_CALL queryClosing( const com::sun::star::lang::EventObject& aEvent, sal_Bool bDeliverOwnership ) ;
164 virtual void SAL_CALL notifyClosing( const com::sun::star::lang::EventObject& aEvent ) ;
165 virtual void SAL_CALL disposing( const com::sun::star::lang::EventObject& aEvent ) ;
166
167 };
168
queryClosing(const com::sun::star::lang::EventObject &,sal_Bool)169 void SAL_CALL SfxModelListener_Impl::queryClosing( const com::sun::star::lang::EventObject& , sal_Bool )
170 {
171 }
172
notifyClosing(const com::sun::star::lang::EventObject &)173 void SAL_CALL SfxModelListener_Impl::notifyClosing( const com::sun::star::lang::EventObject& )
174 {
175 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
176 mpDoc->Broadcast( SfxSimpleHint(SFX_HINT_DEINITIALIZING) );
177 }
178
disposing(const com::sun::star::lang::EventObject & _rEvent)179 void SAL_CALL SfxModelListener_Impl::disposing( const com::sun::star::lang::EventObject& _rEvent )
180 {
181 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
182
183 // am I ThisComponent in AppBasic?
184 if ( SfxObjectShell::GetCurrentComponent() == _rEvent.Source )
185 {
186 // remove ThisComponent reference from AppBasic
187 SfxObjectShell::SetCurrentComponent( Reference< XInterface >() );
188 }
189
190 /* Remove VBA component from AppBasic. As every application registers its
191 own current component, the disposed component may not be the "current
192 component" of the SfxObjectShell. */
193 if ( _rEvent.Source.is() )
194 {
195 VBAConstantNameMap::iterator aIt = s_aRegisteredVBAConstants.find( _rEvent.Source.get() );
196 if ( aIt != s_aRegisteredVBAConstants.end() )
197 {
198 if ( BasicManager* pAppMgr = SFX_APP()->GetBasicManager() )
199 pAppMgr->SetGlobalUNOConstant( aIt->second.getStr(), Any( Reference< XInterface >() ) );
200 s_aRegisteredVBAConstants.erase( aIt );
201 }
202 }
203
204 if ( !mpDoc->Get_Impl()->bClosing )
205 // GCC stuerzt ab, wenn schon im dtor, also vorher Flag abfragen
206 // check flag before entering dtor in order to avoid crash of GCC
207 mpDoc->DoClose();
208 }
209
210 TYPEINIT1(SfxObjectShell, SfxShell);
211
212 //--------------------------------------------------------------------
SfxObjectShell_Impl(SfxObjectShell & _rDocShell)213 SfxObjectShell_Impl::SfxObjectShell_Impl( SfxObjectShell& _rDocShell )
214 :mpObjectContainer(0)
215 ,pBasicManager( new SfxBasicManagerHolder )
216 ,rDocShell( _rDocShell )
217 ,aMacroMode( *this )
218 ,pProgress( 0)
219 ,nTime()
220 ,nVisualDocumentNumber( USHRT_MAX)
221 ,nDocumentSignatureState( SIGNATURESTATE_UNKNOWN )
222 ,nScriptingSignatureState( SIGNATURESTATE_UNKNOWN )
223 ,bInList( sal_False)
224 ,bClosing( sal_False)
225 ,bIsSaving( sal_False)
226 ,bPasswd( sal_False)
227 ,bIsTmp( sal_False)
228 ,bIsNamedVisible( sal_False)
229 ,bIsTemplate(sal_False)
230 ,bIsAbortingImport ( sal_False)
231 ,bImportDone ( sal_False)
232 ,bInPrepareClose( sal_False )
233 ,bPreparedForClose( sal_False )
234 ,bWaitingForPicklist( sal_True )
235 ,bForbidReload( sal_False )
236 ,bBasicInitialized( sal_False )
237 ,bIsPrintJobCancelable( sal_True )
238 ,bOwnsStorage( sal_True )
239 ,bNoBaseURL( sal_False )
240 ,bInitialized( sal_False )
241 ,bSignatureErrorIsShown( sal_False )
242 ,bModelInitialized( sal_False )
243 ,bPreserveVersions( sal_True )
244 ,m_bMacroSignBroken( sal_False )
245 ,m_bNoBasicCapabilities( sal_False )
246 ,m_bDocRecoverySupport( sal_True )
247 ,bQueryLoadTemplate( sal_True )
248 ,bLoadReadonly( sal_False )
249 ,bUseUserData( sal_True )
250 ,bSaveVersionOnClose( sal_False )
251 ,m_bSharedXMLFlag( sal_False )
252 ,m_bAllowShareControlFileClean( sal_True )
253 ,lErr(ERRCODE_NONE)
254 ,nEventId ( 0)
255 ,pReloadTimer ( 0)
256 ,pMarkData( 0 )
257 ,nLoadedFlags ( SFX_LOADED_ALL )
258 ,nFlagsInProgress( 0 )
259 ,bModalMode( sal_False )
260 ,bRunningMacro( sal_False )
261 ,bReloadAvailable( sal_False )
262 ,nAutoLoadLocks( 0 )
263 ,pModule( 0 )
264 ,eFlags( SFXOBJECTSHELL_UNDEFINED )
265 ,bReadOnlyUI( sal_False )
266 ,bHiddenLockedByAPI( sal_False )
267 ,nStyleFilter( 0 )
268 ,bDisposing( sal_False )
269 ,m_bEnableSetModified( sal_True )
270 ,m_bIsModified( sal_False )
271 ,m_nMapUnit( MAP_100TH_MM )
272 ,m_bCreateTempStor( sal_False )
273 ,m_bIsInit( sal_False )
274 ,m_bIncomplEncrWarnShown( sal_False )
275 ,m_nModifyPasswordHash( 0 )
276 ,m_bModifyPasswordEntered( sal_False )
277 {
278 SfxObjectShell* pDoc = &_rDocShell;
279 SfxObjectShellArr_Impl &rArr = SFX_APP()->GetObjectShells_Impl();
280 rArr.C40_INSERT( SfxObjectShell, pDoc, rArr.Count() );
281 bInList = sal_True;
282 }
283
284 //--------------------------------------------------------------------
285
~SfxObjectShell_Impl()286 SfxObjectShell_Impl::~SfxObjectShell_Impl()
287 {
288 delete pBasicManager;
289 }
290
291 //--------------------------------------------------------------------
292
SfxObjectShell(const sal_uInt64 i_nCreationFlags)293 SfxObjectShell::SfxObjectShell( const sal_uInt64 i_nCreationFlags )
294 : pImp( new SfxObjectShell_Impl( *this ) )
295 , pMedium(0)
296 , pStyleSheetPool(0)
297 , eCreateMode( ( i_nCreationFlags & SFXMODEL_EMBEDDED_OBJECT ) ? SFX_CREATE_MODE_EMBEDDED : SFX_CREATE_MODE_STANDARD )
298 , bHasName( sal_False )
299 {
300 DBG_CTOR(SfxObjectShell, 0);
301
302 const bool bScriptSupport = ( i_nCreationFlags & SFXMODEL_DISABLE_EMBEDDED_SCRIPTS ) == 0;
303 if ( !bScriptSupport )
304 SetHasNoBasic();
305
306 const bool bDocRecovery = ( i_nCreationFlags & SFXMODEL_DISABLE_DOCUMENT_RECOVERY ) == 0;
307 if ( !bDocRecovery )
308 pImp->m_bDocRecoverySupport = sal_False;
309 }
310
311 //--------------------------------------------------------------------
312
313 // initializes a document from a file-description
314
SfxObjectShell(SfxObjectCreateMode eMode)315 SfxObjectShell::SfxObjectShell
316 (
317 SfxObjectCreateMode eMode /* purpose to generate SfxObjectShel:
318
319 SFX_CREATE_MODE_EMBEDDED (default)
320 as SO-Server from a different document
321
322 SFX_CREATE_MODE_STANDARD,
323 as normal, self opening document
324
325 SFX_CREATE_MODE_PREVIEW
326 in order to create a preview, possible
327 less data is needed
328
329 SFX_CREATE_MODE_ORGANIZER
330 as a representation in an Organiser
331 no data needed
332 */
333 )
334
335 /* [Description]
336
337 class constructor SfxObjectShell.
338 */
339
340 : pImp( new SfxObjectShell_Impl( *this ) ),
341 pMedium(0),
342 pStyleSheetPool(0),
343 eCreateMode(eMode),
344 bHasName( sal_False )
345 {
346 DBG_CTOR(SfxObjectShell, 0);
347 }
348
349 //--------------------------------------------------------------------
350
351 // virtual dtor of typical base-class SfxObjectShell
352
~SfxObjectShell()353 SfxObjectShell::~SfxObjectShell()
354 {
355 DBG_DTOR(SfxObjectShell, 0);
356
357 if ( IsEnableSetModified() )
358 EnableSetModified( sal_False );
359
360 // do not call GetInPlaceObject(). Access to the inheritage path of SfxInternObject
361 // is not allowed because of a bug in the compiler
362 SfxObjectShell::Close();
363 pImp->pBaseModel.set( NULL );
364
365 DELETEX(pImp->pReloadTimer );
366
367 SfxApplication *pSfxApp = SFX_APP();
368 if ( USHRT_MAX != pImp->nVisualDocumentNumber )
369 pSfxApp->ReleaseIndex(pImp->nVisualDocumentNumber);
370
371 // destroy BasicManager
372 pImp->pBasicManager->reset( NULL );
373
374 if ( pSfxApp->GetDdeService() )
375 pSfxApp->RemoveDdeTopic( this );
376
377 pImp->pBaseModel.set( NULL );
378
379 // don't call GetStorage() here, in case of Load Failure it's possible that a storage was never assigned!
380 if ( pMedium && pMedium->HasStorage_Impl() && pMedium->GetStorage( sal_False ) == pImp->m_xDocStorage )
381 pMedium->CanDisposeStorage_Impl( sal_False );
382
383 if ( pImp->mpObjectContainer )
384 {
385 pImp->mpObjectContainer->CloseEmbeddedObjects();
386 delete pImp->mpObjectContainer;
387 }
388
389 if ( pImp->bOwnsStorage && pImp->m_xDocStorage.is() )
390 pImp->m_xDocStorage->dispose();
391
392 if ( pMedium )
393 {
394 pMedium->CloseAndReleaseStreams_Impl();
395
396 if ( IsDocShared() )
397 FreeSharedFile();
398
399 DELETEX( pMedium );
400 }
401
402 // The removing of the temporary file must be done as the latest step in the document destruction
403 if ( pImp->aTempName.Len() )
404 {
405 String aTmp;
406 ::utl::LocalFileHelper::ConvertPhysicalNameToURL( pImp->aTempName, aTmp );
407 ::utl::UCBContentHelper::Kill( aTmp );
408 }
409
410 delete pImp;
411 }
412
413 //--------------------------------------------------------------------
414
Stamp_SetPrintCancelState(sal_Bool bState)415 void SfxObjectShell::Stamp_SetPrintCancelState(sal_Bool bState)
416 {
417 pImp->bIsPrintJobCancelable = bState;
418 }
419
420 //--------------------------------------------------------------------
421
Stamp_GetPrintCancelState() const422 sal_Bool SfxObjectShell::Stamp_GetPrintCancelState() const
423 {
424 return pImp->bIsPrintJobCancelable;
425 }
426
427 //--------------------------------------------------------------------
428
ViewAssigned()429 void SfxObjectShell::ViewAssigned()
430
431 /* [Description]
432
433 This module is called, when a view is assigned
434 */
435
436 {
437 }
438
439 //--------------------------------------------------------------------
440 // closes the Object and all its views
441
Close()442 sal_Bool SfxObjectShell::Close()
443 {
444 {DBG_CHKTHIS(SfxObjectShell, 0);}
445 SfxObjectShellRef aRef(this);
446 if ( !pImp->bClosing )
447 {
448 // if a process is still running -> dont close
449 if ( !pImp->bDisposing && GetProgress() )
450 return sal_False;
451
452 pImp->bClosing = sal_True;
453 Reference< util::XCloseable > xCloseable( GetBaseModel(), UNO_QUERY );
454
455 if ( xCloseable.is() )
456 {
457 try
458 {
459 xCloseable->close( sal_True );
460 }
461 catch( Exception& )
462 {
463 pImp->bClosing = sal_False;
464 }
465 }
466
467 if ( pImp->bClosing )
468 {
469 // remove from Document-List
470 SfxApplication *pSfxApp = SFX_APP();
471 SfxObjectShellArr_Impl &rDocs = pSfxApp->GetObjectShells_Impl();
472 const SfxObjectShell *pThis = this;
473 sal_uInt16 nPos = rDocs.GetPos(pThis);
474 if ( nPos < rDocs.Count() )
475 rDocs.Remove( nPos );
476 pImp->bInList = sal_False;
477 }
478 }
479
480 return sal_True;
481 }
482
483 //--------------------------------------------------------------------
484
485 // returns a pointer the first SfxDocument of specified type
486
GetFirst(const TypeId * pType,sal_Bool bOnlyVisible)487 SfxObjectShell* SfxObjectShell::GetFirst
488 (
489 const TypeId* pType ,
490 sal_Bool bOnlyVisible
491 )
492 {
493 SfxObjectShellArr_Impl &rDocs = SFX_APP()->GetObjectShells_Impl();
494
495 // search for a SfxDocument of the specified type
496 for ( sal_uInt16 nPos = 0; nPos < rDocs.Count(); ++nPos )
497 {
498 SfxObjectShell* pSh = rDocs.GetObject( nPos );
499 if ( bOnlyVisible && pSh->IsPreview() && pSh->IsReadOnly() )
500 continue;
501
502 if ( ( !pType || pSh->IsA(*pType) ) &&
503 ( !bOnlyVisible || SfxViewFrame::GetFirst( pSh, sal_True )))
504 return pSh;
505 }
506
507 return 0;
508 }
509 //--------------------------------------------------------------------
510
511 // returns a pointer to the next SfxDocument of specified type behind *pDoc
512
GetNext(const SfxObjectShell & rPrev,const TypeId * pType,sal_Bool bOnlyVisible)513 SfxObjectShell* SfxObjectShell::GetNext
514 (
515 const SfxObjectShell& rPrev,
516 const TypeId* pType,
517 sal_Bool bOnlyVisible
518 )
519 {
520 SfxObjectShellArr_Impl &rDocs = SFX_APP()->GetObjectShells_Impl();
521
522 // refind the specified predecessor
523 sal_uInt16 nPos;
524 for ( nPos = 0; nPos < rDocs.Count(); ++nPos )
525 if ( rDocs.GetObject(nPos) == &rPrev )
526 break;
527
528 // search for the next SfxDocument of the specified type
529 for ( ++nPos; nPos < rDocs.Count(); ++nPos )
530 {
531 SfxObjectShell* pSh = rDocs.GetObject( nPos );
532 if ( bOnlyVisible && pSh->IsPreview() && pSh->IsReadOnly() )
533 continue;
534
535 if ( ( !pType || pSh->IsA(*pType) ) &&
536 ( !bOnlyVisible || SfxViewFrame::GetFirst( pSh, sal_True )))
537 return pSh;
538 }
539 return 0;
540 }
541
542 //--------------------------------------------------------------------
543
Current()544 SfxObjectShell* SfxObjectShell::Current()
545 {
546 SfxViewFrame *pFrame = SfxViewFrame::Current();
547 return pFrame ? pFrame->GetObjectShell() : 0;
548 }
549
550 //-------------------------------------------------------------------------
551
IsInPrepareClose() const552 sal_Bool SfxObjectShell::IsInPrepareClose() const
553 {
554 return pImp->bInPrepareClose;
555 }
556
557 //------------------------------------------------------------------------
558
559 struct BoolEnv_Impl
560 {
561 SfxObjectShell_Impl* pImp;
BoolEnv_ImplBoolEnv_Impl562 BoolEnv_Impl( SfxObjectShell_Impl* pImpP) : pImp( pImpP )
563 { pImpP->bInPrepareClose = sal_True; }
~BoolEnv_ImplBoolEnv_Impl564 ~BoolEnv_Impl() { pImp->bInPrepareClose = sal_False; }
565 };
566
567
PrepareClose(sal_Bool bUI,sal_Bool bForBrowsing)568 sal_uInt16 SfxObjectShell::PrepareClose
569 (
570 sal_Bool bUI, // sal_True: Dialoge etc. erlaubt, sal_False: silent-mode
571 sal_Bool bForBrowsing
572 )
573 {
574 if( pImp->bInPrepareClose || pImp->bPreparedForClose )
575 return sal_True;
576 BoolEnv_Impl aBoolEnv( pImp );
577
578 // DocModalDialog?
579 if ( IsInModalMode() )
580 return sal_False;
581
582 SfxViewFrame* pFirst = SfxViewFrame::GetFirst( this );
583 if( pFirst && !pFirst->GetFrame().PrepareClose_Impl( bUI, bForBrowsing ) )
584 return sal_False;
585
586 // prepare views for closing
587 for ( SfxViewFrame* pFrm = SfxViewFrame::GetFirst( this );
588 pFrm; pFrm = SfxViewFrame::GetNext( *pFrm, this ) )
589 {
590 DBG_ASSERT(pFrm->GetViewShell(),"KeineShell");
591 if ( pFrm->GetViewShell() )
592 {
593 sal_uInt16 nRet = pFrm->GetViewShell()->PrepareClose( bUI, bForBrowsing );
594 if ( nRet != sal_True )
595 return nRet;
596 }
597 }
598
599 SfxApplication *pSfxApp = SFX_APP();
600 pSfxApp->NotifyEvent( SfxEventHint(SFX_EVENT_PREPARECLOSEDOC, GlobalEventConfig::GetEventName(STR_EVENT_PREPARECLOSEDOC), this) );
601
602 if( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
603 {
604 pImp->bPreparedForClose = sal_True;
605 return sal_True;
606 }
607
608 // if applicable ask if save should be executed
609 // ask only for visible documents
610 SfxViewFrame *pFrame = SfxObjectShell::Current() == this
611 ? SfxViewFrame::Current() : SfxViewFrame::GetFirst( this );
612
613 sal_Bool bClose = sal_False;
614 if ( bUI && IsModified() && pFrame )
615 {
616 //restore minimized
617 SfxFrame& rTop = pFrame->GetTopFrame();
618 SfxViewFrame::SetViewFrame( rTop.GetCurrentViewFrame() );
619 pFrame->GetFrame().Appear();
620
621 // ask for save
622 short nRet = RET_YES;
623 //TODO/CLEANUP
624 //do we still need UI=2 ?
625 //if( SfxApplication::IsPlugin() == sal_False || bUI == 2 )
626 {
627 //initiate help agent to inform about "print modifies the document"
628 SvtPrintWarningOptions aPrintOptions;
629 if (aPrintOptions.IsModifyDocumentOnPrintingAllowed() &&
630 HasName() && getDocProperties()->getPrintDate().Month > 0)
631 {
632 SfxHelp::OpenHelpAgent( &pFirst->GetFrame(), HID_CLOSE_WARNING );
633 }
634 const Reference< XTitle > xTitle( *pImp->pBaseModel.get(), UNO_QUERY_THROW );
635 const ::rtl::OUString sTitle = xTitle->getTitle ();
636 nRet = ExecuteQuerySaveDocument(&pFrame->GetWindow(),sTitle);
637 }
638 /*HACK for plugin::destroy()*/
639
640 if ( RET_YES == nRet )
641 {
642 // save by Dispatcher
643 const SfxPoolItem *pPoolItem;
644 if ( IsSaveVersionOnClose() )
645 {
646 SfxStringItem aItem( SID_DOCINFO_COMMENTS, String( SfxResId( STR_AUTOMATICVERSION ) ) );
647 SfxBoolItem aWarnItem( SID_FAIL_ON_WARNING, bUI );
648 const SfxPoolItem* ppArgs[] = { &aItem, &aWarnItem, 0 };
649 pPoolItem = pFrame->GetBindings().ExecuteSynchron( SID_SAVEDOC, ppArgs );
650 }
651 else
652 {
653 SfxBoolItem aWarnItem( SID_FAIL_ON_WARNING, bUI );
654 const SfxPoolItem* ppArgs[] = { &aWarnItem, 0 };
655 pPoolItem = pFrame->GetBindings().ExecuteSynchron( SID_SAVEDOC, ppArgs );
656 }
657
658 if ( !pPoolItem || pPoolItem->ISA(SfxVoidItem) || ( pPoolItem->ISA(SfxBoolItem) && !( (const SfxBoolItem*) pPoolItem )->GetValue() ) )
659 return sal_False;
660 else
661 bClose = sal_True;
662 }
663 else if ( RET_CANCEL == nRet )
664 // canceled
665 return sal_False;
666 else if ( RET_NEWTASK == nRet )
667 {
668 return RET_NEWTASK;
669 }
670 else
671 {
672 // At No selection don't loose information
673 bClose = sal_True;
674 }
675 }
676
677 pImp->bPreparedForClose = sal_True;
678 return sal_True;
679 }
680
681 //--------------------------------------------------------------------
682 namespace
683 {
lcl_getBasicManagerForDocument(const SfxObjectShell & _rDocument)684 static BasicManager* lcl_getBasicManagerForDocument( const SfxObjectShell& _rDocument )
685 {
686 if ( !_rDocument.Get_Impl()->m_bNoBasicCapabilities )
687 {
688 if ( !_rDocument.Get_Impl()->bBasicInitialized )
689 const_cast< SfxObjectShell& >( _rDocument ).InitBasicManager_Impl();
690 return _rDocument.Get_Impl()->pBasicManager->get();
691 }
692
693 // assume we do not have Basic ourself, but we can refer to another
694 // document which does (by our model's XScriptInvocationContext::getScriptContainer).
695 // In this case, we return the BasicManager of this other document.
696
697 OSL_ENSURE( !Reference< XEmbeddedScripts >( _rDocument.GetModel(), UNO_QUERY ).is(),
698 "lcl_getBasicManagerForDocument: inconsistency: no Basic, but an XEmbeddedScripts?" );
699 Reference< XModel > xForeignDocument;
700 Reference< XScriptInvocationContext > xContext( _rDocument.GetModel(), UNO_QUERY );
701 if ( xContext.is() )
702 {
703 xForeignDocument.set( xContext->getScriptContainer(), UNO_QUERY );
704 OSL_ENSURE( xForeignDocument.is() && xForeignDocument != _rDocument.GetModel(),
705 "lcl_getBasicManagerForDocument: no Basic, but providing ourself as script container?" );
706 }
707
708 BasicManager* pBasMgr = NULL;
709 if ( xForeignDocument.is() )
710 pBasMgr = ::basic::BasicManagerRepository::getDocumentBasicManager( xForeignDocument );
711
712 return pBasMgr;
713 }
714 }
715
716 //--------------------------------------------------------------------
717
GetBasicManager() const718 BasicManager* SfxObjectShell::GetBasicManager() const
719 {
720 BasicManager* pBasMgr = lcl_getBasicManagerForDocument( *this );
721 if ( !pBasMgr )
722 pBasMgr = SFX_APP()->GetBasicManager();
723 return pBasMgr;
724 }
725
726 //--------------------------------------------------------------------
727
SetHasNoBasic()728 void SfxObjectShell::SetHasNoBasic()
729 {
730 pImp->m_bNoBasicCapabilities = sal_True;
731 }
732
733 //--------------------------------------------------------------------
734
HasBasic() const735 sal_Bool SfxObjectShell::HasBasic() const
736 {
737 if ( pImp->m_bNoBasicCapabilities )
738 return sal_False;
739
740 if ( !pImp->bBasicInitialized )
741 const_cast< SfxObjectShell* >( this )->InitBasicManager_Impl();
742
743 return pImp->pBasicManager->isValid();
744 }
745
746 //--------------------------------------------------------------------
747 namespace
748 {
749 const Reference< XLibraryContainer >&
lcl_getOrCreateLibraryContainer(bool _bScript,Reference<XLibraryContainer> & _rxContainer,const Reference<XModel> & _rxDocument)750 lcl_getOrCreateLibraryContainer( bool _bScript, Reference< XLibraryContainer >& _rxContainer,
751 const Reference< XModel >& _rxDocument )
752 {
753 if ( !_rxContainer.is() )
754 {
755 try
756 {
757 Reference< XStorageBasedDocument > xStorageDoc( _rxDocument, UNO_QUERY );
758 const Reference< XComponentContext > xContext(
759 ::comphelper::getProcessComponentContext() );
760 _rxContainer.set ( _bScript
761 ? DocumentScriptLibraryContainer::create(
762 xContext, xStorageDoc )
763 : DocumentDialogLibraryContainer::create(
764 xContext, xStorageDoc )
765 , UNO_QUERY_THROW );
766 }
767 catch( const Exception& )
768 {
769 DBG_UNHANDLED_EXCEPTION();
770 }
771 }
772 return _rxContainer;
773 }
774 }
775
776 //--------------------------------------------------------------------
777
GetDialogContainer()778 Reference< XLibraryContainer > SfxObjectShell::GetDialogContainer()
779 {
780 if ( !pImp->m_bNoBasicCapabilities )
781 return lcl_getOrCreateLibraryContainer( false, pImp->xDialogLibraries, GetModel() );
782
783 BasicManager* pBasMgr = lcl_getBasicManagerForDocument( *this );
784 if ( pBasMgr )
785 return pBasMgr->GetDialogLibraryContainer().get();
786
787 OSL_ENSURE( false, "SfxObjectShell::GetDialogContainer: falling back to the application - is this really expected here?" );
788 return SFX_APP()->GetDialogContainer();
789 }
790
791 //--------------------------------------------------------------------
792
GetBasicContainer()793 Reference< XLibraryContainer > SfxObjectShell::GetBasicContainer()
794 {
795 if ( !pImp->m_bNoBasicCapabilities )
796 return lcl_getOrCreateLibraryContainer( true, pImp->xBasicLibraries, GetModel() );
797
798 BasicManager* pBasMgr = lcl_getBasicManagerForDocument( *this );
799 if ( pBasMgr )
800 return pBasMgr->GetScriptLibraryContainer().get();
801
802 OSL_ENSURE( false, "SfxObjectShell::GetBasicContainer: falling back to the application - is this really expected here?" );
803 return SFX_APP()->GetBasicContainer();
804 }
805
806 //--------------------------------------------------------------------
807
GetBasic() const808 StarBASIC* SfxObjectShell::GetBasic() const
809 {
810 return GetBasicManager()->GetLib(0);
811 }
812
813 //--------------------------------------------------------------------
814
InitBasicManager_Impl()815 void SfxObjectShell::InitBasicManager_Impl()
816 /* [Description]
817
818 creates a document's BasicManager and loads it, if we are already based on
819 a storage.
820
821 [Note]
822
823 This method must be called with overloaded
824 <SvPersist::Load()> (with pStor from Parameter from Load())
825 and <SvPersist::InitNew()> (with pStor = 0)
826 */
827
828 {
829 /* #163556# (DR) - Handling of recursive calls while creating the Bacic (shouldn't that be Basic?)
830 manager.
831
832 It is possible that (while creating the Basic manager) the code that
833 imports the Basic storage wants to access the Basic manager again.
834 Especially in VBA compatibility mode, there is code that wants to
835 access the "VBA Globals" object which is stored as global UNO constant
836 in the Basic manager.
837
838 To achieve correct handling of the recursive calls of this function
839 from lcl_getBasicManagerForDocument(), the implementation of the
840 function BasicManagerRepository::getDocumentBasicManager() has been
841 changed to return the Basic manager currently under construction, when
842 called repeatedly.
843
844 The variable pImp->bBasicInitialized will be set to sal_True after
845 construction now, to ensure that the recursive call of the function
846 lcl_getBasicManagerForDocument() will be routed into this function too.
847
848 Calling BasicManagerHolder::reset() twice is not a big problem, as it
849 does not take ownership but stores only the raw pointer. Owner of all
850 Basic managers is the global BasicManagerRepository instance.
851 */
852 DBG_ASSERT( !pImp->bBasicInitialized && !pImp->pBasicManager->isValid(), "Lokaler BasicManager bereits vorhanden");
853 pImp->pBasicManager->reset( BasicManagerRepository::getDocumentBasicManager( GetModel() ) );
854 DBG_ASSERT( pImp->pBasicManager->isValid(), "SfxObjectShell::InitBasicManager_Impl: did not get a BasicManager!" );
855 pImp->bBasicInitialized = sal_True;
856 }
857
858 //--------------------------------------------------------------------
859
Count()860 sal_uInt16 SfxObjectShell::Count()
861 {
862 return SFX_APP()->GetObjectShells_Impl().Count();
863 }
864
865 //--------------------------------------------------------------------
866
DoClose()867 sal_Bool SfxObjectShell::DoClose()
868 {
869 return Close();
870 }
871
872 //--------------------------------------------------------------------
873
GetObjectShell()874 SfxObjectShell* SfxObjectShell::GetObjectShell()
875 {
876 return this;
877 }
878
879 //--------------------------------------------------------------------
880
GetEventNames()881 uno::Sequence< ::rtl::OUString > SfxObjectShell::GetEventNames()
882 {
883 static uno::Sequence< ::rtl::OUString >* pEventNameContainer = NULL;
884
885 if ( !pEventNameContainer )
886 {
887 ::vos::OGuard aGuard( Application::GetSolarMutex() );
888 if ( !pEventNameContainer )
889 {
890 static uno::Sequence< ::rtl::OUString > aEventNameContainer = GlobalEventConfig().getElementNames();
891 pEventNameContainer = &aEventNameContainer;
892 }
893 }
894
895 return *pEventNameContainer;
896 }
897
898 //--------------------------------------------------------------------
899
GetModel() const900 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > SfxObjectShell::GetModel() const
901 {
902 return GetBaseModel();
903 }
904
SetBaseModel(SfxBaseModel * pModel)905 void SfxObjectShell::SetBaseModel( SfxBaseModel* pModel )
906 {
907 OSL_ENSURE( !pImp->pBaseModel.is() || pModel == NULL, "Model already set!" );
908 pImp->pBaseModel.set( pModel );
909 if ( pImp->pBaseModel.is() )
910 {
911 pImp->pBaseModel->addCloseListener( new SfxModelListener_Impl(this) );
912 }
913 }
914
915 //--------------------------------------------------------------------
916
GetBaseModel() const917 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > SfxObjectShell::GetBaseModel() const
918 {
919 return pImp->pBaseModel.get();
920 }
921 /* -----------------------------10.09.2001 15:56------------------------------
922
923 ---------------------------------------------------------------------------*/
SetAutoStyleFilterIndex(sal_uInt16 nSet)924 void SfxObjectShell::SetAutoStyleFilterIndex(sal_uInt16 nSet)
925 {
926 pImp->nStyleFilter = nSet;
927 }
928
GetAutoStyleFilterIndex()929 sal_uInt16 SfxObjectShell::GetAutoStyleFilterIndex()
930 {
931 return pImp->nStyleFilter;
932 }
933
934
SetCurrentComponent(const Reference<XInterface> & _rxComponent)935 void SfxObjectShell::SetCurrentComponent( const Reference< XInterface >& _rxComponent )
936 {
937 Reference< XInterface > xOldCurrentComp(s_xCurrentComponent);
938 if ( _rxComponent == xOldCurrentComp )
939 // nothing to do
940 return;
941 // note that "_rxComponent.get() == s_xCurrentComponent.get().get()" is /sufficient/, but not
942 // /required/ for "_rxComponent == s_xCurrentComponent.get()".
943 // In other words, it's still possible that we here do something which is not necessary,
944 // but we should have filtered quite some unnecessary calls already.
945
946 BasicManager* pAppMgr = SFX_APP()->GetBasicManager();
947 s_xCurrentComponent = _rxComponent;
948 if ( pAppMgr )
949 {
950 // set "ThisComponent" for Basic
951 pAppMgr->SetGlobalUNOConstant( "ThisComponent", Any( _rxComponent ) );
952
953 // set new current component for VBA compatibility
954 if ( _rxComponent.is() )
955 {
956 ::rtl::OString aVBAConstName = lclGetVBAGlobalConstName( _rxComponent );
957 if ( aVBAConstName.getLength() > 0 )
958 {
959 pAppMgr->SetGlobalUNOConstant( aVBAConstName.getStr(), Any( _rxComponent ) );
960 s_aRegisteredVBAConstants[ _rxComponent.get() ] = aVBAConstName;
961 }
962 }
963 // no new component passed -> remove last registered VBA component
964 else if ( xOldCurrentComp.is() )
965 {
966 ::rtl::OString aVBAConstName = lclGetVBAGlobalConstName( xOldCurrentComp );
967 if ( aVBAConstName.getLength() > 0 )
968 {
969 pAppMgr->SetGlobalUNOConstant( aVBAConstName.getStr(), Any( Reference< XInterface >() ) );
970 s_aRegisteredVBAConstants.erase( xOldCurrentComp.get() );
971 }
972 }
973 }
974 }
975
GetCurrentComponent()976 Reference< XInterface > SfxObjectShell::GetCurrentComponent()
977 {
978 return s_xCurrentComponent;
979 }
980
981
GetServiceNameFromFactory(const String & rFact)982 String SfxObjectShell::GetServiceNameFromFactory( const String& rFact )
983 {
984 //! Remove everything behind name!
985 String aFact( rFact );
986 String aPrefix = String::CreateFromAscii( "private:factory/" );
987 if ( aPrefix.Len() == aFact.Match( aPrefix ) )
988 aFact.Erase( 0, aPrefix.Len() );
989 sal_uInt16 nPos = aFact.Search( '?' );
990 String aParam;
991 if ( nPos != STRING_NOTFOUND )
992 {
993 aParam = aFact.Copy( nPos, aFact.Len() );
994 aFact.Erase( nPos, aFact.Len() );
995 aParam.Erase(0,1);
996 }
997 aFact.EraseAllChars('4').ToLowerAscii();
998
999 // HACK: sometimes a real document service name is given here instead of
1000 // a factory short name. Set return value directly to this service name as fallback
1001 // in case next lines of code does nothing ...
1002 // use rFact instead of normed aFact value !
1003 ::rtl::OUString aServiceName = rFact;
1004
1005 if ( aFact.EqualsAscii("swriter") )
1006 {
1007 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.text.TextDocument");
1008 }
1009 else if ( aFact.EqualsAscii("sweb") || aFact.EqualsAscii("swriter/web") )
1010 {
1011 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.text.WebDocument");
1012 }
1013 else if ( aFact.EqualsAscii("sglobal") || aFact.EqualsAscii("swriter/globaldocument") )
1014 {
1015 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.text.GlobalDocument");
1016 }
1017 else if ( aFact.EqualsAscii("scalc") )
1018 {
1019 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.sheet.SpreadsheetDocument");
1020 }
1021 else if ( aFact.EqualsAscii("sdraw") )
1022 {
1023 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.drawing.DrawingDocument");
1024 }
1025 else if ( aFact.EqualsAscii("simpress") )
1026 {
1027 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.presentation.PresentationDocument");
1028 }
1029 else if ( aFact.EqualsAscii("schart") )
1030 {
1031 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.chart.ChartDocument");
1032 }
1033 else if ( aFact.EqualsAscii("smath") )
1034 {
1035 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.formula.FormulaProperties");
1036 }
1037 else if ( aFact.EqualsAscii("sbasic") )
1038 {
1039 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.script.BasicIDE");
1040 }
1041 else if ( aFact.EqualsAscii("sdatabase") )
1042 {
1043 aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.sdb.OfficeDatabaseDocument");
1044 }
1045
1046 return aServiceName;
1047 }
1048
CreateObjectByFactoryName(const String & rFact,SfxObjectCreateMode eMode)1049 SfxObjectShell* SfxObjectShell::CreateObjectByFactoryName( const String& rFact, SfxObjectCreateMode eMode )
1050 {
1051 return CreateObject( GetServiceNameFromFactory( rFact ), eMode );
1052 }
1053
1054
CreateObject(const String & rServiceName,SfxObjectCreateMode eCreateMode)1055 SfxObjectShell* SfxObjectShell::CreateObject( const String& rServiceName, SfxObjectCreateMode eCreateMode )
1056 {
1057 if ( rServiceName.Len() )
1058 {
1059 ::com::sun::star::uno::Reference < ::com::sun::star::frame::XModel > xDoc(
1060 ::comphelper::getProcessServiceFactory()->createInstance( rServiceName ), UNO_QUERY );
1061 if ( xDoc.is() )
1062 {
1063 ::com::sun::star::uno::Reference < ::com::sun::star::lang::XUnoTunnel > xObj( xDoc, UNO_QUERY );
1064 ::com::sun::star::uno::Sequence < sal_Int8 > aSeq( SvGlobalName( SFX_GLOBAL_CLASSID ).GetByteSequence() );
1065 sal_Int64 nHandle = xObj->getSomething( aSeq );
1066 if ( nHandle )
1067 {
1068 SfxObjectShell* pRet = reinterpret_cast< SfxObjectShell* >( sal::static_int_cast< sal_IntPtr >( nHandle ));
1069 pRet->SetCreateMode_Impl( eCreateMode );
1070 return pRet;
1071 }
1072 }
1073 }
1074
1075 return 0;
1076 }
1077
CreateAndLoadObject(const SfxItemSet & rSet,SfxFrame * pFrame)1078 SfxObjectShell* SfxObjectShell::CreateAndLoadObject( const SfxItemSet& rSet, SfxFrame* pFrame )
1079 {
1080 uno::Sequence < beans::PropertyValue > aProps;
1081 TransformItems( SID_OPENDOC, rSet, aProps );
1082 SFX_ITEMSET_ARG(&rSet, pFileNameItem, SfxStringItem, SID_FILE_NAME, sal_False);
1083 SFX_ITEMSET_ARG(&rSet, pTargetItem, SfxStringItem, SID_TARGETNAME, sal_False);
1084 ::rtl::OUString aURL;
1085 ::rtl::OUString aTarget = rtl::OUString::createFromAscii("_blank");
1086 if ( pFileNameItem )
1087 aURL = pFileNameItem->GetValue();
1088 if ( pTargetItem )
1089 aTarget = pTargetItem->GetValue();
1090
1091 uno::Reference < frame::XComponentLoader > xLoader;
1092 if ( pFrame )
1093 {
1094 xLoader = uno::Reference < frame::XComponentLoader >( pFrame->GetFrameInterface(), uno::UNO_QUERY );
1095 }
1096 else
1097 xLoader = uno::Reference < frame::XComponentLoader >( comphelper::getProcessServiceFactory()->createInstance(
1098 ::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop") ), uno::UNO_QUERY );
1099
1100 uno::Reference < lang::XUnoTunnel > xObj;
1101 try
1102 {
1103 xObj = uno::Reference< lang::XUnoTunnel >( xLoader->loadComponentFromURL( aURL, aTarget, 0, aProps ), uno::UNO_QUERY );
1104 }
1105 catch( uno::Exception& )
1106 {}
1107
1108 if ( xObj.is() )
1109 {
1110 ::com::sun::star::uno::Sequence < sal_Int8 > aSeq( SvGlobalName( SFX_GLOBAL_CLASSID ).GetByteSequence() );
1111 sal_Int64 nHandle = xObj->getSomething( aSeq );
1112 if ( nHandle )
1113 return reinterpret_cast< SfxObjectShell* >(sal::static_int_cast< sal_IntPtr >( nHandle ));
1114 }
1115
1116 return NULL;
1117 }
1118
SetInitialized_Impl(const bool i_fromInitNew)1119 void SfxObjectShell::SetInitialized_Impl( const bool i_fromInitNew )
1120 {
1121 pImp->bInitialized = sal_True;
1122 if ( i_fromInitNew )
1123 {
1124 SetActivateEvent_Impl( SFX_EVENT_CREATEDOC );
1125 SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_DOCCREATED, GlobalEventConfig::GetEventName(STR_EVENT_DOCCREATED), this ) );
1126 }
1127 else
1128 {
1129 SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_LOADFINISHED, GlobalEventConfig::GetEventName(STR_EVENT_LOADFINISHED), this ) );
1130 }
1131 }
1132
1133
IsChangeRecording() const1134 bool SfxObjectShell::IsChangeRecording() const
1135 {
1136 // currently this function needs to be overwritten by Writer and Calc only
1137 DBG_ASSERT( 0, "function not implemented" );
1138 return false;
1139 }
1140
1141
HasChangeRecordProtection() const1142 bool SfxObjectShell::HasChangeRecordProtection() const
1143 {
1144 // currently this function needs to be overwritten by Writer and Calc only
1145 DBG_ASSERT( 0, "function not implemented" );
1146 return false;
1147 }
1148
1149
SetChangeRecording(bool)1150 void SfxObjectShell::SetChangeRecording( bool /*bActivate*/ )
1151 {
1152 // currently this function needs to be overwritten by Writer and Calc only
1153 DBG_ASSERT( 0, "function not implemented" );
1154 }
1155
1156
SetProtectionPassword(const String &)1157 bool SfxObjectShell::SetProtectionPassword( const String & /*rPassword*/ )
1158 {
1159 // currently this function needs to be overwritten by Writer and Calc only
1160 DBG_ASSERT( 0, "function not implemented" );
1161 return false;
1162 }
1163
1164
GetProtectionHash(::com::sun::star::uno::Sequence<sal_Int8> &)1165 bool SfxObjectShell::GetProtectionHash( /*out*/ ::com::sun::star::uno::Sequence< sal_Int8 > & /*rPasswordHash*/ )
1166 {
1167 // currently this function needs to be overwritten by Writer and Calc only
1168 DBG_ASSERT( 0, "function not implemented" );
1169 return false;
1170 }
1171