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_feature_desktop.h>
21 #include <osl/file.hxx>
22 #include <sfx2/docfilt.hxx>
23 #include <sfx2/infobar.hxx>
24 #include <sfx2/sfxsids.hrc>
25 #include <sfx2/viewfrm.hxx>
26 #include <sfx2/classificationhelper.hxx>
27 #include <sfx2/notebookbar/SfxNotebookBar.hxx>
28 #include <com/sun/star/document/MacroExecMode.hpp>
29 #include <com/sun/star/frame/Desktop.hpp>
30 #include <com/sun/star/frame/DispatchRecorder.hpp>
31 #include <com/sun/star/frame/DispatchRecorderSupplier.hpp>
32 #include <com/sun/star/frame/XLoadable.hpp>
33 #include <com/sun/star/frame/XLayoutManager.hpp>
34 #include <com/sun/star/frame/XComponentLoader.hpp>
35 #include <com/sun/star/drawing/XShapes.hpp>
36 #include <officecfg/Office/Common.hxx>
37 #include <officecfg/Setup.hxx>
38 #include <toolkit/helper/vclunohelper.hxx>
39 #include <vcl/wrkwin.hxx>
40 #include <unotools/moduleoptions.hxx>
41 #include <svl/intitem.hxx>
42 #include <svl/visitem.hxx>
43 #include <svl/stritem.hxx>
44 #include <svl/eitem.hxx>
45 #include <svl/whiter.hxx>
46 #include <svl/undo.hxx>
47 #include <vcl/stdtext.hxx>
48 #include <vcl/weld.hxx>
49 #include <svtools/miscopt.hxx>
50 #include <tools/diagnose_ex.h>
51 #include <com/sun/star/container/XIndexAccess.hpp>
52 #include <com/sun/star/frame/XFramesSupplier.hpp>
53 #include <com/sun/star/frame/FrameSearchFlag.hpp>
54 #include <com/sun/star/frame/XFrame.hpp>
55 #include <com/sun/star/awt/XWindow.hpp>
56 #include <com/sun/star/frame/XController.hpp>
57 #include <com/sun/star/util/URLTransformer.hpp>
58 #include <com/sun/star/util/XURLTransformer.hpp>
59 #include <com/sun/star/util/XCloseable.hpp>
60 #include <com/sun/star/frame/XDispatchRecorderSupplier.hpp>
61 #include <com/sun/star/document/UpdateDocMode.hpp>
62 #include <com/sun/star/beans/XPropertySet.hpp>
63 #include <com/sun/star/uri/UriReferenceFactory.hpp>
64 #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
65 #include <com/sun/star/document/XViewDataSupplier.hpp>
66 #include <com/sun/star/container/XIndexContainer.hpp>
67 #include <com/sun/star/task/InteractionHandler.hpp>
68 #include <com/sun/star/drawing/XDrawView.hpp>
69 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
70 #include <rtl/ustrbuf.hxx>
71 #include <sal/log.hxx>
73 #include <unotools/ucbhelper.hxx>
74 #include <comphelper/lok.hxx>
75 #include <comphelper/processfactory.hxx>
76 #include <comphelper/namedvaluecollection.hxx>
77 #include <comphelper/docpasswordrequest.hxx>
78 #include <comphelper/docpasswordhelper.hxx>
80 #include <com/sun/star/uno/Reference.h>
82 #include <basic/basmgr.hxx>
83 #include <basic/sbmod.hxx>
84 #include <basic/sbmeth.hxx>
85 #include <svtools/strings.hrc>
86 #include <svtools/svtresid.hxx>
87 #include <framework/framelistanalyzer.hxx>
88 #include <shellimpl.hxx>
92 #include <unotools/configmgr.hxx>
93 #include <comphelper/sequenceashashmap.hxx>
95 using namespace ::com::sun::star
;
96 using namespace ::com::sun::star::uno
;
97 using namespace ::com::sun::star::ucb
;
98 using namespace ::com::sun::star::frame
;
99 using namespace ::com::sun::star::lang
;
100 using ::com::sun::star::awt::XWindow
;
101 using ::com::sun::star::beans::PropertyValue
;
102 using ::com::sun::star::document::XViewDataSupplier
;
103 using ::com::sun::star::container::XIndexContainer
;
105 // Due to ViewFrame::Current
106 #include <appdata.hxx>
107 #include <sfx2/app.hxx>
108 #include <sfx2/objface.hxx>
109 #include <openflag.hxx>
110 #include <objshimp.hxx>
111 #include <sfx2/viewsh.hxx>
112 #include <sfx2/objsh.hxx>
113 #include <sfx2/bindings.hxx>
114 #include <sfx2/dispatch.hxx>
115 #include <sfx2/request.hxx>
116 #include <sfx2/docfac.hxx>
117 #include <sfx2/ipclient.hxx>
118 #include <sfx2/sfxresid.hxx>
119 #include <sfx2/viewfac.hxx>
120 #include <sfx2/event.hxx>
121 #include <sfx2/fcontnr.hxx>
122 #include <sfx2/docfile.hxx>
123 #include <sfx2/module.hxx>
124 #include <sfx2/sfxuno.hxx>
125 #include <sfx2/progress.hxx>
126 #include <sfx2/sidebar/Sidebar.hxx>
127 #include <workwin.hxx>
128 #include <sfx2/minfitem.hxx>
129 #include <sfx2/strings.hrc>
130 #include "impviewframe.hxx"
131 #include <vcl/commandinfoprovider.hxx>
132 #include <vcl/svapp.hxx>
134 #define ShellClass_SfxViewFrame
135 #include <sfxslots.hxx>
137 SFX_IMPL_SUPERCLASS_INTERFACE(SfxViewFrame
,SfxShell
)
139 void SfxViewFrame::InitInterface_Impl()
141 GetStaticInterface()->RegisterChildWindow(SID_BROWSER
);
142 GetStaticInterface()->RegisterChildWindow(SID_RECORDING_FLOATWINDOW
);
143 #if HAVE_FEATURE_DESKTOP
144 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_FULLSCREEN
, SfxVisibilityFlags::FullScreen
, ToolbarId::FullScreenToolbox
);
145 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_APPLICATION
, SfxVisibilityFlags::Standard
, ToolbarId::EnvToolbox
);
150 /// Asks the user if editing a read-only document is really wanted.
151 class SfxEditDocumentDialog
: public weld::MessageDialogController
154 std::unique_ptr
<weld::Button
> m_xEditDocument
;
155 std::unique_ptr
<weld::Button
> m_xCancel
;
158 SfxEditDocumentDialog(weld::Widget
* pParent
);
161 SfxEditDocumentDialog::SfxEditDocumentDialog(weld::Widget
* pParent
)
162 : MessageDialogController(pParent
, "sfx/ui/editdocumentdialog.ui",
163 "EditDocumentDialog")
164 , m_xEditDocument(m_xBuilder
->weld_button("edit"))
165 , m_xCancel(m_xBuilder
->weld_button("cancel"))
169 class SfxQueryOpenAsTemplate
172 std::unique_ptr
<weld::MessageDialog
> m_xQueryBox
;
174 SfxQueryOpenAsTemplate(weld::Window
* pParent
, bool bAllowIgnoreLock
, LockFileEntry
& rLockData
)
175 : m_xQueryBox(Application::CreateMessageDialog(pParent
, VclMessageType::Question
,
176 VclButtonsType::NONE
, ""))
178 m_xQueryBox
->add_button(SfxResId(STR_QUERY_OPENASTEMPLATE_OPENCOPY_BTN
), RET_YES
);
180 = bAllowIgnoreLock
&& officecfg::Office::Common::Misc::AllowOverrideLocking::get();
181 if (bAllowIgnoreLock
)
182 m_xQueryBox
->add_button(SfxResId(STR_QUERY_OPENASTEMPLATE_OPEN_BTN
), RET_IGNORE
);
183 m_xQueryBox
->add_button(GetStandardText( StandardButtonType::Cancel
), RET_CANCEL
);
184 m_xQueryBox
->set_primary_text(QueryString(bAllowIgnoreLock
, rLockData
));
185 m_xQueryBox
->set_default_response(RET_YES
);
187 short run() { return m_xQueryBox
->run(); }
190 static OUString
QueryString(bool bAllowIgnoreLock
, LockFileEntry
& rLockData
)
192 OUString sLockUserData
;
193 if (!rLockData
[LockFileComponent::OOOUSERNAME
].isEmpty())
194 sLockUserData
= rLockData
[LockFileComponent::OOOUSERNAME
];
196 sLockUserData
= rLockData
[LockFileComponent::SYSUSERNAME
];
198 if (!sLockUserData
.isEmpty() && !rLockData
[LockFileComponent::EDITTIME
].isEmpty())
199 sLockUserData
+= " ( " + rLockData
[LockFileComponent::EDITTIME
] + " )";
201 if (!sLockUserData
.isEmpty())
202 sLockUserData
= "\n\n" + sLockUserData
+ "\n";
204 const bool bUseLockStr
= bAllowIgnoreLock
|| !sLockUserData
.isEmpty();
207 SfxResId(bUseLockStr
? STR_QUERY_OPENASTEMPLATE_LOCKED
: STR_QUERY_OPENASTEMPLATE
));
209 if (bAllowIgnoreLock
)
210 sMsg
+= "\n\n" + SfxResId(STR_QUERY_OPENASTEMPLATE_ALLOW_IGNORE
);
212 return sMsg
.replaceFirst("%LOCKINFO", sLockUserData
);
216 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
)
218 // TODO/LATER: In future the info should replace the direct hash completely
219 bool bResult
= ( !nPasswordHash
&& !aInfo
.hasElements() );
221 SAL_WARN_IF( !(pFilter
&& ( pFilter
->GetFilterFlags() & SfxFilterFlags::PASSWORDTOMODIFY
)), "sfx.view",
222 "PasswordToModify feature is active for a filter that does not support it!");
224 if ( pFilter
&& xHandler
.is() )
226 bool bCancel
= false;
227 bool bFirstTime
= true;
229 while ( !bResult
&& !bCancel
)
231 bool bMSType
= !pFilter
->IsOwnFormat();
233 ::rtl::Reference
< ::comphelper::DocPasswordRequest
> pPasswordRequest(
234 new ::comphelper::DocPasswordRequest(
235 bMSType
? ::comphelper::DocPasswordRequestType::MS
: ::comphelper::DocPasswordRequestType::Standard
,
236 bFirstTime
? css::task::PasswordRequestMode_PASSWORD_ENTER
: css::task::PasswordRequestMode_PASSWORD_REENTER
,
240 uno::Reference
< css::task::XInteractionRequest
> rRequest( pPasswordRequest
.get() );
241 xHandler
->handle( rRequest
);
243 if ( pPasswordRequest
->isPassword() )
245 if ( aInfo
.hasElements() )
247 bResult
= ::comphelper::DocPasswordHelper::IsModifyPasswordCorrect( pPasswordRequest
->getPasswordToModify(), aInfo
);
252 bResult
= ( SfxMedium::CreatePasswordToModifyHash( pPasswordRequest
->getPasswordToModify(), pFilter
->GetServiceName()=="com.sun.star.text.TextDocument" ) == nPasswordHash
);
266 void SfxViewFrame::ExecReload_Impl( SfxRequest
& rReq
)
268 SfxObjectShell
* pSh
= GetObjectShell();
269 switch ( rReq
.GetSlot() )
272 case SID_READONLYDOC
:
274 // Due to Double occupancy in toolboxes (with or without Ctrl),
275 // it is also possible that the slot is enabled, but Ctrl-click
276 // despite this is not!
277 if( !pSh
|| !pSh
->HasName() || !(pSh
->Get_Impl()->nLoadedFlags
& SfxLoadedFlags::MAINDOCUMENT
))
280 if (pSh
->isEditDocLocked())
283 // Only change read-only UI and remove info bar when we succeed
284 struct ReadOnlyUIGuard
286 SfxViewFrame
* m_pFrame
;
287 SfxObjectShell
* m_pSh
;
288 SfxMedium
* m_pMed
= nullptr;
290 ReadOnlyUIGuard(SfxViewFrame
* pFrame
, SfxObjectShell
* p_Sh
)
291 : m_pFrame(pFrame
), m_pSh(p_Sh
), m_bSetRO(p_Sh
->IsReadOnlyUI())
293 ~ReadOnlyUIGuard() COVERITY_NOEXCEPT_FALSE
295 if (m_bSetRO
!= m_pSh
->IsReadOnlyUI())
297 m_pSh
->SetReadOnlyUI(m_bSetRO
);
299 m_pFrame
->RemoveInfoBar("readonly");
302 // tdf#116066: DoSaveCompleted should be called after SetReadOnlyUI
303 m_pSh
->DoSaveCompleted(m_pMed
);
304 m_pSh
->Broadcast(SfxHint(SfxHintId::ModeChanged
));
308 } aReadOnlyUIGuard(this, pSh
);
310 SfxMedium
* pMed
= pSh
->GetMedium();
312 const SfxBoolItem
* pItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pSh
->GetMedium()->GetItemSet(), SID_VIEWONLY
, false);
313 if ( pItem
&& pItem
->GetValue() )
315 SfxApplication
* pApp
= SfxGetpApp();
316 SfxAllItemSet
aSet( pApp
->GetPool() );
317 aSet
.Put( SfxStringItem( SID_FILE_NAME
, pMed
->GetURLObject().GetMainURL(INetURLObject::DecodeMechanism::NONE
) ) );
318 aSet
.Put( SfxBoolItem( SID_TEMPLATE
, true ) );
319 aSet
.Put( SfxStringItem( SID_TARGETNAME
, "_blank" ) );
320 const SfxStringItem
* pReferer
= SfxItemSet::GetItem
<SfxStringItem
>(pMed
->GetItemSet(), SID_REFERER
, false);
322 aSet
.Put( *pReferer
);
323 const SfxInt16Item
* pVersionItem
= SfxItemSet::GetItem
<SfxInt16Item
>(pSh
->GetMedium()->GetItemSet(), SID_VERSION
, false);
325 aSet
.Put( *pVersionItem
);
327 if( pMed
->GetFilter() )
329 aSet
.Put( SfxStringItem( SID_FILTER_NAME
, pMed
->GetFilter()->GetFilterName() ) );
330 const SfxStringItem
* pOptions
= SfxItemSet::GetItem
<SfxStringItem
>(pMed
->GetItemSet(), SID_FILE_FILTEROPTIONS
, false);
332 aSet
.Put( *pOptions
);
335 GetDispatcher()->Execute( SID_OPENDOC
, SfxCallMode::ASYNCHRON
, aSet
);
339 StreamMode nOpenMode
;
340 bool bNeedsReload
= false;
341 if ( !pSh
->IsReadOnly() )
343 // Save and reload Readonly
344 if( pSh
->IsModified() )
346 if ( pSh
->PrepareClose() )
348 // the storing could let the medium be changed
349 pMed
= pSh
->GetMedium();
354 rReq
.SetReturnValue( SfxBoolItem( rReq
.GetSlot(), false ) );
358 nOpenMode
= SFX_STREAM_READONLY
;
359 aReadOnlyUIGuard
.m_bSetRO
= true;
363 if ( pSh
->IsReadOnlyMedium()
364 && ( pSh
->GetModifyPasswordHash() || pSh
->GetModifyPasswordInfo().hasElements() )
365 && !pSh
->IsModifyPasswordEntered() )
367 const OUString aDocumentName
= INetURLObject( pMed
->GetOrigURL() ).GetMainURL( INetURLObject::DecodeMechanism::WithCharset
);
368 if( !AskPasswordToModify_Impl( pMed
->GetInteractionHandler(), aDocumentName
, pMed
->GetFilter(), pSh
->GetModifyPasswordHash(), pSh
->GetModifyPasswordInfo() ) )
370 // this is a read-only document, if it has "Password to modify"
371 // the user should enter password before he can edit the document
372 rReq
.SetReturnValue( SfxBoolItem( rReq
.GetSlot(), false ) );
376 pSh
->SetModifyPasswordEntered();
379 nOpenMode
= pSh
->IsOriginallyReadOnlyMedium() ? SFX_STREAM_READONLY
: SFX_STREAM_READWRITE
;
380 aReadOnlyUIGuard
.m_bSetRO
= false;
382 // if only the view was in the readonly mode then there is no need to do the reload
383 if ( !pSh
->IsReadOnlyMedium() )
385 // SetReadOnlyUI causes recomputation of window title, using
386 // open mode among other things, so call SetOpenMode before
388 pMed
->SetOpenMode( nOpenMode
);
395 // Control through API if r/w or r/o
396 const SfxBoolItem
* pEditItem
= rReq
.GetArg
<SfxBoolItem
>(SID_EDITDOC
);
398 nOpenMode
= pEditItem
->GetValue() ? SFX_STREAM_READWRITE
: SFX_STREAM_READONLY
;
404 osl::FileBase::getFileURLFromSystemPath( pMed
->GetPhysicalName(), sTemp
);
405 INetURLObject
aPhysObj( sTemp
);
406 const SfxInt16Item
* pVersionItem
= SfxItemSet::GetItem
<SfxInt16Item
>(pSh
->GetMedium()->GetItemSet(), SID_VERSION
, false);
408 INetURLObject
aMedObj( pMed
->GetName() );
411 // the logic below is following:
412 // if the document seems not to need to be reloaded
413 // and the physical name is different to the logical one,
414 // then on file system it can be checked that the copy is still newer than the original and no document reload is required.
415 // Did some semplification to enhance readability of the 'if' expression
417 // when the 'http/https' protocol is active, the bool bPhysObjIsYounger relies upon the getlastmodified Property of a WebDAV resource.
418 // Said property should be implemented, but sometimes it's not.
419 // implemented. On this case the reload activated here will not work properly.
420 // TODO: change the check age method for WebDAV to etag (entity-tag) property value, need some rethinking, since the
421 // etag tells that the cache representation (e.g. in LO) is different from the one on the server,
422 // but tells nothing about the age
423 // Details at this link: http://tools.ietf.org/html/rfc4918#section-15, section 15.7
424 bool bPhysObjIsYounger
= ::utl::UCBContentHelper::IsYounger( aMedObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
),
425 aPhysObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
426 bool bIsWebDAV
= aMedObj
.isAnyKnownWebDAVScheme();
428 if ( ( !bNeedsReload
&& ( ( aMedObj
.GetProtocol() == INetProtocol::File
&&
429 aMedObj
.getFSysPath( FSysStyle::Detect
) != aPhysObj
.getFSysPath( FSysStyle::Detect
) &&
431 || ( bIsWebDAV
&& !bPhysObjIsYounger
)
432 || ( pMed
->IsRemote() && !bIsWebDAV
) ) )
439 bool bRetryIgnoringLock
= false;
440 bool bOpenTemplate
= false;
441 std::optional
<bool> aOrigROVal
;
444 auto pRO
= pMed
->GetItemSet()->GetItem
<SfxBoolItem
>(SID_DOC_READONLY
, false);
446 aOrigROVal
= pRO
->GetValue();
449 LockFileEntry aLockData
;
452 if (bRetryIgnoringLock
)
455 bool bHasStorage
= pMed
->HasStorage_Impl();
456 // switching edit mode could be possible without reload
457 if ( bHasStorage
&& pMed
->GetStorage() == pSh
->GetStorage() )
459 // TODO/LATER: faster creation of copy
460 if ( !pSh
->ConnectTmpStorage_Impl( pMed
->GetStorage(), pMed
) )
464 pMed
->CloseAndRelease();
465 pMed
->SetOpenMode( nOpenMode
);
466 // We need to clear the SID_DOC_READONLY item from the set, to allow
467 // MediaDescriptor::impl_openStreamWithURL (called indirectly by
468 // SfxMedium::CompleteReOpen) to properly fill input stream of the
469 // descriptor, even when the file can't be open in read-write mode.
470 // Only then can following call to SfxMedium::LockOrigFileOnDemand
471 // return proper information about who has locked the file, to show
472 // in the SfxQueryOpenAsTemplate box below; otherwise it exits right
473 // after call to SfxMedium::GetMedium_Impl. This mimics what happens
474 // when the file is opened initially, when filter detection code also
475 // calls MediaDescriptor::impl_openStreamWithURL without the item set.
476 pMed
->GetItemSet()->ClearItem(SID_DOC_READONLY
);
477 pMed
->CompleteReOpen();
478 pMed
->GetItemSet()->Put(
479 SfxBoolItem(SID_DOC_READONLY
, !(nOpenMode
& StreamMode::WRITE
)));
480 if ( nOpenMode
& StreamMode::WRITE
)
482 auto eResult
= pMed
->LockOrigFileOnDemand(
483 true, true, bRetryIgnoringLock
, &aLockData
);
485 = eResult
== SfxMedium::LockFileResult::FailedLockFile
;
488 // LockOrigFileOnDemand might set the readonly flag itself, it should be set back
489 pMed
->GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY
, !( nOpenMode
& StreamMode::WRITE
) ) );
491 if ( !pMed
->GetErrorCode() )
497 if (nOpenMode
== SFX_STREAM_READWRITE
&& !rReq
.IsAPI())
499 // css::sdbcx::User offering to open it as a template
500 SfxQueryOpenAsTemplate
aBox(GetWindow().GetFrameWeld(),
501 bRetryIgnoringLock
, aLockData
);
503 short nUserAnswer
= aBox
.run();
504 bOpenTemplate
= RET_YES
== nUserAnswer
;
505 // Always reset this here to avoid infinite loop
506 bRetryIgnoringLock
= RET_IGNORE
== nUserAnswer
;
509 bRetryIgnoringLock
= false;
512 while ( !bOK
&& bRetryIgnoringLock
);
516 ErrCode nErr
= pMed
->GetErrorCode();
518 nErr
= ERRCODE_IO_ACCESSDENIED
;
522 pMed
->SetOpenMode( SFX_STREAM_READONLY
);
524 pMed
->GetItemSet()->Put(SfxBoolItem(SID_DOC_READONLY
, *aOrigROVal
));
526 pMed
->GetItemSet()->ClearItem(SID_DOC_READONLY
);
528 pSh
->DoSaveCompleted( pMed
);
531 // Readonly document can not be switched to edit mode?
534 if ( nOpenMode
== SFX_STREAM_READWRITE
&& !rReq
.IsAPI() )
538 SfxApplication
* pApp
= SfxGetpApp();
539 SfxAllItemSet
aSet( pApp
->GetPool() );
540 aSet
.Put( SfxStringItem( SID_FILE_NAME
, pMed
->GetName() ) );
541 const SfxStringItem
* pReferer
= SfxItemSet::GetItem
<SfxStringItem
>(pMed
->GetItemSet(), SID_REFERER
, false);
543 aSet
.Put( *pReferer
);
544 aSet
.Put( SfxBoolItem( SID_TEMPLATE
, true ) );
546 aSet
.Put( *pVersionItem
);
548 if( pMed
->GetFilter() )
550 aSet
.Put( SfxStringItem( SID_FILTER_NAME
, pMed
->GetFilter()->GetFilterName() ) );
551 const SfxStringItem
* pOptions
= SfxItemSet::GetItem
<SfxStringItem
>(pMed
->GetItemSet(), SID_FILE_FILTEROPTIONS
, false);
553 aSet
.Put( *pOptions
);
556 GetDispatcher()->Execute( SID_OPENDOC
, SfxCallMode::ASYNCHRON
, aSet
);
563 // Keep the read-only UI
564 aReadOnlyUIGuard
.m_bSetRO
= true;
566 ErrorHandler::HandleError( nErr
);
568 SfxBoolItem( rReq
.GetSlot(), false ) );
573 aReadOnlyUIGuard
.m_pMed
= pMed
;
574 rReq
.SetReturnValue( SfxBoolItem( rReq
.GetSlot(), true ) );
580 rReq
.AppendItem( SfxBoolItem( SID_FORCERELOAD
, bNeedsReload
) );
581 rReq
.AppendItem( SfxBoolItem( SID_SILENT
, true ));
583 [[fallthrough
]]; //TODO ???
588 // Due to Double occupancy in toolboxes (with or without Ctrl),
589 // it is also possible that the slot is enabled, but Ctrl-click
590 // despite this is not!
591 if ( !pSh
|| !pSh
->CanReload_Impl() )
593 SfxApplication
* pApp
= SfxGetpApp();
594 const SfxBoolItem
* pForceReloadItem
= rReq
.GetArg
<SfxBoolItem
>(SID_FORCERELOAD
);
595 if( pForceReloadItem
&& !pForceReloadItem
->GetValue() &&
596 !pSh
->GetMedium()->IsExpired() )
598 if( m_pImpl
->bReloading
|| pSh
->IsInModalMode() )
601 // AutoLoad is prohibited if possible
602 const SfxBoolItem
* pAutoLoadItem
= rReq
.GetArg
<SfxBoolItem
>(SID_AUTOLOAD
);
603 if ( pAutoLoadItem
&& pAutoLoadItem
->GetValue() &&
604 GetFrame().IsAutoLoadLocked_Impl() )
607 SfxObjectShellLock
xOldObj( pSh
);
608 m_pImpl
->bReloading
= true;
609 const SfxStringItem
* pURLItem
= rReq
.GetArg
<SfxStringItem
>(SID_FILE_NAME
);
611 bool bForEdit
= !pSh
->IsReadOnly();
613 // If possible ask the User
614 bool bDo
= GetViewShell()->PrepareClose();
615 const SfxBoolItem
* pSilentItem
= rReq
.GetArg
<SfxBoolItem
>(SID_SILENT
);
616 if ( bDo
&& GetFrame().DocIsModified_Impl() &&
617 !rReq
.IsAPI() && ( !pSilentItem
|| !pSilentItem
->GetValue() ) )
619 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(GetWindow().GetFrameWeld(),
620 VclMessageType::Question
, VclButtonsType::YesNo
,
621 SfxResId(STR_QUERY_LASTVERSION
)));
622 bDo
= RET_YES
== xBox
->run();
627 SfxMedium
*pMedium
= xOldObj
->GetMedium();
630 ( pMedium
->GetURLObject().GetProtocol() == INetProtocol::File
&& !xOldObj
->IsDocShared() );
632 // Empty existing SfxMDIFrames for this Document
633 // in native format or R/O, open it now for editing?
634 SfxObjectShellLock xNewObj
;
636 // collect the views of the document
637 // TODO: when UNO ViewFactories are available for SFX-based documents, the below code should
639 typedef ::std::pair
< Reference
< XFrame
>, SfxInterfaceId
> ViewDescriptor
;
640 ::std::vector
< ViewDescriptor
> aViewFrames
;
641 SfxViewFrame
*pView
= GetFirst( xOldObj
);
644 Reference
< XFrame
> xFrame( pView
->GetFrame().GetFrameInterface() );
645 SAL_WARN_IF( !xFrame
.is(), "sfx.view", "SfxViewFrame::ExecReload_Impl: no XFrame?!");
646 aViewFrames
.emplace_back( xFrame
, pView
->GetCurViewId() );
648 pView
= GetNext( *pView
, xOldObj
);
651 xOldObj
->Get_Impl()->pReloadTimer
.reset();
653 std::unique_ptr
<SfxItemSet
> pNewSet
;
654 std::shared_ptr
<const SfxFilter
> pFilter
= pMedium
->GetFilter();
657 pNewSet
.reset(new SfxAllItemSet( pApp
->GetPool() ));
658 pNewSet
->Put( *pURLItem
);
662 const SfxStringItem
* refererItem
= rReq
.GetArg
<SfxStringItem
>(SID_REFERER
);
663 if (refererItem
!= nullptr) {
664 referer
= refererItem
->GetValue();
666 SfxMedium
aMedium( pURLItem
->GetValue(), referer
, SFX_STREAM_READWRITE
);
667 SfxFilterMatcher().GuessFilter( aMedium
, pFilter
);
669 pNewSet
->Put( SfxStringItem( SID_FILTER_NAME
, pFilter
->GetName() ) );
670 pNewSet
->Put( *aMedium
.GetItemSet() );
674 pNewSet
.reset(new SfxAllItemSet( *pMedium
->GetItemSet() ));
675 pNewSet
->ClearItem( SID_VIEW_ID
);
676 pNewSet
->ClearItem( SID_STREAM
);
677 pNewSet
->ClearItem( SID_INPUTSTREAM
);
678 pNewSet
->Put( SfxStringItem( SID_FILTER_NAME
, pMedium
->GetFilter()->GetName() ) );
680 // let the current security settings be checked again
681 pNewSet
->Put( SfxUInt16Item( SID_MACROEXECMODE
, document::MacroExecMode::USE_CONFIG
) );
683 if ( pSh
->IsOriginallyReadOnlyMedium()
684 || pSh
->IsOriginallyLoadedReadOnlyMedium() )
685 // edit mode is switched or reload of readonly document
686 pNewSet
->Put( SfxBoolItem( SID_DOC_READONLY
, true ) );
688 // Reload of file opened for writing
689 pNewSet
->ClearItem( SID_DOC_READONLY
);
692 // If a salvaged file is present, do not enclose the OrigURL
693 // again, since the Template is invalid after reload.
694 const SfxStringItem
* pSalvageItem
= SfxItemSet::GetItem
<SfxStringItem
>(pNewSet
.get(), SID_DOC_SALVAGE
, false);
697 pNewSet
->ClearItem( SID_DOC_SALVAGE
);
700 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
701 // TODO/LATER: Temporary solution, the SfxMedium must know the original URL as aLogicName
702 // SfxMedium::Transfer_Impl() will be forbidden then.
703 if ( xOldObj
->IsDocShared() )
704 pNewSet
->Put( SfxStringItem( SID_FILE_NAME
, xOldObj
->GetSharedFileURL() ) );
707 pNewSet
->Put( SfxStringItem( SID_REFERER
, pMedium
->GetName() ) );
709 pNewSet
->Put( SfxStringItem( SID_REFERER
, OUString() ) );
711 xOldObj
->CancelTransfers();
714 if ( pSilentItem
&& pSilentItem
->GetValue() )
715 pNewSet
->Put( SfxBoolItem( SID_SILENT
, true ) );
717 const SfxUnoAnyItem
* pInteractionItem
= SfxItemSet::GetItem
<SfxUnoAnyItem
>(pNewSet
.get(), SID_INTERACTIONHANDLER
, false);
718 const SfxUInt16Item
* pMacroExecItem
= SfxItemSet::GetItem
<SfxUInt16Item
>(pNewSet
.get(), SID_MACROEXECMODE
, false);
719 const SfxUInt16Item
* pDocTemplateItem
= SfxItemSet::GetItem
<SfxUInt16Item
>(pNewSet
.get(), SID_UPDATEDOCMODE
, false);
721 if (!pInteractionItem
)
723 Reference
< task::XInteractionHandler2
> xHdl
= task::InteractionHandler::createWithParent( ::comphelper::getProcessComponentContext(), nullptr );
725 pNewSet
->Put( SfxUnoAnyItem(SID_INTERACTIONHANDLER
,css::uno::makeAny(xHdl
)) );
729 pNewSet
->Put( SfxUInt16Item(SID_MACROEXECMODE
,css::document::MacroExecMode::USE_CONFIG
) );
730 if (!pDocTemplateItem
)
731 pNewSet
->Put( SfxUInt16Item(SID_UPDATEDOCMODE
,css::document::UpdateDocMode::ACCORDING_TO_CONFIG
) );
733 xOldObj
->SetModified( false );
734 // Do not cache the old Document! Is invalid when loading
737 const SfxStringItem
* pSavedOptions
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_FILE_FILTEROPTIONS
, false);
738 const SfxStringItem
* pSavedReferer
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_REFERER
, false);
740 bool bHasStorage
= pMedium
->HasStorage_Impl();
743 if ( bHasStorage
&& pMedium
->GetStorage() == xOldObj
->GetStorage() )
745 // TODO/LATER: faster creation of copy
746 if ( !xOldObj
->ConnectTmpStorage_Impl( pMedium
->GetStorage(), pMedium
) )
750 pMedium
->CloseAndRelease();
753 xNewObj
= SfxObjectShell::CreateObject( pFilter
->GetServiceName() );
755 if ( xOldObj
->IsModifyPasswordEntered() )
756 xNewObj
->SetModifyPasswordEntered();
758 uno::Sequence
< beans::PropertyValue
> aLoadArgs
;
759 TransformItems( SID_OPENDOC
, *pNewSet
, aLoadArgs
);
762 uno::Reference
< frame::XLoadable
> xLoad( xNewObj
->GetModel(), uno::UNO_QUERY
);
763 xLoad
->load( aLoadArgs
);
765 catch ( uno::Exception
& )
777 // back to old medium
779 pMedium
->LockOrigFileOnDemand( false, true );
781 xOldObj
->DoSaveCompleted( pMedium
);
784 // r/o-Doc couldn't be switched to writing mode
785 if ( bForEdit
&& ( SID_EDITDOC
== rReq
.GetSlot() || SID_READONLYDOC
== rReq
.GetSlot() ) )
787 // ask user for opening as template
788 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(GetWindow().GetFrameWeld(),
789 VclMessageType::Question
, VclButtonsType::YesNo
,
790 SfxResId(STR_QUERY_OPENASTEMPLATE
)));
791 if (RET_YES
== xBox
->run())
793 SfxAllItemSet
aSet( pApp
->GetPool() );
794 aSet
.Put( SfxStringItem( SID_FILE_NAME
, pMedium
->GetName() ) );
795 aSet
.Put( SfxStringItem( SID_TARGETNAME
, "_blank" ) );
797 aSet
.Put( *pSavedOptions
);
799 aSet
.Put( *pSavedReferer
);
800 aSet
.Put( SfxBoolItem( SID_TEMPLATE
, true ) );
802 aSet
.Put( SfxStringItem( SID_FILTER_NAME
, pFilter
->GetFilterName() ) );
803 GetDispatcher()->Execute( SID_OPENDOC
, SfxCallMode::ASYNCHRON
, aSet
);
809 if ( xNewObj
->GetModifyPasswordHash() && xNewObj
->GetModifyPasswordHash() != xOldObj
->GetModifyPasswordHash() )
811 xNewObj
->SetModifyPasswordEntered( false );
812 xNewObj
->SetReadOnly();
814 else if ( rReq
.GetSlot() == SID_EDITDOC
|| rReq
.GetSlot() == SID_READONLYDOC
)
816 xNewObj
->SetReadOnlyUI( !bForEdit
);
819 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
820 if ( xNewObj
->IsDocShared() )
822 // the file is shared but the closing can change the sharing control file
823 xOldObj
->DoNotCleanShareControlFile();
826 // the Reload and Silent items were only temporary, remove them
827 xNewObj
->GetMedium()->GetItemSet()->ClearItem( SID_RELOAD
);
828 xNewObj
->GetMedium()->GetItemSet()->ClearItem( SID_SILENT
);
829 TransformItems( SID_OPENDOC
, *xNewObj
->GetMedium()->GetItemSet(), aLoadArgs
);
831 UpdateDocument_Impl();
833 if (vcl::CommandInfoProvider::GetModuleIdentifier(GetFrame().GetFrameInterface()) == "com.sun.star.text.TextDocument")
834 sfx2::SfxNotebookBar::ReloadNotebookBar("modules/swriter/ui/");
838 for (auto const& viewFrame
: aViewFrames
)
840 LoadViewIntoFrame_Impl( *xNewObj
, viewFrame
.first
, aLoadArgs
, viewFrame
.second
, false );
844 catch( const Exception
& )
846 // close the remaining frames
847 // Don't catch exceptions herein, if this fails, then we're left in an indetermined state, and
848 // crashing is better than trying to proceed
849 for (auto const& viewFrame
: aViewFrames
)
851 Reference
< util::XCloseable
> xClose( viewFrame
.first
, UNO_QUERY_THROW
);
852 xClose
->close( true );
857 const SfxInt32Item
* pPageNumber
= rReq
.GetArg
<SfxInt32Item
>(SID_PAGE_NUMBER
);
858 if (pPageNumber
&& pPageNumber
->GetValue() >= 0)
860 // Restore current page after reload.
861 uno::Reference
<drawing::XDrawView
> xController(
862 xNewObj
->GetModel()->getCurrentController(), uno::UNO_QUERY
);
863 uno::Reference
<drawing::XDrawPagesSupplier
> xSupplier(xNewObj
->GetModel(),
865 uno::Reference
<drawing::XDrawPages
> xDrawPages
= xSupplier
->getDrawPages();
866 uno::Reference
<drawing::XDrawPage
> xDrawPage(
867 xDrawPages
->getByIndex(pPageNumber
->GetValue()), uno::UNO_QUERY
);
868 xController
->setCurrentPage(xDrawPage
);
871 // Propagate document closure.
872 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::CloseDoc
, GlobalEventConfig::GetEventName( GlobalEventId::CLOSEDOC
), xOldObj
) );
877 rReq
.SetReturnValue(SfxBoolItem(rReq
.GetSlot(), true));
882 // Record as not done
884 rReq
.SetReturnValue(SfxBoolItem(rReq
.GetSlot(), false));
885 m_pImpl
->bReloading
= false;
892 void SfxViewFrame::StateReload_Impl( SfxItemSet
& rSet
)
894 SfxObjectShell
* pSh
= GetObjectShell();
897 // I'm just on reload and am yielding myself ...
901 SfxWhichIter
aIter( rSet
);
902 for ( sal_uInt16 nWhich
= aIter
.FirstWhich(); nWhich
; nWhich
= aIter
.NextWhich() )
907 case SID_READONLYDOC
:
909 const SfxViewShell
*pVSh
;
910 const SfxShell
*pFSh
;
911 if ( !pSh
->HasName() ||
912 !( pSh
->Get_Impl()->nLoadedFlags
& SfxLoadedFlags::MAINDOCUMENT
) ||
913 (pSh
->isEditDocLocked()) ||
914 ( pSh
->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
&&
915 ( !(pVSh
= pSh
->GetViewShell()) ||
916 !(pFSh
= pVSh
->GetFormShell()) ||
917 !pFSh
->IsDesignMode())))
918 rSet
.DisableItem( nWhich
);
921 const SfxBoolItem
* pItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pSh
->GetMedium()->GetItemSet(), SID_EDITDOC
, false);
922 if ( pItem
&& !pItem
->GetValue() )
923 rSet
.DisableItem( nWhich
);
926 if (nWhich
==SID_EDITDOC
)
927 rSet
.Put( SfxBoolItem( nWhich
, !pSh
->IsReadOnly() ) );
928 else if (nWhich
==SID_READONLYDOC
)
929 rSet
.Put( SfxBoolItem( nWhich
, pSh
->IsReadOnly() ) );
937 if ( !pSh
->CanReload_Impl() || pSh
->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
938 rSet
.DisableItem(nWhich
);
941 // If any ChildFrame is reloadable, the slot is enabled,
942 // so you can perform CTRL-Reload
943 rSet
.Put( SfxBoolItem( nWhich
, false));
952 void SfxViewFrame::ExecHistory_Impl( SfxRequest
&rReq
)
954 // Is there an Undo-Manager on the top Shell?
955 SfxShell
*pSh
= GetDispatcher()->GetShell(0);
956 SfxUndoManager
* pShUndoMgr
= pSh
->GetUndoManager();
960 switch ( rReq
.GetSlot() )
962 case SID_CLEARHISTORY
:
969 GetBindings().InvalidateAll(false);
975 GetBindings().InvalidateAll(false);
980 if ( pSh
->GetRepeatTarget() )
981 pShUndoMgr
->Repeat( *pSh
->GetRepeatTarget() );
986 else if ( GetViewShell() )
988 // The SW has its own undo in the View
989 const SfxPoolItem
*pRet
= GetViewShell()->ExecuteSlot( rReq
);
991 bOK
= static_cast<const SfxBoolItem
*>(pRet
)->GetValue();
994 rReq
.SetReturnValue( SfxBoolItem( rReq
.GetSlot(), bOK
) );
998 void SfxViewFrame::StateHistory_Impl( SfxItemSet
&rSet
)
1000 // Search for Undo-Manager
1001 SfxShell
*pSh
= GetDispatcher()->GetShell(0);
1003 // I'm just on reload and am yielding myself ...
1006 SfxUndoManager
*pShUndoMgr
= pSh
->GetUndoManager();
1009 // The SW has its own undo in the View
1010 SfxWhichIter
aIter( rSet
);
1011 SfxViewShell
*pViewSh
= GetViewShell();
1012 if( !pViewSh
) return;
1013 for ( sal_uInt16 nSID
= aIter
.FirstWhich(); nSID
; nSID
= aIter
.NextWhich() )
1014 pViewSh
->GetSlotState( nSID
, nullptr, &rSet
);
1018 if ( pShUndoMgr
->GetUndoActionCount() == 0 &&
1019 pShUndoMgr
->GetRedoActionCount() == 0 &&
1020 pShUndoMgr
->GetRepeatActionCount() == 0 )
1021 rSet
.DisableItem( SID_CLEARHISTORY
);
1023 if (pShUndoMgr
->GetUndoActionCount())
1025 const SfxUndoAction
* pAction
= pShUndoMgr
->GetUndoAction();
1026 SfxViewShell
*pViewSh
= GetViewShell();
1027 if (pViewSh
&& pAction
->GetViewShellId() != pViewSh
->GetViewShellId())
1029 rSet
.Put(SfxUInt32Item(SID_UNDO
, static_cast<sal_uInt32
>(SID_REPAIRPACKAGE
)));
1033 rSet
.Put( SfxStringItem( SID_UNDO
, SvtResId(STR_UNDO
)+pShUndoMgr
->GetUndoActionComment() ) );
1037 rSet
.DisableItem( SID_UNDO
);
1039 if (pShUndoMgr
->GetRedoActionCount())
1041 const SfxUndoAction
* pAction
= pShUndoMgr
->GetRedoAction();
1042 SfxViewShell
*pViewSh
= GetViewShell();
1043 if (pViewSh
&& pAction
->GetViewShellId() != pViewSh
->GetViewShellId())
1045 rSet
.Put(SfxUInt32Item(SID_REDO
, static_cast<sal_uInt32
>(SID_REPAIRPACKAGE
)));
1049 rSet
.Put(SfxStringItem(SID_REDO
, SvtResId(STR_REDO
) + pShUndoMgr
->GetRedoActionComment()));
1053 rSet
.DisableItem( SID_REDO
);
1055 SfxRepeatTarget
*pTarget
= pSh
->GetRepeatTarget();
1056 if (pTarget
&& pShUndoMgr
->GetRepeatActionCount() && pShUndoMgr
->CanRepeat(*pTarget
))
1057 rSet
.Put( SfxStringItem( SID_REPEAT
, SvtResId(STR_REPEAT
)+pShUndoMgr
->GetRepeatActionComment(*pTarget
) ) );
1059 rSet
.DisableItem( SID_REPEAT
);
1062 void SfxViewFrame::PopShellAndSubShells_Impl( SfxViewShell
& i_rViewShell
)
1064 i_rViewShell
.PopSubShells_Impl();
1065 sal_uInt16 nLevel
= m_pDispatcher
->GetShellLevel( i_rViewShell
);
1066 if ( nLevel
!= USHRT_MAX
)
1070 // more sub shells on the stack, which were not affected by PopSubShells_Impl
1071 SfxShell
*pSubShell
= m_pDispatcher
->GetShell( nLevel
-1 );
1072 m_pDispatcher
->Pop( *pSubShell
, SfxDispatcherPopFlags::POP_UNTIL
| SfxDispatcherPopFlags::POP_DELETE
);
1074 m_pDispatcher
->Pop( i_rViewShell
);
1075 m_pDispatcher
->Flush();
1082 This method empties the SfxViewFrame, i.e. takes the <SfxObjectShell>
1083 from the dispatcher and ends its <SfxListener> Relationship to this
1084 SfxObjectShell (by which they may even destroy themselves).
1086 Thus, by invoking ReleaseObjectShell() and SetObjectShell() the
1087 SfxObjectShell can be replaced.
1089 Between ReleaseObjectShell() and SetObjectShell() the control cannot
1090 be handed over to the system.
1094 <SfxViewFrame::SetObjectShell(SfxObjectShell&)>
1096 void SfxViewFrame::ReleaseObjectShell_Impl()
1098 DBG_ASSERT( m_xObjSh
.is(), "no SfxObjectShell to release!" );
1100 GetFrame().ReleasingComponent_Impl();
1101 if ( GetWindow().HasChildPathFocus( true ) )
1103 GetWindow().GrabFocus();
1106 SfxViewShell
*pDyingViewSh
= GetViewShell();
1109 PopShellAndSubShells_Impl( *pDyingViewSh
);
1110 pDyingViewSh
->DisconnectAllClients();
1111 SetViewShell_Impl(nullptr);
1112 delete pDyingViewSh
;
1116 OSL_FAIL("No Shell");
1119 if ( m_xObjSh
.is() )
1121 m_pDispatcher
->Pop( *m_xObjSh
);
1122 SfxModule
* pModule
= m_xObjSh
->GetModule();
1124 m_pDispatcher
->RemoveShell_Impl( *pModule
);
1125 m_pDispatcher
->Flush();
1126 EndListening( *m_xObjSh
);
1128 Notify( *m_xObjSh
, SfxHint(SfxHintId::TitleChanged
) );
1129 Notify( *m_xObjSh
, SfxHint(SfxHintId::DocChanged
) );
1131 if ( 1 == m_xObjSh
->GetOwnerLockCount() && m_pImpl
->bObjLocked
&& m_xObjSh
->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
1132 m_xObjSh
->DoClose();
1133 SfxObjectShellRef xDyingObjSh
= m_xObjSh
;
1135 if( GetFrame().GetHasTitle() && m_pImpl
->nDocViewNo
)
1136 xDyingObjSh
->GetNoSet_Impl().ReleaseIndex(m_pImpl
->nDocViewNo
-1);
1137 if ( m_pImpl
->bObjLocked
)
1139 xDyingObjSh
->OwnerLock( false );
1140 m_pImpl
->bObjLocked
= false;
1144 GetDispatcher()->SetDisableFlags( SfxDisableFlags::NONE
);
1147 void SfxViewFrame::Close()
1150 DBG_ASSERT( GetFrame().IsClosing_Impl() || !GetFrame().GetFrameInterface().is(), "ViewFrame closed too early!" );
1152 // If no saving have been made up until now, then embedded Objects should
1153 // not be saved automatically anymore.
1154 if ( GetViewShell() )
1155 GetViewShell()->DisconnectAllClients();
1156 Broadcast( SfxHint( SfxHintId::Dying
) );
1158 if (SfxViewFrame::Current() == this)
1159 SfxViewFrame::SetViewFrame( nullptr );
1161 // Since the Dispatcher is emptied, it can not be used in any reasonable
1162 // manner, thus it is better to let the dispatcher be.
1163 GetDispatcher()->Lock(true);
1167 void SfxViewFrame::DoActivate( bool bUI
)
1169 m_pDispatcher
->DoActivate_Impl( bUI
);
1172 void SfxViewFrame::DoDeactivate(bool bUI
, SfxViewFrame
const * pNewFrame
)
1174 m_pDispatcher
->DoDeactivate_Impl( bUI
, pNewFrame
);
1177 void SfxViewFrame::InvalidateBorderImpl( const SfxViewShell
* pSh
)
1179 if( !pSh
|| m_nAdjustPosPixelLock
)
1182 if ( GetViewShell() && GetWindow().IsVisible() )
1184 if ( GetFrame().IsInPlace() )
1189 DoAdjustPosSizePixel( GetViewShell(), Point(),
1190 GetWindow().GetOutputSizePixel(),
1195 void SfxViewFrame::SetBorderPixelImpl
1197 const SfxViewShell
* pVSh
,
1198 const SvBorder
& rBorder
1202 m_pImpl
->aBorder
= rBorder
;
1204 if ( m_pImpl
->bResizeInToOut
&& !GetFrame().IsInPlace() )
1206 Size aSize
= pVSh
->GetWindow()->GetOutputSizePixel();
1207 if ( aSize
.Width() && aSize
.Height() )
1209 aSize
.AdjustWidth(rBorder
.Left() + rBorder
.Right() );
1210 aSize
.AdjustHeight(rBorder
.Top() + rBorder
.Bottom() );
1212 Size aOldSize
= GetWindow().GetOutputSizePixel();
1213 GetWindow().SetOutputSizePixel( aSize
);
1214 vcl::Window
* pParent
= &GetWindow();
1215 while ( pParent
->GetParent() )
1216 pParent
= pParent
->GetParent();
1217 Size aOuterSize
= pParent
->GetOutputSizePixel();
1218 aOuterSize
.AdjustWidth( aSize
.Width() - aOldSize
.Width() );
1219 aOuterSize
.AdjustHeight( aSize
.Height() - aOldSize
.Height() );
1220 pParent
->SetOutputSizePixel( aOuterSize
);
1225 tools::Rectangle
aEditArea( Point(), GetWindow().GetOutputSizePixel() );
1226 aEditArea
.AdjustLeft(rBorder
.Left() );
1227 aEditArea
.AdjustRight( -(rBorder
.Right()) );
1228 aEditArea
.AdjustTop(rBorder
.Top() );
1229 aEditArea
.AdjustBottom( -(rBorder
.Bottom()) );
1230 pVSh
->GetWindow()->SetPosSizePixel( aEditArea
.TopLeft(), aEditArea
.GetSize() );
1234 const SvBorder
& SfxViewFrame::GetBorderPixelImpl() const
1236 return m_pImpl
->aBorder
;
1239 void SfxViewFrame::AppendReadOnlyInfobar()
1241 bool bSignPDF
= m_xObjSh
->IsSignPDF();
1242 bool bSignWithCert
= false;
1245 SfxObjectShell
* pObjectShell
= GetObjectShell();
1246 uno::Reference
<security::XCertificate
> xCertificate
= pObjectShell
->GetSignPDFCertificate();
1247 bSignWithCert
= xCertificate
.is();
1250 auto pInfoBar
= AppendInfoBar("readonly", "",
1251 SfxResId(bSignPDF
? STR_READONLY_PDF
: STR_READONLY_DOCUMENT
),
1258 // SID_SIGNPDF opened a read-write PDF
1259 // read-only for signing purposes.
1260 weld::Button
& rSignButton
= pInfoBar
->addButton();
1263 rSignButton
.set_label(SfxResId(STR_READONLY_FINISH_SIGN
));
1267 rSignButton
.set_label(SfxResId(STR_READONLY_SIGN
));
1270 rSignButton
.connect_clicked(LINK(this, SfxViewFrame
, SignDocumentHandler
));
1273 bool showEditDocumentButton
= true;
1274 if (m_xObjSh
->isEditDocLocked())
1275 showEditDocumentButton
= false;
1277 if (showEditDocumentButton
)
1279 weld::Button
& rBtn
= pInfoBar
->addButton();
1280 rBtn
.set_label(SfxResId(STR_READONLY_EDIT
));
1281 rBtn
.connect_clicked(LINK(this, SfxViewFrame
, SwitchReadOnlyHandler
));
1285 void SfxViewFrame::Notify( SfxBroadcaster
& /*rBC*/, const SfxHint
& rHint
)
1287 if(m_pImpl
->bIsDowning
)
1290 // we know only SfxEventHint or simple SfxHint
1291 if (const SfxEventHint
* pEventHint
= dynamic_cast<const SfxEventHint
*>(&rHint
))
1293 // When the Document is loaded asynchronously, was the Dispatcher
1294 // set as ReadOnly, to what must be returned when the document itself
1295 // is not read only, and the loading is finished.
1296 switch ( pEventHint
->GetEventId() )
1298 case SfxEventHintId::ModifyChanged
:
1300 SfxBindings
& rBind
= GetBindings();
1301 rBind
.Invalidate( SID_DOC_MODIFIED
);
1302 rBind
.Invalidate( SID_RELOAD
);
1303 rBind
.Invalidate( SID_EDITDOC
);
1307 case SfxEventHintId::OpenDoc
:
1308 case SfxEventHintId::CreateDoc
:
1310 if ( !m_xObjSh
.is() )
1313 SfxBindings
& rBind
= GetBindings();
1314 rBind
.Invalidate( SID_RELOAD
);
1315 rBind
.Invalidate( SID_EDITDOC
);
1317 const auto t0
= std::chrono::system_clock::now().time_since_epoch();
1319 bool bIsUITest
= false; //uitest.uicheck fails when the dialog is open
1320 for( sal_uInt16 i
= 0; i
< Application::GetCommandLineParamCount(); i
++ )
1322 if( Application::GetCommandLineParam(i
) == "--nologo" )
1326 //what's new infobar
1327 OUString sSetupVersion
= utl::ConfigManager::getProductVersion();
1328 sal_Int32 iCurrent
= sSetupVersion
.getToken(0,'.').toInt32() * 10 + sSetupVersion
.getToken(1,'.').toInt32();
1329 OUString sLastVersion
1330 = officecfg::Setup::Product::ooSetupLastVersion::get().value_or("0.0");
1331 sal_Int32 iLast
= sLastVersion
.getToken(0,'.').toInt32() * 10 + sLastVersion
.getToken(1,'.').toInt32();
1332 if ((iCurrent
> iLast
) && !Application::IsHeadlessModeEnabled() && !bIsUITest
)
1334 VclPtr
<SfxInfoBarWindow
> pInfoBar
= AppendInfoBar("whatsnew", "", SfxResId(STR_WHATSNEW_TEXT
), InfobarType::INFO
);
1337 weld::Button
& rWhatsNewButton
= pInfoBar
->addButton();
1338 rWhatsNewButton
.set_label(SfxResId(STR_WHATSNEW_BUTTON
));
1339 rWhatsNewButton
.connect_clicked(LINK(this, SfxViewFrame
, WhatsNewHandler
));
1341 //update lastversion
1342 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(comphelper::ConfigurationChanges::create());
1343 officecfg::Setup::Product::ooSetupLastVersion::set(sSetupVersion
, batch
);
1347 // show tip-of-the-day dialog
1348 const bool bShowTipOfTheDay
= officecfg::Office::Common::Misc::ShowTipOfTheDay::get();
1349 if (bShowTipOfTheDay
&& !Application::IsHeadlessModeEnabled() && !bIsUITest
) {
1350 const sal_Int32 nLastTipOfTheDay
= officecfg::Office::Common::Misc::LastTipOfTheDayShown::get();
1351 const sal_Int32 nDay
= std::chrono::duration_cast
<std::chrono::hours
>(t0
).count()/24; // days since 1970-01-01
1352 if (nDay
-nLastTipOfTheDay
> 0) { //only once per day
1353 // tdf#127946 pass in argument for dialog parent
1354 SfxUnoFrameItem
aDocFrame(SID_FILLFRAME
, GetFrame().GetFrameInterface());
1355 GetDispatcher()->ExecuteList(SID_TIPOFTHEDAY
, SfxCallMode::SLOT
, {}, { &aDocFrame
});
1357 } //bShowTipOfTheDay
1359 // inform about the community involvement
1360 const sal_Int64 nLastGetInvolvedShown
= officecfg::Setup::Product::LastTimeGetInvolvedShown::get();
1361 const sal_Int64 nNow
= std::chrono::duration_cast
<std::chrono::seconds
>(t0
).count();
1362 const sal_Int64
nPeriodSec(60 * 60 * 24 * 180); // 180 days in seconds
1363 bool bUpdateLastTimeGetInvolvedShown
= false;
1365 if (nLastGetInvolvedShown
== 0)
1366 bUpdateLastTimeGetInvolvedShown
= true;
1367 else if (nPeriodSec
< nNow
&& nLastGetInvolvedShown
< (nNow
+ nPeriodSec
/2) - nPeriodSec
) // 90d alternating with donation
1369 bUpdateLastTimeGetInvolvedShown
= true;
1371 VclPtr
<SfxInfoBarWindow
> pInfoBar
= AppendInfoBar("getinvolved", "", SfxResId(STR_GET_INVOLVED_TEXT
), InfobarType::INFO
);
1375 weld::Button
& rGetInvolvedButton
= pInfoBar
->addButton();
1376 rGetInvolvedButton
.set_label(SfxResId(STR_GET_INVOLVED_BUTTON
));
1377 rGetInvolvedButton
.connect_clicked(LINK(this, SfxViewFrame
, GetInvolvedHandler
));
1381 if (bUpdateLastTimeGetInvolvedShown
1382 && !officecfg::Setup::Product::LastTimeGetInvolvedShown::isReadOnly())
1384 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(comphelper::ConfigurationChanges::create());
1385 officecfg::Setup::Product::LastTimeGetInvolvedShown::set(nNow
, batch
);
1389 // inform about donations
1390 const sal_Int64 nLastDonateShown
= officecfg::Setup::Product::LastTimeDonateShown::get();
1391 bool bUpdateLastTimeDonateShown
= false;
1393 if (nLastDonateShown
== 0)
1394 bUpdateLastTimeDonateShown
= true;
1395 else if (nPeriodSec
< nNow
&& nLastDonateShown
< nNow
- nPeriodSec
) // 90d alternating with getinvolved
1397 bUpdateLastTimeDonateShown
= true;
1399 VclPtr
<SfxInfoBarWindow
> pInfoBar
= AppendInfoBar("donate", "", SfxResId(STR_DONATE_TEXT
), InfobarType::INFO
);
1402 weld::Button
& rDonateButton
= pInfoBar
->addButton();
1403 rDonateButton
.set_label(SfxResId(STR_DONATE_BUTTON
));
1404 rDonateButton
.connect_clicked(LINK(this, SfxViewFrame
, DonationHandler
));
1408 if (bUpdateLastTimeDonateShown
1409 && !officecfg::Setup::Product::LastTimeDonateShown::isReadOnly())
1411 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(comphelper::ConfigurationChanges::create());
1412 officecfg::Setup::Product::LastTimeDonateShown::set(nNow
, batch
);
1416 // read-only infobar if necessary
1417 const SfxViewShell
*pVSh
;
1418 const SfxShell
*pFSh
;
1419 if ( m_xObjSh
->IsReadOnly() &&
1420 ! m_xObjSh
->IsSecurityOptOpenReadOnly() &&
1421 ( m_xObjSh
->GetCreateMode() != SfxObjectCreateMode::EMBEDDED
||
1422 (( pVSh
= m_xObjSh
->GetViewShell()) && (pFSh
= pVSh
->GetFormShell()) && pFSh
->IsDesignMode())))
1424 AppendReadOnlyInfobar();
1427 if (vcl::CommandInfoProvider::GetModuleIdentifier(GetFrame().GetFrameInterface()) == "com.sun.star.text.TextDocument")
1428 sfx2::SfxNotebookBar::ReloadNotebookBar("modules/swriter/ui/");
1430 if (SfxClassificationHelper::IsClassified(m_xObjSh
->getDocProperties()))
1432 // Document has BAILS properties, display an infobar accordingly.
1433 SfxClassificationHelper
aHelper(m_xObjSh
->getDocProperties());
1434 aHelper
.UpdateInfobar(*this);
1437 // Add pending infobars
1438 std::vector
<InfobarData
>& aPendingInfobars
= m_xObjSh
->getPendingInfobars();
1439 while (!aPendingInfobars
.empty())
1441 InfobarData
& aInfobarData
= aPendingInfobars
.back();
1442 AppendInfoBar(aInfobarData
.msId
, aInfobarData
.msPrimaryMessage
,
1443 aInfobarData
.msSecondaryMessage
, aInfobarData
.maInfobarType
,
1444 aInfobarData
.mbShowCloseButton
);
1445 aPendingInfobars
.pop_back();
1455 switch( rHint
.GetId() )
1457 case SfxHintId::ModeChanged
:
1461 if ( !m_xObjSh
.is() )
1465 SfxBindings
& rBind
= GetBindings();
1466 rBind
.Invalidate( SID_RELOAD
);
1467 SfxDispatcher
*pDispat
= GetDispatcher();
1468 bool bWasReadOnly
= pDispat
->GetReadOnly_Impl();
1469 bool bIsReadOnly
= m_xObjSh
->IsReadOnly();
1470 if ( bWasReadOnly
!= bIsReadOnly
)
1472 // Then also TITLE_CHANGED
1474 rBind
.Invalidate( SID_FILE_NAME
);
1475 rBind
.Invalidate( SID_DOCINFO_TITLE
);
1476 rBind
.Invalidate( SID_EDITDOC
);
1478 pDispat
->GetBindings()->InvalidateAll(true);
1479 pDispat
->SetReadOnly_Impl( bIsReadOnly
);
1481 // Only force and Dispatcher-Update, if it is done next
1482 // anyway, otherwise flickering or GPF is possible since
1483 // the Writer for example prefers in Resize perform some
1484 // actions which has a SetReadOnlyUI in Dispatcher as a
1487 if ( pDispat
->IsUpdated_Impl() )
1488 pDispat
->Update_Impl(true);
1491 Enable( !m_xObjSh
->IsInModalMode() );
1495 case SfxHintId::TitleChanged
:
1498 SfxBindings
& rBind
= GetBindings();
1499 rBind
.Invalidate( SID_FILE_NAME
);
1500 rBind
.Invalidate( SID_DOCINFO_TITLE
);
1501 rBind
.Invalidate( SID_EDITDOC
);
1502 rBind
.Invalidate( SID_RELOAD
);
1506 case SfxHintId::DocumentRepair
:
1508 GetBindings().Invalidate( SID_DOC_REPAIR
);
1512 case SfxHintId::Deinitializing
:
1514 vcl::Window
* pFrameWin
= GetWindow().GetFrameWindow();
1515 if (pFrameWin
&& pFrameWin
->GetLOKNotifier())
1516 pFrameWin
->ReleaseLOKNotifier();
1518 GetFrame().DoClose();
1521 case SfxHintId::Dying
:
1522 // when the Object is being deleted, destroy the view too
1523 if ( m_xObjSh
.is() )
1524 ReleaseObjectShell_Impl();
1526 GetFrame().DoClose();
1533 IMPL_LINK_NOARG(SfxViewFrame
, WhatsNewHandler
, weld::Button
&, void)
1535 GetDispatcher()->Execute(SID_WHATSNEW
);
1538 IMPL_LINK_NOARG(SfxViewFrame
, GetInvolvedHandler
, weld::Button
&, void)
1540 GetDispatcher()->Execute(SID_GETINVOLVED
);
1543 IMPL_LINK_NOARG(SfxViewFrame
, DonationHandler
, weld::Button
&, void)
1545 GetDispatcher()->Execute(SID_DONATION
);
1548 IMPL_LINK(SfxViewFrame
, SwitchReadOnlyHandler
, weld::Button
&, rButton
, void)
1550 if (m_xObjSh
.is() && m_xObjSh
->IsSignPDF())
1552 SfxEditDocumentDialog
aDialog(&rButton
);
1553 if (aDialog
.run() != RET_OK
)
1556 GetDispatcher()->Execute(SID_EDITDOC
);
1559 IMPL_LINK_NOARG(SfxViewFrame
, SignDocumentHandler
, weld::Button
&, void)
1561 GetDispatcher()->Execute(SID_SIGNATURE
);
1564 void SfxViewFrame::Construct_Impl( SfxObjectShell
*pObjSh
)
1566 m_pImpl
->bResizeInToOut
= true;
1567 m_pImpl
->bObjLocked
= false;
1568 m_pImpl
->nCurViewId
= SFX_INTERFACE_NONE
;
1569 m_pImpl
->bReloading
= false;
1570 m_pImpl
->bIsDowning
= false;
1571 m_pImpl
->bModal
= false;
1572 m_pImpl
->bEnabled
= true;
1573 m_pImpl
->nDocViewNo
= 0;
1574 m_pImpl
->aMargin
= Size( -1, -1 );
1575 m_pImpl
->pWindow
= nullptr;
1577 SetPool( &SfxGetpApp()->GetPool() );
1578 m_pDispatcher
.reset( new SfxDispatcher(this) );
1579 if ( !GetBindings().GetDispatcher() )
1580 GetBindings().SetDispatcher( m_pDispatcher
.get() );
1583 if ( m_xObjSh
.is() && m_xObjSh
->IsPreview() )
1584 GetDispatcher()->SetQuietMode_Impl( true );
1588 m_pDispatcher
->Push( *SfxGetpApp() );
1589 SfxModule
* pModule
= m_xObjSh
->GetModule();
1591 m_pDispatcher
->Push( *pModule
);
1592 m_pDispatcher
->Push( *this );
1593 m_pDispatcher
->Push( *pObjSh
);
1594 m_pDispatcher
->Flush();
1595 StartListening( *pObjSh
);
1596 Notify( *pObjSh
, SfxHint(SfxHintId::TitleChanged
) );
1597 Notify( *pObjSh
, SfxHint(SfxHintId::DocChanged
) );
1598 m_pDispatcher
->SetReadOnly_Impl( pObjSh
->IsReadOnly() );
1602 m_pDispatcher
->Push( *SfxGetpApp() );
1603 m_pDispatcher
->Push( *this );
1604 m_pDispatcher
->Flush();
1607 SfxViewFrameArr_Impl
&rViewArr
= SfxGetpApp()->GetViewFrames_Impl();
1608 rViewArr
.push_back( this );
1613 Constructor of SfxViewFrame for a <SfxObjectShell> from the Resource.
1614 The 'nViewId' to the created <SfxViewShell> can be returned.
1615 (default is the SfxViewShell-Subclass that was registered first).
1617 SfxViewFrame::SfxViewFrame
1620 SfxObjectShell
* pObjShell
1622 : m_pImpl( new SfxViewFrame_Impl( rFrame
) )
1623 , m_pBindings( new SfxBindings
)
1624 , m_pHelpData(CreateSVHelpData())
1625 , m_pWinData(CreateSVWinData())
1626 , m_nAdjustPosPixelLock( 0 )
1629 rFrame
.SetCurrentViewFrame_Impl( this );
1630 rFrame
.SetHasTitle( true );
1631 Construct_Impl( pObjShell
);
1633 m_pImpl
->pWindow
= VclPtr
<SfxFrameViewWindow_Impl
>::Create( this, rFrame
.GetWindow() );
1634 m_pImpl
->pWindow
->SetSizePixel( rFrame
.GetWindow().GetOutputSizePixel() );
1635 rFrame
.SetOwnsBindings_Impl( true );
1636 rFrame
.CreateWorkWindow_Impl();
1639 SfxViewFrame::~SfxViewFrame()
1641 m_pImpl
->bIsDowning
= true;
1643 if ( SfxViewFrame::Current() == this )
1644 SfxViewFrame::SetViewFrame( nullptr );
1646 ReleaseObjectShell_Impl();
1648 if ( GetFrame().OwnsBindings_Impl() )
1649 // The Bindings delete the Frame!
1650 KillDispatcher_Impl();
1652 m_pImpl
->pWindow
.disposeAndClear();
1654 if ( GetFrame().GetCurrentViewFrame() == this )
1655 GetFrame().SetCurrentViewFrame_Impl( nullptr );
1657 // Unregister from the Frame List.
1658 SfxApplication
*pSfxApp
= SfxApplication::Get();
1661 SfxViewFrameArr_Impl
&rFrames
= pSfxApp
->GetViewFrames_Impl();
1662 SfxViewFrameArr_Impl::iterator it
= std::find( rFrames
.begin(), rFrames
.end(), this );
1663 rFrames
.erase( it
);
1667 KillDispatcher_Impl();
1669 DestroySVHelpData(m_pHelpData
);
1670 m_pHelpData
= nullptr;
1672 DestroySVWinData(m_pWinData
);
1673 m_pWinData
= nullptr;
1676 // Remove and delete the Dispatcher.
1677 void SfxViewFrame::KillDispatcher_Impl()
1680 SfxModule
* pModule
= m_xObjSh
.is() ? m_xObjSh
->GetModule() : nullptr;
1681 if ( m_xObjSh
.is() )
1682 ReleaseObjectShell_Impl();
1683 if ( m_pDispatcher
)
1686 m_pDispatcher
->Pop( *pModule
, SfxDispatcherPopFlags::POP_UNTIL
);
1688 m_pDispatcher
->Pop( *this );
1689 m_pDispatcher
.reset();
1693 SfxViewFrame
* SfxViewFrame::Current()
1695 SfxApplication
* pApp
= SfxApplication::Get();
1696 return pApp
? pApp
->Get_Impl()->pViewFrame
: nullptr;
1699 // returns the first window of spec. type viewing the specified doc.
1700 SfxViewFrame
* SfxViewFrame::GetFirst
1702 const SfxObjectShell
* pDoc
,
1706 SfxApplication
*pSfxApp
= SfxApplication::Get();
1710 SfxViewFrameArr_Impl
&rFrames
= pSfxApp
->GetViewFrames_Impl();
1712 // search for a SfxDocument of the specified type
1713 for (SfxViewFrame
* pFrame
: rFrames
)
1715 if ( ( !pDoc
|| pDoc
== pFrame
->GetObjectShell() )
1716 && ( !bOnlyIfVisible
|| pFrame
->IsVisible() )
1724 // returns the next window of spec. type viewing the specified doc.
1725 SfxViewFrame
* SfxViewFrame::GetNext
1727 const SfxViewFrame
& rPrev
,
1728 const SfxObjectShell
* pDoc
,
1732 SfxApplication
*pSfxApp
= SfxApplication::Get();
1736 SfxViewFrameArr_Impl
&rFrames
= pSfxApp
->GetViewFrames_Impl();
1738 // refind the specified predecessor
1740 for ( nPos
= 0; nPos
< rFrames
.size(); ++nPos
)
1741 if ( rFrames
[nPos
] == &rPrev
)
1744 // search for a Frame of the specified type
1745 for ( ++nPos
; nPos
< rFrames
.size(); ++nPos
)
1747 SfxViewFrame
*pFrame
= rFrames
[nPos
];
1748 if ( ( !pDoc
|| pDoc
== pFrame
->GetObjectShell() )
1749 && ( !bOnlyIfVisible
|| pFrame
->IsVisible() )
1756 SfxProgress
* SfxViewFrame::GetProgress() const
1758 SfxObjectShell
*pObjSh
= m_xObjSh
.get();
1759 return pObjSh
? pObjSh
->GetProgress() : nullptr;
1762 void SfxViewFrame::DoAdjustPosSizePixel
//! divide on Inner.../Outer...
1767 bool inplaceEditModeChange
1771 // Components do not use this Method!
1772 if( pSh
&& pSh
->GetWindow() && !m_nAdjustPosPixelLock
)
1774 m_nAdjustPosPixelLock
++;
1775 if ( m_pImpl
->bResizeInToOut
)
1776 pSh
->InnerResizePixel( rPos
, rSize
, inplaceEditModeChange
);
1778 pSh
->OuterResizePixel( rPos
, rSize
);
1779 m_nAdjustPosPixelLock
--;
1783 bool SfxViewFrameItem::operator==( const SfxPoolItem
&rItem
) const
1785 return SfxPoolItem::operator==(rItem
) &&
1786 static_cast<const SfxViewFrameItem
&>(rItem
).pFrame
== pFrame
;
1789 SfxViewFrameItem
* SfxViewFrameItem::Clone( SfxItemPool
*) const
1791 return new SfxViewFrameItem( *this );
1794 void SfxViewFrame::SetViewShell_Impl( SfxViewShell
*pVSh
)
1797 Internal Method to set the current <SfxViewShell> Instance,
1798 that is active int this SfxViewFrame at the moment.
1801 SfxShell::SetViewShell_Impl( pVSh
);
1803 // Hack: InPlaceMode
1805 m_pImpl
->bResizeInToOut
= false;
1808 void SfxViewFrame::ForceOuterResize_Impl()
1810 m_pImpl
->bResizeInToOut
= true;
1813 void SfxViewFrame::GetDocNumber_Impl()
1815 DBG_ASSERT( GetObjectShell(), "No Document!" );
1816 GetObjectShell()->SetNamedVisibility_Impl();
1817 m_pImpl
->nDocViewNo
= GetObjectShell()->GetNoSet_Impl().GetFreeIndex()+1;
1820 void SfxViewFrame::Enable( bool bEnable
)
1822 if ( bEnable
== m_pImpl
->bEnabled
)
1825 m_pImpl
->bEnabled
= bEnable
;
1827 vcl::Window
*pWindow
= &GetFrame().GetWindow();
1829 m_pImpl
->bWindowWasEnabled
= pWindow
->IsInputEnabled();
1830 if ( !bEnable
|| m_pImpl
->bWindowWasEnabled
)
1831 pWindow
->EnableInput( bEnable
);
1834 SfxViewShell
* pViewSh
= GetViewShell();
1839 pViewSh
->ShowCursor();
1845 pViewSh
->ShowCursor(false);
1851 This method makes the Frame-Window visible and before transmits the
1852 window name. In addition, the document is held. In general one can never
1853 show the window directly!
1855 void SfxViewFrame::Show()
1857 // First lock the objectShell so that UpdateTitle() is valid:
1858 // IsVisible() == true (:#)
1859 if ( m_xObjSh
.is() )
1861 m_xObjSh
->GetMedium()->GetItemSet()->ClearItem( SID_HIDDEN
);
1862 if ( !m_pImpl
->bObjLocked
)
1863 LockObjectShell_Impl();
1865 // Adjust Doc-Shell title number, get unique view-no
1866 if ( 0 == m_pImpl
->nDocViewNo
)
1868 GetDocNumber_Impl();
1875 // Display Frame-window, but only if the ViewFrame has no window of its
1876 // own or if it does not contain a Component
1878 GetFrame().GetWindow().Show();
1882 bool SfxViewFrame::IsVisible() const
1884 return m_pImpl
->bObjLocked
;
1888 void SfxViewFrame::LockObjectShell_Impl()
1890 DBG_ASSERT( !m_pImpl
->bObjLocked
, "Wrong Locked status!" );
1892 DBG_ASSERT( GetObjectShell(), "No Document!" );
1893 GetObjectShell()->OwnerLock(true);
1894 m_pImpl
->bObjLocked
= true;
1898 void SfxViewFrame::MakeActive_Impl( bool bGrabFocus
)
1900 if ( !GetViewShell() || GetFrame().IsClosing_Impl() )
1906 bool bPreview
= false;
1907 if (GetObjectShell()->IsPreview())
1912 css::uno::Reference
<css::frame::XFrame
> xFrame
= GetFrame().GetFrameInterface();
1916 GetBindings().SetActiveFrame(css::uno::Reference
<css::frame::XFrame
>());
1917 uno::Reference
<frame::XFramesSupplier
> xSupp(xFrame
, uno::UNO_QUERY
);
1919 xSupp
->setActiveFrame(uno::Reference
<frame::XFrame
>());
1921 css::uno::Reference
< css::awt::XWindow
> xContainerWindow
= xFrame
->getContainerWindow();
1922 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow(xContainerWindow
);
1923 if (pWindow
&& pWindow
->HasChildPathFocus() && bGrabFocus
)
1925 SfxInPlaceClient
*pCli
= GetViewShell()->GetUIActiveClient();
1926 if (!pCli
|| !pCli
->IsObjectUIActive())
1927 GetFrame().GrabFocusOnComponent_Impl();
1932 GetBindings().SetDispatcher(GetDispatcher());
1933 GetBindings().SetActiveFrame(css::uno::Reference
<css::frame::XFrame
>());
1934 GetDispatcher()->Update_Impl();
1938 SfxObjectShell
* SfxViewFrame::GetObjectShell()
1940 return m_xObjSh
.get();
1943 const Size
& SfxViewFrame::GetMargin_Impl() const
1945 return m_pImpl
->aMargin
;
1948 SfxViewFrame
* SfxViewFrame::LoadViewIntoFrame_Impl_NoThrow( const SfxObjectShell
& i_rDoc
, const Reference
< XFrame
>& i_rFrame
,
1949 const SfxInterfaceId i_nViewId
, const bool i_bHidden
)
1951 Reference
< XFrame
> xFrame( i_rFrame
);
1952 bool bOwnFrame
= false;
1953 SfxViewShell
* pSuccessView
= nullptr;
1958 Reference
< XDesktop2
> xDesktop
= Desktop::create( ::comphelper::getProcessComponentContext() );
1964 // if there is a backing component, use it
1965 ::framework::FrameListAnalyzer
aAnalyzer( xDesktop
, Reference
< XFrame
>(), FrameAnalyzerFlags::BackingComponent
);
1967 if ( aAnalyzer
.m_xBackingComponent
.is() )
1968 xFrame
= aAnalyzer
.m_xBackingComponent
;
1970 catch( uno::Exception
& )
1975 xFrame
.set( xDesktop
->findFrame( "_blank", 0 ), UNO_SET_THROW
);
1980 pSuccessView
= LoadViewIntoFrame_Impl(
1983 Sequence
< PropertyValue
>(), // means "reuse existing model's args"
1988 if ( bOwnFrame
&& !i_bHidden
)
1990 // ensure the frame/window is visible
1991 Reference
< XWindow
> xContainerWindow( xFrame
->getContainerWindow(), UNO_SET_THROW
);
1992 xContainerWindow
->setVisible( true );
1995 catch( const Exception
& )
1997 DBG_UNHANDLED_EXCEPTION("sfx.view");
2001 return pSuccessView
->GetViewFrame();
2009 catch( const Exception
& )
2011 DBG_UNHANDLED_EXCEPTION("sfx.view");
2018 SfxViewShell
* SfxViewFrame::LoadViewIntoFrame_Impl( const SfxObjectShell
& i_rDoc
, const Reference
< XFrame
>& i_rFrame
,
2019 const Sequence
< PropertyValue
>& i_rLoadArgs
, const SfxInterfaceId i_nViewId
,
2020 const bool i_bHidden
)
2022 Reference
< XModel
> xDocument( i_rDoc
.GetModel(), UNO_SET_THROW
);
2024 ::comphelper::NamedValueCollection
aTransformLoadArgs( i_rLoadArgs
.hasElements() ? i_rLoadArgs
: xDocument
->getArgs() );
2025 aTransformLoadArgs
.put( "Model", xDocument
);
2027 aTransformLoadArgs
.put( "ViewId", sal_uInt16( i_nViewId
) );
2029 aTransformLoadArgs
.put( "Hidden", i_bHidden
);
2031 aTransformLoadArgs
.remove( "Hidden" );
2033 Reference
< XComponentLoader
> xLoader( i_rFrame
, UNO_QUERY_THROW
);
2034 xLoader
->loadComponentFromURL( "private:object", "_self", 0,
2035 aTransformLoadArgs
.getPropertyValues() );
2037 SfxViewShell
* pViewShell
= SfxViewShell::Get( i_rFrame
->getController() );
2038 ENSURE_OR_THROW( pViewShell
,
2039 "SfxViewFrame::LoadViewIntoFrame_Impl: loading an SFX doc into a frame resulted in a non-SFX view - quite impossible" );
2043 SfxViewFrame
* SfxViewFrame::LoadHiddenDocument( SfxObjectShell
const & i_rDoc
, SfxInterfaceId i_nViewId
)
2045 return LoadViewIntoFrame_Impl_NoThrow( i_rDoc
, Reference
< XFrame
>(), i_nViewId
, true );
2048 SfxViewFrame
* SfxViewFrame::LoadDocument( SfxObjectShell
const & i_rDoc
, SfxInterfaceId i_nViewId
)
2050 return LoadViewIntoFrame_Impl_NoThrow( i_rDoc
, Reference
< XFrame
>(), i_nViewId
, false );
2053 SfxViewFrame
* SfxViewFrame::LoadDocumentIntoFrame( SfxObjectShell
const & i_rDoc
, const Reference
< XFrame
>& i_rTargetFrame
)
2055 return LoadViewIntoFrame_Impl_NoThrow( i_rDoc
, i_rTargetFrame
, SFX_INTERFACE_NONE
, false );
2058 SfxViewFrame
* SfxViewFrame::LoadDocumentIntoFrame( SfxObjectShell
const & i_rDoc
, const SfxFrameItem
* i_pFrameItem
, SfxInterfaceId i_nViewId
)
2060 return LoadViewIntoFrame_Impl_NoThrow( i_rDoc
, i_pFrameItem
&& i_pFrameItem
->GetFrame() ? i_pFrameItem
->GetFrame()->GetFrameInterface() : nullptr, i_nViewId
, false );
2063 SfxViewFrame
* SfxViewFrame::DisplayNewDocument( SfxObjectShell
const & i_rDoc
, const SfxRequest
& i_rCreateDocRequest
)
2065 const SfxUnoFrameItem
* pFrameItem
= i_rCreateDocRequest
.GetArg
<SfxUnoFrameItem
>(SID_FILLFRAME
);
2066 const SfxBoolItem
* pHiddenItem
= i_rCreateDocRequest
.GetArg
<SfxBoolItem
>(SID_HIDDEN
);
2068 return LoadViewIntoFrame_Impl_NoThrow(
2070 pFrameItem
? pFrameItem
->GetFrame() : nullptr,
2072 pHiddenItem
&& pHiddenItem
->GetValue()
2076 SfxViewFrame
* SfxViewFrame::Get( const Reference
< XController
>& i_rController
, const SfxObjectShell
* i_pDoc
)
2078 if ( !i_rController
.is() )
2081 const SfxObjectShell
* pDoc
= i_pDoc
;
2084 Reference
< XModel
> xDocument( i_rController
->getModel() );
2085 for ( pDoc
= SfxObjectShell::GetFirst( nullptr, false );
2087 pDoc
= SfxObjectShell::GetNext( *pDoc
, nullptr, false )
2090 if ( pDoc
->GetModel() == xDocument
)
2095 SfxViewFrame
* pViewFrame
= nullptr;
2096 for ( pViewFrame
= SfxViewFrame::GetFirst( pDoc
, false );
2098 pViewFrame
= SfxViewFrame::GetNext( *pViewFrame
, pDoc
, false )
2101 if ( pViewFrame
->GetViewShell()->GetController() == i_rController
)
2108 void SfxViewFrame::SaveCurrentViewData_Impl( const SfxInterfaceId i_nNewViewId
)
2110 SfxViewShell
* pCurrentShell
= GetViewShell();
2111 ENSURE_OR_RETURN_VOID( pCurrentShell
!= nullptr, "SfxViewFrame::SaveCurrentViewData_Impl: no current view shell -> no current view data!" );
2113 // determine the logical (API) view name
2114 const SfxObjectFactory
& rDocFactory( pCurrentShell
->GetObjectShell()->GetFactory() );
2115 const sal_uInt16 nCurViewNo
= rDocFactory
.GetViewNo_Impl( GetCurViewId(), 0 );
2116 const OUString sCurrentViewName
= rDocFactory
.GetViewFactory( nCurViewNo
).GetAPIViewName();
2117 const sal_uInt16 nNewViewNo
= rDocFactory
.GetViewNo_Impl( i_nNewViewId
, 0 );
2118 const OUString sNewViewName
= rDocFactory
.GetViewFactory( nNewViewNo
).GetAPIViewName();
2119 if ( sCurrentViewName
.isEmpty() || sNewViewName
.isEmpty() )
2121 // can't say anything about the view, the respective application did not yet migrate its code to
2122 // named view factories => bail out
2123 OSL_FAIL( "SfxViewFrame::SaveCurrentViewData_Impl: views without API names? Shouldn't happen anymore?" );
2126 SAL_WARN_IF(sNewViewName
== sCurrentViewName
, "sfx.view", "SfxViewFrame::SaveCurrentViewData_Impl: suspicious: new and old view name are identical!");
2128 // save the view data only when we're moving from a non-print-preview to the print-preview view
2129 if ( sNewViewName
!= "PrintPreview" )
2132 // retrieve the view data from the view
2133 Sequence
< PropertyValue
> aViewData
;
2134 pCurrentShell
->WriteUserDataSequence( aViewData
);
2138 // retrieve view data (for *all* views) from the model
2139 const Reference
< XController
> xController( pCurrentShell
->GetController(), UNO_SET_THROW
);
2140 const Reference
< XViewDataSupplier
> xViewDataSupplier( xController
->getModel(), UNO_QUERY_THROW
);
2141 const Reference
< XIndexContainer
> xViewData( xViewDataSupplier
->getViewData(), UNO_QUERY_THROW
);
2143 // look up the one view data item which corresponds to our current view, and remove it
2144 const sal_Int32 nCount
= xViewData
->getCount();
2145 for ( sal_Int32 i
=0; i
<nCount
; ++i
)
2147 const ::comphelper::NamedValueCollection
aCurViewData( xViewData
->getByIndex(i
) );
2148 const OUString
sViewId( aCurViewData
.getOrDefault( "ViewId", OUString() ) );
2149 if ( sViewId
.isEmpty() )
2152 const SfxViewFactory
* pViewFactory
= rDocFactory
.GetViewFactoryByViewName( sViewId
);
2153 if ( pViewFactory
== nullptr )
2156 if ( pViewFactory
->GetOrdinal() == GetCurViewId() )
2158 xViewData
->removeByIndex(i
);
2163 // then replace it with the most recent view data we just obtained
2164 xViewData
->insertByIndex( 0, makeAny( aViewData
) );
2166 catch( const Exception
& )
2168 DBG_UNHANDLED_EXCEPTION("sfx.view");
2174 Internal Method for switching to another <SfxViewShell> subclass,
2175 which should be created in this SfxMDIFrame. If no SfxViewShell exist
2176 in this SfxMDIFrame, then one will first be created.
2182 requested SfxViewShell was created and a
2183 possibly existing one deleted
2186 SfxViewShell requested could not be created,
2187 the existing SfxViewShell thus continue to exist
2189 bool SfxViewFrame::SwitchToViewShell_Impl
2191 sal_uInt16 nViewIdOrNo
, /* > 0
2192 Registration-Id of the View, to which the
2193 method should switch, for example the one
2194 that will be created.
2197 First use the Default view. */
2199 bool bIsIndex
/* true
2200 'nViewIdOrNo' is no Registration-Id instead
2201 an Index of <SfxViewFrame> in <SfxObjectShell>.
2207 ENSURE_OR_THROW( GetObjectShell() != nullptr, "not possible without a document" );
2209 // if we already have a view shell, remove it
2210 SfxViewShell
* pOldSh
= GetViewShell();
2211 OSL_PRECOND( pOldSh
, "SfxViewFrame::SwitchToViewShell_Impl: that's called *switch* (not for *initial-load*) for a reason" );
2214 // ask whether it can be closed
2215 if ( !pOldSh
->PrepareClose() )
2218 // remove sub shells from Dispatcher before switching to new ViewShell
2219 PopShellAndSubShells_Impl( *pOldSh
);
2222 GetBindings().ENTERREGISTRATIONS();
2223 LockAdjustPosSizePixel();
2225 // ID of the new view
2226 SfxObjectFactory
& rDocFact
= GetObjectShell()->GetFactory();
2227 const SfxInterfaceId nViewId
= ( bIsIndex
|| !nViewIdOrNo
) ? rDocFact
.GetViewFactory( nViewIdOrNo
).GetOrdinal() : SfxInterfaceId(nViewIdOrNo
);
2229 // save the view data of the old view, so it can be restored later on (when needed)
2230 SaveCurrentViewData_Impl( nViewId
);
2232 // create and load new ViewShell
2233 SfxViewShell
* pNewSh
= LoadViewIntoFrame_Impl(
2235 GetFrame().GetFrameInterface(),
2236 Sequence
< PropertyValue
>(), // means "reuse existing model's args"
2241 // allow resize events to be processed
2242 UnlockAdjustPosSizePixel();
2244 if ( GetWindow().IsReallyVisible() )
2245 DoAdjustPosSizePixel( pNewSh
, Point(), GetWindow().GetOutputSizePixel(), false );
2247 GetBindings().LEAVEREGISTRATIONS();
2250 catch ( const css::uno::Exception
& )
2252 // the SfxCode is not able to cope with exceptions thrown while creating views
2253 // the code will crash in the stack unwinding procedure, so we shouldn't let exceptions go through here
2254 DBG_UNHANDLED_EXCEPTION("sfx.view");
2258 DBG_ASSERT( SfxGetpApp()->GetViewFrames_Impl().size() == SfxGetpApp()->GetViewShells_Impl().size(), "Inconsistent view arrays!" );
2262 void SfxViewFrame::SetCurViewId_Impl( const SfxInterfaceId i_nID
)
2264 m_pImpl
->nCurViewId
= i_nID
;
2267 SfxInterfaceId
SfxViewFrame::GetCurViewId() const
2269 return m_pImpl
->nCurViewId
;
2274 Internal method to run the slot for the <SfxShell> Subclass in the
2275 SfxViewFrame <SVIDL> described slots.
2277 void SfxViewFrame::ExecView_Impl
2279 SfxRequest
& rReq
// The executable <SfxRequest>
2283 // If the Shells are just being replaced...
2284 if ( !GetObjectShell() || !GetViewShell() )
2287 switch ( rReq
.GetSlot() )
2289 case SID_TERMINATE_INPLACEACTIVATION
:
2291 SfxInPlaceClient
* pClient
= GetViewShell()->GetUIActiveClient();
2293 pClient
->DeactivateObject();
2299 const SfxPoolItem
*pItem
= nullptr;
2301 && SfxItemState::SET
== rReq
.GetArgs()->GetItemState( SID_VIEWSHELL
, false, &pItem
)
2304 const sal_uInt16 nViewId
= static_cast< const SfxUInt16Item
* >( pItem
)->GetValue();
2305 bool bSuccess
= SwitchToViewShell_Impl( nViewId
);
2306 rReq
.SetReturnValue( SfxBoolItem( 0, bSuccess
) );
2311 case SID_VIEWSHELL0
:
2312 case SID_VIEWSHELL1
:
2313 case SID_VIEWSHELL2
:
2314 case SID_VIEWSHELL3
:
2315 case SID_VIEWSHELL4
:
2317 const sal_uInt16 nViewNo
= rReq
.GetSlot() - SID_VIEWSHELL0
;
2318 bool bSuccess
= SwitchToViewShell_Impl( nViewNo
, true );
2319 rReq
.SetReturnValue( SfxBoolItem( 0, bSuccess
) );
2325 // Hack. at the moment a virtual Function
2326 if ( !GetViewShell()->NewWindowAllowed() )
2328 OSL_FAIL( "You should have disabled the 'Window/New Window' slot!" );
2332 // Get ViewData of FrameSets recursively.
2333 GetFrame().GetViewData_Impl();
2334 SfxMedium
* pMed
= GetObjectShell()->GetMedium();
2336 // do not open the new window hidden
2337 pMed
->GetItemSet()->ClearItem( SID_HIDDEN
);
2339 // the view ID (optional arg. TODO: this is currently not supported in the slot definition ...)
2340 const SfxUInt16Item
* pViewIdItem
= rReq
.GetArg
<SfxUInt16Item
>(SID_VIEW_ID
);
2341 const SfxInterfaceId nViewId
= pViewIdItem
? SfxInterfaceId(pViewIdItem
->GetValue()) : GetCurViewId();
2343 Reference
< XFrame
> xFrame
;
2344 // the frame (optional arg. TODO: this is currently not supported in the slot definition ...)
2345 const SfxUnoFrameItem
* pFrameItem
= rReq
.GetArg
<SfxUnoFrameItem
>(SID_FILLFRAME
);
2347 xFrame
= pFrameItem
->GetFrame();
2349 LoadViewIntoFrame_Impl_NoThrow( *GetObjectShell(), xFrame
, nViewId
, false );
2357 const SfxInt16Item
* pItem
= rReq
.GetArg
<SfxInt16Item
>(SID_OBJECT
);
2361 GetViewShell()->DoVerb( pItem
->GetValue() );
2370 This method try to collect information about the count of currently open documents.
2371 But the algorithm is implemented very simple ...
2372 E.g. hidden documents should be ignored here ... but they are counted.
2373 TODO: export special helper "framework::FrameListAnalyzer" within the framework module
2376 static bool impl_maxOpenDocCountReached()
2378 css::uno::Reference
< css::uno::XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
2379 std::optional
<sal_Int32
> x(officecfg::Office::Common::Misc::MaxOpenDocuments::get(xContext
));
2380 // NIL means: count of allowed documents = infinite !
2383 sal_Int32
nMaxDocs(*x
);
2384 sal_Int32 nOpenDocs
= 0;
2386 css::uno::Reference
< css::frame::XDesktop2
> xDesktop
= css::frame::Desktop::create(xContext
);
2387 css::uno::Reference
< css::container::XIndexAccess
> xCont(xDesktop
->getFrames(), css::uno::UNO_QUERY_THROW
);
2389 sal_Int32 c
= xCont
->getCount();
2396 css::uno::Reference
< css::frame::XFrame
> xFrame
;
2397 xCont
->getByIndex(i
) >>= xFrame
;
2401 // a) do not count the help window
2402 if ( xFrame
->getName() == "OFFICE_HELP_TASK" )
2405 // b) count all other frames
2408 catch(const css::uno::Exception
&)
2409 // An IndexOutOfBoundsException can happen in multithreaded
2410 // environments, where any other thread can change this
2415 return (nOpenDocs
>= nMaxDocs
);
2420 This internal method returns in 'rSet' the Status for the <SfxShell>
2421 Subclass SfxViewFrame in the <SVIDL> described <Slots>.
2423 Thus exactly those Slots-IDs that are recognized as being invalid by Sfx
2424 are included as Which-ranges in 'rSet'. If there exists a mapping for
2425 single slot-IDs of the <SfxItemPool> set in the shell, then the respective
2426 Which-IDs are used so that items can be replaced directly with a working
2427 Core::sun::com::star::script::Engine of the Which-IDs if possible. .
2429 void SfxViewFrame::StateView_Impl
2431 SfxItemSet
& rSet
/* empty <SfxItemSet> with <Which-Ranges>,
2432 which describes the Slot Ids */
2436 SfxObjectShell
*pDocSh
= GetObjectShell();
2439 // I'm just on reload and am yielding myself ...
2442 const sal_uInt16
*pRanges
= rSet
.GetRanges();
2443 assert(pRanges
&& "Set with no Range");
2446 sal_uInt16 nStartWhich
= *pRanges
++;
2447 sal_uInt16 nEndWhich
= *pRanges
++;
2448 for ( sal_uInt16 nWhich
= nStartWhich
; nWhich
<= nEndWhich
; ++nWhich
)
2454 rSet
.Put( SfxUInt16Item( nWhich
, sal_uInt16(m_pImpl
->nCurViewId
)) );
2458 case SID_VIEWSHELL0
:
2459 case SID_VIEWSHELL1
:
2460 case SID_VIEWSHELL2
:
2461 case SID_VIEWSHELL3
:
2462 case SID_VIEWSHELL4
:
2464 sal_uInt16 nViewNo
= nWhich
- SID_VIEWSHELL0
;
2465 if ( GetObjectShell()->GetFactory().GetViewFactoryCount() >
2466 nViewNo
&& !GetObjectShell()->IsInPlaceActive() )
2468 SfxViewFactory
&rViewFactory
=
2469 GetObjectShell()->GetFactory().GetViewFactory(nViewNo
);
2470 rSet
.Put( SfxBoolItem(
2471 nWhich
, m_pImpl
->nCurViewId
== rViewFactory
.GetOrdinal() ) );
2474 rSet
.DisableItem( nWhich
);
2480 if ( !GetViewShell()->NewWindowAllowed()
2481 || impl_maxOpenDocCountReached()
2483 rSet
.DisableItem( nWhich
);
2492 void SfxViewFrame::ToTop()
2494 GetFrame().Appear();
2500 GetFrame returns the Frame, in which the ViewFrame is located.
2502 SfxFrame
& SfxViewFrame::GetFrame() const
2504 return m_pImpl
->rFrame
;
2507 SfxViewFrame
* SfxViewFrame::GetTopViewFrame() const
2509 return GetFrame().GetCurrentViewFrame();
2512 vcl::Window
& SfxViewFrame::GetWindow() const
2514 return m_pImpl
->pWindow
? *m_pImpl
->pWindow
: GetFrame().GetWindow();
2517 bool SfxViewFrame::DoClose()
2519 return GetFrame().DoClose();
2522 OUString
SfxViewFrame::GetActualPresentationURL_Impl() const
2524 if ( m_xObjSh
.is() )
2525 return m_xObjSh
->GetMedium()->GetName();
2529 void SfxViewFrame::SetModalMode( bool bModal
)
2531 // no real modality for LOK
2532 if (comphelper::LibreOfficeKit::isActive())
2535 m_pImpl
->bModal
= bModal
;
2536 if ( m_xObjSh
.is() )
2538 for ( SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( m_xObjSh
.get() );
2539 !bModal
&& pFrame
; pFrame
= SfxViewFrame::GetNext( *pFrame
, m_xObjSh
.get() ) )
2540 bModal
= pFrame
->m_pImpl
->bModal
;
2541 m_xObjSh
->SetModalMode_Impl( bModal
);
2545 bool SfxViewFrame::IsInModalMode() const
2547 return m_pImpl
->bModal
|| GetFrame().GetWindow().IsInModalMode();
2550 void SfxViewFrame::Resize( bool bForce
)
2552 Size aSize
= GetWindow().GetOutputSizePixel();
2553 if ( !bForce
&& aSize
== m_pImpl
->aSize
)
2556 m_pImpl
->aSize
= aSize
;
2557 SfxViewShell
*pShell
= GetViewShell();
2560 if ( GetFrame().IsInPlace() )
2562 Point aPoint
= GetWindow().GetPosPixel();
2563 DoAdjustPosSizePixel( pShell
, aPoint
, aSize
, true );
2567 DoAdjustPosSizePixel( pShell
, Point(), aSize
, false );
2572 #if HAVE_FEATURE_SCRIPTING
2574 #define LINE_SEP 0x0A
2576 static void CutLines( OUString
& rStr
, sal_Int32 nStartLine
, sal_Int32 nLines
)
2578 sal_Int32 nStartPos
= 0;
2579 sal_Int32 nLine
= 0;
2580 while ( nLine
< nStartLine
)
2582 nStartPos
= rStr
.indexOf( LINE_SEP
, nStartPos
);
2583 if( nStartPos
== -1 )
2585 nStartPos
++; // not the \n.
2589 SAL_WARN_IF(nStartPos
== -1, "sfx.view", "CutLines: Start row not found!");
2591 if ( nStartPos
!= -1 )
2593 sal_Int32 nEndPos
= nStartPos
;
2594 for ( sal_Int32 i
= 0; i
< nLines
; i
++ )
2595 nEndPos
= rStr
.indexOf( LINE_SEP
, nEndPos
+1 );
2597 if ( nEndPos
== -1 ) // Can happen at the last row.
2598 nEndPos
= rStr
.getLength();
2602 rStr
= OUString::Concat(rStr
.subView( 0, nStartPos
)) + rStr
.subView( nEndPos
);
2604 // erase trailing lines
2605 if ( nStartPos
!= -1 )
2607 sal_Int32 n
= nStartPos
;
2608 sal_Int32 nLen
= rStr
.getLength();
2609 while ( ( n
< nLen
) && ( rStr
[ n
] == LINE_SEP
) )
2612 if ( n
> nStartPos
)
2613 rStr
= OUString::Concat(rStr
.subView( 0, nStartPos
)) + rStr
.subView( n
);
2620 add new recorded dispatch macro script into the application global basic
2621 lib container. It generates a new unique id for it and insert the macro
2622 by using this number as name for the module
2624 void SfxViewFrame::AddDispatchMacroToBasic_Impl( const OUString
& sMacro
)
2626 #if !HAVE_FEATURE_SCRIPTING
2629 if ( sMacro
.isEmpty() )
2632 SfxApplication
* pSfxApp
= SfxGetpApp();
2633 SfxItemPool
& rPool
= pSfxApp
->GetPool();
2634 SfxRequest
aReq(SID_BASICCHOOSER
, SfxCallMode::SYNCHRON
, rPool
);
2636 //seen in tdf#122598, no parent for subsequent dialog
2637 SfxAllItemSet
aSet(rPool
);
2638 css::uno::Reference
< css::frame::XFrame
> xFrame
=
2639 GetFrame().GetFrameInterface();
2640 aSet
.Put(SfxUnoFrameItem(SID_FILLFRAME
, xFrame
));
2641 aReq
.SetInternalArgs_Impl(aSet
);
2643 aReq
.AppendItem( SfxBoolItem(SID_RECORDMACRO
,true) );
2644 const SfxPoolItem
* pRet
= SfxGetpApp()->ExecuteSlot( aReq
);
2645 OUString aScriptURL
;
2647 aScriptURL
= static_cast<const SfxStringItem
*>(pRet
)->GetValue();
2648 if ( !aScriptURL
.isEmpty() )
2652 OUString aModuleName
;
2653 OUString aMacroName
;
2655 Reference
< XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
2656 Reference
< css::uri::XUriReferenceFactory
> xFactory
=
2657 css::uri::UriReferenceFactory::create( xContext
);
2658 Reference
< css::uri::XVndSunStarScriptUrl
> xUrl( xFactory
->parse( aScriptURL
), UNO_QUERY
);
2662 const OUString aName
= xUrl
->getName();
2663 const sal_Unicode cTok
= '.';
2664 sal_Int32 nIndex
= 0;
2665 aLibName
= aName
.getToken( 0, cTok
, nIndex
);
2667 aModuleName
= aName
.getToken( 0, cTok
, nIndex
);
2669 aMacroName
= aName
.getToken( 0, cTok
, nIndex
);
2672 aLocation
= xUrl
->getParameter( "location" );
2675 BasicManager
* pBasMgr
= nullptr;
2676 if ( aLocation
== "application" )
2678 // application basic
2679 pBasMgr
= SfxApplication::GetBasicManager();
2681 else if ( aLocation
== "document" )
2683 pBasMgr
= GetObjectShell()->GetBasicManager();
2689 StarBASIC
* pBasic
= pBasMgr
->GetLib( aLibName
);
2692 SbModule
* pModule
= pBasic
->FindModule( aModuleName
);
2693 SbMethod
* pMethod
= pModule
? pModule
->FindMethod(aMacroName
, SbxClassType::Method
) : nullptr;
2696 aOUSource
= pModule
->GetSource32();
2697 sal_uInt16 nStart
, nEnd
;
2698 pMethod
->GetLineRange( nStart
, nEnd
);
2699 sal_uInt16 nlStart
= nStart
;
2700 sal_uInt16 nlEnd
= nEnd
;
2701 CutLines( aOUSource
, nlStart
-1, nlEnd
-nlStart
+1 );
2706 // open lib container and break operation if it couldn't be opened
2707 css::uno::Reference
< css::script::XLibraryContainer
> xLibCont
;
2708 if ( aLocation
== "application" )
2710 xLibCont
= SfxGetpApp()->GetBasicContainer();
2712 else if ( aLocation
== "document" )
2714 xLibCont
= GetObjectShell()->GetBasicContainer();
2719 SAL_WARN("sfx.view", "couldn't get access to the basic lib container. Adding of macro isn't possible.");
2723 // get LibraryContainer
2724 css::uno::Any aTemp
;
2726 css::uno::Reference
< css::container::XNameAccess
> xLib
;
2727 if(xLibCont
->hasByName(aLibName
))
2729 // library must be loaded
2730 aTemp
= xLibCont
->getByName(aLibName
);
2731 xLibCont
->loadLibrary(aLibName
);
2736 xLib
= xLibCont
->createLibrary(aLibName
);
2739 // pack the macro as direct usable "sub" routine
2740 OUStringBuffer
sRoutine(10000);
2741 bool bReplace
= false;
2744 if(xLib
->hasByName(aModuleName
))
2746 if ( !aOUSource
.isEmpty() )
2748 sRoutine
.append( aOUSource
);
2753 aTemp
= xLib
->getByName(aModuleName
);
2755 sRoutine
.append( sCode
);
2761 // append new method
2762 sRoutine
.append( "\nsub " );
2763 sRoutine
.append(aMacroName
);
2764 sRoutine
.append( "\n" );
2765 sRoutine
.append(sMacro
);
2766 sRoutine
.append( "\nend sub\n" );
2768 // create the module inside the library and insert the macro routine
2769 aTemp
<<= sRoutine
.makeStringAndClear();
2772 css::uno::Reference
< css::container::XNameContainer
> xModulCont(
2774 css::uno::UNO_QUERY
);
2775 xModulCont
->replaceByName(aModuleName
,aTemp
);
2779 css::uno::Reference
< css::container::XNameContainer
> xModulCont(
2781 css::uno::UNO_QUERY
);
2782 xModulCont
->insertByName(aModuleName
,aTemp
);
2785 // #i17355# update the Basic IDE
2786 for ( SfxViewShell
* pViewShell
= SfxViewShell::GetFirst(); pViewShell
; pViewShell
= SfxViewShell::GetNext( *pViewShell
) )
2788 if ( pViewShell
->GetName() == "BasicIDE" )
2790 SfxViewFrame
* pViewFrame
= pViewShell
->GetViewFrame();
2791 SfxDispatcher
* pDispat
= pViewFrame
? pViewFrame
->GetDispatcher() : nullptr;
2794 SfxMacroInfoItem
aInfoItem( SID_BASICIDE_ARG_MACROINFO
, pBasMgr
, aLibName
, aModuleName
, OUString(), OUString() );
2795 pDispat
->ExecuteList(SID_BASICIDE_UPDATEMODULESOURCE
,
2796 SfxCallMode::SYNCHRON
, { &aInfoItem
});
2803 // add code for "session only" macro
2808 void SfxViewFrame::MiscExec_Impl( SfxRequest
& rReq
)
2810 switch ( rReq
.GetSlot() )
2812 case SID_STOP_RECORDING
:
2813 case SID_RECORDMACRO
:
2815 // try to find any active recorder on this frame
2816 const OUString
sProperty("DispatchRecorderSupplier");
2817 css::uno::Reference
< css::frame::XFrame
> xFrame
=
2818 GetFrame().GetFrameInterface();
2820 css::uno::Reference
< css::beans::XPropertySet
> xSet(xFrame
,css::uno::UNO_QUERY
);
2821 css::uno::Any aProp
= xSet
->getPropertyValue(sProperty
);
2822 css::uno::Reference
< css::frame::XDispatchRecorderSupplier
> xSupplier
;
2823 aProp
>>= xSupplier
;
2824 css::uno::Reference
< css::frame::XDispatchRecorder
> xRecorder
;
2826 xRecorder
= xSupplier
->getDispatchRecorder();
2828 bool bIsRecording
= xRecorder
.is();
2829 const SfxBoolItem
* pItem
= rReq
.GetArg
<SfxBoolItem
>(SID_RECORDMACRO
);
2830 if ( pItem
&& pItem
->GetValue() == bIsRecording
)
2833 if ( xRecorder
.is() )
2835 // disable active recording
2836 aProp
<<= css::uno::Reference
< css::frame::XDispatchRecorderSupplier
>();
2837 xSet
->setPropertyValue(sProperty
,aProp
);
2839 const SfxBoolItem
* pRecordItem
= rReq
.GetArg
<SfxBoolItem
>(FN_PARAM_1
);
2840 if ( !pRecordItem
|| !pRecordItem
->GetValue() )
2841 // insert script into basic library container of application
2842 AddDispatchMacroToBasic_Impl(xRecorder
->getRecordedMacro());
2844 xRecorder
->endRecording();
2845 xRecorder
= nullptr;
2846 GetBindings().SetRecorder_Impl( xRecorder
);
2848 SetChildWindow( SID_RECORDING_FLOATWINDOW
, false );
2849 if ( rReq
.GetSlot() != SID_RECORDMACRO
)
2850 GetBindings().Invalidate( SID_RECORDMACRO
);
2852 else if ( rReq
.GetSlot() == SID_RECORDMACRO
)
2855 css::uno::Reference
< css::uno::XComponentContext
> xContext(
2856 ::comphelper::getProcessComponentContext());
2858 xRecorder
= css::frame::DispatchRecorder::create( xContext
);
2860 xSupplier
= css::frame::DispatchRecorderSupplier::create( xContext
);
2862 xSupplier
->setDispatchRecorder(xRecorder
);
2863 xRecorder
->startRecording(xFrame
);
2864 aProp
<<= xSupplier
;
2865 xSet
->setPropertyValue(sProperty
,aProp
);
2866 GetBindings().SetRecorder_Impl( xRecorder
);
2867 SetChildWindow( SID_RECORDING_FLOATWINDOW
, true );
2874 case SID_TOGGLESTATUSBAR
:
2876 css::uno::Reference
< css::frame::XFrame
> xFrame
=
2877 GetFrame().GetFrameInterface();
2879 Reference
< css::beans::XPropertySet
> xPropSet( xFrame
, UNO_QUERY
);
2880 Reference
< css::frame::XLayoutManager
> xLayoutManager
;
2881 if ( xPropSet
.is() )
2885 Any aValue
= xPropSet
->getPropertyValue("LayoutManager");
2886 aValue
>>= xLayoutManager
;
2888 catch ( Exception
& )
2893 if ( xLayoutManager
.is() )
2895 const OUString
aStatusbarResString( "private:resource/statusbar/statusbar" );
2896 // Evaluate parameter.
2897 const SfxBoolItem
* pShowItem
= rReq
.GetArg
<SfxBoolItem
>(rReq
.GetSlot());
2900 bShow
= xLayoutManager
->isElementVisible( aStatusbarResString
);
2902 bShow
= pShowItem
->GetValue();
2906 xLayoutManager
->createElement( aStatusbarResString
);
2907 xLayoutManager
->showElement( aStatusbarResString
);
2910 xLayoutManager
->hideElement( aStatusbarResString
);
2913 rReq
.AppendItem( SfxBoolItem( SID_TOGGLESTATUSBAR
, bShow
) );
2919 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2920 case SID_WIN_FULLSCREEN
:
2922 const SfxBoolItem
* pItem
= rReq
.GetArg
<SfxBoolItem
>(rReq
.GetSlot());
2923 SfxViewFrame
*pTop
= GetTopViewFrame();
2926 WorkWindow
* pWork
= static_cast<WorkWindow
*>( pTop
->GetFrame().GetTopWindow_Impl() );
2929 css::uno::Reference
< css::frame::XFrame
> xFrame
=
2930 GetFrame().GetFrameInterface();
2932 Reference
< css::beans::XPropertySet
> xPropSet( xFrame
, UNO_QUERY
);
2933 Reference
< css::frame::XLayoutManager
> xLayoutManager
;
2934 if ( xPropSet
.is() )
2938 Any aValue
= xPropSet
->getPropertyValue("LayoutManager");
2939 aValue
>>= xLayoutManager
;
2941 catch ( Exception
& )
2946 bool bNewFullScreenMode
= pItem
? pItem
->GetValue() : !pWork
->IsFullScreenMode();
2947 if ( bNewFullScreenMode
!= pWork
->IsFullScreenMode() )
2949 if ( bNewFullScreenMode
)
2950 sfx2::SfxNotebookBar::LockNotebookBar();
2952 sfx2::SfxNotebookBar::UnlockNotebookBar();
2954 Reference
< css::beans::XPropertySet
> xLMPropSet( xLayoutManager
, UNO_QUERY
);
2955 if ( xLMPropSet
.is() )
2959 xLMPropSet
->setPropertyValue(
2961 makeAny( bNewFullScreenMode
));
2963 catch ( css::beans::UnknownPropertyException
& )
2967 pWork
->ShowFullScreenMode( bNewFullScreenMode
);
2968 pWork
->SetMenuBarMode( bNewFullScreenMode
? MenuBarMode::Hide
: MenuBarMode::Normal
);
2969 GetFrame().GetWorkWindow_Impl()->SetFullScreen_Impl( bNewFullScreenMode
);
2971 rReq
.AppendItem( SfxBoolItem( SID_WIN_FULLSCREEN
, bNewFullScreenMode
) );
2981 GetDispatcher()->Update_Impl( true );
2987 void SfxViewFrame::MiscState_Impl(SfxItemSet
&rSet
)
2989 const sal_uInt16
*pRanges
= rSet
.GetRanges();
2990 DBG_ASSERT(pRanges
&& *pRanges
, "Set without range");
2993 for(sal_uInt16 nWhich
= *pRanges
++; nWhich
<= *pRanges
; ++nWhich
)
2997 case SID_CURRENT_URL
:
2999 rSet
.Put( SfxStringItem( nWhich
, GetActualPresentationURL_Impl() ) );
3003 case SID_RECORDMACRO
:
3005 SvtMiscOptions aMiscOptions
;
3006 const OUString
& sName
{GetObjectShell()->GetFactory().GetFactoryName()};
3007 bool bMacrosDisabled
= officecfg::Office::Common::Security::Scripting::DisableMacrosExecution::get();
3008 if (bMacrosDisabled
||
3009 !officecfg::Office::Common::Misc::MacroRecorderMode::get() ||
3010 ( sName
!="swriter" && sName
!="scalc" ) )
3012 rSet
.DisableItem( nWhich
);
3013 rSet
.Put(SfxVisibilityItem(nWhich
, false));
3017 css::uno::Reference
< css::beans::XPropertySet
> xSet(
3018 GetFrame().GetFrameInterface(),
3019 css::uno::UNO_QUERY
);
3021 css::uno::Any aProp
= xSet
->getPropertyValue("DispatchRecorderSupplier");
3022 css::uno::Reference
< css::frame::XDispatchRecorderSupplier
> xSupplier
;
3023 if ( aProp
>>= xSupplier
)
3024 rSet
.Put( SfxBoolItem( nWhich
, xSupplier
.is() ) );
3026 rSet
.DisableItem( nWhich
);
3030 case SID_STOP_RECORDING
:
3032 SvtMiscOptions aMiscOptions
;
3033 const OUString
& sName
{GetObjectShell()->GetFactory().GetFactoryName()};
3034 if ( !officecfg::Office::Common::Misc::MacroRecorderMode::get() ||
3035 ( sName
!="swriter" && sName
!="scalc" ) )
3037 rSet
.DisableItem( nWhich
);
3041 css::uno::Reference
< css::beans::XPropertySet
> xSet(
3042 GetFrame().GetFrameInterface(),
3043 css::uno::UNO_QUERY
);
3045 css::uno::Any aProp
= xSet
->getPropertyValue("DispatchRecorderSupplier");
3046 css::uno::Reference
< css::frame::XDispatchRecorderSupplier
> xSupplier
;
3047 if ( !(aProp
>>= xSupplier
) || !xSupplier
.is() )
3048 rSet
.DisableItem( nWhich
);
3052 case SID_TOGGLESTATUSBAR
:
3054 css::uno::Reference
< css::frame::XLayoutManager
> xLayoutManager
;
3055 css::uno::Reference
< css::beans::XPropertySet
> xSet(
3056 GetFrame().GetFrameInterface(),
3057 css::uno::UNO_QUERY
);
3058 css::uno::Any aProp
= xSet
->getPropertyValue( "LayoutManager" );
3060 if ( !( aProp
>>= xLayoutManager
))
3061 rSet
.Put( SfxBoolItem( nWhich
, false ));
3064 bool bShow
= xLayoutManager
->isElementVisible( "private:resource/statusbar/statusbar" );
3065 rSet
.Put( SfxBoolItem( nWhich
, bShow
));
3070 case SID_WIN_FULLSCREEN
:
3072 SfxViewFrame
* pTop
= GetTopViewFrame();
3075 WorkWindow
* pWork
= static_cast<WorkWindow
*>( pTop
->GetFrame().GetTopWindow_Impl() );
3078 rSet
.Put( SfxBoolItem( nWhich
, pWork
->IsFullScreenMode() ) );
3083 rSet
.DisableItem( nWhich
);
3098 This method can be included in the Execute method for the on- and off-
3099 switching of ChildWindows, to implement this and API-bindings.
3101 Simply include as 'ExecuteMethod' in the IDL.
3103 void SfxViewFrame::ChildWindowExecute( SfxRequest
&rReq
)
3105 // Evaluate Parameter
3106 sal_uInt16 nSID
= rReq
.GetSlot();
3108 const SfxBoolItem
* pShowItem
= rReq
.GetArg
<SfxBoolItem
>(nSID
);
3109 if ( nSID
== SID_VIEW_DATA_SOURCE_BROWSER
)
3111 if (!SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::EModule::DATABASE
))
3113 Reference
< XFrame
> xFrame
= GetFrame().GetFrameInterface();
3114 Reference
< XFrame
> xBeamer( xFrame
->findFrame( "_beamer", FrameSearchFlag::CHILDREN
) );
3115 bool bHasChild
= xBeamer
.is();
3116 bool bShow
= pShowItem
? pShowItem
->GetValue() : !bHasChild
;
3119 if( bShow
== bHasChild
)
3123 rReq
.AppendItem( SfxBoolItem( nSID
, bShow
) );
3127 SetChildWindow( SID_BROWSER
, false );
3131 css::util::URL aTargetURL
;
3132 aTargetURL
.Complete
= ".component:DB/DataSourceBrowser";
3133 Reference
< css::util::XURLTransformer
> xTrans(
3134 css::util::URLTransformer::create(
3135 ::comphelper::getProcessComponentContext() ) );
3136 xTrans
->parseStrict( aTargetURL
);
3138 Reference
< XDispatchProvider
> xProv( xFrame
, UNO_QUERY
);
3139 Reference
< css::frame::XDispatch
> xDisp
;
3141 xDisp
= xProv
->queryDispatch( aTargetURL
, "_beamer", 31 );
3144 Sequence
< css::beans::PropertyValue
> aArgs(1);
3145 css::beans::PropertyValue
* pArg
= aArgs
.getArray();
3146 pArg
[0].Name
= "Referer";
3147 pArg
[0].Value
<<= OUString("private:user");
3148 xDisp
->dispatch( aTargetURL
, aArgs
);
3155 if (nSID
== SID_STYLE_DESIGNER
)
3157 // First make sure that the sidebar is visible
3158 ShowChildWindow(SID_SIDEBAR
);
3160 ::sfx2::sidebar::Sidebar::ShowPanel("StyleListPanel",
3161 GetFrame().GetFrameInterface(), true);
3166 bool bHasChild
= HasChildWindow(nSID
);
3167 bool bShow
= pShowItem
? pShowItem
->GetValue() : !bHasChild
;
3168 GetDispatcher()->Update_Impl( true );
3171 if ( !pShowItem
|| bShow
!= bHasChild
)
3172 ToggleChildWindow( nSID
);
3174 GetBindings().Invalidate( nSID
);
3176 // Record if possible.
3177 if ( nSID
== SID_HYPERLINK_DIALOG
|| nSID
== SID_SEARCH_DLG
)
3183 rReq
.AppendItem( SfxBoolItem( nSID
, bShow
) );
3190 This method can be used in the state method for the on and off-state
3191 of child-windows, in order to implement this.
3193 Just register the IDL as 'StateMethod'.
3195 void SfxViewFrame::ChildWindowState( SfxItemSet
& rState
)
3197 SfxWhichIter
aIter( rState
);
3198 for ( sal_uInt16 nSID
= aIter
.FirstWhich(); nSID
; nSID
= aIter
.NextWhich() )
3200 if ( nSID
== SID_VIEW_DATA_SOURCE_BROWSER
)
3202 rState
.Put( SfxBoolItem( nSID
, HasChildWindow( SID_BROWSER
) ) );
3204 else if ( nSID
== SID_HYPERLINK_DIALOG
)
3206 const SfxPoolItem
* pDummy
= nullptr;
3207 SfxItemState eState
= GetDispatcher()->QueryState( SID_HYPERLINK_SETLINK
, pDummy
);
3208 if ( SfxItemState::DISABLED
== eState
)
3209 rState
.DisableItem(nSID
);
3212 if ( KnowsChildWindow(nSID
) )
3213 rState
.Put( SfxBoolItem( nSID
, HasChildWindow(nSID
)) );
3215 rState
.DisableItem(nSID
);
3218 else if ( nSID
== SID_BROWSER
)
3220 Reference
< XFrame
> xFrame
= GetFrame().GetFrameInterface()->
3221 findFrame( "_beamer", FrameSearchFlag::CHILDREN
);
3223 rState
.DisableItem( nSID
);
3224 else if ( KnowsChildWindow(nSID
) )
3225 rState
.Put( SfxBoolItem( nSID
, HasChildWindow(nSID
) ) );
3227 else if ( nSID
== SID_SIDEBAR
)
3229 if ( !KnowsChildWindow( nSID
) )
3231 SAL_INFO("sfx.view", "SID_SIDEBAR state requested, but no task pane child window exists for this ID!");
3232 rState
.DisableItem( nSID
);
3236 rState
.Put( SfxBoolItem( nSID
, HasChildWindow( nSID
) ) );
3239 else if ( KnowsChildWindow(nSID
) )
3240 rState
.Put( SfxBoolItem( nSID
, HasChildWindow(nSID
) ) );
3242 rState
.DisableItem(nSID
);
3246 SfxWorkWindow
* SfxViewFrame::GetWorkWindow_Impl()
3248 SfxWorkWindow
* pWork
= GetFrame().GetWorkWindow_Impl();
3252 void SfxViewFrame::SetChildWindow(sal_uInt16 nId
, bool bOn
, bool bSetFocus
)
3254 SfxWorkWindow
* pWork
= GetWorkWindow_Impl();
3256 pWork
->SetChildWindow_Impl( nId
, bOn
, bSetFocus
);
3259 void SfxViewFrame::ToggleChildWindow(sal_uInt16 nId
)
3261 SfxWorkWindow
* pWork
= GetWorkWindow_Impl();
3263 pWork
->ToggleChildWindow_Impl( nId
, true );
3266 bool SfxViewFrame::HasChildWindow( sal_uInt16 nId
)
3268 SfxWorkWindow
* pWork
= GetWorkWindow_Impl();
3269 return pWork
&& pWork
->HasChildWindow_Impl(nId
);
3272 bool SfxViewFrame::KnowsChildWindow( sal_uInt16 nId
)
3274 SfxWorkWindow
* pWork
= GetWorkWindow_Impl();
3275 return pWork
&& pWork
->KnowsChildWindow_Impl(nId
);
3278 void SfxViewFrame::ShowChildWindow( sal_uInt16 nId
, bool bVisible
)
3280 SfxWorkWindow
* pWork
= GetWorkWindow_Impl();
3283 GetDispatcher()->Update_Impl(true);
3284 pWork
->ShowChildWindow_Impl(nId
, bVisible
, true );
3288 SfxChildWindow
* SfxViewFrame::GetChildWindow(sal_uInt16 nId
)
3290 SfxWorkWindow
* pWork
= GetWorkWindow_Impl();
3291 return pWork
? pWork
->GetChildWindow_Impl(nId
) : nullptr;
3294 void SfxViewFrame::UpdateDocument_Impl()
3296 SfxObjectShell
* pDoc
= GetObjectShell();
3297 if ( pDoc
->IsLoadingFinished() )
3298 pDoc
->CheckSecurityOnLoading_Impl();
3300 // check if document depends on a template
3301 pDoc
->UpdateFromTemplate_Impl();
3304 void SfxViewFrame::SetViewFrame( SfxViewFrame
* pFrame
)
3307 SetSVHelpData(pFrame
->m_pHelpData
);
3309 SetSVWinData(pFrame
? pFrame
->m_pWinData
: nullptr);
3311 SfxGetpApp()->SetViewFrame_Impl( pFrame
);
3314 VclPtr
<SfxInfoBarWindow
> SfxViewFrame::AppendInfoBar(const OUString
& sId
,
3315 const OUString
& sPrimaryMessage
,
3316 const OUString
& sSecondaryMessage
,
3317 InfobarType aInfobarType
, bool bShowCloseButton
)
3319 SfxChildWindow
* pChild
= GetChildWindow(SfxInfoBarContainerChild::GetChildWindowId());
3323 if (HasInfoBarWithID(sId
))
3326 SfxInfoBarContainerWindow
* pInfoBarContainer
= static_cast<SfxInfoBarContainerWindow
*>(pChild
->GetWindow());
3327 auto pInfoBar
= pInfoBarContainer
->appendInfoBar(sId
, sPrimaryMessage
, sSecondaryMessage
,
3328 aInfobarType
, bShowCloseButton
);
3329 ShowChildWindow(SfxInfoBarContainerChild::GetChildWindowId());
3333 void SfxViewFrame::UpdateInfoBar(const OUString
& sId
, const OUString
& sPrimaryMessage
,
3334 const OUString
& sSecondaryMessage
, InfobarType eType
)
3336 const sal_uInt16 nId
= SfxInfoBarContainerChild::GetChildWindowId();
3338 // Make sure the InfoBar container is visible
3339 if (!HasChildWindow(nId
))
3340 ToggleChildWindow(nId
);
3342 SfxChildWindow
* pChild
= GetChildWindow(nId
);
3345 SfxInfoBarContainerWindow
* pInfoBarContainer
= static_cast<SfxInfoBarContainerWindow
*>(pChild
->GetWindow());
3346 auto pInfoBar
= pInfoBarContainer
->getInfoBar(sId
);
3349 pInfoBar
->Update(sPrimaryMessage
, sSecondaryMessage
, eType
);
3353 void SfxViewFrame::RemoveInfoBar( const OUString
& sId
)
3355 const sal_uInt16 nId
= SfxInfoBarContainerChild::GetChildWindowId();
3357 // Make sure the InfoBar container is visible
3358 if (!HasChildWindow(nId
))
3359 ToggleChildWindow(nId
);
3361 SfxChildWindow
* pChild
= GetChildWindow(nId
);
3364 SfxInfoBarContainerWindow
* pInfoBarContainer
= static_cast<SfxInfoBarContainerWindow
*>(pChild
->GetWindow());
3365 auto pInfoBar
= pInfoBarContainer
->getInfoBar(sId
);
3366 pInfoBarContainer
->removeInfoBar(pInfoBar
);
3367 ShowChildWindow(nId
);
3371 bool SfxViewFrame::HasInfoBarWithID( const OUString
& sId
)
3373 const sal_uInt16 nId
= SfxInfoBarContainerChild::GetChildWindowId();
3375 SfxChildWindow
* pChild
= GetChildWindow(nId
);
3378 SfxInfoBarContainerWindow
* pInfoBarContainer
= static_cast<SfxInfoBarContainerWindow
*>(pChild
->GetWindow());
3379 return pInfoBarContainer
->hasInfoBarWithID(sId
);
3385 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */