1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_features.h>
21 #include <osl/file.hxx>
22 #include <sfx2/infobar.hxx>
23 #include <sfx2/viewfrm.hxx>
24 #include <sfx2/classificationhelper.hxx>
25 #include <com/sun/star/document/MacroExecMode.hpp>
26 #include <com/sun/star/frame/Desktop.hpp>
27 #include <com/sun/star/frame/DispatchRecorder.hpp>
28 #include <com/sun/star/frame/DispatchRecorderSupplier.hpp>
29 #include <com/sun/star/frame/XLoadable.hpp>
30 #include <com/sun/star/frame/XLayoutManager.hpp>
31 #include <com/sun/star/frame/XComponentLoader.hpp>
32 #include <officecfg/Office/Common.hxx>
33 #include <toolkit/helper/vclunohelper.hxx>
34 #include <vcl/splitwin.hxx>
35 #include <unotools/moduleoptions.hxx>
36 #include <svl/intitem.hxx>
37 #include <svl/visitem.hxx>
38 #include <svl/stritem.hxx>
39 #include <svl/eitem.hxx>
40 #include <svl/slstitm.hxx>
41 #include <svl/whiter.hxx>
42 #include <svl/undo.hxx>
43 #include <vcl/layout.hxx>
44 #include <svtools/sfxecode.hxx>
45 #include <svtools/miscopt.hxx>
46 #include <svtools/ehdl.hxx>
47 #include <tools/diagnose_ex.h>
48 #include <com/sun/star/container/XIndexAccess.hpp>
49 #include <com/sun/star/frame/XFramesSupplier.hpp>
50 #include <com/sun/star/frame/FrameSearchFlag.hpp>
51 #include <com/sun/star/frame/XFrame.hpp>
52 #include <com/sun/star/frame/XFrames.hpp>
53 #include <com/sun/star/awt/XWindow.hpp>
54 #include <com/sun/star/frame/XController.hpp>
55 #include <com/sun/star/frame/XModel2.hpp>
56 #include <com/sun/star/util/URLTransformer.hpp>
57 #include <com/sun/star/util/XURLTransformer.hpp>
58 #include <com/sun/star/util/XCloseable.hpp>
59 #include <com/sun/star/frame/XDispatchRecorderSupplier.hpp>
60 #include <com/sun/star/document/UpdateDocMode.hpp>
61 #include <com/sun/star/beans/XPropertySet.hpp>
62 #include <com/sun/star/uri/UriReferenceFactory.hpp>
63 #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
64 #include <com/sun/star/embed/XStorage.hpp>
65 #include <com/sun/star/embed/EmbedStates.hpp>
66 #include <com/sun/star/document/XViewDataSupplier.hpp>
67 #include <com/sun/star/container/XIndexContainer.hpp>
68 #include <com/sun/star/task/InteractionHandler.hpp>
69 #include <rtl/ustrbuf.hxx>
71 #include <unotools/ucbhelper.hxx>
72 #include <comphelper/processfactory.hxx>
73 #include <comphelper/namedvaluecollection.hxx>
74 #include <comphelper/docpasswordrequest.hxx>
75 #include <comphelper/docpasswordhelper.hxx>
77 #include <com/sun/star/uno/Reference.h>
78 #include <com/sun/star/ucb/XContent.hpp>
80 #include <basic/basmgr.hxx>
81 #include <basic/sbmod.hxx>
82 #include <basic/sbmeth.hxx>
83 #include <basic/sbx.hxx>
84 #include <comphelper/storagehelper.hxx>
85 #include <svtools/asynclink.hxx>
86 #include <svl/sharecontrolfile.hxx>
87 #include <svtools/svtools.hrc>
88 #include <svtools/svtresid.hxx>
89 #include <framework/framelistanalyzer.hxx>
90 #include <shellimpl.hxx>
92 #include <boost/optional.hpp>
94 using namespace ::com::sun::star
;
95 using namespace ::com::sun::star::uno
;
96 using namespace ::com::sun::star::ucb
;
97 using namespace ::com::sun::star::frame
;
98 using namespace ::com::sun::star::lang
;
99 using ::com::sun::star::awt::XWindow
;
100 using ::com::sun::star::beans::PropertyValue
;
101 using ::com::sun::star::document::XViewDataSupplier
;
102 using ::com::sun::star::container::XIndexContainer
;
104 // Due to ViewFrame::Current
105 #include "appdata.hxx"
106 #include <sfx2/app.hxx>
107 #include <sfx2/objface.hxx>
108 #include "openflag.hxx"
109 #include "objshimp.hxx"
110 #include <sfx2/viewsh.hxx>
111 #include <sfx2/objsh.hxx>
112 #include <sfx2/bindings.hxx>
113 #include <sfx2/dispatch.hxx>
114 #include "arrdecl.hxx"
115 #include "sfxtypes.hxx"
116 #include <sfx2/request.hxx>
117 #include <sfx2/docfac.hxx>
118 #include <sfx2/ipclient.hxx>
119 #include <sfx2/sfxresid.hxx>
120 #include <sfx2/objitem.hxx>
121 #include <sfx2/viewfac.hxx>
122 #include <sfx2/event.hxx>
123 #include <sfx2/fcontnr.hxx>
124 #include <sfx2/docfile.hxx>
125 #include <sfx2/module.hxx>
126 #include <sfx2/msgpool.hxx>
127 #include "viewimp.hxx"
128 #include <sfx2/sfxbasecontroller.hxx>
129 #include <sfx2/sfx.hrc>
131 #include <sfx2/frmdescr.hxx>
132 #include <sfx2/sfxuno.hxx>
133 #include <sfx2/progress.hxx>
134 #include <sfx2/sidebar/Sidebar.hxx>
135 #include "workwin.hxx"
136 #include "helper.hxx"
137 #include <sfx2/minfitem.hxx>
138 #include "../appl/app.hrc"
139 #include "impviewframe.hxx"
142 #include "sfxslots.hxx"
145 SFX_IMPL_SUPERCLASS_INTERFACE(SfxViewFrame
,SfxShell
)
147 void SfxViewFrame::InitInterface_Impl()
149 GetStaticInterface()->RegisterChildWindow(SID_BROWSER
);
150 GetStaticInterface()->RegisterChildWindow(SID_RECORDING_FLOATWINDOW
);
151 #if HAVE_FEATURE_DESKTOP
152 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_FULLSCREEN
| SFX_VISIBILITY_FULLSCREEN
, RID_FULLSCREENTOOLBOX
);
153 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_APPLICATION
| SFX_VISIBILITY_STANDARD
, RID_ENVTOOLBOX
);
157 /// Asks the user if editing a read-only document is really wanted.
158 class SfxEditDocumentDialog
: public MessageDialog
161 VclPtr
<PushButton
> m_pEditDocument
;
162 VclPtr
<PushButton
> m_pCancel
;
165 SfxEditDocumentDialog(vcl::Window
* pParent
);
166 ~SfxEditDocumentDialog() override
;
167 void dispose() override
;
170 SfxEditDocumentDialog::SfxEditDocumentDialog(vcl::Window
* pParent
)
171 : MessageDialog(pParent
, "EditDocumentDialog", "sfx/ui/editdocumentdialog.ui")
173 get(m_pEditDocument
, "edit");
174 get(m_pCancel
, "cancel");
177 SfxEditDocumentDialog::~SfxEditDocumentDialog()
182 void SfxEditDocumentDialog::dispose()
184 m_pEditDocument
.clear();
186 MessageDialog::dispose();
189 /// Is this read-only object shell opened via .uno:SignPDF?
190 static bool IsSignPDF(SfxObjectShellRef xObjSh
)
195 SfxMedium
* pMedium
= xObjSh
->GetMedium();
196 if (pMedium
&& !pMedium
->IsOriginallyReadOnly())
198 std::shared_ptr
<const SfxFilter
> pFilter
= pMedium
->GetFilter();
199 if (pFilter
&& pFilter
->GetName() == "draw_pdf_import")
206 static bool AskPasswordToModify_Impl( const uno::Reference
< task::XInteractionHandler
>& xHandler
, const OUString
& aPath
, const std::shared_ptr
<const SfxFilter
>& pFilter
, sal_uInt32 nPasswordHash
, const uno::Sequence
< beans::PropertyValue
>& aInfo
)
208 // TODO/LATER: In future the info should replace the direct hash completely
209 bool bResult
= ( !nPasswordHash
&& !aInfo
.getLength() );
211 SAL_WARN_IF( !(pFilter
&& ( pFilter
->GetFilterFlags() & SfxFilterFlags::PASSWORDTOMODIFY
)), "sfx.view",
212 "PasswordToModify feature is active for a filter that does not support it!");
214 if ( pFilter
&& xHandler
.is() )
216 bool bCancel
= false;
217 bool bFirstTime
= true;
219 while ( !bResult
&& !bCancel
)
221 bool bMSType
= !pFilter
->IsOwnFormat();
223 ::rtl::Reference
< ::comphelper::DocPasswordRequest
> pPasswordRequest(
224 new ::comphelper::DocPasswordRequest(
225 bMSType
? ::comphelper::DocPasswordRequestType::MS
: ::comphelper::DocPasswordRequestType::Standard
,
226 bFirstTime
? css::task::PasswordRequestMode_PASSWORD_ENTER
: css::task::PasswordRequestMode_PASSWORD_REENTER
,
230 uno::Reference
< css::task::XInteractionRequest
> rRequest( pPasswordRequest
.get() );
231 xHandler
->handle( rRequest
);
233 if ( pPasswordRequest
->isPassword() )
235 if ( aInfo
.getLength() )
237 bResult
= ::comphelper::DocPasswordHelper::IsModifyPasswordCorrect( pPasswordRequest
->getPasswordToModify(), aInfo
);
242 bResult
= ( SfxMedium::CreatePasswordToModifyHash( pPasswordRequest
->getPasswordToModify(), OUString( "com.sun.star.text.TextDocument" ).equals( pFilter
->GetServiceName() ) ) == nPasswordHash
);
255 void SfxViewFrame::ExecReload_Impl( SfxRequest
& rReq
)
257 if ( rReq
.GetSlot() == SID_RELOAD
)
259 // When CTRL-Reload, reload the active Frame
260 SfxViewFrame
* pActFrame
= this;
262 pActFrame
= pActFrame
->GetActiveChildFrame_Impl();
266 sal_uInt16 nModifier
= rReq
.GetModifier();
267 if ( nModifier
& KEY_MOD1
)
269 pActFrame
->ExecReload_Impl( rReq
);
275 SfxObjectShell
* pSh
= GetObjectShell();
276 switch ( rReq
.GetSlot() )
280 // Due to Double occupancy in toolboxes (with or without Ctrl),
281 // it is also possible that the slot is enabled, but Ctrl-click
282 // despite this is not!
283 if( !pSh
|| !pSh
->HasName() || !(pSh
->Get_Impl()->nLoadedFlags
& SfxLoadedFlags::MAINDOCUMENT
))
286 SfxMedium
* pMed
= pSh
->GetMedium();
288 const SfxBoolItem
* pItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pSh
->GetMedium()->GetItemSet(), SID_VIEWONLY
, false);
289 if ( pItem
&& pItem
->GetValue() )
291 SfxApplication
* pApp
= SfxGetpApp();
292 SfxAllItemSet
aSet( pApp
->GetPool() );
293 aSet
.Put( SfxStringItem( SID_FILE_NAME
, pMed
->GetURLObject().GetMainURL(INetURLObject::NO_DECODE
) ) );
294 aSet
.Put( SfxBoolItem( SID_TEMPLATE
, true ) );
295 aSet
.Put( SfxStringItem( SID_TARGETNAME
, OUString("_blank") ) );
296 const SfxStringItem
* pReferer
= SfxItemSet::GetItem
<SfxStringItem
>(pMed
->GetItemSet(), SID_REFERER
, false);
298 aSet
.Put( *pReferer
);
299 const SfxInt16Item
* pVersionItem
= SfxItemSet::GetItem
<SfxInt16Item
>(pSh
->GetMedium()->GetItemSet(), SID_VERSION
, false);
301 aSet
.Put( *pVersionItem
);
303 if( pMed
->GetFilter() )
305 aSet
.Put( SfxStringItem( SID_FILTER_NAME
, pMed
->GetFilter()->GetFilterName() ) );
306 const SfxStringItem
* pOptions
= SfxItemSet::GetItem
<SfxStringItem
>(pMed
->GetItemSet(), SID_FILE_FILTEROPTIONS
, false);
308 aSet
.Put( *pOptions
);
311 GetDispatcher()->Execute( SID_OPENDOC
, SfxCallMode::ASYNCHRON
, aSet
);
315 StreamMode nOpenMode
;
316 bool bNeedsReload
= false;
317 if ( !pSh
->IsReadOnly() )
319 // Save and reload Readonly
320 if( pSh
->IsModified() )
322 if ( pSh
->PrepareClose() )
324 // the storing could let the medium be changed
325 pMed
= pSh
->GetMedium();
330 rReq
.SetReturnValue( SfxBoolItem( rReq
.GetSlot(), false ) );
334 nOpenMode
= SFX_STREAM_READONLY
;
335 pSh
->SetReadOnlyUI();
339 if ( pSh
->IsReadOnlyMedium()
340 && ( pSh
->GetModifyPasswordHash() || pSh
->GetModifyPasswordInfo().getLength() )
341 && !pSh
->IsModifyPasswordEntered() )
343 OUString aDocumentName
= INetURLObject( pMed
->GetOrigURL() ).GetMainURL( INetURLObject::DECODE_WITH_CHARSET
);
344 if( !AskPasswordToModify_Impl( pMed
->GetInteractionHandler(), aDocumentName
, pMed
->GetOrigFilter(), pSh
->GetModifyPasswordHash(), pSh
->GetModifyPasswordInfo() ) )
346 // this is a read-only document, if it has "Password to modify"
347 // the user should enter password before he can edit the document
348 rReq
.SetReturnValue( SfxBoolItem( rReq
.GetSlot(), false ) );
352 pSh
->SetModifyPasswordEntered();
355 // Remove infobar if document was read-only (after password check)
356 RemoveInfoBar("readonly");
358 nOpenMode
= pSh
->IsOriginallyReadOnlyMedium() ? SFX_STREAM_READONLY
: SFX_STREAM_READWRITE
;
360 // if only the view was in the readonly mode then there is no need to do the reload
361 if ( !pSh
->IsReadOnlyMedium() )
363 // SetReadOnlyUI causes recomputation of window title, using
364 // open mode among other things, so call SetOpenMode before
366 pMed
->SetOpenMode( nOpenMode
);
367 pSh
->SetReadOnlyUI( false );
372 pSh
->SetReadOnlyUI( false );
377 // Control through API if r/w or r/o
378 const SfxBoolItem
* pEditItem
= rReq
.GetArg
<SfxBoolItem
>(SID_EDITDOC
);
380 nOpenMode
= pEditItem
->GetValue() ? SFX_STREAM_READWRITE
: SFX_STREAM_READONLY
;
386 osl::FileBase::getFileURLFromSystemPath( pMed
->GetPhysicalName(), aTemp
);
387 INetURLObject
aPhysObj( aTemp
);
388 const SfxInt16Item
* pVersionItem
= SfxItemSet::GetItem
<SfxInt16Item
>(pSh
->GetMedium()->GetItemSet(), SID_VERSION
, false);
390 INetURLObject
aMedObj( pMed
->GetName() );
393 // the logic below is following:
394 // if the document seems not to need to be reloaded
395 // and the physical name is different to the logical one,
396 // then on file system it can be checked that the copy is still newer than the original and no document reload is required.
397 // Did some semplification to enhance readability of the 'if' expression
399 // when the 'http/https' protocol is active, the bool bPhysObjIsYounger relies upon the getlastmodified Property of a WebDAV resource.
400 // Said property should be implemented, but sometimes it's not.
401 // implemented. On this case the reload activated here will not work properly.
402 // TODO: change the check age method for WebDAV to etag (entity-tag) property value, need some rethinking, since the
403 // etag tells that the cache representation (e.g. in LO) is different from the one on the server,
404 // but tells nothing about the age
405 // Details at this link: http://tools.ietf.org/html/rfc4918#section-15, section 15.7
406 bool bPhysObjIsYounger
= ::utl::UCBContentHelper::IsYounger( aMedObj
.GetMainURL( INetURLObject::NO_DECODE
),
407 aPhysObj
.GetMainURL( INetURLObject::NO_DECODE
) );
408 bool bIsWebDAV
= aMedObj
.isAnyKnownWebDAVScheme();
410 if ( ( !bNeedsReload
&& ( ( aMedObj
.GetProtocol() == INetProtocol::File
&&
411 aMedObj
.getFSysPath( INetURLObject::FSYS_DETECT
) != aPhysObj
.getFSysPath( INetURLObject::FSYS_DETECT
) &&
413 || ( bIsWebDAV
&& !bPhysObjIsYounger
)
414 || ( pMed
->IsRemote() && !bIsWebDAV
) ) )
421 bool bHasStorage
= pMed
->HasStorage_Impl();
422 // switching edit mode could be possible without reload
423 if ( bHasStorage
&& pMed
->GetStorage() == pSh
->GetStorage() )
425 // TODO/LATER: faster creation of copy
426 if ( !pSh
->ConnectTmpStorage_Impl( pMed
->GetStorage(), pMed
) )
430 pMed
->CloseAndRelease();
431 pMed
->GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY
, !( nOpenMode
& StreamMode::WRITE
) ) );
432 pMed
->SetOpenMode( nOpenMode
);
434 pMed
->CompleteReOpen();
435 if ( nOpenMode
& StreamMode::WRITE
)
436 pMed
->LockOrigFileOnDemand( false, true );
438 // LockOrigFileOnDemand might set the readonly flag itself, it should be set back
439 pMed
->GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY
, !( nOpenMode
& StreamMode::WRITE
) ) );
441 if ( !pMed
->GetErrorCode() )
447 ErrCode nErr
= pMed
->GetErrorCode();
449 nErr
= ERRCODE_IO_ACCESSDENIED
;
453 pMed
->SetOpenMode( SFX_STREAM_READONLY
);
455 pSh
->DoSaveCompleted( pMed
);
458 // Readonly document can not be switched to edit mode?
461 if ( nOpenMode
== SFX_STREAM_READWRITE
&& !rReq
.IsAPI() )
463 // css::sdbcx::User offering to open it as a template
464 ScopedVclPtrInstance
<MessageDialog
> aBox(&GetWindow(), SfxResId(STR_QUERY_OPENASTEMPLATE
),
465 VclMessageType::Question
, VCL_BUTTONS_YES_NO
);
466 if ( RET_YES
== aBox
->Execute() )
468 SfxApplication
* pApp
= SfxGetpApp();
469 SfxAllItemSet
aSet( pApp
->GetPool() );
470 aSet
.Put( SfxStringItem( SID_FILE_NAME
, pMed
->GetName() ) );
471 const SfxStringItem
* pReferer
= SfxItemSet::GetItem
<SfxStringItem
>(pMed
->GetItemSet(), SID_REFERER
, false);
473 aSet
.Put( *pReferer
);
474 aSet
.Put( SfxBoolItem( SID_TEMPLATE
, true ) );
476 aSet
.Put( *pVersionItem
);
478 if( pMed
->GetFilter() )
480 aSet
.Put( SfxStringItem( SID_FILTER_NAME
, pMed
->GetFilter()->GetFilterName() ) );
481 const SfxStringItem
* pOptions
= SfxItemSet::GetItem
<SfxStringItem
>(pMed
->GetItemSet(), SID_FILE_FILTEROPTIONS
, false);
483 aSet
.Put( *pOptions
);
486 GetDispatcher()->Execute( SID_OPENDOC
, SfxCallMode::ASYNCHRON
, aSet
);
493 ErrorHandler::HandleError( nErr
);
495 SfxBoolItem( rReq
.GetSlot(), false ) );
500 pSh
->DoSaveCompleted( pMed
);
501 pSh
->Broadcast( SfxHint(SFX_HINT_MODECHANGED
) );
502 rReq
.SetReturnValue( SfxBoolItem( rReq
.GetSlot(), true ) );
508 rReq
.AppendItem( SfxBoolItem( SID_FORCERELOAD
, true) );
509 rReq
.AppendItem( SfxBoolItem( SID_SILENT
, true ));
511 SAL_FALLTHROUGH
; //TODO ???
516 // Due to Double occupancy in toolboxes (with or without Ctrl),
517 // it is also possible that the slot is enabled, but Ctrl-click
518 // despite this is not!
519 if ( !pSh
|| !pSh
->CanReload_Impl() )
521 SfxApplication
* pApp
= SfxGetpApp();
522 const SfxBoolItem
* pForceReloadItem
= rReq
.GetArg
<SfxBoolItem
>(SID_FORCERELOAD
);
523 if( pForceReloadItem
&& !pForceReloadItem
->GetValue() &&
524 !pSh
->GetMedium()->IsExpired() )
526 if( m_pImpl
->bReloading
|| pSh
->IsInModalMode() )
529 // AutoLoad is prohibited if possible
530 const SfxBoolItem
* pAutoLoadItem
= rReq
.GetArg
<SfxBoolItem
>(SID_AUTOLOAD
);
531 if ( pAutoLoadItem
&& pAutoLoadItem
->GetValue() &&
532 GetFrame().IsAutoLoadLocked_Impl() )
535 SfxObjectShellLock
xOldObj( pSh
);
536 m_pImpl
->bReloading
= true;
537 const SfxStringItem
* pURLItem
= rReq
.GetArg
<SfxStringItem
>(SID_FILE_NAME
);
539 bool bForEdit
= !pSh
->IsReadOnly();
541 // If possible ask the User
542 bool bDo
= GetViewShell()->PrepareClose();
543 const SfxBoolItem
* pSilentItem
= rReq
.GetArg
<SfxBoolItem
>(SID_SILENT
);
544 if ( bDo
&& GetFrame().DocIsModified_Impl() &&
545 !rReq
.IsAPI() && ( !pSilentItem
|| !pSilentItem
->GetValue() ) )
547 ScopedVclPtrInstance
<MessageDialog
> aBox(&GetWindow(), SfxResId(STR_QUERY_LASTVERSION
),
548 VclMessageType::Question
, VCL_BUTTONS_YES_NO
);
549 bDo
= ( RET_YES
== aBox
->Execute() );
554 SfxMedium
*pMedium
= xOldObj
->GetMedium();
556 // Remove Frameset before the FramesetView may disappear
559 aURL
= pURLItem
->GetValue();
561 aURL
= pMedium
->GetName();
564 ( pMedium
->GetURLObject().GetProtocol() == INetProtocol::File
&& !xOldObj
->IsDocShared() );
566 // Empty existing SfxMDIFrames for this Document
567 // in native format or R/O, open it now for editing?
568 SfxObjectShellLock xNewObj
;
570 // collect the views of the document
571 // TODO: when UNO ViewFactories are available for SFX-based documents, the below code should
573 typedef ::std::pair
< Reference
< XFrame
>, sal_uInt16
> ViewDescriptor
;
574 ::std::list
< ViewDescriptor
> aViewFrames
;
575 SfxViewFrame
*pView
= GetFirst( xOldObj
);
578 Reference
< XFrame
> xFrame( pView
->GetFrame().GetFrameInterface() );
579 SAL_WARN_IF( !xFrame
.is(), "sfx.view", "SfxViewFrame::ExecReload_Impl: no XFrame?!");
580 aViewFrames
.push_back( ViewDescriptor( xFrame
, pView
->GetCurViewId() ) );
582 pView
= GetNext( *pView
, xOldObj
);
585 DELETEZ( xOldObj
->Get_Impl()->pReloadTimer
);
587 SfxItemSet
* pNewSet
= nullptr;
588 std::shared_ptr
<const SfxFilter
> pFilter
= pMedium
->GetFilter();
591 pNewSet
= new SfxAllItemSet( pApp
->GetPool() );
592 pNewSet
->Put( *pURLItem
);
596 const SfxStringItem
* refererItem
= rReq
.GetArg
<SfxStringItem
>(SID_REFERER
);
597 if (refererItem
!= nullptr) {
598 referer
= refererItem
->GetValue();
600 SfxMedium
aMedium( pURLItem
->GetValue(), referer
, SFX_STREAM_READWRITE
);
601 SfxFilterMatcher().GuessFilter( aMedium
, pFilter
);
603 pNewSet
->Put( SfxStringItem( SID_FILTER_NAME
, pFilter
->GetName() ) );
604 pNewSet
->Put( *aMedium
.GetItemSet() );
608 pNewSet
= new SfxAllItemSet( *pMedium
->GetItemSet() );
609 pNewSet
->ClearItem( SID_VIEW_ID
);
610 pNewSet
->ClearItem( SID_STREAM
);
611 pNewSet
->ClearItem( SID_INPUTSTREAM
);
612 pNewSet
->Put( SfxStringItem( SID_FILTER_NAME
, pMedium
->GetFilter()->GetName() ) );
614 // let the current security settings be checked again
615 pNewSet
->Put( SfxUInt16Item( SID_MACROEXECMODE
, document::MacroExecMode::USE_CONFIG
) );
617 if ( pSh
->IsOriginallyReadOnlyMedium()
618 || pSh
->IsOriginallyLoadedReadOnlyMedium() )
619 // edit mode is switched or reload of readonly document
620 pNewSet
->Put( SfxBoolItem( SID_DOC_READONLY
, true ) );
622 // Reload of file opened for writing
623 pNewSet
->ClearItem( SID_DOC_READONLY
);
626 // If a salvaged file is present, do not enclose the OrigURL
627 // again, since the Template is invalid after reload.
628 const SfxStringItem
* pSalvageItem
= SfxItemSet::GetItem
<SfxStringItem
>(pNewSet
, SID_DOC_SALVAGE
, false);
631 aURL
= pSalvageItem
->GetValue();
632 pNewSet
->ClearItem( SID_DOC_SALVAGE
);
635 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
636 // TODO/LATER: Temporary solution, the SfxMedium must know the original URL as aLogicName
637 // SfxMedium::Transfer_Impl() will be forbidden then.
638 if ( xOldObj
->IsDocShared() )
639 pNewSet
->Put( SfxStringItem( SID_FILE_NAME
, xOldObj
->GetSharedFileURL() ) );
642 pNewSet
->Put( SfxStringItem( SID_REFERER
, pMedium
->GetName() ) );
644 pNewSet
->Put( SfxStringItem( SID_REFERER
, OUString() ) );
646 xOldObj
->CancelTransfers();
649 if ( pSilentItem
&& pSilentItem
->GetValue() )
650 pNewSet
->Put( SfxBoolItem( SID_SILENT
, true ) );
652 const SfxUnoAnyItem
* pInteractionItem
= SfxItemSet::GetItem
<SfxUnoAnyItem
>(pNewSet
, SID_INTERACTIONHANDLER
, false);
653 const SfxUInt16Item
* pMacroExecItem
= SfxItemSet::GetItem
<SfxUInt16Item
>(pNewSet
, SID_MACROEXECMODE
, false);
654 const SfxUInt16Item
* pDocTemplateItem
= SfxItemSet::GetItem
<SfxUInt16Item
>(pNewSet
, SID_UPDATEDOCMODE
, false);
656 if (!pInteractionItem
)
658 Reference
< task::XInteractionHandler2
> xHdl
= task::InteractionHandler::createWithParent( ::comphelper::getProcessComponentContext(), nullptr );
660 pNewSet
->Put( SfxUnoAnyItem(SID_INTERACTIONHANDLER
,css::uno::makeAny(xHdl
)) );
664 pNewSet
->Put( SfxUInt16Item(SID_MACROEXECMODE
,css::document::MacroExecMode::USE_CONFIG
) );
665 if (!pDocTemplateItem
)
666 pNewSet
->Put( SfxUInt16Item(SID_UPDATEDOCMODE
,css::document::UpdateDocMode::ACCORDING_TO_CONFIG
) );
668 xOldObj
->SetModified( false );
669 // Do not chache the old Document! Is invalid when loading
672 const SfxStringItem
* pSavedOptions
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_FILE_FILTEROPTIONS
, false);
673 const SfxStringItem
* pSavedReferer
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_REFERER
, false);
675 bool bHasStorage
= pMedium
->HasStorage_Impl();
678 if ( bHasStorage
&& pMedium
->GetStorage() == xOldObj
->GetStorage() )
680 // TODO/LATER: faster creation of copy
681 if ( !xOldObj
->ConnectTmpStorage_Impl( pMedium
->GetStorage(), pMedium
) )
685 pMedium
->CloseAndRelease();
688 xNewObj
= SfxObjectShell::CreateObject( pFilter
->GetServiceName() );
690 if ( xOldObj
->IsModifyPasswordEntered() )
691 xNewObj
->SetModifyPasswordEntered();
693 uno::Sequence
< beans::PropertyValue
> aLoadArgs
;
694 TransformItems( SID_OPENDOC
, *pNewSet
, aLoadArgs
);
697 uno::Reference
< frame::XLoadable
> xLoad( xNewObj
->GetModel(), uno::UNO_QUERY
);
698 xLoad
->load( aLoadArgs
);
700 catch ( uno::Exception
& )
712 // back to old medium
714 pMedium
->LockOrigFileOnDemand( false, true );
716 xOldObj
->DoSaveCompleted( pMedium
);
719 // r/o-Doc couldn't be switched to writing mode
720 if ( bForEdit
&& SID_EDITDOC
== rReq
.GetSlot() )
722 // ask user for opening as template
723 ScopedVclPtrInstance
<MessageDialog
> aBox(&GetWindow(), SfxResId(STR_QUERY_OPENASTEMPLATE
),
724 VclMessageType::Question
, VCL_BUTTONS_YES_NO
);
725 if ( RET_YES
== aBox
->Execute() )
727 SfxAllItemSet
aSet( pApp
->GetPool() );
728 aSet
.Put( SfxStringItem( SID_FILE_NAME
, pMedium
->GetName() ) );
729 aSet
.Put( SfxStringItem( SID_TARGETNAME
, OUString("_blank") ) );
731 aSet
.Put( *pSavedOptions
);
733 aSet
.Put( *pSavedReferer
);
734 aSet
.Put( SfxBoolItem( SID_TEMPLATE
, true ) );
736 aSet
.Put( SfxStringItem( SID_FILTER_NAME
, pFilter
->GetFilterName() ) );
737 GetDispatcher()->Execute( SID_OPENDOC
, SfxCallMode::ASYNCHRON
, aSet
);
743 if ( xNewObj
->GetModifyPasswordHash() && xNewObj
->GetModifyPasswordHash() != xOldObj
->GetModifyPasswordHash() )
745 xNewObj
->SetModifyPasswordEntered( false );
746 xNewObj
->SetReadOnly();
748 else if ( rReq
.GetSlot() == SID_EDITDOC
)
750 xNewObj
->SetReadOnlyUI( !bForEdit
);
753 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
754 if ( xNewObj
->IsDocShared() )
756 // the file is shared but the closing can change the sharing control file
757 xOldObj
->DoNotCleanShareControlFile();
760 // the Reload and Silent items were only temporary, remove them
761 xNewObj
->GetMedium()->GetItemSet()->ClearItem( SID_RELOAD
);
762 xNewObj
->GetMedium()->GetItemSet()->ClearItem( SID_SILENT
);
763 TransformItems( SID_OPENDOC
, *xNewObj
->GetMedium()->GetItemSet(), aLoadArgs
);
765 UpdateDocument_Impl();
769 while ( !aViewFrames
.empty() )
771 LoadViewIntoFrame_Impl( *xNewObj
, aViewFrames
.front().first
, aLoadArgs
, aViewFrames
.front().second
, false );
772 aViewFrames
.pop_front();
775 catch( const Exception
& )
777 // close the remaining frames
778 // Don't catch exceptions herein, if this fails, then we're left in an indetermined state, and
779 // crashing is better than trying to proceed
780 while ( !aViewFrames
.empty() )
782 Reference
< util::XCloseable
> xClose( aViewFrames
.front().first
, UNO_QUERY_THROW
);
783 xClose
->close( true );
784 aViewFrames
.pop_front();
788 // Propagate document closure.
789 SfxGetpApp()->NotifyEvent( SfxEventHint( SFX_EVENT_CLOSEDOC
, GlobalEventConfig::GetEventName( GlobalEventId::CLOSEDOC
), xOldObj
) );
794 rReq
.SetReturnValue(SfxBoolItem(rReq
.GetSlot(), true));
799 // Record as not done
801 rReq
.SetReturnValue(SfxBoolItem(rReq
.GetSlot(), false));
802 m_pImpl
->bReloading
= false;
809 void SfxViewFrame::StateReload_Impl( SfxItemSet
& rSet
)
811 SfxObjectShell
* pSh
= GetObjectShell();
814 // I'm just on reload and am yielding myself ...
818 SfxWhichIter
aIter( rSet
);
819 for ( sal_uInt16 nWhich
= aIter
.FirstWhich(); nWhich
; nWhich
= aIter
.NextWhich() )
825 const SfxViewShell
*pVSh
;
826 const SfxShell
*pFSh
;
829 !( pSh
->Get_Impl()->nLoadedFlags
& SfxLoadedFlags::MAINDOCUMENT
) ||
830 ( pSh
->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
&&
831 ( !(pVSh
= pSh
->GetViewShell()) ||
832 !(pFSh
= pVSh
->GetFormShell()) ||
833 !pFSh
->IsDesignMode())))
834 rSet
.DisableItem( SID_EDITDOC
);
837 const SfxBoolItem
* pItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pSh
->GetMedium()->GetItemSet(), SID_EDITDOC
, false);
838 if ( pItem
&& !pItem
->GetValue() )
839 rSet
.DisableItem( SID_EDITDOC
);
841 rSet
.Put( SfxBoolItem( nWhich
, !pSh
->IsReadOnly() ) );
848 if ( !pSh
|| !pSh
->CanReload_Impl() || pSh
->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
849 rSet
.DisableItem(nWhich
);
852 // If any ChildFrame is reloadable, the slot is enabled,
853 // so you can perfom CTRL-Reload
854 rSet
.Put( SfxBoolItem( nWhich
, false));
863 void SfxViewFrame::ExecHistory_Impl( SfxRequest
&rReq
)
865 // Is there an Undo-Manager on the top Shell?
866 SfxShell
*pSh
= GetDispatcher()->GetShell(0);
867 ::svl::IUndoManager
* pShUndoMgr
= pSh
->GetUndoManager();
871 switch ( rReq
.GetSlot() )
873 case SID_CLEARHISTORY
:
880 GetBindings().InvalidateAll(false);
886 GetBindings().InvalidateAll(false);
891 if ( pSh
->GetRepeatTarget() )
892 pShUndoMgr
->Repeat( *pSh
->GetRepeatTarget() );
897 else if ( GetViewShell() )
899 // The SW has its own undo in the View
900 const SfxPoolItem
*pRet
= GetViewShell()->ExecuteSlot( rReq
);
902 bOK
= static_cast<const SfxBoolItem
*>(pRet
)->GetValue();
905 rReq
.SetReturnValue( SfxBoolItem( rReq
.GetSlot(), bOK
) );
909 void SfxViewFrame::StateHistory_Impl( SfxItemSet
&rSet
)
911 // Search for Undo-Manager
912 SfxShell
*pSh
= GetDispatcher()->GetShell(0);
914 // I'm just on reload and am yielding myself ...
917 ::svl::IUndoManager
*pShUndoMgr
= pSh
->GetUndoManager();
920 // The SW has its own undo in the View
921 SfxWhichIter
aIter( rSet
);
922 SfxViewShell
*pViewSh
= GetViewShell();
923 if( !pViewSh
) return;
924 for ( sal_uInt16 nSID
= aIter
.FirstWhich(); nSID
; nSID
= aIter
.NextWhich() )
925 pViewSh
->GetSlotState( nSID
, nullptr, &rSet
);
929 if ( pShUndoMgr
->GetUndoActionCount() == 0 &&
930 pShUndoMgr
->GetRedoActionCount() == 0 &&
931 pShUndoMgr
->GetRepeatActionCount() == 0 )
932 rSet
.DisableItem( SID_CLEARHISTORY
);
934 if ( pShUndoMgr
&& pShUndoMgr
->GetUndoActionCount() )
936 const SfxUndoAction
* pAction
= pShUndoMgr
->GetUndoAction();
937 SfxViewShell
*pViewSh
= GetViewShell();
938 if (pViewSh
&& pAction
->GetViewShellId() != static_cast<sal_Int32
>(pViewSh
->GetViewShellId()))
940 rSet
.Put(SfxUInt32Item(SID_UNDO
, static_cast<sal_uInt32
>(SID_REPAIRPACKAGE
)));
944 OUString
aTmp(SvtResId(STR_UNDO
).toString());
945 aTmp
+= pShUndoMgr
->GetUndoActionComment();
946 rSet
.Put( SfxStringItem( SID_UNDO
, aTmp
) );
950 rSet
.DisableItem( SID_UNDO
);
952 if ( pShUndoMgr
&& pShUndoMgr
->GetRedoActionCount() )
954 const SfxUndoAction
* pAction
= pShUndoMgr
->GetRedoAction();
955 SfxViewShell
*pViewSh
= GetViewShell();
956 if (pViewSh
&& pAction
->GetViewShellId() != static_cast<sal_Int32
>(pViewSh
->GetViewShellId()))
958 rSet
.Put(SfxUInt32Item(SID_REDO
, static_cast<sal_uInt32
>(SID_REPAIRPACKAGE
)));
962 OUString
aTmp(SvtResId(STR_REDO
).toString());
963 aTmp
+= pShUndoMgr
->GetRedoActionComment();
964 rSet
.Put( SfxStringItem( SID_REDO
, aTmp
) );
968 rSet
.DisableItem( SID_REDO
);
969 SfxRepeatTarget
*pTarget
= pSh
->GetRepeatTarget();
970 if ( pShUndoMgr
&& pTarget
&& pShUndoMgr
->GetRepeatActionCount() &&
971 pShUndoMgr
->CanRepeat(*pTarget
) )
973 OUString
aTmp(SvtResId(STR_REPEAT
).toString());
974 aTmp
+= pShUndoMgr
->GetRepeatActionComment(*pTarget
);
975 rSet
.Put( SfxStringItem( SID_REPEAT
, aTmp
) );
978 rSet
.DisableItem( SID_REPEAT
);
981 void SfxViewFrame::PopShellAndSubShells_Impl( SfxViewShell
& i_rViewShell
)
983 i_rViewShell
.PopSubShells_Impl();
984 sal_uInt16 nLevel
= m_pDispatcher
->GetShellLevel( i_rViewShell
);
985 if ( nLevel
!= USHRT_MAX
)
989 // more sub shells on the stack, which were not affected by PopSubShells_Impl
990 SfxShell
*pSubShell
= m_pDispatcher
->GetShell( nLevel
-1 );
991 if ( pSubShell
== i_rViewShell
.GetSubShell() )
992 // "real" sub shells will be deleted elsewhere
993 m_pDispatcher
->Pop( *pSubShell
, SfxDispatcherPopFlags::POP_UNTIL
);
995 m_pDispatcher
->Pop( *pSubShell
, SfxDispatcherPopFlags::POP_UNTIL
| SfxDispatcherPopFlags::POP_DELETE
);
997 m_pDispatcher
->Pop( i_rViewShell
);
998 m_pDispatcher
->Flush();
1005 This method empties the SfxViewFrame, i.e. takes the <SfxObjectShell>
1006 from the dispatcher and ends its <SfxListener> Relationship to this
1007 SfxObjectShell (by which they may even destroy themselves).
1009 Thus, by invoking ReleaseObjectShell() and SetObjectShell() the
1010 SfxObjectShell can be replaced.
1012 Between RealeaseObjectShell() and SetObjectShell() can the control not
1013 be handed over to the system.
1017 <SfxViewFrame::SetObjectShell(SfxObjectShell&)>
1019 void SfxViewFrame::ReleaseObjectShell_Impl()
1021 DBG_ASSERT( m_xObjSh
.Is(), "no SfxObjectShell to release!" );
1023 GetFrame().ReleasingComponent_Impl();
1024 if ( GetWindow().HasChildPathFocus( true ) )
1026 DBG_ASSERT( !GetActiveChildFrame_Impl(), "Wrong active child frame!" );
1027 GetWindow().GrabFocus();
1030 SfxViewShell
*pDyingViewSh
= GetViewShell();
1033 PopShellAndSubShells_Impl( *pDyingViewSh
);
1034 pDyingViewSh
->DisconnectAllClients();
1035 SetViewShell_Impl(nullptr);
1036 delete pDyingViewSh
;
1040 OSL_FAIL("No Shell");
1043 if ( m_xObjSh
.Is() )
1045 m_pDispatcher
->Pop( *m_xObjSh
);
1046 SfxModule
* pModule
= m_xObjSh
->GetModule();
1048 m_pDispatcher
->RemoveShell_Impl( *pModule
);
1049 m_pDispatcher
->Flush();
1050 EndListening( *m_xObjSh
);
1052 Notify( *m_xObjSh
, SfxHint(SFX_HINT_TITLECHANGED
) );
1053 Notify( *m_xObjSh
, SfxHint(SFX_HINT_DOCCHANGED
) );
1055 if ( 1 == m_xObjSh
->GetOwnerLockCount() && m_pImpl
->bObjLocked
&& m_xObjSh
->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
1056 m_xObjSh
->DoClose();
1057 SfxObjectShellRef xDyingObjSh
= m_xObjSh
;
1059 if( ( GetFrameType() & SFXFRAME_HASTITLE
) && m_pImpl
->nDocViewNo
)
1060 xDyingObjSh
->GetNoSet_Impl().ReleaseIndex(m_pImpl
->nDocViewNo
-1);
1061 if ( m_pImpl
->bObjLocked
)
1063 xDyingObjSh
->OwnerLock( false );
1064 m_pImpl
->bObjLocked
= false;
1068 GetDispatcher()->SetDisableFlags( 0 );
1071 bool SfxViewFrame::Close()
1074 DBG_ASSERT( GetFrame().IsClosing_Impl() || !GetFrame().GetFrameInterface().is(), "ViewFrame closed too early!" );
1076 // If no saving have been made up until now, then embedded Objects should
1077 // not be saved automatically anymore.
1078 if ( GetViewShell() )
1079 GetViewShell()->DiscardClients_Impl();
1080 Broadcast( SfxHint( SFX_HINT_DYING
) );
1082 if (SfxViewFrame::Current() == this)
1083 SfxViewFrame::SetViewFrame( nullptr );
1085 // Since the Dispatcher is emptied, it can not be used in any reasnable
1086 // manner, thus it is better to let the dispatcher be.
1087 GetDispatcher()->Lock(true);
1093 void SfxViewFrame::DoActivate( bool bUI
)
1096 m_pDispatcher
->DoActivate_Impl( bUI
);
1099 void SfxViewFrame::DoDeactivate(bool bUI
, SfxViewFrame
* pNewFrame
)
1102 m_pDispatcher
->DoDeactivate_Impl( bUI
, pNewFrame
);
1105 void SfxViewFrame::InvalidateBorderImpl( const SfxViewShell
* pSh
)
1107 if( pSh
&& !m_nAdjustPosPixelLock
)
1109 if ( GetViewShell() && GetWindow().IsVisible() )
1111 if ( GetFrame().IsInPlace() )
1116 DoAdjustPosSizePixel( GetViewShell(), Point(),
1117 GetWindow().GetOutputSizePixel(),
1123 void SfxViewFrame::SetBorderPixelImpl
1125 const SfxViewShell
* pVSh
,
1126 const SvBorder
& rBorder
1130 m_pImpl
->aBorder
= rBorder
;
1132 if ( m_pImpl
->bResizeInToOut
&& !GetFrame().IsInPlace() )
1134 Size aSize
= pVSh
->GetWindow()->GetOutputSizePixel();
1135 if ( aSize
.Width() && aSize
.Height() )
1137 aSize
.Width() += rBorder
.Left() + rBorder
.Right();
1138 aSize
.Height() += rBorder
.Top() + rBorder
.Bottom();
1140 Size aOldSize
= GetWindow().GetOutputSizePixel();
1141 GetWindow().SetOutputSizePixel( aSize
);
1142 vcl::Window
* pParent
= &GetWindow();
1143 while ( pParent
->GetParent() )
1144 pParent
= pParent
->GetParent();
1145 Size aOuterSize
= pParent
->GetOutputSizePixel();
1146 aOuterSize
.Width() += ( aSize
.Width() - aOldSize
.Width() );
1147 aOuterSize
.Height() += ( aSize
.Height() - aOldSize
.Height() );
1148 pParent
->SetOutputSizePixel( aOuterSize
);
1154 Rectangle
aEditArea( aPoint
, GetWindow().GetOutputSizePixel() );
1155 aEditArea
.Left() += rBorder
.Left();
1156 aEditArea
.Right() -= rBorder
.Right();
1157 aEditArea
.Top() += rBorder
.Top();
1158 aEditArea
.Bottom() -= rBorder
.Bottom();
1159 pVSh
->GetWindow()->SetPosSizePixel( aEditArea
.TopLeft(), aEditArea
.GetSize() );
1163 const SvBorder
& SfxViewFrame::GetBorderPixelImpl() const
1165 return m_pImpl
->aBorder
;
1168 void SfxViewFrame::Notify( SfxBroadcaster
& /*rBC*/, const SfxHint
& rHint
)
1170 if(m_pImpl
->bIsDowning
)
1173 // we know only SfxEventHint or simple SfxHint
1174 if (const SfxEventHint
* pEventHint
= dynamic_cast<const SfxEventHint
*>(&rHint
))
1176 // When the Document is loaded asynchronously, was the Dispatcher
1177 // set as ReadOnly, to what must be returned when the document itself
1178 // is not read only, and the loading is finished.
1179 switch ( pEventHint
->GetEventId() )
1181 case SFX_EVENT_MODIFYCHANGED
:
1183 SfxBindings
& rBind
= GetBindings();
1184 rBind
.Invalidate( SID_DOC_MODIFIED
);
1185 rBind
.Invalidate( SID_RELOAD
);
1186 rBind
.Invalidate( SID_EDITDOC
);
1190 case SFX_EVENT_OPENDOC
:
1191 case SFX_EVENT_CREATEDOC
:
1193 if ( !m_xObjSh
.Is() )
1196 SfxBindings
& rBind
= GetBindings();
1197 rBind
.Invalidate( SID_RELOAD
);
1198 rBind
.Invalidate( SID_EDITDOC
);
1199 const SfxViewShell
*pVSh
;
1200 const SfxShell
*pFSh
;
1201 if ( !m_xObjSh
->IsReadOnly() ||
1202 ( m_xObjSh
->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
&&
1203 (pVSh
= m_xObjSh
->GetViewShell()) &&
1204 (pFSh
= pVSh
->GetFormShell()) &&
1205 !pFSh
->IsDesignMode()))
1207 // In contrast to above (TITLE_CHANGED) does the UI not
1208 // have to be updated because it was not obstructed
1210 // #i21560# InvalidateAll() causes the assertion
1211 // 'SfxBindings::Invalidate while in update" when
1212 // the sfx slot SID_BASICIDE_APPEAR is executed
1213 // via API from another thread (Java).
1214 // According to MBA this call is not necessary anymore,
1215 // because each document has its own SfxBindings.
1216 //GetDispatcher()->GetBindings()->InvalidateAll(true);
1220 bool bSignPDF
= IsSignPDF(m_xObjSh
);
1222 SfxInfoBarWindow
* pInfoBar
= AppendInfoBar("readonly", SfxResId(bSignPDF
? STR_READONLY_PDF
: STR_READONLY_DOCUMENT
));
1227 // SID_SIGNPDF opened a read-write PDF
1228 // read-only for signing purposes.
1229 VclPtrInstance
<PushButton
> xSignButton(&GetWindow());
1230 xSignButton
->SetText(SfxResId(STR_READONLY_SIGN
));
1231 xSignButton
->SetSizePixel(xSignButton
->GetOptimalSize());
1232 xSignButton
->SetClickHdl(LINK(this, SfxViewFrame
, SignDocumentHandler
));
1233 pInfoBar
->addButton(xSignButton
);
1236 VclPtrInstance
<PushButton
> xBtn(&GetWindow());
1237 xBtn
->SetText(SfxResId(STR_READONLY_EDIT
));
1238 xBtn
->SetSizePixel(xBtn
->GetOptimalSize());
1239 xBtn
->SetClickHdl(LINK(this, SfxViewFrame
, SwitchReadOnlyHandler
));
1240 pInfoBar
->addButton(xBtn
);
1244 if (SfxClassificationHelper::IsClassified(m_xObjSh
->getDocProperties()))
1246 // Document has BAILS properties, display an infobar accordingly.
1247 SfxClassificationHelper
aHelper(m_xObjSh
->getDocProperties());
1248 aHelper
.UpdateInfobar(*this);
1254 case SFX_EVENT_TOGGLEFULLSCREENMODE
:
1256 if ( GetFrame().OwnsBindings_Impl() )
1257 GetBindings().GetDispatcher_Impl()->Update_Impl( true );
1264 switch( rHint
.GetId() )
1266 case SFX_HINT_MODECHANGED
:
1270 if ( !m_xObjSh
.Is() )
1274 SfxBindings
& rBind
= GetBindings();
1275 rBind
.Invalidate( SID_RELOAD
);
1276 SfxDispatcher
*pDispat
= GetDispatcher();
1277 bool bWasReadOnly
= pDispat
->GetReadOnly_Impl();
1278 bool bIsReadOnly
= m_xObjSh
->IsReadOnly();
1279 if ( bWasReadOnly
!= bIsReadOnly
)
1281 // Then also TITLE_CHANGED
1283 rBind
.Invalidate( SID_FILE_NAME
);
1284 rBind
.Invalidate( SID_DOCINFO_TITLE
);
1285 rBind
.Invalidate( SID_EDITDOC
);
1287 pDispat
->GetBindings()->InvalidateAll(true);
1288 pDispat
->SetReadOnly_Impl( bIsReadOnly
);
1290 // Only force and Dispatcher-Update, if it is done next
1291 // anyway, otherwise flickering or GPF is possibel since
1292 // the Writer for example prefers in Resize perform some
1293 // actions which has a SetReadOnlyUI in Dispatcher as a
1296 if ( pDispat
->IsUpdated_Impl() )
1297 pDispat
->Update_Impl(true);
1300 Enable( !m_xObjSh
->IsInModalMode() );
1304 case SFX_HINT_TITLECHANGED
:
1307 SfxBindings
& rBind
= GetBindings();
1308 rBind
.Invalidate( SID_FILE_NAME
);
1309 rBind
.Invalidate( SID_DOCINFO_TITLE
);
1310 rBind
.Invalidate( SID_EDITDOC
);
1311 rBind
.Invalidate( SID_RELOAD
);
1315 case SFX_HINT_DEINITIALIZING
:
1316 GetFrame().DoClose();
1318 case SFX_HINT_DYING
:
1319 // when the Object is being deleted, destroy the view too
1320 if ( m_xObjSh
.Is() )
1321 ReleaseObjectShell_Impl();
1323 GetFrame().DoClose();
1330 IMPL_LINK_NOARG(SfxViewFrame
, SwitchReadOnlyHandler
, Button
*, void)
1332 if (m_xObjSh
.Is() && IsSignPDF(m_xObjSh
))
1334 ScopedVclPtrInstance
<SfxEditDocumentDialog
> pDialog(nullptr);
1335 if (pDialog
->Execute() != RET_OK
)
1338 GetDispatcher()->Execute(SID_EDITDOC
);
1341 IMPL_LINK_NOARG(SfxViewFrame
, SignDocumentHandler
, Button
*, void)
1343 GetDispatcher()->Execute(SID_SIGNATURE
);
1346 void SfxViewFrame::Construct_Impl( SfxObjectShell
*pObjSh
)
1348 m_pImpl
->bResizeInToOut
= true;
1349 m_pImpl
->bObjLocked
= false;
1350 m_pImpl
->pFocusWin
= nullptr;
1351 m_pImpl
->pActiveChild
= nullptr;
1352 m_pImpl
->nCurViewId
= 0;
1353 m_pImpl
->bReloading
= false;
1354 m_pImpl
->bIsDowning
= false;
1355 m_pImpl
->bModal
= false;
1356 m_pImpl
->bEnabled
= true;
1357 m_pImpl
->nDocViewNo
= 0;
1358 m_pImpl
->aMargin
= Size( -1, -1 );
1359 m_pImpl
->pWindow
= nullptr;
1361 SetPool( &SfxGetpApp()->GetPool() );
1362 m_pDispatcher
= new SfxDispatcher(this);
1363 if ( !GetBindings().GetDispatcher() )
1364 GetBindings().SetDispatcher( m_pDispatcher
);
1367 if ( m_xObjSh
.Is() && m_xObjSh
->IsPreview() )
1368 GetDispatcher()->SetQuietMode_Impl( true );
1372 m_pDispatcher
->Push( *SfxGetpApp() );
1373 SfxModule
* pModule
= m_xObjSh
->GetModule();
1375 m_pDispatcher
->Push( *pModule
);
1376 m_pDispatcher
->Push( *this );
1377 m_pDispatcher
->Push( *pObjSh
);
1378 m_pDispatcher
->Flush();
1379 StartListening( *pObjSh
);
1380 Notify( *pObjSh
, SfxHint(SFX_HINT_TITLECHANGED
) );
1381 Notify( *pObjSh
, SfxHint(SFX_HINT_DOCCHANGED
) );
1382 m_pDispatcher
->SetReadOnly_Impl( pObjSh
->IsReadOnly() );
1386 m_pDispatcher
->Push( *SfxGetpApp() );
1387 m_pDispatcher
->Push( *this );
1388 m_pDispatcher
->Flush();
1391 SfxViewFrameArr_Impl
&rViewArr
= SfxGetpApp()->GetViewFrames_Impl();
1392 rViewArr
.push_back( this );
1397 Constructor of SfxViewFrame for a <SfxObjectShell> from the Resource.
1398 The 'nViewId' to the created <SfxViewShell> can be returned.
1399 (default is the SfxViewShell-Subclass that was registered first).
1401 SfxViewFrame::SfxViewFrame
1404 SfxObjectShell
* pObjShell
1406 : m_pImpl( new SfxViewFrame_Impl( rFrame
) )
1407 , m_pDispatcher(nullptr)
1408 , m_pBindings( new SfxBindings
)
1409 , m_nAdjustPosPixelLock( 0 )
1412 rFrame
.SetCurrentViewFrame_Impl( this );
1413 rFrame
.SetFrameType_Impl( GetFrameType() | SFXFRAME_HASTITLE
);
1414 Construct_Impl( pObjShell
);
1416 m_pImpl
->pWindow
= VclPtr
<SfxFrameViewWindow_Impl
>::Create( this, rFrame
.GetWindow() );
1417 m_pImpl
->pWindow
->SetSizePixel( rFrame
.GetWindow().GetOutputSizePixel() );
1418 rFrame
.SetOwnsBindings_Impl( true );
1419 rFrame
.CreateWorkWindow_Impl();
1422 SfxViewFrame::~SfxViewFrame()
1424 m_pImpl
->bIsDowning
= true;
1426 if ( SfxViewFrame::Current() == this )
1427 SfxViewFrame::SetViewFrame( nullptr );
1429 ReleaseObjectShell_Impl();
1431 if ( GetFrame().OwnsBindings_Impl() )
1432 // The Bindings delete the Frame!
1433 KillDispatcher_Impl();
1435 m_pImpl
->pWindow
.disposeAndClear();
1436 m_pImpl
->pFocusWin
.clear();
1438 if ( GetFrame().GetCurrentViewFrame() == this )
1439 GetFrame().SetCurrentViewFrame_Impl( nullptr );
1441 // Unregister from the Frame List.
1442 SfxApplication
*pSfxApp
= SfxGetpApp();
1443 SfxViewFrameArr_Impl
&rFrames
= pSfxApp
->GetViewFrames_Impl();
1444 SfxViewFrameArr_Impl::iterator it
= std::find( rFrames
.begin(), rFrames
.end(), this );
1445 rFrames
.erase( it
);
1448 KillDispatcher_Impl();
1451 // Remove and delete the Dispatcher.
1452 void SfxViewFrame::KillDispatcher_Impl()
1455 SfxModule
* pModule
= m_xObjSh
.Is() ? m_xObjSh
->GetModule() : nullptr;
1456 if ( m_xObjSh
.Is() )
1457 ReleaseObjectShell_Impl();
1458 if ( m_pDispatcher
)
1461 m_pDispatcher
->Pop( *pModule
, SfxDispatcherPopFlags::POP_UNTIL
);
1463 m_pDispatcher
->Pop( *this );
1464 DELETEZ(m_pDispatcher
);
1468 SfxViewFrame
* SfxViewFrame::Current()
1470 return SfxApplication::Get() ? SfxGetpApp()->Get_Impl()->pViewFrame
: nullptr;
1473 // returns the first window of spec. type viewing the specified doc.
1474 SfxViewFrame
* SfxViewFrame::GetFirst
1476 const SfxObjectShell
* pDoc
,
1480 SfxApplication
*pSfxApp
= SfxGetpApp();
1481 SfxViewFrameArr_Impl
&rFrames
= pSfxApp
->GetViewFrames_Impl();
1483 // search for a SfxDocument of the specified type
1484 for (SfxViewFrame
* pFrame
: rFrames
)
1486 if ( ( !pDoc
|| pDoc
== pFrame
->GetObjectShell() )
1487 && ( !bOnlyIfVisible
|| pFrame
->IsVisible() )
1495 // returns the next window of spec. type viewing the specified doc.
1496 SfxViewFrame
* SfxViewFrame::GetNext
1498 const SfxViewFrame
& rPrev
,
1499 const SfxObjectShell
* pDoc
,
1503 SfxApplication
*pSfxApp
= SfxGetpApp();
1504 SfxViewFrameArr_Impl
&rFrames
= pSfxApp
->GetViewFrames_Impl();
1506 // refind the specified predecessor
1508 for ( nPos
= 0; nPos
< rFrames
.size(); ++nPos
)
1509 if ( rFrames
[nPos
] == &rPrev
)
1512 // search for a Frame of the specified type
1513 for ( ++nPos
; nPos
< rFrames
.size(); ++nPos
)
1515 SfxViewFrame
*pFrame
= rFrames
[nPos
];
1516 if ( ( !pDoc
|| pDoc
== pFrame
->GetObjectShell() )
1517 && ( !bOnlyIfVisible
|| pFrame
->IsVisible() )
1524 SfxProgress
* SfxViewFrame::GetProgress() const
1526 SfxObjectShell
*pObjSh
= m_xObjSh
.get();
1527 return pObjSh
? pObjSh
->GetProgress() : nullptr;
1530 void SfxViewFrame::DoAdjustPosSizePixel
//! divide on Inner.../Outer...
1535 bool inplaceEditModeChange
1539 // Components do not use this Method!
1540 if( pSh
&& pSh
->GetWindow() && !m_nAdjustPosPixelLock
)
1542 m_nAdjustPosPixelLock
++;
1543 if ( m_pImpl
->bResizeInToOut
)
1544 pSh
->InnerResizePixel( rPos
, rSize
, inplaceEditModeChange
);
1546 pSh
->OuterResizePixel( rPos
, rSize
);
1547 m_nAdjustPosPixelLock
--;
1551 bool SfxViewFrameItem::operator==( const SfxPoolItem
&rItem
) const
1553 return dynamic_cast<const SfxViewFrameItem
&>(rItem
).pFrame
== pFrame
;
1556 SfxPoolItem
* SfxViewFrameItem::Clone( SfxItemPool
*) const
1558 return new SfxViewFrameItem( pFrame
);
1561 void SfxViewFrame::SetViewShell_Impl( SfxViewShell
*pVSh
)
1564 Internal Method to set the current <SfxViewShell> Instance,
1565 that is active int this SfxViewFrame at the moment.
1568 SfxShell::SetViewShell_Impl( pVSh
);
1570 // Hack: InPlaceMode
1572 m_pImpl
->bResizeInToOut
= false;
1575 void SfxViewFrame::ForceOuterResize_Impl()
1577 m_pImpl
->bResizeInToOut
= true;
1580 void SfxViewFrame::GetDocNumber_Impl()
1582 DBG_ASSERT( GetObjectShell(), "No Document!" );
1583 GetObjectShell()->SetNamedVisibility_Impl();
1584 m_pImpl
->nDocViewNo
= GetObjectShell()->GetNoSet_Impl().GetFreeIndex()+1;
1587 void SfxViewFrame::Enable( bool bEnable
)
1589 if ( bEnable
!= m_pImpl
->bEnabled
)
1591 m_pImpl
->bEnabled
= bEnable
;
1593 vcl::Window
*pWindow
= &GetFrame().GetWindow();
1595 m_pImpl
->bWindowWasEnabled
= pWindow
->IsInputEnabled();
1596 if ( !bEnable
|| m_pImpl
->bWindowWasEnabled
)
1597 pWindow
->EnableInput( bEnable
);
1600 SfxViewShell
* pViewSh
= GetViewShell();
1605 pViewSh
->ShowCursor();
1611 pViewSh
->ShowCursor(false);
1618 This method makes the Frame-Window visible and before transmits the
1619 window name. In addition, the document is held. In general one can never
1620 show the window directly!
1622 void SfxViewFrame::Show()
1624 // First lock the objectShell so that UpdateTitle() is valid:
1625 // IsVisible() == true (:#)
1626 if ( m_xObjSh
.Is() )
1628 m_xObjSh
->GetMedium()->GetItemSet()->ClearItem( SID_HIDDEN
);
1629 if ( !m_pImpl
->bObjLocked
)
1630 LockObjectShell_Impl();
1632 // Adjust Doc-Shell title number, get unique view-no
1633 if ( 0 == m_pImpl
->nDocViewNo
)
1635 GetDocNumber_Impl();
1642 // Display Frame-window, but only if the ViewFrame has no window of its
1643 // own or if it does not contain a Component
1645 GetFrame().GetWindow().Show();
1649 bool SfxViewFrame::IsVisible() const
1651 return m_pImpl
->bObjLocked
;
1655 void SfxViewFrame::LockObjectShell_Impl()
1657 DBG_ASSERT( !m_pImpl
->bObjLocked
, "Wrong Locked status!" );
1659 DBG_ASSERT( GetObjectShell(), "No Document!" );
1660 GetObjectShell()->OwnerLock(true);
1661 m_pImpl
->bObjLocked
= true;
1665 void SfxViewFrame::MakeActive_Impl( bool bGrabFocus
)
1667 if ( GetViewShell() && !GetFrame().IsClosing_Impl() )
1671 if ( GetViewShell() )
1673 bool bPreview
= false;
1674 if ( GetObjectShell()->IsPreview() )
1679 css::uno::Reference
< css::frame::XFrame
> xFrame
= GetFrame().GetFrameInterface();
1682 SetViewFrame( this );
1683 GetBindings().SetActiveFrame( css::uno::Reference
< css::frame::XFrame
>() );
1684 uno::Reference
< frame::XFramesSupplier
> xSupp( xFrame
, uno::UNO_QUERY
);
1686 xSupp
->setActiveFrame( uno::Reference
< frame::XFrame
>() );
1688 css::uno::Reference
< css::awt::XWindow
> xContainerWindow
= xFrame
->getContainerWindow();
1689 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow(xContainerWindow
);
1690 if (pWindow
&& pWindow
->HasChildPathFocus() && bGrabFocus
)
1692 SfxInPlaceClient
*pCli
= GetViewShell()->GetUIActiveClient();
1693 if ( !pCli
|| !pCli
->IsObjectUIActive() )
1694 GetFrame().GrabFocusOnComponent_Impl();
1699 GetBindings().SetDispatcher( GetDispatcher() );
1700 GetBindings().SetActiveFrame( css::uno::Reference
< css::frame::XFrame
> () );
1701 GetDispatcher()->Update_Impl();
1708 SfxObjectShell
* SfxViewFrame::GetObjectShell()
1710 return m_xObjSh
.get();
1713 const Size
& SfxViewFrame::GetMargin_Impl() const
1715 return m_pImpl
->aMargin
;
1718 SfxViewFrame
* SfxViewFrame::GetActiveChildFrame_Impl() const
1720 SfxViewFrame
*pViewFrame
= m_pImpl
->pActiveChild
;
1724 SfxViewFrame
* SfxViewFrame::LoadViewIntoFrame_Impl_NoThrow( const SfxObjectShell
& i_rDoc
, const Reference
< XFrame
>& i_rFrame
,
1725 const sal_uInt16 i_nViewId
, const bool i_bHidden
)
1727 Reference
< XFrame
> xFrame( i_rFrame
);
1728 bool bOwnFrame
= false;
1729 SfxViewShell
* pSuccessView
= nullptr;
1734 Reference
< XDesktop2
> xDesktop
= Desktop::create( ::comphelper::getProcessComponentContext() );
1740 // if there is a backing component, use it
1741 ::framework::FrameListAnalyzer
aAnalyzer( xDesktop
, Reference
< XFrame
>(), ::framework::FrameListAnalyzer::E_BACKINGCOMPONENT
);
1743 if ( aAnalyzer
.m_xBackingComponent
.is() )
1744 xFrame
= aAnalyzer
.m_xBackingComponent
;
1746 catch( uno::Exception
& )
1751 xFrame
.set( xDesktop
->findFrame( "_blank", 0 ), UNO_SET_THROW
);
1756 pSuccessView
= LoadViewIntoFrame_Impl(
1759 Sequence
< PropertyValue
>(), // means "reuse existing model's args"
1764 if ( bOwnFrame
&& !i_bHidden
)
1766 // ensure the frame/window is visible
1767 Reference
< XWindow
> xContainerWindow( xFrame
->getContainerWindow(), UNO_SET_THROW
);
1768 xContainerWindow
->setVisible( true );
1771 catch( const Exception
& )
1773 DBG_UNHANDLED_EXCEPTION();
1777 return pSuccessView
->GetViewFrame();
1785 catch( const Exception
& )
1787 DBG_UNHANDLED_EXCEPTION();
1794 SfxViewShell
* SfxViewFrame::LoadViewIntoFrame_Impl( const SfxObjectShell
& i_rDoc
, const Reference
< XFrame
>& i_rFrame
,
1795 const Sequence
< PropertyValue
>& i_rLoadArgs
, const sal_uInt16 i_nViewId
,
1796 const bool i_bHidden
)
1798 Reference
< XModel
> xDocument( i_rDoc
.GetModel(), UNO_SET_THROW
);
1800 ::comphelper::NamedValueCollection
aTransformLoadArgs( i_rLoadArgs
.getLength() ? i_rLoadArgs
: xDocument
->getArgs() );
1801 aTransformLoadArgs
.put( "Model", xDocument
);
1803 aTransformLoadArgs
.put( "ViewId", sal_Int16( i_nViewId
) );
1805 aTransformLoadArgs
.put( "Hidden", i_bHidden
);
1807 aTransformLoadArgs
.remove( "Hidden" );
1809 OUString
sURL( "private:object" );
1810 if ( sURL
.isEmpty() )
1811 sURL
= i_rDoc
.GetFactory().GetFactoryURL();
1813 Reference
< XComponentLoader
> xLoader( i_rFrame
, UNO_QUERY_THROW
);
1814 xLoader
->loadComponentFromURL( sURL
, "_self", 0,
1815 aTransformLoadArgs
.getPropertyValues() );
1817 SfxViewShell
* pViewShell
= SfxViewShell::Get( i_rFrame
->getController() );
1818 ENSURE_OR_THROW( pViewShell
,
1819 "SfxViewFrame::LoadViewIntoFrame_Impl: loading an SFX doc into a frame resulted in a non-SFX view - quite impossible" );
1823 SfxViewFrame
* SfxViewFrame::LoadHiddenDocument( SfxObjectShell
& i_rDoc
, const sal_uInt16 i_nViewId
)
1825 return LoadViewIntoFrame_Impl_NoThrow( i_rDoc
, Reference
< XFrame
>(), i_nViewId
, true );
1828 SfxViewFrame
* SfxViewFrame::LoadDocument( SfxObjectShell
& i_rDoc
, const sal_uInt16 i_nViewId
)
1830 return LoadViewIntoFrame_Impl_NoThrow( i_rDoc
, Reference
< XFrame
>(), i_nViewId
, false );
1833 SfxViewFrame
* SfxViewFrame::LoadDocumentIntoFrame( SfxObjectShell
& i_rDoc
, const Reference
< XFrame
>& i_rTargetFrame
)
1835 return LoadViewIntoFrame_Impl_NoThrow( i_rDoc
, i_rTargetFrame
, 0, false );
1838 SfxViewFrame
* SfxViewFrame::LoadDocumentIntoFrame( SfxObjectShell
& i_rDoc
, const SfxFrameItem
* i_pFrameItem
, const sal_uInt16 i_nViewId
)
1840 return LoadViewIntoFrame_Impl_NoThrow( i_rDoc
, i_pFrameItem
&& i_pFrameItem
->GetFrame() ? i_pFrameItem
->GetFrame()->GetFrameInterface() : nullptr, i_nViewId
, false );
1843 SfxViewFrame
* SfxViewFrame::DisplayNewDocument( SfxObjectShell
& i_rDoc
, const SfxRequest
& i_rCreateDocRequest
)
1845 const SfxUnoFrameItem
* pFrameItem
= i_rCreateDocRequest
.GetArg
<SfxUnoFrameItem
>(SID_FILLFRAME
);
1846 const SfxBoolItem
* pHiddenItem
= i_rCreateDocRequest
.GetArg
<SfxBoolItem
>(SID_HIDDEN
);
1848 return LoadViewIntoFrame_Impl_NoThrow(
1850 pFrameItem
? pFrameItem
->GetFrame() : nullptr,
1852 pHiddenItem
&& pHiddenItem
->GetValue()
1856 SfxViewFrame
* SfxViewFrame::Get( const Reference
< XController
>& i_rController
, const SfxObjectShell
* i_pDoc
)
1858 if ( !i_rController
.is() )
1861 const SfxObjectShell
* pDoc
= i_pDoc
;
1864 Reference
< XModel
> xDocument( i_rController
->getModel() );
1865 for ( pDoc
= SfxObjectShell::GetFirst( nullptr, false );
1867 pDoc
= SfxObjectShell::GetNext( *pDoc
, nullptr, false )
1870 if ( pDoc
->GetModel() == xDocument
)
1875 SfxViewFrame
* pViewFrame
= nullptr;
1876 for ( pViewFrame
= SfxViewFrame::GetFirst( pDoc
, false );
1878 pViewFrame
= SfxViewFrame::GetNext( *pViewFrame
, pDoc
, false )
1881 if ( pViewFrame
->GetViewShell()->GetController() == i_rController
)
1888 void SfxViewFrame::SaveCurrentViewData_Impl( const sal_uInt16 i_nNewViewId
)
1890 SfxViewShell
* pCurrentShell
= GetViewShell();
1891 ENSURE_OR_RETURN_VOID( pCurrentShell
!= nullptr, "SfxViewFrame::SaveCurrentViewData_Impl: no current view shell -> no current view data!" );
1893 // determine the logical (API) view name
1894 const SfxObjectFactory
& rDocFactory( pCurrentShell
->GetObjectShell()->GetFactory() );
1895 const sal_uInt16 nCurViewNo
= rDocFactory
.GetViewNo_Impl( GetCurViewId(), 0 );
1896 const OUString sCurrentViewName
= rDocFactory
.GetViewFactory( nCurViewNo
).GetAPIViewName();
1897 const sal_uInt16 nNewViewNo
= rDocFactory
.GetViewNo_Impl( i_nNewViewId
, 0 );
1898 const OUString sNewViewName
= rDocFactory
.GetViewFactory( nNewViewNo
).GetAPIViewName();
1899 if ( sCurrentViewName
.isEmpty() || sNewViewName
.isEmpty() )
1901 // can't say anything about the view, the respective application did not yet migrate its code to
1902 // named view factories => bail out
1903 OSL_FAIL( "SfxViewFrame::SaveCurrentViewData_Impl: views without API names? Shouldn't happen anymore?" );
1906 SAL_WARN_IF(sNewViewName
== sCurrentViewName
, "sfx.view", "SfxViewFrame::SaveCurrentViewData_Impl: suspicious: new and old view name are identical!");
1908 // save the view data only when we're moving from a non-print-preview to the print-preview view
1909 if ( sNewViewName
!= "PrintPreview" )
1912 // retrieve the view data from the view
1913 Sequence
< PropertyValue
> aViewData
;
1914 pCurrentShell
->WriteUserDataSequence( aViewData
);
1918 // retrieve view data (for *all* views) from the model
1919 const Reference
< XController
> xController( pCurrentShell
->GetController(), UNO_SET_THROW
);
1920 const Reference
< XViewDataSupplier
> xViewDataSupplier( xController
->getModel(), UNO_QUERY_THROW
);
1921 const Reference
< XIndexContainer
> xViewData( xViewDataSupplier
->getViewData(), UNO_QUERY_THROW
);
1923 // look up the one view data item which corresponds to our current view, and remove it
1924 const sal_Int32 nCount
= xViewData
->getCount();
1925 for ( sal_Int32 i
=0; i
<nCount
; ++i
)
1927 const ::comphelper::NamedValueCollection
aCurViewData( xViewData
->getByIndex(i
) );
1928 OUString
sViewId( aCurViewData
.getOrDefault( "ViewId", OUString() ) );
1929 if ( sViewId
.isEmpty() )
1932 const SfxViewFactory
* pViewFactory
= rDocFactory
.GetViewFactoryByViewName( sViewId
);
1933 if ( pViewFactory
== nullptr )
1936 if ( pViewFactory
->GetOrdinal() == GetCurViewId() )
1938 xViewData
->removeByIndex(i
);
1943 // then replace it with the most recent view data we just obtained
1944 xViewData
->insertByIndex( 0, makeAny( aViewData
) );
1946 catch( const Exception
& )
1948 DBG_UNHANDLED_EXCEPTION();
1954 Internal Method for switching to another <SfxViewShell> subclass,
1955 which should be created in this SfxMDIFrame. If no SfxViewShell exist
1956 in this SfxMDIFrame, then one will first be created.
1962 requested SfxViewShell was created and a
1963 possibly existing one deleted
1966 SfxViewShell requested could not be created,
1967 the existing SfxViewShell thus continue to exist
1969 bool SfxViewFrame::SwitchToViewShell_Impl
1971 sal_uInt16 nViewIdOrNo
, /* > 0
1972 Registration-Id of the View, to which the
1973 the method should switch, for example the one
1974 that will be created.
1977 First use the Default view. */
1979 bool bIsIndex
/* true
1980 'nViewIdOrNo' is no Registration-Id instead
1981 an Index of <SfxViewFrame> in <SfxObjectShell>.
1987 ENSURE_OR_THROW( GetObjectShell() != nullptr, "not possible without a document" );
1989 // if we already have a view shell, remove it
1990 SfxViewShell
* pOldSh
= GetViewShell();
1991 OSL_PRECOND( pOldSh
, "SfxViewFrame::SwitchToViewShell_Impl: that's called *switch* (not for *initial-load*) for a reason" );
1994 // ask whether it can be closed
1995 if ( !pOldSh
->PrepareClose() )
1998 // remove sub shells from Dispatcher before switching to new ViewShell
1999 PopShellAndSubShells_Impl( *pOldSh
);
2002 GetBindings().ENTERREGISTRATIONS();
2003 LockAdjustPosSizePixel();
2005 // ID of the new view
2006 SfxObjectFactory
& rDocFact
= GetObjectShell()->GetFactory();
2007 const sal_uInt16 nViewId
= ( bIsIndex
|| !nViewIdOrNo
) ? rDocFact
.GetViewFactory( nViewIdOrNo
).GetOrdinal() : nViewIdOrNo
;
2009 // save the view data of the old view, so it can be restored later on (when needed)
2010 SaveCurrentViewData_Impl( nViewId
);
2012 // create and load new ViewShell
2013 SfxViewShell
* pNewSh
= LoadViewIntoFrame_Impl(
2015 GetFrame().GetFrameInterface(),
2016 Sequence
< PropertyValue
>(), // means "reuse existing model's args"
2021 // allow resize events to be processed
2022 UnlockAdjustPosSizePixel();
2024 if ( GetWindow().IsReallyVisible() )
2025 DoAdjustPosSizePixel( pNewSh
, Point(), GetWindow().GetOutputSizePixel(), false );
2027 GetBindings().LEAVEREGISTRATIONS();
2030 catch ( const css::uno::Exception
& )
2032 // the SfxCode is not able to cope with exceptions thrown while creating views
2033 // the code will crash in the stack unwinding procedure, so we shouldn't let exceptions go through here
2034 DBG_UNHANDLED_EXCEPTION();
2038 DBG_ASSERT( SfxGetpApp()->GetViewFrames_Impl().size() == SfxGetpApp()->GetViewShells_Impl().size(), "Inconsistent view arrays!" );
2042 void SfxViewFrame::SetCurViewId_Impl( const sal_uInt16 i_nID
)
2044 m_pImpl
->nCurViewId
= i_nID
;
2047 sal_uInt16
SfxViewFrame::GetCurViewId() const
2049 return m_pImpl
->nCurViewId
;
2054 Internal method to run the slot for the <SfxShell> Subclass in the
2055 SfxViewFrame <SVIDL> described slots.
2057 void SfxViewFrame::ExecView_Impl
2059 SfxRequest
& rReq
// The executable <SfxRequest>
2063 // If the Shells are just being replaced...
2064 if ( !GetObjectShell() || !GetViewShell() )
2067 switch ( rReq
.GetSlot() )
2069 case SID_TERMINATE_INPLACEACTIVATION
:
2071 SfxInPlaceClient
* pClient
= GetViewShell()->GetUIActiveClient();
2073 pClient
->DeactivateObject();
2079 const SfxPoolItem
*pItem
= nullptr;
2081 && SfxItemState::SET
== rReq
.GetArgs()->GetItemState( SID_VIEWSHELL
, false, &pItem
)
2084 const sal_uInt16 nViewId
= static_cast< const SfxUInt16Item
* >( pItem
)->GetValue();
2085 bool bSuccess
= SwitchToViewShell_Impl( nViewId
);
2086 rReq
.SetReturnValue( SfxBoolItem( 0, bSuccess
) );
2091 case SID_VIEWSHELL0
:
2092 case SID_VIEWSHELL1
:
2093 case SID_VIEWSHELL2
:
2094 case SID_VIEWSHELL3
:
2095 case SID_VIEWSHELL4
:
2097 const sal_uInt16 nViewNo
= rReq
.GetSlot() - SID_VIEWSHELL0
;
2098 bool bSuccess
= SwitchToViewShell_Impl( nViewNo
, true );
2099 rReq
.SetReturnValue( SfxBoolItem( 0, bSuccess
) );
2105 // Hack. at the moment a virtual Function
2106 if ( !GetViewShell()->NewWindowAllowed() )
2108 OSL_FAIL( "You should have disabled the 'Window/New Window' slot!" );
2112 // Get ViewData of FrameSets recursivly.
2113 GetFrame().GetViewData_Impl();
2114 SfxMedium
* pMed
= GetObjectShell()->GetMedium();
2116 // do not open the new window hidden
2117 pMed
->GetItemSet()->ClearItem( SID_HIDDEN
);
2119 // the view ID (optional arg. TODO: this is currently not supported in the slot definition ...)
2120 const SfxUInt16Item
* pViewIdItem
= rReq
.GetArg
<SfxUInt16Item
>(SID_VIEW_ID
);
2121 const sal_uInt16 nViewId
= pViewIdItem
? pViewIdItem
->GetValue() : GetCurViewId();
2123 Reference
< XFrame
> xFrame
;
2124 // the frame (optional arg. TODO: this is currently not supported in the slot definition ...)
2125 const SfxUnoFrameItem
* pFrameItem
= rReq
.GetArg
<SfxUnoFrameItem
>(SID_FILLFRAME
);
2127 xFrame
= pFrameItem
->GetFrame();
2129 LoadViewIntoFrame_Impl_NoThrow( *GetObjectShell(), xFrame
, nViewId
, false );
2137 const SfxInt16Item
* pItem
= rReq
.GetArg
<SfxInt16Item
>(SID_OBJECT
);
2139 SfxViewShell
*pViewShell
= GetViewShell();
2140 if ( pViewShell
&& pItem
)
2142 pViewShell
->DoVerb( pItem
->GetValue() );
2151 This method try to collect information about the count of currently open documents.
2152 But the algorithm is implemented very simple ...
2153 E.g. hidden documents should be ignored here ... but they are counted.
2154 TODO: export special helper "framework::FrameListAnalyzer" within the framework module
2157 bool impl_maxOpenDocCountReached()
2159 css::uno::Reference
< css::uno::XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
2160 boost::optional
<sal_Int32
> x(officecfg::Office::Common::Misc::MaxOpenDocuments::get(xContext
));
2161 // NIL means: count of allowed documents = infinite !
2164 sal_Int32
nMaxDocs(x
.get());
2165 sal_Int32 nOpenDocs
= 0;
2167 css::uno::Reference
< css::frame::XDesktop2
> xDesktop
= css::frame::Desktop::create(xContext
);
2168 css::uno::Reference
< css::container::XIndexAccess
> xCont(xDesktop
->getFrames(), css::uno::UNO_QUERY_THROW
);
2170 sal_Int32 c
= xCont
->getCount();
2177 css::uno::Reference
< css::frame::XFrame
> xFrame
;
2178 xCont
->getByIndex(i
) >>= xFrame
;
2182 // a) do not count the help window
2183 if ( xFrame
->getName() == "OFFICE_HELP_TASK" )
2186 // b) count all other frames
2189 catch(const css::uno::Exception
&)
2190 // A IndexOutOfBoundException can happen in multithreaded
2191 // environments, where any other thread can change this
2196 return (nOpenDocs
>= nMaxDocs
);
2201 This internal methode returns in 'rSet' the Status for the <SfxShell>
2202 Subclass SfxViewFrame in the <SVIDL> described <Slots>.
2204 Thus exactly those Slots-IDs that are recognized as being invalid by Sfx
2205 are included as Which-ranges in 'rSet'. If there exists a mapping for
2206 single slot-IDs of the <SfxItemPool> set in the shell, then the respective
2207 Which-IDs are used so that items can be replaced directly with a working
2208 Core::sun::com::star::script::Engine of the Which-IDs if possible. .
2210 void SfxViewFrame::StateView_Impl
2212 SfxItemSet
& rSet
/* empty <SfxItemSet> with <Which-Ranges>,
2213 which describes the Slot Ids */
2217 SfxObjectShell
*pDocSh
= GetObjectShell();
2220 // I'm just on reload and am yielding myself ...
2223 const sal_uInt16
*pRanges
= rSet
.GetRanges();
2224 assert(pRanges
&& "Set with no Range");
2227 for ( sal_uInt16 nWhich
= *pRanges
++; nWhich
<= *pRanges
; ++nWhich
)
2233 rSet
.Put( SfxUInt16Item( nWhich
, m_pImpl
->nCurViewId
) );
2237 case SID_VIEWSHELL0
:
2238 case SID_VIEWSHELL1
:
2239 case SID_VIEWSHELL2
:
2240 case SID_VIEWSHELL3
:
2241 case SID_VIEWSHELL4
:
2243 sal_uInt16 nViewNo
= nWhich
- SID_VIEWSHELL0
;
2244 if ( GetObjectShell()->GetFactory().GetViewFactoryCount() >
2245 nViewNo
&& !GetObjectShell()->IsInPlaceActive() )
2247 SfxViewFactory
&rViewFactory
=
2248 GetObjectShell()->GetFactory().GetViewFactory(nViewNo
);
2249 rSet
.Put( SfxBoolItem(
2250 nWhich
, m_pImpl
->nCurViewId
== rViewFactory
.GetOrdinal() ) );
2253 rSet
.DisableItem( nWhich
);
2259 if ( !GetViewShell()->NewWindowAllowed()
2260 || impl_maxOpenDocCountReached()
2262 rSet
.DisableItem( nWhich
);
2271 void SfxViewFrame::ToTop()
2273 GetFrame().Appear();
2279 GetFrame returns the Frame, in which the ViewFrame is located.
2281 SfxFrame
& SfxViewFrame::GetFrame() const
2283 return m_pImpl
->rFrame
;
2286 SfxViewFrame
* SfxViewFrame::GetTopViewFrame() const
2288 return GetFrame().GetCurrentViewFrame();
2291 vcl::Window
& SfxViewFrame::GetWindow() const
2293 return m_pImpl
->pWindow
? *m_pImpl
->pWindow
: GetFrame().GetWindow();
2296 bool SfxViewFrame::DoClose()
2298 return GetFrame().DoClose();
2301 OUString
SfxViewFrame::GetActualPresentationURL_Impl() const
2303 if ( m_xObjSh
.Is() )
2304 return m_xObjSh
->GetMedium()->GetName();
2308 void SfxViewFrame::SetModalMode( bool bModal
)
2310 m_pImpl
->bModal
= bModal
;
2311 if ( m_xObjSh
.Is() )
2313 for ( SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( m_xObjSh
.get() );
2314 !bModal
&& pFrame
; pFrame
= SfxViewFrame::GetNext( *pFrame
, m_xObjSh
.get() ) )
2315 bModal
= pFrame
->m_pImpl
->bModal
;
2316 m_xObjSh
->SetModalMode_Impl( bModal
);
2320 bool SfxViewFrame::IsInModalMode() const
2322 return m_pImpl
->bModal
|| GetFrame().GetWindow().IsInModalMode();
2325 void SfxViewFrame::Resize( bool bForce
)
2327 Size aSize
= GetWindow().GetOutputSizePixel();
2328 if ( bForce
|| aSize
!= m_pImpl
->aSize
)
2330 m_pImpl
->aSize
= aSize
;
2331 SfxViewShell
*pShell
= GetViewShell();
2334 if ( GetFrame().IsInPlace() )
2336 Point aPoint
= GetWindow().GetPosPixel();
2337 DoAdjustPosSizePixel( pShell
, aPoint
, aSize
, true );
2341 DoAdjustPosSizePixel( pShell
, Point(), aSize
, false );
2347 #define LINE_SEP 0x0A
2349 void CutLines( OUString
& rStr
, sal_Int32 nStartLine
, sal_Int32 nLines
, bool bEraseTrailingEmptyLines
)
2351 sal_Int32 nStartPos
= 0;
2352 sal_Int32 nLine
= 0;
2353 while ( nLine
< nStartLine
)
2355 nStartPos
= rStr
.indexOf( LINE_SEP
, nStartPos
);
2356 if( nStartPos
== -1 )
2358 nStartPos
++; // not the \n.
2362 SAL_WARN_IF(nStartPos
== -1, "sfx.view", "CutLines: Start row not found!");
2364 if ( nStartPos
!= -1 )
2366 sal_Int32 nEndPos
= nStartPos
;
2367 for ( sal_Int32 i
= 0; i
< nLines
; i
++ )
2368 nEndPos
= rStr
.indexOf( LINE_SEP
, nEndPos
+1 );
2370 if ( nEndPos
== -1 ) // Can happen at the last row.
2371 nEndPos
= rStr
.getLength();
2375 OUString aEndStr
= rStr
.copy( nEndPos
);
2376 rStr
= rStr
.copy( 0, nStartPos
);
2379 if ( bEraseTrailingEmptyLines
&& nStartPos
!= -1 )
2381 sal_Int32 n
= nStartPos
;
2382 sal_Int32 nLen
= rStr
.getLength();
2383 while ( ( n
< nLen
) && ( rStr
[ n
] == LINE_SEP
) )
2386 if ( n
> nStartPos
)
2388 OUString aEndStr
= rStr
.copy( n
);
2389 rStr
= rStr
.copy( 0, nStartPos
);
2396 add new recorded dispatch macro script into the application global basic
2397 lib container. It generates a new unique id for it and insert the macro
2398 by using this number as name for the modul
2400 void SfxViewFrame::AddDispatchMacroToBasic_Impl( const OUString
& sMacro
)
2402 #if !HAVE_FEATURE_SCRIPTING
2405 if ( sMacro
.isEmpty() )
2408 SfxApplication
* pSfxApp
= SfxGetpApp();
2409 SfxRequest
aReq( SID_BASICCHOOSER
, SfxCallMode::SYNCHRON
, pSfxApp
->GetPool() );
2410 aReq
.AppendItem( SfxBoolItem(SID_RECORDMACRO
,true) );
2411 const SfxPoolItem
* pRet
= SfxGetpApp()->ExecuteSlot( aReq
);
2412 OUString aScriptURL
;
2414 aScriptURL
= static_cast<const SfxStringItem
*>(pRet
)->GetValue();
2415 if ( !aScriptURL
.isEmpty() )
2419 OUString aModuleName
;
2420 OUString aMacroName
;
2422 Reference
< XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
2423 Reference
< css::uri::XUriReferenceFactory
> xFactory
=
2424 css::uri::UriReferenceFactory::create( xContext
);
2425 Reference
< css::uri::XVndSunStarScriptUrl
> xUrl( xFactory
->parse( aScriptURL
), UNO_QUERY
);
2429 OUString aName
= xUrl
->getName();
2430 sal_Unicode cTok
= '.';
2431 sal_Int32 nIndex
= 0;
2432 aLibName
= aName
.getToken( 0, cTok
, nIndex
);
2434 aModuleName
= aName
.getToken( 0, cTok
, nIndex
);
2436 aMacroName
= aName
.getToken( 0, cTok
, nIndex
);
2439 OUString
aLocKey("location");
2440 if ( xUrl
->hasParameter( aLocKey
) )
2441 aLocation
= xUrl
->getParameter( aLocKey
);
2444 BasicManager
* pBasMgr
= nullptr;
2445 if ( aLocation
.equalsIgnoreAsciiCase( "application" ) )
2447 // application basic
2448 pBasMgr
= SfxApplication::GetBasicManager();
2450 else if ( aLocation
.equalsIgnoreAsciiCase( "document" ) )
2452 pBasMgr
= GetObjectShell()->GetBasicManager();
2458 StarBASIC
* pBasic
= pBasMgr
->GetLib( aLibName
);
2461 SbModule
* pModule
= pBasic
->FindModule( aModuleName
);
2462 SbMethod
* pMethod
= pModule
? pModule
->FindMethod(aMacroName
, SbxClassType::Method
) : nullptr;
2465 aOUSource
= pModule
->GetSource32();
2466 sal_uInt16 nStart
, nEnd
;
2467 pMethod
->GetLineRange( nStart
, nEnd
);
2468 sal_uIntPtr nlStart
= nStart
;
2469 sal_uIntPtr nlEnd
= nEnd
;
2470 CutLines( aOUSource
, nlStart
-1, nlEnd
-nlStart
+1, true );
2475 // open lib container and break operation if it couldn't be opened
2476 css::uno::Reference
< css::script::XLibraryContainer
> xLibCont
;
2477 if ( aLocation
.equalsIgnoreAsciiCase( "application" ) )
2479 xLibCont
= SfxGetpApp()->GetBasicContainer();
2481 else if ( aLocation
.equalsIgnoreAsciiCase( "document" ) )
2483 xLibCont
= GetObjectShell()->GetBasicContainer();
2488 SAL_WARN("sfx.view", "couldn't get access to the basic lib container. Adding of macro isn't possible.");
2492 // get LibraryContainer
2493 css::uno::Any aTemp
;
2494 css::uno::Reference
< css::container::XNameAccess
> xRoot(
2496 css::uno::UNO_QUERY
);
2498 OUString
sLib( aLibName
);
2499 css::uno::Reference
< css::container::XNameAccess
> xLib
;
2500 if(xRoot
->hasByName(sLib
))
2502 // library must be loaded
2503 aTemp
= xRoot
->getByName(sLib
);
2504 xLibCont
->loadLibrary(sLib
);
2509 xLib
.set( xLibCont
->createLibrary(sLib
), css::uno::UNO_QUERY
);
2512 // pack the macro as direct usable "sub" routine
2514 OUStringBuffer
sRoutine(10000);
2515 OUString
sMacroName( aMacroName
);
2516 bool bReplace
= false;
2519 OUString
sModule( aModuleName
);
2520 if(xLib
->hasByName(sModule
))
2522 if ( !aOUSource
.isEmpty() )
2524 sRoutine
.append( aOUSource
);
2528 aTemp
= xLib
->getByName(sModule
);
2530 sRoutine
.append( sCode
);
2536 // append new method
2537 sRoutine
.append( "\nsub " );
2538 sRoutine
.append(sMacroName
);
2539 sRoutine
.append( "\n" );
2540 sRoutine
.append(sMacro
);
2541 sRoutine
.append( "\nend sub\n" );
2543 // create the modul inside the library and insert the macro routine
2544 aTemp
<<= sRoutine
.makeStringAndClear();
2547 css::uno::Reference
< css::container::XNameContainer
> xModulCont(
2549 css::uno::UNO_QUERY
);
2550 xModulCont
->replaceByName(sModule
,aTemp
);
2554 css::uno::Reference
< css::container::XNameContainer
> xModulCont(
2556 css::uno::UNO_QUERY
);
2557 xModulCont
->insertByName(sModule
,aTemp
);
2560 // #i17355# update the Basic IDE
2561 for ( SfxViewShell
* pViewShell
= SfxViewShell::GetFirst(); pViewShell
; pViewShell
= SfxViewShell::GetNext( *pViewShell
) )
2563 if ( pViewShell
->GetName() == "BasicIDE" )
2565 SfxViewFrame
* pViewFrame
= pViewShell
->GetViewFrame();
2566 SfxDispatcher
* pDispat
= pViewFrame
? pViewFrame
->GetDispatcher() : nullptr;
2569 SfxMacroInfoItem
aInfoItem( SID_BASICIDE_ARG_MACROINFO
, pBasMgr
, aLibName
, aModuleName
, OUString(), OUString() );
2570 pDispat
->ExecuteList(SID_BASICIDE_UPDATEMODULESOURCE
,
2571 SfxCallMode::SYNCHRON
, { &aInfoItem
});
2578 // add code for "session only" macro
2583 void SfxViewFrame::MiscExec_Impl( SfxRequest
& rReq
)
2585 switch ( rReq
.GetSlot() )
2587 case SID_STOP_RECORDING
:
2588 case SID_RECORDMACRO
:
2590 // try to find any active recorder on this frame
2591 OUString
sProperty("DispatchRecorderSupplier");
2592 css::uno::Reference
< css::frame::XFrame
> xFrame(
2593 GetFrame().GetFrameInterface(),
2594 css::uno::UNO_QUERY
);
2596 css::uno::Reference
< css::beans::XPropertySet
> xSet(xFrame
,css::uno::UNO_QUERY
);
2597 css::uno::Any aProp
= xSet
->getPropertyValue(sProperty
);
2598 css::uno::Reference
< css::frame::XDispatchRecorderSupplier
> xSupplier
;
2599 aProp
>>= xSupplier
;
2600 css::uno::Reference
< css::frame::XDispatchRecorder
> xRecorder
;
2602 xRecorder
= xSupplier
->getDispatchRecorder();
2604 bool bIsRecording
= xRecorder
.is();
2605 const SfxBoolItem
* pItem
= rReq
.GetArg
<SfxBoolItem
>(SID_RECORDMACRO
);
2606 if ( pItem
&& pItem
->GetValue() == bIsRecording
)
2609 if ( xRecorder
.is() )
2611 // disable active recording
2612 aProp
<<= css::uno::Reference
< css::frame::XDispatchRecorderSupplier
>();
2613 xSet
->setPropertyValue(sProperty
,aProp
);
2615 const SfxBoolItem
* pRecordItem
= rReq
.GetArg
<SfxBoolItem
>(FN_PARAM_1
);
2616 if ( !pRecordItem
|| !pRecordItem
->GetValue() )
2617 // insert script into basic library container of application
2618 AddDispatchMacroToBasic_Impl(xRecorder
->getRecordedMacro());
2620 xRecorder
->endRecording();
2621 xRecorder
= nullptr;
2622 GetBindings().SetRecorder_Impl( xRecorder
);
2624 SetChildWindow( SID_RECORDING_FLOATWINDOW
, false );
2625 if ( rReq
.GetSlot() != SID_RECORDMACRO
)
2626 GetBindings().Invalidate( SID_RECORDMACRO
);
2628 else if ( rReq
.GetSlot() == SID_RECORDMACRO
)
2631 css::uno::Reference
< css::uno::XComponentContext
> xContext(
2632 ::comphelper::getProcessComponentContext());
2634 xRecorder
= css::frame::DispatchRecorder::create( xContext
);
2636 xSupplier
= css::frame::DispatchRecorderSupplier::create( xContext
);
2638 xSupplier
->setDispatchRecorder(xRecorder
);
2639 xRecorder
->startRecording(xFrame
);
2640 aProp
<<= xSupplier
;
2641 xSet
->setPropertyValue(sProperty
,aProp
);
2642 GetBindings().SetRecorder_Impl( xRecorder
);
2643 SetChildWindow( SID_RECORDING_FLOATWINDOW
, true );
2650 case SID_TOGGLESTATUSBAR
:
2652 css::uno::Reference
< css::frame::XFrame
> xFrame(
2653 GetFrame().GetFrameInterface(),
2654 css::uno::UNO_QUERY
);
2656 Reference
< css::beans::XPropertySet
> xPropSet( xFrame
, UNO_QUERY
);
2657 Reference
< css::frame::XLayoutManager
> xLayoutManager
;
2658 if ( xPropSet
.is() )
2662 Any aValue
= xPropSet
->getPropertyValue("LayoutManager");
2663 aValue
>>= xLayoutManager
;
2665 catch ( Exception
& )
2670 if ( xLayoutManager
.is() )
2672 OUString
aStatusbarResString( "private:resource/statusbar/statusbar" );
2673 // Evaluate parameter.
2674 const SfxBoolItem
* pShowItem
= rReq
.GetArg
<SfxBoolItem
>(rReq
.GetSlot());
2677 bShow
= xLayoutManager
->isElementVisible( aStatusbarResString
);
2679 bShow
= pShowItem
->GetValue();
2683 xLayoutManager
->createElement( aStatusbarResString
);
2684 xLayoutManager
->showElement( aStatusbarResString
);
2687 xLayoutManager
->hideElement( aStatusbarResString
);
2690 rReq
.AppendItem( SfxBoolItem( SID_TOGGLESTATUSBAR
, bShow
) );
2696 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2697 case SID_WIN_FULLSCREEN
:
2699 const SfxBoolItem
* pItem
= rReq
.GetArg
<SfxBoolItem
>(rReq
.GetSlot());
2700 SfxViewFrame
*pTop
= GetTopViewFrame();
2703 WorkWindow
* pWork
= static_cast<WorkWindow
*>( pTop
->GetFrame().GetTopWindow_Impl() );
2706 css::uno::Reference
< css::frame::XFrame
> xFrame(
2707 GetFrame().GetFrameInterface(),
2708 css::uno::UNO_QUERY
);
2710 Reference
< css::beans::XPropertySet
> xPropSet( xFrame
, UNO_QUERY
);
2711 Reference
< css::frame::XLayoutManager
> xLayoutManager
;
2712 if ( xPropSet
.is() )
2716 Any aValue
= xPropSet
->getPropertyValue("LayoutManager");
2717 aValue
>>= xLayoutManager
;
2719 catch ( Exception
& )
2724 bool bNewFullScreenMode
= pItem
? pItem
->GetValue() : !pWork
->IsFullScreenMode();
2725 if ( bNewFullScreenMode
!= pWork
->IsFullScreenMode() )
2727 Reference
< css::beans::XPropertySet
> xLMPropSet( xLayoutManager
, UNO_QUERY
);
2728 if ( xLMPropSet
.is() )
2732 xLMPropSet
->setPropertyValue(
2734 makeAny( bNewFullScreenMode
));
2736 catch ( css::beans::UnknownPropertyException
& )
2740 pWork
->ShowFullScreenMode( bNewFullScreenMode
);
2741 pWork
->SetMenuBarMode( bNewFullScreenMode
? MenuBarMode::Hide
: MenuBarMode::Normal
);
2742 GetFrame().GetWorkWindow_Impl()->SetFullScreen_Impl( bNewFullScreenMode
);
2744 rReq
.AppendItem( SfxBoolItem( SID_WIN_FULLSCREEN
, bNewFullScreenMode
) );
2754 GetDispatcher()->Update_Impl( true );
2760 void SfxViewFrame::MiscState_Impl(SfxItemSet
&rSet
)
2762 const sal_uInt16
*pRanges
= rSet
.GetRanges();
2763 DBG_ASSERT(pRanges
&& *pRanges
, "Set without range");
2766 for(sal_uInt16 nWhich
= *pRanges
++; nWhich
<= *pRanges
; ++nWhich
)
2770 case SID_CURRENT_URL
:
2772 rSet
.Put( SfxStringItem( nWhich
, GetActualPresentationURL_Impl() ) );
2776 case SID_RECORDMACRO
:
2778 SvtMiscOptions aMiscOptions
;
2779 const char* pName
= GetObjectShell()->GetFactory().GetShortName();
2780 if ( !aMiscOptions
.IsMacroRecorderMode() ||
2781 ( strcmp(pName
,"swriter") && strcmp(pName
,"scalc") ) )
2783 rSet
.DisableItem( nWhich
);
2784 rSet
.Put(SfxVisibilityItem(nWhich
, false));
2788 OUString
sProperty("DispatchRecorderSupplier");
2789 css::uno::Reference
< css::beans::XPropertySet
> xSet(
2790 GetFrame().GetFrameInterface(),
2791 css::uno::UNO_QUERY
);
2793 css::uno::Any aProp
= xSet
->getPropertyValue(sProperty
);
2794 css::uno::Reference
< css::frame::XDispatchRecorderSupplier
> xSupplier
;
2795 if ( aProp
>>= xSupplier
)
2796 rSet
.Put( SfxBoolItem( nWhich
, xSupplier
.is() ) );
2798 rSet
.DisableItem( nWhich
);
2802 case SID_STOP_RECORDING
:
2804 SvtMiscOptions aMiscOptions
;
2805 const char* pName
= GetObjectShell()->GetFactory().GetShortName();
2806 if ( !aMiscOptions
.IsMacroRecorderMode() ||
2807 ( strcmp(pName
,"swriter") && strcmp(pName
,"scalc") ) )
2809 rSet
.DisableItem( nWhich
);
2813 OUString
sProperty("DispatchRecorderSupplier");
2814 css::uno::Reference
< css::beans::XPropertySet
> xSet(
2815 GetFrame().GetFrameInterface(),
2816 css::uno::UNO_QUERY
);
2818 css::uno::Any aProp
= xSet
->getPropertyValue(sProperty
);
2819 css::uno::Reference
< css::frame::XDispatchRecorderSupplier
> xSupplier
;
2820 if ( !(aProp
>>= xSupplier
) || !xSupplier
.is() )
2821 rSet
.DisableItem( nWhich
);
2825 case SID_TOGGLESTATUSBAR
:
2827 css::uno::Reference
< css::frame::XLayoutManager
> xLayoutManager
;
2828 css::uno::Reference
< css::beans::XPropertySet
> xSet(
2829 GetFrame().GetFrameInterface(),
2830 css::uno::UNO_QUERY
);
2831 css::uno::Any aProp
= xSet
->getPropertyValue( "LayoutManager" );
2833 if ( !( aProp
>>= xLayoutManager
))
2834 rSet
.Put( SfxBoolItem( nWhich
, false ));
2837 OUString
aStatusbarResString( "private:resource/statusbar/statusbar" );
2838 bool bShow
= xLayoutManager
->isElementVisible( aStatusbarResString
);
2839 rSet
.Put( SfxBoolItem( nWhich
, bShow
));
2844 case SID_WIN_FULLSCREEN
:
2846 SfxViewFrame
* pTop
= GetTopViewFrame();
2849 WorkWindow
* pWork
= static_cast<WorkWindow
*>( pTop
->GetFrame().GetTopWindow_Impl() );
2852 rSet
.Put( SfxBoolItem( nWhich
, pWork
->IsFullScreenMode() ) );
2857 rSet
.DisableItem( nWhich
);
2861 case SID_FORMATMENUSTATE
:
2863 OSL_FAIL("Outdated slot!");
2864 rSet
.DisableItem( nWhich
);
2879 This method can be included in the Execute method for the on- and off-
2880 switching of ChildWindows, to implement this and API-bindings.
2882 Simply include as 'ExecuteMethod' in the IDL.
2884 void SfxViewFrame::ChildWindowExecute( SfxRequest
&rReq
)
2886 // Evaluate Parameter
2887 sal_uInt16 nSID
= rReq
.GetSlot();
2889 const SfxBoolItem
* pShowItem
= rReq
.GetArg
<SfxBoolItem
>(nSID
);
2890 if ( nSID
== SID_VIEW_DATA_SOURCE_BROWSER
)
2892 if (!SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::EModule::DATABASE
))
2894 Reference
< XFrame
> xFrame
= GetFrame().GetFrameInterface();
2895 Reference
< XFrame
> xBeamer( xFrame
->findFrame( "_beamer", FrameSearchFlag::CHILDREN
) );
2896 bool bHasChild
= xBeamer
.is();
2897 bool bShow
= pShowItem
? pShowItem
->GetValue() : !bHasChild
;
2900 if( bShow
== bHasChild
)
2904 rReq
.AppendItem( SfxBoolItem( nSID
, bShow
) );
2908 SetChildWindow( SID_BROWSER
, false );
2912 css::util::URL aTargetURL
;
2913 aTargetURL
.Complete
= ".component:DB/DataSourceBrowser";
2914 Reference
< css::util::XURLTransformer
> xTrans(
2915 css::util::URLTransformer::create(
2916 ::comphelper::getProcessComponentContext() ) );
2917 xTrans
->parseStrict( aTargetURL
);
2919 Reference
< XDispatchProvider
> xProv( xFrame
, UNO_QUERY
);
2920 Reference
< css::frame::XDispatch
> xDisp
;
2922 xDisp
= xProv
->queryDispatch( aTargetURL
, "_beamer", 31 );
2925 Sequence
< css::beans::PropertyValue
> aArgs(1);
2926 css::beans::PropertyValue
* pArg
= aArgs
.getArray();
2927 pArg
[0].Name
= "Referer";
2928 pArg
[0].Value
<<= OUString("private:user");
2929 xDisp
->dispatch( aTargetURL
, aArgs
);
2936 if (nSID
== SID_STYLE_DESIGNER
)
2938 // First make sure that the sidebar is visible
2939 ShowChildWindow(SID_SIDEBAR
);
2941 ::sfx2::sidebar::Sidebar::TogglePanel("StyleListPanel",
2942 GetFrame().GetFrameInterface());
2947 bool bHasChild
= HasChildWindow(nSID
);
2948 bool bShow
= pShowItem
? pShowItem
->GetValue() : !bHasChild
;
2949 GetDispatcher()->Update_Impl( true );
2952 if ( !pShowItem
|| bShow
!= bHasChild
)
2953 ToggleChildWindow( nSID
);
2955 GetBindings().Invalidate( nSID
);
2957 // Record if possible.
2958 if ( nSID
== SID_HYPERLINK_DIALOG
|| nSID
== SID_SEARCH_DLG
)
2964 rReq
.AppendItem( SfxBoolItem( nSID
, bShow
) );
2971 This method can be used in the state method for the on and off-state
2972 of child-windows, in order to implement this.
2974 Just register the IDL as 'StateMethod'.
2976 void SfxViewFrame::ChildWindowState( SfxItemSet
& rState
)
2978 SfxWhichIter
aIter( rState
);
2979 for ( sal_uInt16 nSID
= aIter
.FirstWhich(); nSID
; nSID
= aIter
.NextWhich() )
2981 if ( nSID
== SID_VIEW_DATA_SOURCE_BROWSER
)
2983 rState
.Put( SfxBoolItem( nSID
, HasChildWindow( SID_BROWSER
) ) );
2985 else if ( nSID
== SID_HYPERLINK_DIALOG
)
2987 const SfxPoolItem
* pDummy
= nullptr;
2988 SfxItemState eState
= GetDispatcher()->QueryState( SID_HYPERLINK_SETLINK
, pDummy
);
2989 if ( SfxItemState::DISABLED
== eState
)
2990 rState
.DisableItem(nSID
);
2993 if ( KnowsChildWindow(nSID
) )
2994 rState
.Put( SfxBoolItem( nSID
, HasChildWindow(nSID
)) );
2996 rState
.DisableItem(nSID
);
2999 else if ( nSID
== SID_BROWSER
)
3001 Reference
< XFrame
> xFrame
= GetFrame().GetFrameInterface()->
3002 findFrame( "_beamer", FrameSearchFlag::CHILDREN
);
3004 rState
.DisableItem( nSID
);
3005 else if ( KnowsChildWindow(nSID
) )
3006 rState
.Put( SfxBoolItem( nSID
, HasChildWindow(nSID
) ) );
3008 else if ( nSID
== SID_SIDEBAR
)
3010 if ( !KnowsChildWindow( nSID
) )
3012 SAL_WARN("sfx.view", "SID_SIDEBAR state requested, but no task pane child window exists for this ID!");
3013 rState
.DisableItem( nSID
);
3017 rState
.Put( SfxBoolItem( nSID
, HasChildWindow( nSID
) ) );
3020 else if ( KnowsChildWindow(nSID
) )
3021 rState
.Put( SfxBoolItem( nSID
, HasChildWindow(nSID
) ) );
3023 rState
.DisableItem(nSID
);
3027 SfxWorkWindow
* SfxViewFrame::GetWorkWindow_Impl( sal_uInt16
/*nId*/ )
3029 SfxWorkWindow
* pWork
= GetFrame().GetWorkWindow_Impl();
3033 void SfxViewFrame::SetChildWindow(sal_uInt16 nId
, bool bOn
, bool bSetFocus
)
3035 SfxWorkWindow
* pWork
= GetWorkWindow_Impl( nId
);
3037 pWork
->SetChildWindow_Impl( nId
, bOn
, bSetFocus
);
3040 void SfxViewFrame::ToggleChildWindow(sal_uInt16 nId
)
3042 SfxWorkWindow
* pWork
= GetWorkWindow_Impl( nId
);
3044 pWork
->ToggleChildWindow_Impl( nId
, true );
3047 bool SfxViewFrame::HasChildWindow( sal_uInt16 nId
)
3049 SfxWorkWindow
* pWork
= GetWorkWindow_Impl( nId
);
3050 return pWork
&& pWork
->HasChildWindow_Impl(nId
);
3053 bool SfxViewFrame::KnowsChildWindow( sal_uInt16 nId
)
3055 SfxWorkWindow
* pWork
= GetWorkWindow_Impl( nId
);
3056 return pWork
&& pWork
->KnowsChildWindow_Impl(nId
);
3059 void SfxViewFrame::ShowChildWindow( sal_uInt16 nId
, bool bVisible
)
3061 SfxWorkWindow
* pWork
= GetWorkWindow_Impl( nId
);
3064 GetDispatcher()->Update_Impl(true);
3065 pWork
->ShowChildWindow_Impl(nId
, bVisible
, true );
3069 SfxChildWindow
* SfxViewFrame::GetChildWindow(sal_uInt16 nId
)
3071 SfxWorkWindow
* pWork
= GetWorkWindow_Impl( nId
);
3072 return pWork
? pWork
->GetChildWindow_Impl(nId
) : nullptr;
3075 void SfxViewFrame::UpdateDocument_Impl()
3077 SfxObjectShell
* pDoc
= GetObjectShell();
3078 if ( pDoc
->IsLoadingFinished() )
3079 pDoc
->CheckSecurityOnLoading_Impl();
3081 // check if document depends on a template
3082 pDoc
->UpdateFromTemplate_Impl();
3085 void SfxViewFrame::SetViewFrame( SfxViewFrame
* pFrame
)
3087 SfxGetpApp()->SetViewFrame_Impl( pFrame
);
3090 SfxInfoBarWindow
* SfxViewFrame::AppendInfoBar( const OUString
& sId
,
3091 const OUString
& sMessage
,
3092 const basegfx::BColor
* pBackgroundColor
,
3093 const basegfx::BColor
* pForegroundColor
,
3094 const basegfx::BColor
* pMessageColor
,
3095 WinBits nMessageStyle
)
3097 const sal_uInt16 nId
= SfxInfoBarContainerChild::GetChildWindowId();
3099 // Make sure the InfoBar container is visible
3100 if (!HasChildWindow(nId
))
3101 ToggleChildWindow(nId
);
3103 SfxChildWindow
* pChild
= GetChildWindow(nId
);
3106 SfxInfoBarContainerWindow
* pInfoBarContainer
= static_cast<SfxInfoBarContainerWindow
*>(pChild
->GetWindow());
3107 SfxInfoBarWindow
* pInfoBar
= pInfoBarContainer
->appendInfoBar(sId
, sMessage
, pBackgroundColor
, pForegroundColor
, pMessageColor
, nMessageStyle
);
3108 ShowChildWindow(nId
);
3114 void SfxViewFrame::RemoveInfoBar( const OUString
& sId
)
3116 const sal_uInt16 nId
= SfxInfoBarContainerChild::GetChildWindowId();
3118 // Make sure the InfoBar container is visible
3119 if (!HasChildWindow(nId
))
3120 ToggleChildWindow(nId
);
3122 SfxChildWindow
* pChild
= GetChildWindow(nId
);
3125 SfxInfoBarContainerWindow
* pInfoBarContainer
= static_cast<SfxInfoBarContainerWindow
*>(pChild
->GetWindow());
3126 SfxInfoBarWindow
* pInfoBar
= pInfoBarContainer
->getInfoBar(sId
);
3127 pInfoBarContainer
->removeInfoBar(pInfoBar
);
3128 ShowChildWindow(nId
);
3132 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */