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 <svx/svdview.hxx>
29 #include <com/sun/star/document/MacroExecMode.hpp>
30 #include <com/sun/star/frame/Desktop.hpp>
31 #include <com/sun/star/frame/DispatchRecorder.hpp>
32 #include <com/sun/star/frame/DispatchRecorderSupplier.hpp>
33 #include <com/sun/star/frame/XLoadable.hpp>
34 #include <com/sun/star/frame/XLayoutManager.hpp>
35 #include <com/sun/star/frame/XComponentLoader.hpp>
36 #include <com/sun/star/task/PasswordContainer.hpp>
37 #include <officecfg/Office/Common.hxx>
38 #include <officecfg/Setup.hxx>
39 #include <toolkit/helper/vclunohelper.hxx>
40 #include <vcl/wrkwin.hxx>
41 #include <unotools/moduleoptions.hxx>
42 #include <svl/intitem.hxx>
43 #include <svl/visitem.hxx>
44 #include <svl/stritem.hxx>
45 #include <svl/eitem.hxx>
46 #include <svl/whiter.hxx>
47 #include <svl/undo.hxx>
48 #include <vcl/stdtext.hxx>
49 #include <vcl/weld.hxx>
50 #include <vcl/weldutils.hxx>
51 #include <unotools/VersionConfig.hxx>
52 #include <svtools/miscopt.hxx>
53 #include <tools/diagnose_ex.h>
54 #include <com/sun/star/container/XIndexAccess.hpp>
55 #include <com/sun/star/frame/XFramesSupplier.hpp>
56 #include <com/sun/star/frame/FrameSearchFlag.hpp>
57 #include <com/sun/star/frame/XFrame.hpp>
58 #include <com/sun/star/awt/XWindow.hpp>
59 #include <com/sun/star/frame/XController.hpp>
60 #include <com/sun/star/util/URLTransformer.hpp>
61 #include <com/sun/star/util/XURLTransformer.hpp>
62 #include <com/sun/star/util/XCloseable.hpp>
63 #include <com/sun/star/frame/XDispatchRecorderSupplier.hpp>
64 #include <com/sun/star/document/UpdateDocMode.hpp>
65 #include <com/sun/star/beans/XPropertySet.hpp>
66 #include <com/sun/star/uri/UriReferenceFactory.hpp>
67 #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
68 #include <com/sun/star/document/XViewDataSupplier.hpp>
69 #include <com/sun/star/container/XIndexContainer.hpp>
70 #include <com/sun/star/task/InteractionHandler.hpp>
71 #include <com/sun/star/drawing/XDrawView.hpp>
72 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
73 #include <com/sun/star/frame/ModuleManager.hpp>
74 #include <com/sun/star/frame/UnknownModuleException.hpp>
75 #include <rtl/ustrbuf.hxx>
76 #include <sal/log.hxx>
78 #include <unotools/ucbhelper.hxx>
79 #include <comphelper/lok.hxx>
80 #include <comphelper/processfactory.hxx>
81 #include <comphelper/namedvaluecollection.hxx>
82 #include <comphelper/docpasswordrequest.hxx>
83 #include <comphelper/docpasswordhelper.hxx>
85 #include <com/sun/star/uno/Reference.h>
87 #include <basic/basmgr.hxx>
88 #include <basic/sbmod.hxx>
89 #include <basic/sbmeth.hxx>
90 #include <svtools/strings.hrc>
91 #include <svtools/svtresid.hxx>
92 #include <framework/framelistanalyzer.hxx>
96 #include <unotools/configmgr.hxx>
97 #include <comphelper/sequenceashashmap.hxx>
99 #include <commandpopup/CommandPopup.hxx>
102 using namespace ::com::sun::star
;
103 using namespace ::com::sun::star::uno
;
104 using namespace ::com::sun::star::ucb
;
105 using namespace ::com::sun::star::frame
;
106 using namespace ::com::sun::star::lang
;
107 using ::com::sun::star::awt::XWindow
;
108 using ::com::sun::star::beans::PropertyValue
;
109 using ::com::sun::star::document::XViewDataSupplier
;
110 using ::com::sun::star::container::XIndexContainer
;
112 // Due to ViewFrame::Current
113 #include <appdata.hxx>
114 #include <sfx2/app.hxx>
115 #include <sfx2/objface.hxx>
116 #include <openflag.hxx>
117 #include <objshimp.hxx>
118 #include <sfx2/viewsh.hxx>
119 #include <sfx2/objsh.hxx>
120 #include <sfx2/bindings.hxx>
121 #include <sfx2/dispatch.hxx>
122 #include <sfx2/request.hxx>
123 #include <sfx2/docfac.hxx>
124 #include <sfx2/ipclient.hxx>
125 #include <sfx2/sfxresid.hxx>
126 #include <sfx2/viewfac.hxx>
127 #include <sfx2/event.hxx>
128 #include <sfx2/fcontnr.hxx>
129 #include <sfx2/docfile.hxx>
130 #include <sfx2/module.hxx>
131 #include <sfx2/sfxuno.hxx>
132 #include <sfx2/progress.hxx>
133 #include <sfx2/sidebar/Sidebar.hxx>
134 #include <workwin.hxx>
135 #include <sfx2/minfitem.hxx>
136 #include <sfx2/strings.hrc>
137 #include "impviewframe.hxx"
138 #include <vcl/commandinfoprovider.hxx>
139 #include <vcl/svapp.hxx>
141 #define ShellClass_SfxViewFrame
142 #include <sfxslots.hxx>
144 #include <sfx2/sidebar/SidebarController.hxx>
145 constexpr OUStringLiteral CHANGES_STR
= u
"private:resource/toolbar/changes";
147 SFX_IMPL_SUPERCLASS_INTERFACE(SfxViewFrame
,SfxShell
)
149 void SfxViewFrame::InitInterface_Impl()
151 GetStaticInterface()->RegisterChildWindow(SID_BROWSER
);
152 GetStaticInterface()->RegisterChildWindow(SID_RECORDING_FLOATWINDOW
);
153 #if HAVE_FEATURE_DESKTOP
154 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_FULLSCREEN
, SfxVisibilityFlags::FullScreen
, ToolbarId::FullScreenToolbox
);
155 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_APPLICATION
, SfxVisibilityFlags::Standard
, ToolbarId::EnvToolbox
);
160 /// Asks the user if editing a read-only document is really wanted.
161 class SfxEditDocumentDialog
: public weld::MessageDialogController
164 std::unique_ptr
<weld::Button
> m_xEditDocument
;
165 std::unique_ptr
<weld::Button
> m_xCancel
;
168 SfxEditDocumentDialog(weld::Widget
* pParent
);
171 SfxEditDocumentDialog::SfxEditDocumentDialog(weld::Widget
* pParent
)
172 : MessageDialogController(pParent
, "sfx/ui/editdocumentdialog.ui",
173 "EditDocumentDialog")
174 , m_xEditDocument(m_xBuilder
->weld_button("edit"))
175 , m_xCancel(m_xBuilder
->weld_button("cancel"))
179 class SfxQueryOpenAsTemplate
182 std::unique_ptr
<weld::MessageDialog
> m_xQueryBox
;
184 SfxQueryOpenAsTemplate(weld::Window
* pParent
, bool bAllowIgnoreLock
, LockFileEntry
& rLockData
)
185 : m_xQueryBox(Application::CreateMessageDialog(pParent
, VclMessageType::Question
,
186 VclButtonsType::NONE
, ""))
188 m_xQueryBox
->add_button(SfxResId(STR_QUERY_OPENASTEMPLATE_OPENCOPY_BTN
), RET_YES
);
190 = bAllowIgnoreLock
&& officecfg::Office::Common::Misc::AllowOverrideLocking::get();
191 if (bAllowIgnoreLock
)
192 m_xQueryBox
->add_button(SfxResId(STR_QUERY_OPENASTEMPLATE_OPEN_BTN
), RET_IGNORE
);
193 m_xQueryBox
->add_button(GetStandardText( StandardButtonType::Cancel
), RET_CANCEL
);
194 m_xQueryBox
->set_primary_text(QueryString(bAllowIgnoreLock
, rLockData
));
195 m_xQueryBox
->set_default_response(RET_YES
);
197 short run() { return m_xQueryBox
->run(); }
200 static OUString
QueryString(bool bAllowIgnoreLock
, LockFileEntry
& rLockData
)
202 OUString sLockUserData
;
203 if (!rLockData
[LockFileComponent::OOOUSERNAME
].isEmpty())
204 sLockUserData
= rLockData
[LockFileComponent::OOOUSERNAME
];
206 sLockUserData
= rLockData
[LockFileComponent::SYSUSERNAME
];
208 if (!sLockUserData
.isEmpty() && !rLockData
[LockFileComponent::EDITTIME
].isEmpty())
209 sLockUserData
+= " ( " + rLockData
[LockFileComponent::EDITTIME
] + " )";
211 if (!sLockUserData
.isEmpty())
212 sLockUserData
= "\n\n" + sLockUserData
+ "\n";
214 const bool bUseLockStr
= bAllowIgnoreLock
|| !sLockUserData
.isEmpty();
217 SfxResId(bUseLockStr
? STR_QUERY_OPENASTEMPLATE_LOCKED
: STR_QUERY_OPENASTEMPLATE
));
219 if (bAllowIgnoreLock
)
220 sMsg
+= "\n\n" + SfxResId(STR_QUERY_OPENASTEMPLATE_ALLOW_IGNORE
);
222 return sMsg
.replaceFirst("%LOCKINFO", sLockUserData
);
226 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
)
228 // TODO/LATER: In future the info should replace the direct hash completely
229 bool bResult
= ( !nPasswordHash
&& !aInfo
.hasElements() );
231 SAL_WARN_IF( !(pFilter
&& ( pFilter
->GetFilterFlags() & SfxFilterFlags::PASSWORDTOMODIFY
)), "sfx.view",
232 "PasswordToModify feature is active for a filter that does not support it!");
234 if ( pFilter
&& xHandler
.is() )
236 bool bCancel
= false;
237 bool bFirstTime
= true;
239 while ( !bResult
&& !bCancel
)
241 bool bMSType
= !pFilter
->IsOwnFormat();
243 ::rtl::Reference
< ::comphelper::DocPasswordRequest
> pPasswordRequest(
244 new ::comphelper::DocPasswordRequest(
245 bMSType
? ::comphelper::DocPasswordRequestType::MS
: ::comphelper::DocPasswordRequestType::Standard
,
246 bFirstTime
? css::task::PasswordRequestMode_PASSWORD_ENTER
: css::task::PasswordRequestMode_PASSWORD_REENTER
,
250 xHandler
->handle( pPasswordRequest
);
252 if ( pPasswordRequest
->isPassword() )
254 if ( aInfo
.hasElements() )
256 bResult
= ::comphelper::DocPasswordHelper::IsModifyPasswordCorrect( pPasswordRequest
->getPasswordToModify(), aInfo
);
261 bResult
= ( SfxMedium::CreatePasswordToModifyHash( pPasswordRequest
->getPasswordToModify(), pFilter
->GetServiceName()=="com.sun.star.text.TextDocument" ) == nPasswordHash
);
274 bool physObjIsOlder(INetURLObject
const & aMedObj
, INetURLObject
const & aPhysObj
) {
275 return ::utl::UCBContentHelper::IsYounger(aMedObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
),
276 aPhysObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
280 void SfxViewFrame::ExecReload_Impl( SfxRequest
& rReq
)
282 SfxObjectShell
* pSh
= GetObjectShell();
283 switch ( rReq
.GetSlot() )
286 case SID_READONLYDOC
:
288 // Due to Double occupancy in toolboxes (with or without Ctrl),
289 // it is also possible that the slot is enabled, but Ctrl-click
290 // despite this is not!
291 if( !pSh
|| !pSh
->HasName() || !(pSh
->Get_Impl()->nLoadedFlags
& SfxLoadedFlags::MAINDOCUMENT
))
294 if (pSh
->isEditDocLocked())
297 // Only change read-only UI and remove info bar when we succeed
298 struct ReadOnlyUIGuard
300 SfxViewFrame
* m_pFrame
;
301 SfxObjectShell
* m_pSh
;
302 SfxMedium
* m_pMed
= nullptr;
304 ReadOnlyUIGuard(SfxViewFrame
* pFrame
, SfxObjectShell
* p_Sh
)
305 : m_pFrame(pFrame
), m_pSh(p_Sh
), m_bSetRO(p_Sh
->IsReadOnlyUI())
307 ~ReadOnlyUIGuard() COVERITY_NOEXCEPT_FALSE
309 if (m_bSetRO
!= m_pSh
->IsReadOnlyUI())
311 m_pSh
->SetReadOnlyUI(m_bSetRO
);
313 m_pFrame
->RemoveInfoBar(u
"readonly");
316 // tdf#116066: DoSaveCompleted should be called after SetReadOnlyUI
317 m_pSh
->DoSaveCompleted(m_pMed
);
318 m_pSh
->Broadcast(SfxHint(SfxHintId::ModeChanged
));
322 } aReadOnlyUIGuard(this, pSh
);
324 SfxMedium
* pMed
= pSh
->GetMedium();
326 std::shared_ptr
<std::recursive_mutex
> pChkEditMutex
= pMed
->GetCheckEditableMutex();
327 std::unique_lock
<std::recursive_mutex
> chkEditLock
;
328 if (pChkEditMutex
!= nullptr)
329 chkEditLock
= std::unique_lock
<std::recursive_mutex
>(*pChkEditMutex
);
330 pMed
->CancelCheckEditableEntry();
332 const SfxBoolItem
* pItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pSh
->GetMedium()->GetItemSet(), SID_VIEWONLY
, false);
333 if ( pItem
&& pItem
->GetValue() )
335 SfxApplication
* pApp
= SfxGetpApp();
336 SfxAllItemSet
aSet( pApp
->GetPool() );
337 aSet
.Put( SfxStringItem( SID_FILE_NAME
, pMed
->GetURLObject().GetMainURL(INetURLObject::DecodeMechanism::NONE
) ) );
338 aSet
.Put( SfxBoolItem( SID_TEMPLATE
, true ) );
339 aSet
.Put( SfxStringItem( SID_TARGETNAME
, "_blank" ) );
340 const SfxStringItem
* pReferer
= SfxItemSet::GetItem
<SfxStringItem
>(pMed
->GetItemSet(), SID_REFERER
, false);
342 aSet
.Put( *pReferer
);
343 const SfxInt16Item
* pVersionItem
= SfxItemSet::GetItem
<SfxInt16Item
>(pSh
->GetMedium()->GetItemSet(), SID_VERSION
, false);
345 aSet
.Put( *pVersionItem
);
347 if( pMed
->GetFilter() )
349 aSet
.Put( SfxStringItem( SID_FILTER_NAME
, pMed
->GetFilter()->GetFilterName() ) );
350 const SfxStringItem
* pOptions
= SfxItemSet::GetItem
<SfxStringItem
>(pMed
->GetItemSet(), SID_FILE_FILTEROPTIONS
, false);
352 aSet
.Put( *pOptions
);
355 GetDispatcher()->Execute( SID_OPENDOC
, SfxCallMode::ASYNCHRON
, aSet
);
359 StreamMode nOpenMode
;
360 bool bNeedsReload
= false;
361 bool bPasswordEntered
= false;
362 if ( !pSh
->IsReadOnly() )
364 // Save and reload Readonly
365 if( pSh
->IsModified() )
367 if ( pSh
->PrepareClose() )
369 // the storing could let the medium be changed
370 pMed
= pSh
->GetMedium();
375 rReq
.SetReturnValue( SfxBoolItem( rReq
.GetSlot(), false ) );
379 nOpenMode
= SFX_STREAM_READONLY
;
380 aReadOnlyUIGuard
.m_bSetRO
= true;
384 if ( pSh
->IsReadOnlyMedium()
385 && ( pSh
->GetModifyPasswordHash() || pSh
->GetModifyPasswordInfo().hasElements() )
386 && !pSh
->IsModifyPasswordEntered() )
388 const OUString aDocumentName
= INetURLObject( pMed
->GetOrigURL() ).GetMainURL( INetURLObject::DecodeMechanism::WithCharset
);
389 if( !AskPasswordToModify_Impl( pMed
->GetInteractionHandler(), aDocumentName
, pMed
->GetFilter(), pSh
->GetModifyPasswordHash(), pSh
->GetModifyPasswordInfo() ) )
391 // this is a read-only document, if it has "Password to modify"
392 // the user should enter password before he can edit the document
393 rReq
.SetReturnValue( SfxBoolItem( rReq
.GetSlot(), false ) );
397 pSh
->SetModifyPasswordEntered();
398 bPasswordEntered
= true;
401 nOpenMode
= pSh
->IsOriginallyReadOnlyMedium() ? SFX_STREAM_READONLY
: SFX_STREAM_READWRITE
;
402 aReadOnlyUIGuard
.m_bSetRO
= false;
404 // if only the view was in the readonly mode then there is no need to do the reload
405 if ( !pSh
->IsReadOnlyMedium() )
407 // SetReadOnlyUI causes recomputation of window title, using
408 // open mode among other things, so call SetOpenMode before
410 pMed
->SetOpenMode( nOpenMode
);
417 // Control through API if r/w or r/o
418 const SfxBoolItem
* pEditItem
= rReq
.GetArg
<SfxBoolItem
>(SID_EDITDOC
);
420 nOpenMode
= pEditItem
->GetValue() ? SFX_STREAM_READWRITE
: SFX_STREAM_READONLY
;
426 osl::FileBase::getFileURLFromSystemPath( pMed
->GetPhysicalName(), sTemp
);
427 INetURLObject
aPhysObj( sTemp
);
428 const SfxInt16Item
* pVersionItem
= SfxItemSet::GetItem
<SfxInt16Item
>(pSh
->GetMedium()->GetItemSet(), SID_VERSION
, false);
430 INetURLObject
aMedObj( pMed
->GetName() );
433 // the logic below is following:
434 // if the document seems not to need to be reloaded
435 // and the physical name is different to the logical one,
436 // then on file system it can be checked that the copy is still newer than the original and no document reload is required.
437 // Did some semplification to enhance readability of the 'if' expression
439 // when the 'http/https' protocol is active, the bool bPhysObjIsYounger relies upon the getlastmodified Property of a WebDAV resource.
440 // Said property should be implemented, but sometimes it's not.
441 // implemented. On this case the reload activated here will not work properly.
442 // TODO: change the check age method for WebDAV to etag (entity-tag) property value, need some rethinking, since the
443 // etag tells that the cache representation (e.g. in LO) is different from the one on the server,
444 // but tells nothing about the age
445 // Details at this link: http://tools.ietf.org/html/rfc4918#section-15, section 15.7
446 bool bIsWebDAV
= aMedObj
.isAnyKnownWebDAVScheme();
448 // tdf#118938 Reload the document when the user enters the editing password,
449 // even if the physical name isn't different to the logical name.
450 if ( ( !bNeedsReload
&& ( ( aMedObj
.GetProtocol() == INetProtocol::File
&&
451 ( aMedObj
.getFSysPath( FSysStyle::Detect
) != aPhysObj
.getFSysPath( FSysStyle::Detect
)
452 || bPasswordEntered
) &&
453 !physObjIsOlder(aMedObj
, aPhysObj
) )
454 || ( bIsWebDAV
&& !physObjIsOlder(aMedObj
, aPhysObj
) )
455 || ( pMed
->IsRemote() && !bIsWebDAV
) ) )
462 bool bRetryIgnoringLock
= false;
463 bool bOpenTemplate
= false;
464 std::optional
<bool> aOrigROVal
;
467 auto pRO
= pMed
->GetItemSet()->GetItem
<SfxBoolItem
>(SID_DOC_READONLY
, false);
469 aOrigROVal
= pRO
->GetValue();
472 LockFileEntry aLockData
;
475 if (bRetryIgnoringLock
)
478 bool bHasStorage
= pMed
->HasStorage_Impl();
479 // switching edit mode could be possible without reload
480 if ( bHasStorage
&& pMed
->GetStorage() == pSh
->GetStorage() )
482 // TODO/LATER: faster creation of copy
483 if ( !pSh
->ConnectTmpStorage_Impl( pMed
->GetStorage(), pMed
) )
487 pMed
->CloseAndRelease();
488 pMed
->SetOpenMode( nOpenMode
);
489 // We need to clear the SID_DOC_READONLY item from the set, to allow
490 // MediaDescriptor::impl_openStreamWithURL (called indirectly by
491 // SfxMedium::CompleteReOpen) to properly fill input stream of the
492 // descriptor, even when the file can't be open in read-write mode.
493 // Only then can following call to SfxMedium::LockOrigFileOnDemand
494 // return proper information about who has locked the file, to show
495 // in the SfxQueryOpenAsTemplate box below; otherwise it exits right
496 // after call to SfxMedium::GetMedium_Impl. This mimics what happens
497 // when the file is opened initially, when filter detection code also
498 // calls MediaDescriptor::impl_openStreamWithURL without the item set.
499 pMed
->GetItemSet()->ClearItem(SID_DOC_READONLY
);
500 pMed
->CompleteReOpen();
501 pMed
->GetItemSet()->Put(
502 SfxBoolItem(SID_DOC_READONLY
, !(nOpenMode
& StreamMode::WRITE
)));
503 if ( nOpenMode
& StreamMode::WRITE
)
505 auto eResult
= pMed
->LockOrigFileOnDemand(
506 true, true, bRetryIgnoringLock
, &aLockData
);
508 = eResult
== SfxMedium::LockFileResult::FailedLockFile
;
511 // LockOrigFileOnDemand might set the readonly flag itself, it should be set back
512 pMed
->GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY
, !( nOpenMode
& StreamMode::WRITE
) ) );
514 if ( !pMed
->GetErrorCode() )
520 if (nOpenMode
== SFX_STREAM_READWRITE
&& !rReq
.IsAPI())
522 // css::sdbcx::User offering to open it as a template
523 SfxQueryOpenAsTemplate
aBox(GetWindow().GetFrameWeld(),
524 bRetryIgnoringLock
, aLockData
);
526 short nUserAnswer
= aBox
.run();
527 bOpenTemplate
= RET_YES
== nUserAnswer
;
528 // Always reset this here to avoid infinite loop
529 bRetryIgnoringLock
= RET_IGNORE
== nUserAnswer
;
530 if (RET_CANCEL
== nUserAnswer
)
531 pMed
->AddToCheckEditableWorkerList();
534 bRetryIgnoringLock
= false;
537 while ( !bOK
&& bRetryIgnoringLock
);
541 ErrCode nErr
= pMed
->GetErrorCode();
543 nErr
= ERRCODE_IO_ACCESSDENIED
;
547 pMed
->SetOpenMode( SFX_STREAM_READONLY
);
549 pMed
->GetItemSet()->Put(SfxBoolItem(SID_DOC_READONLY
, *aOrigROVal
));
551 pMed
->GetItemSet()->ClearItem(SID_DOC_READONLY
);
553 pSh
->DoSaveCompleted( pMed
);
556 // Readonly document can not be switched to edit mode?
559 if ( nOpenMode
== SFX_STREAM_READWRITE
&& !rReq
.IsAPI() )
563 SfxApplication
* pApp
= SfxGetpApp();
564 SfxAllItemSet
aSet( pApp
->GetPool() );
565 aSet
.Put( SfxStringItem( SID_FILE_NAME
, pMed
->GetName() ) );
566 const SfxStringItem
* pReferer
= SfxItemSet::GetItem
<SfxStringItem
>(pMed
->GetItemSet(), SID_REFERER
, false);
568 aSet
.Put( *pReferer
);
569 aSet
.Put( SfxBoolItem( SID_TEMPLATE
, true ) );
571 aSet
.Put( *pVersionItem
);
573 if( pMed
->GetFilter() )
575 aSet
.Put( SfxStringItem( SID_FILTER_NAME
, pMed
->GetFilter()->GetFilterName() ) );
576 const SfxStringItem
* pOptions
= SfxItemSet::GetItem
<SfxStringItem
>(pMed
->GetItemSet(), SID_FILE_FILTEROPTIONS
, false);
578 aSet
.Put( *pOptions
);
581 GetDispatcher()->Execute( SID_OPENDOC
, SfxCallMode::ASYNCHRON
, aSet
);
588 // Keep the read-only UI
589 aReadOnlyUIGuard
.m_bSetRO
= true;
591 ErrorHandler::HandleError( nErr
);
593 SfxBoolItem( rReq
.GetSlot(), false ) );
598 aReadOnlyUIGuard
.m_pMed
= pMed
;
599 rReq
.SetReturnValue( SfxBoolItem( rReq
.GetSlot(), true ) );
605 rReq
.AppendItem( SfxBoolItem(SID_FORCERELOAD
,
606 rReq
.GetSlot() == SID_EDITDOC
|| bNeedsReload
) );
607 rReq
.AppendItem( SfxBoolItem( SID_SILENT
, true ));
609 [[fallthrough
]]; //TODO ???
614 // Due to Double occupancy in toolboxes (with or without Ctrl),
615 // it is also possible that the slot is enabled, but Ctrl-click
616 // despite this is not!
617 if ( !pSh
|| !pSh
->CanReload_Impl() )
619 SfxApplication
* pApp
= SfxGetpApp();
620 const SfxBoolItem
* pForceReloadItem
= rReq
.GetArg
<SfxBoolItem
>(SID_FORCERELOAD
);
621 if( pForceReloadItem
&& !pForceReloadItem
->GetValue() &&
622 !pSh
->GetMedium()->IsExpired() )
624 if( m_pImpl
->bReloading
|| pSh
->IsInModalMode() )
627 // AutoLoad is prohibited if possible
628 const SfxBoolItem
* pAutoLoadItem
= rReq
.GetArg
<SfxBoolItem
>(SID_AUTOLOAD
);
629 if ( pAutoLoadItem
&& pAutoLoadItem
->GetValue() &&
630 GetFrame().IsAutoLoadLocked_Impl() )
633 SfxObjectShellLock
xOldObj( pSh
);
634 m_pImpl
->bReloading
= true;
635 const SfxStringItem
* pURLItem
= rReq
.GetArg
<SfxStringItem
>(SID_FILE_NAME
);
637 bool bForEdit
= !pSh
->IsReadOnly();
639 // If possible ask the User
640 bool bDo
= GetViewShell()->PrepareClose();
641 const SfxBoolItem
* pSilentItem
= rReq
.GetArg
<SfxBoolItem
>(SID_SILENT
);
642 if ( bDo
&& GetFrame().DocIsModified_Impl() &&
643 !rReq
.IsAPI() && ( !pSilentItem
|| !pSilentItem
->GetValue() ) )
645 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(GetWindow().GetFrameWeld(),
646 VclMessageType::Question
, VclButtonsType::YesNo
,
647 SfxResId(STR_QUERY_LASTVERSION
)));
648 bDo
= RET_YES
== xBox
->run();
653 SfxMedium
*pMedium
= xOldObj
->GetMedium();
654 std::shared_ptr
<std::recursive_mutex
> pChkEditMutex
655 = pMedium
->GetCheckEditableMutex();
656 std::unique_lock
<std::recursive_mutex
> chkEditLock
;
657 if (pChkEditMutex
!= nullptr)
658 chkEditLock
= std::unique_lock
<std::recursive_mutex
>(*pChkEditMutex
);
659 pMedium
->CancelCheckEditableEntry();
662 ( pMedium
->GetURLObject().GetProtocol() == INetProtocol::File
&& !xOldObj
->IsDocShared() );
664 // Empty existing SfxMDIFrames for this Document
665 // in native format or R/O, open it now for editing?
666 SfxObjectShellLock xNewObj
;
668 // collect the views of the document
669 // TODO: when UNO ViewFactories are available for SFX-based documents, the below code should
671 typedef ::std::pair
< Reference
< XFrame
>, SfxInterfaceId
> ViewDescriptor
;
672 ::std::vector
< ViewDescriptor
> aViewFrames
;
673 SfxViewFrame
*pView
= GetFirst( xOldObj
);
676 Reference
< XFrame
> xFrame( pView
->GetFrame().GetFrameInterface() );
677 SAL_WARN_IF( !xFrame
.is(), "sfx.view", "SfxViewFrame::ExecReload_Impl: no XFrame?!");
678 aViewFrames
.emplace_back( xFrame
, pView
->GetCurViewId() );
680 pView
= GetNext( *pView
, xOldObj
);
683 xOldObj
->Get_Impl()->pReloadTimer
.reset();
685 std::optional
<SfxAllItemSet
> pNewSet
;
686 std::shared_ptr
<const SfxFilter
> pFilter
= pMedium
->GetFilter();
689 pNewSet
.emplace( pApp
->GetPool() );
690 pNewSet
->Put( *pURLItem
);
694 const SfxStringItem
* refererItem
= rReq
.GetArg
<SfxStringItem
>(SID_REFERER
);
695 if (refererItem
!= nullptr) {
696 referer
= refererItem
->GetValue();
698 SfxMedium
aMedium( pURLItem
->GetValue(), referer
, SFX_STREAM_READWRITE
);
699 SfxFilterMatcher().GuessFilter( aMedium
, pFilter
);
701 pNewSet
->Put( SfxStringItem( SID_FILTER_NAME
, pFilter
->GetName() ) );
702 pNewSet
->Put( *aMedium
.GetItemSet() );
706 pNewSet
.emplace( *pMedium
->GetItemSet() );
707 pNewSet
->ClearItem( SID_VIEW_ID
);
708 pNewSet
->ClearItem( SID_STREAM
);
709 pNewSet
->ClearItem( SID_INPUTSTREAM
);
710 pNewSet
->Put( SfxStringItem( SID_FILTER_NAME
, pMedium
->GetFilter()->GetName() ) );
712 // let the current security settings be checked again
713 pNewSet
->Put( SfxUInt16Item( SID_MACROEXECMODE
, document::MacroExecMode::USE_CONFIG
) );
715 if ( pSh
->IsOriginallyReadOnlyMedium()
716 || pSh
->IsOriginallyLoadedReadOnlyMedium() )
717 // edit mode is switched or reload of readonly document
718 pNewSet
->Put( SfxBoolItem( SID_DOC_READONLY
, true ) );
720 // Reload of file opened for writing
721 pNewSet
->ClearItem( SID_DOC_READONLY
);
724 // If a salvaged file is present, do not enclose the OrigURL
725 // again, since the Template is invalid after reload.
726 const SfxStringItem
* pSalvageItem
= SfxItemSet::GetItem
<SfxStringItem
>(&*pNewSet
, SID_DOC_SALVAGE
, false);
729 pNewSet
->ClearItem( SID_DOC_SALVAGE
);
732 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
733 // TODO/LATER: Temporary solution, the SfxMedium must know the original URL as aLogicName
734 // SfxMedium::Transfer_Impl() will be forbidden then.
735 if ( xOldObj
->IsDocShared() )
736 pNewSet
->Put( SfxStringItem( SID_FILE_NAME
, xOldObj
->GetSharedFileURL() ) );
739 pNewSet
->Put( SfxStringItem( SID_REFERER
, pMedium
->GetName() ) );
741 pNewSet
->Put( SfxStringItem( SID_REFERER
, OUString() ) );
743 xOldObj
->CancelTransfers();
746 if ( pSilentItem
&& pSilentItem
->GetValue() )
747 pNewSet
->Put( SfxBoolItem( SID_SILENT
, true ) );
749 const SfxUnoAnyItem
* pInteractionItem
= SfxItemSet::GetItem
<SfxUnoAnyItem
>(&*pNewSet
, SID_INTERACTIONHANDLER
, false);
750 const SfxUInt16Item
* pMacroExecItem
= SfxItemSet::GetItem
<SfxUInt16Item
>(&*pNewSet
, SID_MACROEXECMODE
, false);
751 const SfxUInt16Item
* pDocTemplateItem
= SfxItemSet::GetItem
<SfxUInt16Item
>(&*pNewSet
, SID_UPDATEDOCMODE
, false);
753 if (!pInteractionItem
)
755 Reference
< task::XInteractionHandler2
> xHdl
= task::InteractionHandler::createWithParent( ::comphelper::getProcessComponentContext(), nullptr );
757 pNewSet
->Put( SfxUnoAnyItem(SID_INTERACTIONHANDLER
,css::uno::makeAny(xHdl
)) );
761 pNewSet
->Put( SfxUInt16Item(SID_MACROEXECMODE
,css::document::MacroExecMode::USE_CONFIG
) );
762 if (!pDocTemplateItem
)
763 pNewSet
->Put( SfxUInt16Item(SID_UPDATEDOCMODE
,css::document::UpdateDocMode::ACCORDING_TO_CONFIG
) );
765 xOldObj
->SetModified( false );
766 // Do not cache the old Document! Is invalid when loading
769 const SfxStringItem
* pSavedOptions
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_FILE_FILTEROPTIONS
, false);
770 const SfxStringItem
* pSavedReferer
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_REFERER
, false);
772 bool bHasStorage
= pMedium
->HasStorage_Impl();
775 if ( bHasStorage
&& pMedium
->GetStorage() == xOldObj
->GetStorage() )
777 // TODO/LATER: faster creation of copy
778 if ( !xOldObj
->ConnectTmpStorage_Impl( pMedium
->GetStorage(), pMedium
) )
782 pMedium
->CloseAndRelease();
785 xNewObj
= SfxObjectShell::CreateObject( pFilter
->GetServiceName() );
787 if ( xOldObj
->IsModifyPasswordEntered() )
788 xNewObj
->SetModifyPasswordEntered();
790 uno::Sequence
< beans::PropertyValue
> aLoadArgs
;
791 TransformItems( SID_OPENDOC
, *pNewSet
, aLoadArgs
);
794 uno::Reference
< frame::XLoadable
> xLoad( xNewObj
->GetModel(), uno::UNO_QUERY
);
795 xLoad
->load( aLoadArgs
);
797 catch ( uno::Exception
& )
801 pMedium
->AddToCheckEditableWorkerList();
810 // back to old medium
812 pMedium
->LockOrigFileOnDemand( false, true );
814 xOldObj
->DoSaveCompleted( pMedium
);
817 // r/o-Doc couldn't be switched to writing mode
818 if ( bForEdit
&& ( SID_EDITDOC
== rReq
.GetSlot() || SID_READONLYDOC
== rReq
.GetSlot() ) )
820 // ask user for opening as template
821 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(GetWindow().GetFrameWeld(),
822 VclMessageType::Question
, VclButtonsType::YesNo
,
823 SfxResId(STR_QUERY_OPENASTEMPLATE
)));
824 if (RET_YES
== xBox
->run())
826 SfxAllItemSet
aSet( pApp
->GetPool() );
827 aSet
.Put( SfxStringItem( SID_FILE_NAME
, pMedium
->GetName() ) );
828 aSet
.Put( SfxStringItem( SID_TARGETNAME
, "_blank" ) );
830 aSet
.Put( *pSavedOptions
);
832 aSet
.Put( *pSavedReferer
);
833 aSet
.Put( SfxBoolItem( SID_TEMPLATE
, true ) );
835 aSet
.Put( SfxStringItem( SID_FILTER_NAME
, pFilter
->GetFilterName() ) );
836 GetDispatcher()->Execute( SID_OPENDOC
, SfxCallMode::ASYNCHRON
, aSet
);
842 if ( xNewObj
->GetModifyPasswordHash() && xNewObj
->GetModifyPasswordHash() != xOldObj
->GetModifyPasswordHash() )
844 xNewObj
->SetModifyPasswordEntered( false );
845 xNewObj
->SetReadOnly();
847 else if ( rReq
.GetSlot() == SID_EDITDOC
|| rReq
.GetSlot() == SID_READONLYDOC
)
849 xNewObj
->SetReadOnlyUI( !bForEdit
);
852 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
853 if ( xNewObj
->IsDocShared() )
855 // the file is shared but the closing can change the sharing control file
856 xOldObj
->DoNotCleanShareControlFile();
859 // the Reload and Silent items were only temporary, remove them
860 xNewObj
->GetMedium()->GetItemSet()->ClearItem( SID_RELOAD
);
861 xNewObj
->GetMedium()->GetItemSet()->ClearItem( SID_SILENT
);
862 TransformItems( SID_OPENDOC
, *xNewObj
->GetMedium()->GetItemSet(), aLoadArgs
);
864 UpdateDocument_Impl();
866 if (vcl::CommandInfoProvider::GetModuleIdentifier(GetFrame().GetFrameInterface()) == "com.sun.star.text.TextDocument")
867 sfx2::SfxNotebookBar::ReloadNotebookBar(u
"modules/swriter/ui/");
871 for (auto const& viewFrame
: aViewFrames
)
873 LoadViewIntoFrame_Impl( *xNewObj
, viewFrame
.first
, aLoadArgs
, viewFrame
.second
, false );
877 catch( const Exception
& )
879 // close the remaining frames
880 // Don't catch exceptions herein, if this fails, then we're left in an indetermined state, and
881 // crashing is better than trying to proceed
882 for (auto const& viewFrame
: aViewFrames
)
884 Reference
< util::XCloseable
> xClose( viewFrame
.first
, UNO_QUERY_THROW
);
885 xClose
->close( true );
890 const SfxInt32Item
* pPageNumber
= rReq
.GetArg
<SfxInt32Item
>(SID_PAGE_NUMBER
);
891 if (pPageNumber
&& pPageNumber
->GetValue() >= 0)
893 // Restore current page after reload.
894 uno::Reference
<drawing::XDrawView
> xController(
895 xNewObj
->GetModel()->getCurrentController(), uno::UNO_QUERY
);
896 uno::Reference
<drawing::XDrawPagesSupplier
> xSupplier(xNewObj
->GetModel(),
898 uno::Reference
<drawing::XDrawPages
> xDrawPages
= xSupplier
->getDrawPages();
899 uno::Reference
<drawing::XDrawPage
> xDrawPage(
900 xDrawPages
->getByIndex(pPageNumber
->GetValue()), uno::UNO_QUERY
);
901 xController
->setCurrentPage(xDrawPage
);
904 // Propagate document closure.
905 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::CloseDoc
, GlobalEventConfig::GetEventName( GlobalEventId::CLOSEDOC
), xOldObj
) );
910 rReq
.SetReturnValue(SfxBoolItem(rReq
.GetSlot(), true));
915 // Record as not done
917 rReq
.SetReturnValue(SfxBoolItem(rReq
.GetSlot(), false));
918 m_pImpl
->bReloading
= false;
925 void SfxViewFrame::StateReload_Impl( SfxItemSet
& rSet
)
927 SfxObjectShell
* pSh
= GetObjectShell();
930 // I'm just on reload and am yielding myself ...
934 SfxWhichIter
aIter( rSet
);
935 for ( sal_uInt16 nWhich
= aIter
.FirstWhich(); nWhich
; nWhich
= aIter
.NextWhich() )
940 case SID_READONLYDOC
:
942 const SfxViewShell
*pVSh
;
943 const SfxShell
*pFSh
;
944 if ( !pSh
->HasName() ||
945 !( pSh
->Get_Impl()->nLoadedFlags
& SfxLoadedFlags::MAINDOCUMENT
) ||
946 (pSh
->isEditDocLocked()) ||
947 ( pSh
->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
&&
948 ( !(pVSh
= pSh
->GetViewShell()) ||
949 !(pFSh
= pVSh
->GetFormShell()) ||
950 !pFSh
->IsDesignMode())))
951 rSet
.DisableItem( nWhich
);
954 const SfxBoolItem
* pItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pSh
->GetMedium()->GetItemSet(), SID_EDITDOC
, false);
955 if ( pItem
&& !pItem
->GetValue() )
956 rSet
.DisableItem( nWhich
);
959 if (nWhich
==SID_EDITDOC
)
960 rSet
.Put( SfxBoolItem( nWhich
, !pSh
->IsReadOnly() ) );
961 else if (nWhich
==SID_READONLYDOC
)
962 rSet
.Put( SfxBoolItem( nWhich
, pSh
->IsReadOnly() ) );
970 if ( !pSh
->CanReload_Impl() || pSh
->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
971 rSet
.DisableItem(nWhich
);
974 // If any ChildFrame is reloadable, the slot is enabled,
975 // so you can perform CTRL-Reload
976 rSet
.Put( SfxBoolItem( nWhich
, false));
985 void SfxViewFrame::ExecHistory_Impl( SfxRequest
&rReq
)
987 // Is there an Undo-Manager on the top Shell?
988 SfxShell
*pSh
= GetDispatcher()->GetShell(0);
989 SfxUndoManager
* pShUndoMgr
= pSh
->GetUndoManager();
993 switch ( rReq
.GetSlot() )
995 case SID_CLEARHISTORY
:
1002 GetBindings().InvalidateAll(false);
1008 GetBindings().InvalidateAll(false);
1013 if ( pSh
->GetRepeatTarget() )
1014 pShUndoMgr
->Repeat( *pSh
->GetRepeatTarget() );
1019 else if ( GetViewShell() )
1021 // The SW has its own undo in the View
1022 const SfxPoolItem
*pRet
= GetViewShell()->ExecuteSlot( rReq
);
1024 bOK
= static_cast<const SfxBoolItem
*>(pRet
)->GetValue();
1027 rReq
.SetReturnValue( SfxBoolItem( rReq
.GetSlot(), bOK
) );
1031 void SfxViewFrame::StateHistory_Impl( SfxItemSet
&rSet
)
1033 // Search for Undo-Manager
1034 SfxShell
*pSh
= GetDispatcher()->GetShell(0);
1036 // I'm just on reload and am yielding myself ...
1039 SfxUndoManager
*pShUndoMgr
= pSh
->GetUndoManager();
1042 // The SW has its own undo in the View
1043 SfxWhichIter
aIter( rSet
);
1044 SfxViewShell
*pViewSh
= GetViewShell();
1045 if( !pViewSh
) return;
1046 for ( sal_uInt16 nSID
= aIter
.FirstWhich(); nSID
; nSID
= aIter
.NextWhich() )
1047 pViewSh
->GetSlotState( nSID
, nullptr, &rSet
);
1051 if ( pShUndoMgr
->GetUndoActionCount() == 0 &&
1052 pShUndoMgr
->GetRedoActionCount() == 0 &&
1053 pShUndoMgr
->GetRepeatActionCount() == 0 )
1054 rSet
.DisableItem( SID_CLEARHISTORY
);
1056 if (pShUndoMgr
->GetUndoActionCount())
1058 const SfxUndoAction
* pAction
= pShUndoMgr
->GetUndoAction();
1059 SfxViewShell
*pViewSh
= GetViewShell();
1060 if (pViewSh
&& pAction
->GetViewShellId() != pViewSh
->GetViewShellId())
1062 rSet
.Put(SfxUInt32Item(SID_UNDO
, static_cast<sal_uInt32
>(SID_REPAIRPACKAGE
)));
1066 rSet
.Put( SfxStringItem( SID_UNDO
, SvtResId(STR_UNDO
)+pShUndoMgr
->GetUndoActionComment() ) );
1070 rSet
.DisableItem( SID_UNDO
);
1072 if (pShUndoMgr
->GetRedoActionCount())
1074 const SfxUndoAction
* pAction
= pShUndoMgr
->GetRedoAction();
1075 SfxViewShell
*pViewSh
= GetViewShell();
1076 if (pViewSh
&& pAction
->GetViewShellId() != pViewSh
->GetViewShellId())
1078 rSet
.Put(SfxUInt32Item(SID_REDO
, static_cast<sal_uInt32
>(SID_REPAIRPACKAGE
)));
1082 rSet
.Put(SfxStringItem(SID_REDO
, SvtResId(STR_REDO
) + pShUndoMgr
->GetRedoActionComment()));
1086 rSet
.DisableItem( SID_REDO
);
1088 SfxRepeatTarget
*pTarget
= pSh
->GetRepeatTarget();
1089 if (pTarget
&& pShUndoMgr
->GetRepeatActionCount() && pShUndoMgr
->CanRepeat(*pTarget
))
1090 rSet
.Put( SfxStringItem( SID_REPEAT
, SvtResId(STR_REPEAT
)+pShUndoMgr
->GetRepeatActionComment(*pTarget
) ) );
1092 rSet
.DisableItem( SID_REPEAT
);
1095 void SfxViewFrame::PopShellAndSubShells_Impl( SfxViewShell
& i_rViewShell
)
1097 i_rViewShell
.PopSubShells_Impl();
1098 sal_uInt16 nLevel
= m_pDispatcher
->GetShellLevel( i_rViewShell
);
1099 if ( nLevel
!= USHRT_MAX
)
1103 // more sub shells on the stack, which were not affected by PopSubShells_Impl
1104 SfxShell
*pSubShell
= m_pDispatcher
->GetShell( nLevel
-1 );
1105 m_pDispatcher
->Pop( *pSubShell
, SfxDispatcherPopFlags::POP_UNTIL
| SfxDispatcherPopFlags::POP_DELETE
);
1107 m_pDispatcher
->Pop( i_rViewShell
);
1108 m_pDispatcher
->Flush();
1115 This method empties the SfxViewFrame, i.e. takes the <SfxObjectShell>
1116 from the dispatcher and ends its <SfxListener> Relationship to this
1117 SfxObjectShell (by which they may even destroy themselves).
1119 Thus, by invoking ReleaseObjectShell() and SetObjectShell() the
1120 SfxObjectShell can be replaced.
1122 Between ReleaseObjectShell() and SetObjectShell() the control cannot
1123 be handed over to the system.
1127 <SfxViewFrame::SetObjectShell(SfxObjectShell&)>
1129 void SfxViewFrame::ReleaseObjectShell_Impl()
1131 DBG_ASSERT( m_xObjSh
.is(), "no SfxObjectShell to release!" );
1133 GetFrame().ReleasingComponent_Impl();
1134 if ( GetWindow().HasChildPathFocus( true ) )
1136 GetWindow().GrabFocus();
1139 SfxViewShell
*pDyingViewSh
= GetViewShell();
1142 PopShellAndSubShells_Impl( *pDyingViewSh
);
1143 pDyingViewSh
->DisconnectAllClients();
1144 SetViewShell_Impl(nullptr);
1145 delete pDyingViewSh
;
1149 OSL_FAIL("No Shell");
1152 if ( m_xObjSh
.is() )
1154 m_pDispatcher
->Pop( *m_xObjSh
);
1155 SfxModule
* pModule
= m_xObjSh
->GetModule();
1157 m_pDispatcher
->RemoveShell_Impl( *pModule
);
1158 m_pDispatcher
->Flush();
1159 EndListening( *m_xObjSh
);
1161 Notify( *m_xObjSh
, SfxHint(SfxHintId::TitleChanged
) );
1162 Notify( *m_xObjSh
, SfxHint(SfxHintId::DocChanged
) );
1164 if ( 1 == m_xObjSh
->GetOwnerLockCount() && m_pImpl
->bObjLocked
&& m_xObjSh
->GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
1165 m_xObjSh
->DoClose();
1166 SfxObjectShellRef xDyingObjSh
= m_xObjSh
;
1168 if( GetFrame().GetHasTitle() && m_pImpl
->nDocViewNo
)
1169 xDyingObjSh
->GetNoSet_Impl().ReleaseIndex(m_pImpl
->nDocViewNo
-1);
1170 if ( m_pImpl
->bObjLocked
)
1172 xDyingObjSh
->OwnerLock( false );
1173 m_pImpl
->bObjLocked
= false;
1177 GetDispatcher()->SetDisableFlags( SfxDisableFlags::NONE
);
1180 void SfxViewFrame::Close()
1183 DBG_ASSERT( GetFrame().IsClosing_Impl() || !GetFrame().GetFrameInterface().is(), "ViewFrame closed too early!" );
1185 // If no saving have been made up until now, then embedded Objects should
1186 // not be saved automatically anymore.
1187 if ( GetViewShell() )
1188 GetViewShell()->DisconnectAllClients();
1189 Broadcast( SfxHint( SfxHintId::Dying
) );
1191 if (SfxViewFrame::Current() == this)
1192 SfxViewFrame::SetViewFrame( nullptr );
1194 // Since the Dispatcher is emptied, it can not be used in any reasonable
1195 // manner, thus it is better to let the dispatcher be.
1196 GetDispatcher()->Lock(true);
1200 void SfxViewFrame::DoActivate( bool bUI
)
1202 m_pDispatcher
->DoActivate_Impl( bUI
);
1205 void SfxViewFrame::DoDeactivate(bool bUI
, SfxViewFrame
const * pNewFrame
)
1207 m_pDispatcher
->DoDeactivate_Impl( bUI
, pNewFrame
);
1210 void SfxViewFrame::InvalidateBorderImpl( const SfxViewShell
* pSh
)
1212 if( !pSh
|| m_nAdjustPosPixelLock
)
1215 if ( GetViewShell() && GetWindow().IsVisible() )
1217 if ( GetFrame().IsInPlace() )
1222 DoAdjustPosSizePixel( GetViewShell(), Point(),
1223 GetWindow().GetOutputSizePixel(),
1228 void SfxViewFrame::SetBorderPixelImpl
1230 const SfxViewShell
* pVSh
,
1231 const SvBorder
& rBorder
1235 m_pImpl
->aBorder
= rBorder
;
1237 if ( m_pImpl
->bResizeInToOut
&& !GetFrame().IsInPlace() )
1239 Size aSize
= pVSh
->GetWindow()->GetOutputSizePixel();
1240 if ( aSize
.Width() && aSize
.Height() )
1242 aSize
.AdjustWidth(rBorder
.Left() + rBorder
.Right() );
1243 aSize
.AdjustHeight(rBorder
.Top() + rBorder
.Bottom() );
1245 Size aOldSize
= GetWindow().GetOutputSizePixel();
1246 GetWindow().SetOutputSizePixel( aSize
);
1247 vcl::Window
* pParent
= &GetWindow();
1248 while ( pParent
->GetParent() )
1249 pParent
= pParent
->GetParent();
1250 Size aOuterSize
= pParent
->GetOutputSizePixel();
1251 aOuterSize
.AdjustWidth( aSize
.Width() - aOldSize
.Width() );
1252 aOuterSize
.AdjustHeight( aSize
.Height() - aOldSize
.Height() );
1253 pParent
->SetOutputSizePixel( aOuterSize
);
1258 tools::Rectangle
aEditArea( Point(), GetWindow().GetOutputSizePixel() );
1259 aEditArea
.AdjustLeft(rBorder
.Left() );
1260 aEditArea
.AdjustRight( -(rBorder
.Right()) );
1261 aEditArea
.AdjustTop(rBorder
.Top() );
1262 aEditArea
.AdjustBottom( -(rBorder
.Bottom()) );
1263 pVSh
->GetWindow()->SetPosSizePixel( aEditArea
.TopLeft(), aEditArea
.GetSize() );
1267 const SvBorder
& SfxViewFrame::GetBorderPixelImpl() const
1269 return m_pImpl
->aBorder
;
1272 void SfxViewFrame::AppendReadOnlyInfobar()
1274 bool bSignPDF
= m_xObjSh
->IsSignPDF();
1275 bool bSignWithCert
= false;
1278 SfxObjectShell
* pObjectShell
= GetObjectShell();
1279 uno::Reference
<security::XCertificate
> xCertificate
= pObjectShell
->GetSignPDFCertificate();
1280 bSignWithCert
= xCertificate
.is();
1283 auto pInfoBar
= AppendInfoBar("readonly", "",
1284 SfxResId(bSignPDF
? STR_READONLY_PDF
: STR_READONLY_DOCUMENT
),
1291 // SID_SIGNPDF opened a read-write PDF
1292 // read-only for signing purposes.
1293 weld::Button
& rSignButton
= pInfoBar
->addButton();
1296 rSignButton
.set_label(SfxResId(STR_READONLY_FINISH_SIGN
));
1300 rSignButton
.set_label(SfxResId(STR_READONLY_SIGN
));
1303 rSignButton
.connect_clicked(LINK(this, SfxViewFrame
, SignDocumentHandler
));
1306 bool showEditDocumentButton
= true;
1307 if (m_xObjSh
->isEditDocLocked())
1308 showEditDocumentButton
= false;
1310 if (showEditDocumentButton
)
1312 weld::Button
& rBtn
= pInfoBar
->addButton();
1313 rBtn
.set_label(SfxResId(STR_READONLY_EDIT
));
1314 rBtn
.connect_clicked(LINK(this, SfxViewFrame
, SwitchReadOnlyHandler
));
1320 css::uno::Reference
<css::frame::XLayoutManager
> getLayoutManager(const SfxFrame
& rFrame
)
1322 css::uno::Reference
<css::frame::XLayoutManager
> xLayoutManager
;
1323 css::uno::Reference
<css::beans::XPropertySet
> xPropSet(rFrame
.GetFrameInterface(),
1329 xLayoutManager
.set(xPropSet
->getPropertyValue("LayoutManager"), uno::UNO_QUERY
);
1331 catch (const Exception
& e
)
1333 SAL_WARN("sfx.view", "Failure getting layout manager: " + e
.Message
);
1336 return xLayoutManager
;
1340 bool SfxApplication::IsHeadlessOrUITest()
1342 if (Application::IsHeadlessModeEnabled())
1345 bool bIsUITest
= false; //uitest.uicheck fails when the dialog is open
1346 for (sal_uInt16 i
= 0, nCount
= Application::GetCommandLineParamCount(); i
< nCount
; ++i
)
1348 if (Application::GetCommandLineParam(i
) == "--nologo")
1357 bool SfxApplication::IsTipOfTheDayDue()
1359 const bool bShowTipOfTheDay
= officecfg::Office::Common::Misc::ShowTipOfTheDay::get();
1360 if (!bShowTipOfTheDay
)
1363 const auto t0
= std::chrono::system_clock::now().time_since_epoch();
1365 // show tip-of-the-day dialog ?
1366 const sal_Int32 nLastTipOfTheDay
= officecfg::Office::Common::Misc::LastTipOfTheDayShown::get();
1367 const sal_Int32 nDay
= std::chrono::duration_cast
<std::chrono::hours
>(t0
).count()/24; // days since 1970-01-01
1368 return nDay
- nLastTipOfTheDay
> 0; //only once per day
1371 void SfxViewFrame::Notify( SfxBroadcaster
& /*rBC*/, const SfxHint
& rHint
)
1373 if(m_pImpl
->bIsDowning
)
1376 // we know only SfxEventHint or simple SfxHint
1377 if (const SfxEventHint
* pEventHint
= dynamic_cast<const SfxEventHint
*>(&rHint
))
1379 // When the Document is loaded asynchronously, was the Dispatcher
1380 // set as ReadOnly, to what must be returned when the document itself
1381 // is not read only, and the loading is finished.
1382 switch ( pEventHint
->GetEventId() )
1384 case SfxEventHintId::ModifyChanged
:
1386 SfxBindings
& rBind
= GetBindings();
1387 rBind
.Invalidate( SID_DOC_MODIFIED
);
1388 rBind
.Invalidate( SID_RELOAD
);
1389 rBind
.Invalidate( SID_EDITDOC
);
1393 case SfxEventHintId::OpenDoc
:
1394 case SfxEventHintId::CreateDoc
:
1396 if ( !m_xObjSh
.is() )
1399 SfxBindings
& rBind
= GetBindings();
1400 rBind
.Invalidate( SID_RELOAD
);
1401 rBind
.Invalidate( SID_EDITDOC
);
1403 bool bIsHeadlessOrUITest
= SfxApplication::IsHeadlessOrUITest(); //uitest.uicheck fails when the dialog is open
1405 //what's new infobar
1406 if (utl::isProductVersionUpgraded(true) && !bIsHeadlessOrUITest
)
1408 VclPtr
<SfxInfoBarWindow
> pInfoBar
= AppendInfoBar("whatsnew", "", SfxResId(STR_WHATSNEW_TEXT
), InfobarType::INFO
);
1411 weld::Button
& rWhatsNewButton
= pInfoBar
->addButton();
1412 rWhatsNewButton
.set_label(SfxResId(STR_WHATSNEW_BUTTON
));
1413 rWhatsNewButton
.connect_clicked(LINK(this, SfxViewFrame
, WhatsNewHandler
));
1417 // show tip-of-the-day dialog if it due, but not if there is the impress modal template dialog
1418 // open where SdModule::ExecuteNewDocument will launch it instead when that dialog is dismissed
1419 if (SfxApplication::IsTipOfTheDayDue() && !bIsHeadlessOrUITest
&& !IsInModalMode())
1421 // tdf#127946 pass in argument for dialog parent
1422 SfxUnoFrameItem
aDocFrame(SID_FILLFRAME
, GetFrame().GetFrameInterface());
1423 GetDispatcher()->ExecuteList(SID_TIPOFTHEDAY
, SfxCallMode::SLOT
, {}, { &aDocFrame
});
1426 if (officecfg::Office::Common::Passwords::HasMaster::get() &&
1427 officecfg::Office::Common::Passwords::StorageVersion::get() == 0)
1429 // master password stored in deprecated format
1430 VclPtr
<SfxInfoBarWindow
> pOldMasterPasswordInfoBar
=
1431 AppendInfoBar("oldmasterpassword", "",
1432 SfxResId(STR_REFRESH_MASTER_PASSWORD
), InfobarType::DANGER
, false);
1433 if (pOldMasterPasswordInfoBar
)
1435 weld::Button
& rButton
= pOldMasterPasswordInfoBar
->addButton();
1436 rButton
.set_label(SfxResId(STR_REFRESH_PASSWORD
));
1437 rButton
.connect_clicked(LINK(this,
1438 SfxViewFrame
, RefreshMasterPasswordHdl
));
1442 // read-only infobar if necessary
1443 const SfxViewShell
*pVSh
;
1444 const SfxShell
*pFSh
;
1445 if ( m_xObjSh
->IsReadOnly() &&
1446 ! m_xObjSh
->IsSecurityOptOpenReadOnly() &&
1447 ( m_xObjSh
->GetCreateMode() != SfxObjectCreateMode::EMBEDDED
||
1448 (( pVSh
= m_xObjSh
->GetViewShell()) && (pFSh
= pVSh
->GetFormShell()) && pFSh
->IsDesignMode())))
1450 AppendReadOnlyInfobar();
1453 if (vcl::CommandInfoProvider::GetModuleIdentifier(GetFrame().GetFrameInterface()) == "com.sun.star.text.TextDocument")
1454 sfx2::SfxNotebookBar::ReloadNotebookBar(u
"modules/swriter/ui/");
1456 if (SfxClassificationHelper::IsClassified(m_xObjSh
->getDocProperties()))
1458 // Document has BAILS properties, display an infobar accordingly.
1459 SfxClassificationHelper
aHelper(m_xObjSh
->getDocProperties());
1460 aHelper
.UpdateInfobar(*this);
1463 // Add pending infobars
1464 std::vector
<InfobarData
>& aPendingInfobars
= m_xObjSh
->getPendingInfobars();
1465 while (!aPendingInfobars
.empty())
1467 InfobarData
& aInfobarData
= aPendingInfobars
.back();
1469 // don't show Track Changes infobar, if Track Changes toolbar is visible
1470 if (aInfobarData
.msId
== "hiddentrackchanges")
1472 if (auto xLayoutManager
= getLayoutManager(GetFrame()))
1474 if ( xLayoutManager
->getElement(CHANGES_STR
).is() )
1476 aPendingInfobars
.pop_back();
1482 // Track Changes infobar: add a button to show/hide Track Changes functions
1483 // Hyphenation infobar: add a button to get more information
1484 // tdf#148913 limit VclPtr usage for these
1485 bool bTrackChanges
= aInfobarData
.msId
== "hiddentrackchanges";
1486 if ( bTrackChanges
|| aInfobarData
.msId
== "hyphenationmissing" )
1488 VclPtr
<SfxInfoBarWindow
> pInfoBar
=
1489 AppendInfoBar(aInfobarData
.msId
, aInfobarData
.msPrimaryMessage
,
1490 aInfobarData
.msSecondaryMessage
, aInfobarData
.maInfobarType
,
1491 aInfobarData
.mbShowCloseButton
);
1493 // tdf#148913 don't extend this condition to keep it thread-safe
1496 weld::Button
& rButton
= pInfoBar
->addButton();
1497 rButton
.set_label(SfxResId(bTrackChanges
1498 ? STR_TRACK_CHANGES_BUTTON
1499 : STR_HYPHENATION_BUTTON
));
1502 rButton
.connect_clicked(LINK(this,
1503 SfxViewFrame
, HiddenTrackChangesHandler
));
1507 rButton
.connect_clicked(LINK(this,
1508 SfxViewFrame
, HyphenationMissingHandler
));
1514 AppendInfoBar(aInfobarData
.msId
, aInfobarData
.msPrimaryMessage
,
1515 aInfobarData
.msSecondaryMessage
, aInfobarData
.maInfobarType
,
1516 aInfobarData
.mbShowCloseButton
);
1519 aPendingInfobars
.pop_back();
1529 switch( rHint
.GetId() )
1531 case SfxHintId::ModeChanged
:
1535 if ( !m_xObjSh
.is() )
1539 SfxBindings
& rBind
= GetBindings();
1540 rBind
.Invalidate( SID_RELOAD
);
1541 SfxDispatcher
*pDispat
= GetDispatcher();
1542 bool bWasReadOnly
= pDispat
->GetReadOnly_Impl();
1543 bool bIsReadOnly
= m_xObjSh
->IsReadOnly();
1544 if ( bWasReadOnly
!= bIsReadOnly
)
1546 // Then also TITLE_CHANGED
1548 rBind
.Invalidate( SID_FILE_NAME
);
1549 rBind
.Invalidate( SID_DOCINFO_TITLE
);
1550 rBind
.Invalidate( SID_EDITDOC
);
1552 pDispat
->GetBindings()->InvalidateAll(true);
1553 pDispat
->SetReadOnly_Impl( bIsReadOnly
);
1555 // Only force and Dispatcher-Update, if it is done next
1556 // anyway, otherwise flickering or GPF is possible since
1557 // the Writer for example prefers in Resize perform some
1558 // actions which has a SetReadOnlyUI in Dispatcher as a
1561 if ( pDispat
->IsUpdated_Impl() )
1562 pDispat
->Update_Impl(true);
1565 Enable( !m_xObjSh
->IsInModalMode() );
1569 case SfxHintId::TitleChanged
:
1572 SfxBindings
& rBind
= GetBindings();
1573 rBind
.Invalidate( SID_FILE_NAME
);
1574 rBind
.Invalidate( SID_DOCINFO_TITLE
);
1575 rBind
.Invalidate( SID_EDITDOC
);
1576 rBind
.Invalidate( SID_RELOAD
);
1580 case SfxHintId::DocumentRepair
:
1582 GetBindings().Invalidate( SID_DOC_REPAIR
);
1586 case SfxHintId::Deinitializing
:
1588 vcl::Window
* pFrameWin
= GetWindow().GetFrameWindow();
1589 if (pFrameWin
&& pFrameWin
->GetLOKNotifier())
1590 pFrameWin
->ReleaseLOKNotifier();
1592 GetFrame().DoClose();
1595 case SfxHintId::Dying
:
1596 // when the Object is being deleted, destroy the view too
1597 if ( m_xObjSh
.is() )
1598 ReleaseObjectShell_Impl();
1600 GetFrame().DoClose();
1607 IMPL_LINK_NOARG(SfxViewFrame
, WhatsNewHandler
, weld::Button
&, void)
1609 GetDispatcher()->Execute(SID_WHATSNEW
);
1612 IMPL_LINK_NOARG(SfxViewFrame
, GetInvolvedHandler
, weld::Button
&, void)
1614 GetDispatcher()->Execute(SID_GETINVOLVED
);
1617 IMPL_LINK_NOARG(SfxViewFrame
, DonationHandler
, weld::Button
&, void)
1619 GetDispatcher()->Execute(SID_DONATION
);
1622 IMPL_LINK(SfxViewFrame
, SwitchReadOnlyHandler
, weld::Button
&, rButton
, void)
1624 if (m_xObjSh
.is() && m_xObjSh
->IsSignPDF())
1626 SfxEditDocumentDialog
aDialog(&rButton
);
1627 if (aDialog
.run() != RET_OK
)
1630 GetDispatcher()->Execute(SID_EDITDOC
);
1633 IMPL_LINK_NOARG(SfxViewFrame
, SignDocumentHandler
, weld::Button
&, void)
1635 GetDispatcher()->Execute(SID_SIGNATURE
);
1638 IMPL_LINK(SfxViewFrame
, HiddenTrackChangesHandler
, weld::Button
&, rButton
, void)
1640 // enable Track Changes toolbar, if it is disabled.
1641 // Otherwise disable the toolbar, and close the infobar
1642 auto xLayoutManager
= getLayoutManager(GetFrame());
1643 if (!xLayoutManager
)
1646 if (!xLayoutManager
->getElement(CHANGES_STR
).is())
1648 xLayoutManager
->createElement(CHANGES_STR
);
1649 xLayoutManager
->showElement(CHANGES_STR
);
1650 rButton
.set_label(SfxResId(STR_TRACK_CHANGES_BUTTON_HIDE
));
1654 xLayoutManager
->hideElement(CHANGES_STR
);
1655 xLayoutManager
->destroyElement(CHANGES_STR
);
1656 RemoveInfoBar(u
"hiddentrackchanges");
1660 IMPL_LINK_NOARG(SfxViewFrame
, HyphenationMissingHandler
, weld::Button
&, void)
1662 GetDispatcher()->Execute(SID_HYPHENATIONMISSING
);
1663 RemoveInfoBar(u
"hyphenationmissing");
1666 IMPL_LINK_NOARG(SfxViewFrame
, RefreshMasterPasswordHdl
, weld::Button
&, void)
1668 bool bChanged
= false;
1671 Reference
< task::XPasswordContainer2
> xMasterPasswd(
1672 task::PasswordContainer::create(comphelper::getProcessComponentContext()));
1674 css::uno::Reference
<css::frame::XFrame
> xFrame
= GetFrame().GetFrameInterface();
1675 css::uno::Reference
<css::awt::XWindow
> xContainerWindow
= xFrame
->getContainerWindow();
1677 uno::Reference
<task::XInteractionHandler
> xTmpHandler(task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(),
1679 bChanged
= xMasterPasswd
->changeMasterPassword(xTmpHandler
);
1681 catch (const Exception
&)
1684 RemoveInfoBar(u
"oldmasterpassword");
1687 void SfxViewFrame::Construct_Impl( SfxObjectShell
*pObjSh
)
1689 m_pImpl
->bResizeInToOut
= true;
1690 m_pImpl
->bObjLocked
= false;
1691 m_pImpl
->nCurViewId
= SFX_INTERFACE_NONE
;
1692 m_pImpl
->bReloading
= false;
1693 m_pImpl
->bIsDowning
= false;
1694 m_pImpl
->bModal
= false;
1695 m_pImpl
->bEnabled
= true;
1696 m_pImpl
->nDocViewNo
= 0;
1697 m_pImpl
->aMargin
= Size( -1, -1 );
1698 m_pImpl
->pWindow
= nullptr;
1700 SetPool( &SfxGetpApp()->GetPool() );
1701 m_pDispatcher
.reset( new SfxDispatcher(this) );
1702 if ( !GetBindings().GetDispatcher() )
1703 GetBindings().SetDispatcher( m_pDispatcher
.get() );
1706 if ( m_xObjSh
.is() && m_xObjSh
->IsPreview() )
1707 GetDispatcher()->SetQuietMode_Impl( true );
1711 m_pDispatcher
->Push( *SfxGetpApp() );
1712 SfxModule
* pModule
= m_xObjSh
->GetModule();
1714 m_pDispatcher
->Push( *pModule
);
1715 m_pDispatcher
->Push( *this );
1716 m_pDispatcher
->Push( *pObjSh
);
1717 m_pDispatcher
->Flush();
1718 StartListening( *pObjSh
);
1719 Notify( *pObjSh
, SfxHint(SfxHintId::TitleChanged
) );
1720 Notify( *pObjSh
, SfxHint(SfxHintId::DocChanged
) );
1721 m_pDispatcher
->SetReadOnly_Impl( pObjSh
->IsReadOnly() );
1725 m_pDispatcher
->Push( *SfxGetpApp() );
1726 m_pDispatcher
->Push( *this );
1727 m_pDispatcher
->Flush();
1730 SfxGetpApp()->GetViewFrames_Impl().push_back(this);
1735 Constructor of SfxViewFrame for a <SfxObjectShell> from the Resource.
1736 The 'nViewId' to the created <SfxViewShell> can be returned.
1737 (default is the SfxViewShell-Subclass that was registered first).
1739 SfxViewFrame::SfxViewFrame
1742 SfxObjectShell
* pObjShell
1744 : m_pImpl( new SfxViewFrame_Impl( rFrame
) )
1745 , m_pBindings( new SfxBindings
)
1746 , m_pHelpData(CreateSVHelpData())
1747 , m_pWinData(CreateSVWinData())
1748 , m_nAdjustPosPixelLock( 0 )
1749 , m_pCommandPopupHandler(new CommandPopupHandler
)
1752 rFrame
.SetCurrentViewFrame_Impl( this );
1753 rFrame
.SetHasTitle( true );
1754 Construct_Impl( pObjShell
);
1756 m_pImpl
->pWindow
= VclPtr
<SfxFrameViewWindow_Impl
>::Create( this, rFrame
.GetWindow() );
1757 m_pImpl
->pWindow
->SetSizePixel( rFrame
.GetWindow().GetOutputSizePixel() );
1758 rFrame
.SetOwnsBindings_Impl( true );
1759 rFrame
.CreateWorkWindow_Impl();
1762 SfxViewFrame::~SfxViewFrame()
1764 m_pImpl
->bIsDowning
= true;
1766 if ( SfxViewFrame::Current() == this )
1767 SfxViewFrame::SetViewFrame( nullptr );
1769 ReleaseObjectShell_Impl();
1771 if ( GetFrame().OwnsBindings_Impl() )
1772 // The Bindings delete the Frame!
1773 KillDispatcher_Impl();
1775 m_pImpl
->pWindow
.disposeAndClear();
1777 if ( GetFrame().GetCurrentViewFrame() == this )
1778 GetFrame().SetCurrentViewFrame_Impl( nullptr );
1780 // Unregister from the Frame List.
1781 SfxApplication
*pSfxApp
= SfxApplication::Get();
1784 auto &rFrames
= pSfxApp
->GetViewFrames_Impl();
1785 auto it
= std::find( rFrames
.begin(), rFrames
.end(), this );
1786 rFrames
.erase( it
);
1790 KillDispatcher_Impl();
1792 DestroySVHelpData(m_pHelpData
);
1793 m_pHelpData
= nullptr;
1795 DestroySVWinData(m_pWinData
);
1796 m_pWinData
= nullptr;
1799 // Remove and delete the Dispatcher.
1800 void SfxViewFrame::KillDispatcher_Impl()
1803 SfxModule
* pModule
= m_xObjSh
.is() ? m_xObjSh
->GetModule() : nullptr;
1804 if ( m_xObjSh
.is() )
1805 ReleaseObjectShell_Impl();
1806 if ( m_pDispatcher
)
1809 m_pDispatcher
->Pop( *pModule
, SfxDispatcherPopFlags::POP_UNTIL
);
1811 m_pDispatcher
->Pop( *this );
1812 m_pDispatcher
.reset();
1816 SfxViewFrame
* SfxViewFrame::Current()
1818 SfxApplication
* pApp
= SfxApplication::Get();
1819 return pApp
? pApp
->Get_Impl()->pViewFrame
: nullptr;
1822 // returns the first window of spec. type viewing the specified doc.
1823 SfxViewFrame
* SfxViewFrame::GetFirst
1825 const SfxObjectShell
* pDoc
,
1829 SfxApplication
*pSfxApp
= SfxApplication::Get();
1833 // search for a SfxDocument of the specified type
1834 for (SfxViewFrame
* pFrame
: pSfxApp
->GetViewFrames_Impl())
1836 if ( ( !pDoc
|| pDoc
== pFrame
->GetObjectShell() )
1837 && ( !bOnlyIfVisible
|| pFrame
->IsVisible() )
1845 // returns the next window of spec. type viewing the specified doc.
1846 SfxViewFrame
* SfxViewFrame::GetNext
1848 const SfxViewFrame
& rPrev
,
1849 const SfxObjectShell
* pDoc
,
1853 SfxApplication
*pSfxApp
= SfxApplication::Get();
1857 auto &rFrames
= pSfxApp
->GetViewFrames_Impl();
1859 // refind the specified predecessor
1861 for ( nPos
= 0; nPos
< rFrames
.size(); ++nPos
)
1862 if ( rFrames
[nPos
] == &rPrev
)
1865 // search for a Frame of the specified type
1866 for ( ++nPos
; nPos
< rFrames
.size(); ++nPos
)
1868 SfxViewFrame
*pFrame
= rFrames
[nPos
];
1869 if ( ( !pDoc
|| pDoc
== pFrame
->GetObjectShell() )
1870 && ( !bOnlyIfVisible
|| pFrame
->IsVisible() )
1877 SfxProgress
* SfxViewFrame::GetProgress() const
1879 SfxObjectShell
*pObjSh
= m_xObjSh
.get();
1880 return pObjSh
? pObjSh
->GetProgress() : nullptr;
1883 void SfxViewFrame::DoAdjustPosSizePixel
//! divide on Inner.../Outer...
1888 bool inplaceEditModeChange
1892 // Components do not use this Method!
1893 if( pSh
&& pSh
->GetWindow() && !m_nAdjustPosPixelLock
)
1895 m_nAdjustPosPixelLock
++;
1896 if ( m_pImpl
->bResizeInToOut
)
1897 pSh
->InnerResizePixel( rPos
, rSize
, inplaceEditModeChange
);
1899 pSh
->OuterResizePixel( rPos
, rSize
);
1900 m_nAdjustPosPixelLock
--;
1904 bool SfxViewFrameItem::operator==( const SfxPoolItem
&rItem
) const
1906 return SfxPoolItem::operator==(rItem
) &&
1907 static_cast<const SfxViewFrameItem
&>(rItem
).pFrame
== pFrame
;
1910 SfxViewFrameItem
* SfxViewFrameItem::Clone( SfxItemPool
*) const
1912 return new SfxViewFrameItem( *this );
1915 void SfxViewFrame::SetViewShell_Impl( SfxViewShell
*pVSh
)
1918 Internal Method to set the current <SfxViewShell> Instance,
1919 that is active int this SfxViewFrame at the moment.
1922 SfxShell::SetViewShell_Impl( pVSh
);
1924 // Hack: InPlaceMode
1926 m_pImpl
->bResizeInToOut
= false;
1929 void SfxViewFrame::ForceOuterResize_Impl()
1931 m_pImpl
->bResizeInToOut
= true;
1934 void SfxViewFrame::GetDocNumber_Impl()
1936 DBG_ASSERT( GetObjectShell(), "No Document!" );
1937 GetObjectShell()->SetNamedVisibility_Impl();
1938 m_pImpl
->nDocViewNo
= GetObjectShell()->GetNoSet_Impl().GetFreeIndex()+1;
1941 void SfxViewFrame::Enable( bool bEnable
)
1943 if ( bEnable
== m_pImpl
->bEnabled
)
1946 m_pImpl
->bEnabled
= bEnable
;
1948 vcl::Window
*pWindow
= &GetFrame().GetWindow();
1950 m_pImpl
->bWindowWasEnabled
= pWindow
->IsInputEnabled();
1951 if ( !bEnable
|| m_pImpl
->bWindowWasEnabled
)
1952 pWindow
->EnableInput( bEnable
);
1955 SfxViewShell
* pViewSh
= GetViewShell();
1960 pViewSh
->ShowCursor();
1966 pViewSh
->ShowCursor(false);
1972 This method makes the Frame-Window visible and before transmits the
1973 window name. In addition, the document is held. In general one can never
1974 show the window directly!
1976 void SfxViewFrame::Show()
1978 // First lock the objectShell so that UpdateTitle() is valid:
1979 // IsVisible() == true (:#)
1980 if ( m_xObjSh
.is() )
1982 m_xObjSh
->GetMedium()->GetItemSet()->ClearItem( SID_HIDDEN
);
1983 if ( !m_pImpl
->bObjLocked
)
1984 LockObjectShell_Impl();
1986 // Adjust Doc-Shell title number, get unique view-no
1987 if ( 0 == m_pImpl
->nDocViewNo
)
1989 GetDocNumber_Impl();
1996 // Display Frame-window, but only if the ViewFrame has no window of its
1997 // own or if it does not contain a Component
1999 GetFrame().GetWindow().Show();
2003 bool SfxViewFrame::IsVisible() const
2005 return m_pImpl
->bObjLocked
;
2009 void SfxViewFrame::LockObjectShell_Impl()
2011 DBG_ASSERT( !m_pImpl
->bObjLocked
, "Wrong Locked status!" );
2013 DBG_ASSERT( GetObjectShell(), "No Document!" );
2014 GetObjectShell()->OwnerLock(true);
2015 m_pImpl
->bObjLocked
= true;
2019 void SfxViewFrame::MakeActive_Impl( bool bGrabFocus
)
2021 if ( !GetViewShell() || GetFrame().IsClosing_Impl() )
2027 bool bPreview
= false;
2028 if (GetObjectShell()->IsPreview())
2033 css::uno::Reference
<css::frame::XFrame
> xFrame
= GetFrame().GetFrameInterface();
2037 GetBindings().SetActiveFrame(css::uno::Reference
<css::frame::XFrame
>());
2038 uno::Reference
<frame::XFramesSupplier
> xSupp(xFrame
, uno::UNO_QUERY
);
2040 xSupp
->setActiveFrame(uno::Reference
<frame::XFrame
>());
2042 css::uno::Reference
< css::awt::XWindow
> xContainerWindow
= xFrame
->getContainerWindow();
2043 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow(xContainerWindow
);
2044 if (pWindow
&& pWindow
->HasChildPathFocus() && bGrabFocus
)
2046 SfxInPlaceClient
*pCli
= GetViewShell()->GetUIActiveClient();
2047 if (!pCli
|| !pCli
->IsObjectUIActive())
2048 GetFrame().GrabFocusOnComponent_Impl();
2053 GetBindings().SetDispatcher(GetDispatcher());
2054 GetBindings().SetActiveFrame(css::uno::Reference
<css::frame::XFrame
>());
2055 GetDispatcher()->Update_Impl();
2059 SfxObjectShell
* SfxViewFrame::GetObjectShell()
2061 return m_xObjSh
.get();
2064 const Size
& SfxViewFrame::GetMargin_Impl() const
2066 return m_pImpl
->aMargin
;
2069 SfxViewFrame
* SfxViewFrame::LoadViewIntoFrame_Impl_NoThrow( const SfxObjectShell
& i_rDoc
, const Reference
< XFrame
>& i_rFrame
,
2070 const SfxInterfaceId i_nViewId
, const bool i_bHidden
)
2072 Reference
< XFrame
> xFrame( i_rFrame
);
2073 bool bOwnFrame
= false;
2074 SfxViewShell
* pSuccessView
= nullptr;
2079 Reference
< XDesktop2
> xDesktop
= Desktop::create( ::comphelper::getProcessComponentContext() );
2085 // if there is a backing component, use it
2086 ::framework::FrameListAnalyzer
aAnalyzer( xDesktop
, Reference
< XFrame
>(), FrameAnalyzerFlags::BackingComponent
);
2088 if ( aAnalyzer
.m_xBackingComponent
.is() )
2089 xFrame
= aAnalyzer
.m_xBackingComponent
;
2091 catch( uno::Exception
& )
2096 xFrame
.set( xDesktop
->findFrame( "_blank", 0 ), UNO_SET_THROW
);
2101 pSuccessView
= LoadViewIntoFrame_Impl(
2104 Sequence
< PropertyValue
>(), // means "reuse existing model's args"
2109 if ( bOwnFrame
&& !i_bHidden
)
2111 // ensure the frame/window is visible
2112 Reference
< XWindow
> xContainerWindow( xFrame
->getContainerWindow(), UNO_SET_THROW
);
2113 xContainerWindow
->setVisible( true );
2116 catch( const Exception
& )
2118 DBG_UNHANDLED_EXCEPTION("sfx.view");
2122 return pSuccessView
->GetViewFrame();
2130 catch( const Exception
& )
2132 DBG_UNHANDLED_EXCEPTION("sfx.view");
2139 SfxViewShell
* SfxViewFrame::LoadViewIntoFrame_Impl( const SfxObjectShell
& i_rDoc
, const Reference
< XFrame
>& i_rFrame
,
2140 const Sequence
< PropertyValue
>& i_rLoadArgs
, const SfxInterfaceId i_nViewId
,
2141 const bool i_bHidden
)
2143 Reference
< XModel
> xDocument( i_rDoc
.GetModel(), UNO_SET_THROW
);
2145 ::comphelper::NamedValueCollection
aTransformLoadArgs( i_rLoadArgs
.hasElements() ? i_rLoadArgs
: xDocument
->getArgs() );
2146 aTransformLoadArgs
.put( "Model", xDocument
);
2148 aTransformLoadArgs
.put( "ViewId", sal_uInt16( i_nViewId
) );
2150 aTransformLoadArgs
.put( "Hidden", i_bHidden
);
2152 aTransformLoadArgs
.remove( "Hidden" );
2154 Reference
< XComponentLoader
> xLoader( i_rFrame
, UNO_QUERY_THROW
);
2155 xLoader
->loadComponentFromURL( "private:object", "_self", 0,
2156 aTransformLoadArgs
.getPropertyValues() );
2158 SfxViewShell
* pViewShell
= SfxViewShell::Get( i_rFrame
->getController() );
2159 ENSURE_OR_THROW( pViewShell
,
2160 "SfxViewFrame::LoadViewIntoFrame_Impl: loading an SFX doc into a frame resulted in a non-SFX view - quite impossible" );
2164 SfxViewFrame
* SfxViewFrame::LoadHiddenDocument( SfxObjectShell
const & i_rDoc
, SfxInterfaceId i_nViewId
)
2166 return LoadViewIntoFrame_Impl_NoThrow( i_rDoc
, Reference
< XFrame
>(), i_nViewId
, true );
2169 SfxViewFrame
* SfxViewFrame::LoadDocument( SfxObjectShell
const & i_rDoc
, SfxInterfaceId i_nViewId
)
2171 return LoadViewIntoFrame_Impl_NoThrow( i_rDoc
, Reference
< XFrame
>(), i_nViewId
, false );
2174 SfxViewFrame
* SfxViewFrame::LoadDocumentIntoFrame( SfxObjectShell
const & i_rDoc
, const Reference
< XFrame
>& i_rTargetFrame
)
2176 return LoadViewIntoFrame_Impl_NoThrow( i_rDoc
, i_rTargetFrame
, SFX_INTERFACE_NONE
, false );
2179 SfxViewFrame
* SfxViewFrame::LoadDocumentIntoFrame( SfxObjectShell
const & i_rDoc
, const SfxFrameItem
* i_pFrameItem
, SfxInterfaceId i_nViewId
)
2181 return LoadViewIntoFrame_Impl_NoThrow( i_rDoc
, i_pFrameItem
&& i_pFrameItem
->GetFrame() ? i_pFrameItem
->GetFrame()->GetFrameInterface() : nullptr, i_nViewId
, false );
2184 SfxViewFrame
* SfxViewFrame::DisplayNewDocument( SfxObjectShell
const & i_rDoc
, const SfxRequest
& i_rCreateDocRequest
)
2186 const SfxUnoFrameItem
* pFrameItem
= i_rCreateDocRequest
.GetArg
<SfxUnoFrameItem
>(SID_FILLFRAME
);
2187 const SfxBoolItem
* pHiddenItem
= i_rCreateDocRequest
.GetArg
<SfxBoolItem
>(SID_HIDDEN
);
2189 return LoadViewIntoFrame_Impl_NoThrow(
2191 pFrameItem
? pFrameItem
->GetFrame() : nullptr,
2193 pHiddenItem
&& pHiddenItem
->GetValue()
2197 SfxViewFrame
* SfxViewFrame::Get( const Reference
< XController
>& i_rController
, const SfxObjectShell
* i_pDoc
)
2199 if ( !i_rController
.is() )
2202 const SfxObjectShell
* pDoc
= i_pDoc
;
2205 Reference
< XModel
> xDocument( i_rController
->getModel() );
2206 for ( pDoc
= SfxObjectShell::GetFirst( nullptr, false );
2208 pDoc
= SfxObjectShell::GetNext( *pDoc
, nullptr, false )
2211 if ( pDoc
->GetModel() == xDocument
)
2216 SfxViewFrame
* pViewFrame
= nullptr;
2217 for ( pViewFrame
= SfxViewFrame::GetFirst( pDoc
, false );
2219 pViewFrame
= SfxViewFrame::GetNext( *pViewFrame
, pDoc
, false )
2222 if ( pViewFrame
->GetViewShell()->GetController() == i_rController
)
2229 void SfxViewFrame::SaveCurrentViewData_Impl( const SfxInterfaceId i_nNewViewId
)
2231 SfxViewShell
* pCurrentShell
= GetViewShell();
2232 ENSURE_OR_RETURN_VOID( pCurrentShell
!= nullptr, "SfxViewFrame::SaveCurrentViewData_Impl: no current view shell -> no current view data!" );
2234 // determine the logical (API) view name
2235 const SfxObjectFactory
& rDocFactory( pCurrentShell
->GetObjectShell()->GetFactory() );
2236 const sal_uInt16 nCurViewNo
= rDocFactory
.GetViewNo_Impl( GetCurViewId(), 0 );
2237 const OUString sCurrentViewName
= rDocFactory
.GetViewFactory( nCurViewNo
).GetAPIViewName();
2238 const sal_uInt16 nNewViewNo
= rDocFactory
.GetViewNo_Impl( i_nNewViewId
, 0 );
2239 const OUString sNewViewName
= rDocFactory
.GetViewFactory( nNewViewNo
).GetAPIViewName();
2240 if ( sCurrentViewName
.isEmpty() || sNewViewName
.isEmpty() )
2242 // can't say anything about the view, the respective application did not yet migrate its code to
2243 // named view factories => bail out
2244 OSL_FAIL( "SfxViewFrame::SaveCurrentViewData_Impl: views without API names? Shouldn't happen anymore?" );
2247 SAL_WARN_IF(sNewViewName
== sCurrentViewName
, "sfx.view", "SfxViewFrame::SaveCurrentViewData_Impl: suspicious: new and old view name are identical!");
2249 // save the view data only when we're moving from a non-print-preview to the print-preview view
2250 if ( sNewViewName
!= "PrintPreview" )
2253 // retrieve the view data from the view
2254 Sequence
< PropertyValue
> aViewData
;
2255 pCurrentShell
->WriteUserDataSequence( aViewData
);
2259 // retrieve view data (for *all* views) from the model
2260 const Reference
< XController
> xController( pCurrentShell
->GetController(), UNO_SET_THROW
);
2261 const Reference
< XViewDataSupplier
> xViewDataSupplier( xController
->getModel(), UNO_QUERY_THROW
);
2262 const Reference
< XIndexContainer
> xViewData( xViewDataSupplier
->getViewData(), UNO_QUERY_THROW
);
2264 // look up the one view data item which corresponds to our current view, and remove it
2265 const sal_Int32 nCount
= xViewData
->getCount();
2266 for ( sal_Int32 i
=0; i
<nCount
; ++i
)
2268 const ::comphelper::NamedValueCollection
aCurViewData( xViewData
->getByIndex(i
) );
2269 const OUString
sViewId( aCurViewData
.getOrDefault( "ViewId", OUString() ) );
2270 if ( sViewId
.isEmpty() )
2273 const SfxViewFactory
* pViewFactory
= rDocFactory
.GetViewFactoryByViewName( sViewId
);
2274 if ( pViewFactory
== nullptr )
2277 if ( pViewFactory
->GetOrdinal() == GetCurViewId() )
2279 xViewData
->removeByIndex(i
);
2284 // then replace it with the most recent view data we just obtained
2285 xViewData
->insertByIndex( 0, makeAny( aViewData
) );
2287 catch( const Exception
& )
2289 DBG_UNHANDLED_EXCEPTION("sfx.view");
2295 Internal Method for switching to another <SfxViewShell> subclass,
2296 which should be created in this SfxMDIFrame. If no SfxViewShell exist
2297 in this SfxMDIFrame, then one will first be created.
2303 requested SfxViewShell was created and a
2304 possibly existing one deleted
2307 SfxViewShell requested could not be created,
2308 the existing SfxViewShell thus continue to exist
2310 bool SfxViewFrame::SwitchToViewShell_Impl
2312 sal_uInt16 nViewIdOrNo
, /* > 0
2313 Registration-Id of the View, to which the
2314 method should switch, for example the one
2315 that will be created.
2318 First use the Default view. */
2320 bool bIsIndex
/* true
2321 'nViewIdOrNo' is no Registration-Id instead
2322 an Index of <SfxViewFrame> in <SfxObjectShell>.
2328 ENSURE_OR_THROW( GetObjectShell() != nullptr, "not possible without a document" );
2330 // if we already have a view shell, remove it
2331 SfxViewShell
* pOldSh
= GetViewShell();
2332 OSL_PRECOND( pOldSh
, "SfxViewFrame::SwitchToViewShell_Impl: that's called *switch* (not for *initial-load*) for a reason" );
2335 // ask whether it can be closed
2336 if ( !pOldSh
->PrepareClose() )
2339 // remove sub shells from Dispatcher before switching to new ViewShell
2340 PopShellAndSubShells_Impl( *pOldSh
);
2343 GetBindings().ENTERREGISTRATIONS();
2344 LockAdjustPosSizePixel();
2346 // ID of the new view
2347 SfxObjectFactory
& rDocFact
= GetObjectShell()->GetFactory();
2348 const SfxInterfaceId nViewId
= ( bIsIndex
|| !nViewIdOrNo
) ? rDocFact
.GetViewFactory( nViewIdOrNo
).GetOrdinal() : SfxInterfaceId(nViewIdOrNo
);
2350 // save the view data of the old view, so it can be restored later on (when needed)
2351 SaveCurrentViewData_Impl( nViewId
);
2353 // create and load new ViewShell
2354 SfxViewShell
* pNewSh
= LoadViewIntoFrame_Impl(
2356 GetFrame().GetFrameInterface(),
2357 Sequence
< PropertyValue
>(), // means "reuse existing model's args"
2362 // allow resize events to be processed
2363 UnlockAdjustPosSizePixel();
2365 if ( GetWindow().IsReallyVisible() )
2366 DoAdjustPosSizePixel( pNewSh
, Point(), GetWindow().GetOutputSizePixel(), false );
2368 GetBindings().LEAVEREGISTRATIONS();
2371 catch ( const css::uno::Exception
& )
2373 // the SfxCode is not able to cope with exceptions thrown while creating views
2374 // the code will crash in the stack unwinding procedure, so we shouldn't let exceptions go through here
2375 DBG_UNHANDLED_EXCEPTION("sfx.view");
2379 DBG_ASSERT( SfxGetpApp()->GetViewFrames_Impl().size() == SfxGetpApp()->GetViewShells_Impl().size(), "Inconsistent view arrays!" );
2383 void SfxViewFrame::SetCurViewId_Impl( const SfxInterfaceId i_nID
)
2385 m_pImpl
->nCurViewId
= i_nID
;
2388 SfxInterfaceId
SfxViewFrame::GetCurViewId() const
2390 return m_pImpl
->nCurViewId
;
2395 Internal method to run the slot for the <SfxShell> Subclass in the
2396 SfxViewFrame <SVIDL> described slots.
2398 void SfxViewFrame::ExecView_Impl
2400 SfxRequest
& rReq
// The executable <SfxRequest>
2404 // If the Shells are just being replaced...
2405 if ( !GetObjectShell() || !GetViewShell() )
2408 switch ( rReq
.GetSlot() )
2410 case SID_TERMINATE_INPLACEACTIVATION
:
2412 SfxInPlaceClient
* pClient
= GetViewShell()->GetUIActiveClient();
2414 pClient
->DeactivateObject();
2420 const SfxPoolItem
*pItem
= nullptr;
2422 && SfxItemState::SET
== rReq
.GetArgs()->GetItemState( SID_VIEWSHELL
, false, &pItem
)
2425 const sal_uInt16 nViewId
= static_cast< const SfxUInt16Item
* >( pItem
)->GetValue();
2426 bool bSuccess
= SwitchToViewShell_Impl( nViewId
);
2427 rReq
.SetReturnValue( SfxBoolItem( 0, bSuccess
) );
2432 case SID_VIEWSHELL0
:
2433 case SID_VIEWSHELL1
:
2434 case SID_VIEWSHELL2
:
2435 case SID_VIEWSHELL3
:
2436 case SID_VIEWSHELL4
:
2438 const sal_uInt16 nViewNo
= rReq
.GetSlot() - SID_VIEWSHELL0
;
2439 bool bSuccess
= SwitchToViewShell_Impl( nViewNo
, true );
2440 rReq
.SetReturnValue( SfxBoolItem( 0, bSuccess
) );
2446 // Hack. at the moment a virtual Function
2447 if ( !GetViewShell()->NewWindowAllowed() )
2449 OSL_FAIL( "You should have disabled the 'Window/New Window' slot!" );
2453 // Get ViewData of FrameSets recursively.
2454 GetFrame().GetViewData_Impl();
2455 SfxMedium
* pMed
= GetObjectShell()->GetMedium();
2457 // do not open the new window hidden
2458 pMed
->GetItemSet()->ClearItem( SID_HIDDEN
);
2460 // the view ID (optional arg. TODO: this is currently not supported in the slot definition ...)
2461 const SfxUInt16Item
* pViewIdItem
= rReq
.GetArg
<SfxUInt16Item
>(SID_VIEW_ID
);
2462 const SfxInterfaceId nViewId
= pViewIdItem
? SfxInterfaceId(pViewIdItem
->GetValue()) : GetCurViewId();
2464 Reference
< XFrame
> xFrame
;
2465 // the frame (optional arg. TODO: this is currently not supported in the slot definition ...)
2466 const SfxUnoFrameItem
* pFrameItem
= rReq
.GetArg
<SfxUnoFrameItem
>(SID_FILLFRAME
);
2468 xFrame
= pFrameItem
->GetFrame();
2470 LoadViewIntoFrame_Impl_NoThrow( *GetObjectShell(), xFrame
, nViewId
, false );
2478 const SfxInt16Item
* pItem
= rReq
.GetArg
<SfxInt16Item
>(SID_OBJECT
);
2482 GetViewShell()->DoVerb( pItem
->GetValue() );
2491 This method try to collect information about the count of currently open documents.
2492 But the algorithm is implemented very simple ...
2493 E.g. hidden documents should be ignored here ... but they are counted.
2494 TODO: export special helper "framework::FrameListAnalyzer" within the framework module
2497 static bool impl_maxOpenDocCountReached()
2499 css::uno::Reference
< css::uno::XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
2500 std::optional
<sal_Int32
> x(officecfg::Office::Common::Misc::MaxOpenDocuments::get(xContext
));
2501 // NIL means: count of allowed documents = infinite !
2504 sal_Int32
nMaxDocs(*x
);
2505 sal_Int32 nOpenDocs
= 0;
2507 css::uno::Reference
< css::frame::XDesktop2
> xDesktop
= css::frame::Desktop::create(xContext
);
2508 css::uno::Reference
< css::container::XIndexAccess
> xCont(xDesktop
->getFrames(), css::uno::UNO_QUERY_THROW
);
2510 sal_Int32 c
= xCont
->getCount();
2517 css::uno::Reference
< css::frame::XFrame
> xFrame
;
2518 xCont
->getByIndex(i
) >>= xFrame
;
2522 // a) do not count the help window
2523 if ( xFrame
->getName() == "OFFICE_HELP_TASK" )
2526 // b) count all other frames
2529 catch(const css::uno::Exception
&)
2530 // An IndexOutOfBoundsException can happen in multithreaded
2531 // environments, where any other thread can change this
2536 return (nOpenDocs
>= nMaxDocs
);
2541 This internal method returns in 'rSet' the Status for the <SfxShell>
2542 Subclass SfxViewFrame in the <SVIDL> described <Slots>.
2544 Thus exactly those Slots-IDs that are recognized as being invalid by Sfx
2545 are included as Which-ranges in 'rSet'. If there exists a mapping for
2546 single slot-IDs of the <SfxItemPool> set in the shell, then the respective
2547 Which-IDs are used so that items can be replaced directly with a working
2548 Core::sun::com::star::script::Engine of the Which-IDs if possible. .
2550 void SfxViewFrame::StateView_Impl
2552 SfxItemSet
& rSet
/* empty <SfxItemSet> with <Which-Ranges>,
2553 which describes the Slot Ids */
2557 SfxObjectShell
*pDocSh
= GetObjectShell();
2560 // I'm just on reload and am yielding myself ...
2563 const WhichRangesContainer
& pRanges
= rSet
.GetRanges();
2564 assert(!pRanges
.empty() && "Set with no Range");
2565 for ( auto const & pRange
: pRanges
)
2567 sal_uInt16 nStartWhich
= pRange
.first
;
2568 sal_uInt16 nEndWhich
= pRange
.second
;
2569 for ( sal_uInt16 nWhich
= nStartWhich
; nWhich
<= nEndWhich
; ++nWhich
)
2575 rSet
.Put( SfxUInt16Item( nWhich
, sal_uInt16(m_pImpl
->nCurViewId
)) );
2579 case SID_VIEWSHELL0
:
2580 case SID_VIEWSHELL1
:
2581 case SID_VIEWSHELL2
:
2582 case SID_VIEWSHELL3
:
2583 case SID_VIEWSHELL4
:
2585 sal_uInt16 nViewNo
= nWhich
- SID_VIEWSHELL0
;
2586 if ( GetObjectShell()->GetFactory().GetViewFactoryCount() >
2587 nViewNo
&& !GetObjectShell()->IsInPlaceActive() )
2589 SfxViewFactory
&rViewFactory
=
2590 GetObjectShell()->GetFactory().GetViewFactory(nViewNo
);
2591 rSet
.Put( SfxBoolItem(
2592 nWhich
, m_pImpl
->nCurViewId
== rViewFactory
.GetOrdinal() ) );
2595 rSet
.DisableItem( nWhich
);
2601 if ( !GetViewShell()->NewWindowAllowed()
2602 || impl_maxOpenDocCountReached()
2604 rSet
.DisableItem( nWhich
);
2613 void SfxViewFrame::ToTop()
2615 GetFrame().Appear();
2621 GetFrame returns the Frame, in which the ViewFrame is located.
2623 SfxFrame
& SfxViewFrame::GetFrame() const
2625 return m_pImpl
->rFrame
;
2628 SfxViewFrame
* SfxViewFrame::GetTopViewFrame() const
2630 return GetFrame().GetCurrentViewFrame();
2633 vcl::Window
& SfxViewFrame::GetWindow() const
2635 return m_pImpl
->pWindow
? *m_pImpl
->pWindow
: GetFrame().GetWindow();
2638 weld::Window
* SfxViewFrame::GetFrameWeld() const
2640 return GetWindow().GetFrameWeld();
2643 bool SfxViewFrame::DoClose()
2645 return GetFrame().DoClose();
2648 OUString
SfxViewFrame::GetActualPresentationURL_Impl() const
2650 if ( m_xObjSh
.is() )
2651 return m_xObjSh
->GetMedium()->GetName();
2655 void SfxViewFrame::SetModalMode( bool bModal
)
2657 // no real modality for LOK
2658 if (comphelper::LibreOfficeKit::isActive())
2661 m_pImpl
->bModal
= bModal
;
2662 if ( m_xObjSh
.is() )
2664 for ( SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( m_xObjSh
.get() );
2665 !bModal
&& pFrame
; pFrame
= SfxViewFrame::GetNext( *pFrame
, m_xObjSh
.get() ) )
2666 bModal
= pFrame
->m_pImpl
->bModal
;
2667 m_xObjSh
->SetModalMode_Impl( bModal
);
2671 bool SfxViewFrame::IsInModalMode() const
2673 return m_pImpl
->bModal
|| GetFrame().GetWindow().IsInModalMode();
2676 void SfxViewFrame::Resize( bool bForce
)
2678 Size aSize
= GetWindow().GetOutputSizePixel();
2679 if ( !bForce
&& aSize
== m_pImpl
->aSize
)
2682 m_pImpl
->aSize
= aSize
;
2683 SfxViewShell
*pShell
= GetViewShell();
2686 if ( GetFrame().IsInPlace() )
2688 Point aPoint
= GetWindow().GetPosPixel();
2689 DoAdjustPosSizePixel( pShell
, aPoint
, aSize
, true );
2693 DoAdjustPosSizePixel( pShell
, Point(), aSize
, false );
2698 #if HAVE_FEATURE_SCRIPTING
2700 #define LINE_SEP 0x0A
2702 static void CutLines( OUString
& rStr
, sal_Int32 nStartLine
, sal_Int32 nLines
)
2704 sal_Int32 nStartPos
= 0;
2705 sal_Int32 nLine
= 0;
2706 while ( nLine
< nStartLine
)
2708 nStartPos
= rStr
.indexOf( LINE_SEP
, nStartPos
);
2709 if( nStartPos
== -1 )
2711 nStartPos
++; // not the \n.
2715 SAL_WARN_IF(nStartPos
== -1, "sfx.view", "CutLines: Start row not found!");
2717 if ( nStartPos
!= -1 )
2719 sal_Int32 nEndPos
= nStartPos
;
2720 for ( sal_Int32 i
= 0; i
< nLines
; i
++ )
2721 nEndPos
= rStr
.indexOf( LINE_SEP
, nEndPos
+1 );
2723 if ( nEndPos
== -1 ) // Can happen at the last row.
2724 nEndPos
= rStr
.getLength();
2728 rStr
= OUString::Concat(rStr
.subView( 0, nStartPos
)) + rStr
.subView( nEndPos
);
2730 // erase trailing lines
2731 if ( nStartPos
!= -1 )
2733 sal_Int32 n
= nStartPos
;
2734 sal_Int32 nLen
= rStr
.getLength();
2735 while ( ( n
< nLen
) && ( rStr
[ n
] == LINE_SEP
) )
2738 if ( n
> nStartPos
)
2739 rStr
= OUString::Concat(rStr
.subView( 0, nStartPos
)) + rStr
.subView( n
);
2746 add new recorded dispatch macro script into the application global basic
2747 lib container. It generates a new unique id for it and insert the macro
2748 by using this number as name for the module
2750 void SfxViewFrame::AddDispatchMacroToBasic_Impl( const OUString
& sMacro
)
2752 #if !HAVE_FEATURE_SCRIPTING
2755 if ( sMacro
.isEmpty() )
2758 SfxApplication
* pSfxApp
= SfxGetpApp();
2759 SfxItemPool
& rPool
= pSfxApp
->GetPool();
2760 SfxRequest
aReq(SID_BASICCHOOSER
, SfxCallMode::SYNCHRON
, rPool
);
2762 //seen in tdf#122598, no parent for subsequent dialog
2763 SfxAllItemSet
aSet(rPool
);
2764 css::uno::Reference
< css::frame::XFrame
> xFrame
=
2765 GetFrame().GetFrameInterface();
2766 aSet
.Put(SfxUnoFrameItem(SID_FILLFRAME
, xFrame
));
2767 aReq
.SetInternalArgs_Impl(aSet
);
2769 aReq
.AppendItem( SfxBoolItem(SID_RECORDMACRO
,true) );
2770 const SfxPoolItem
* pRet
= SfxGetpApp()->ExecuteSlot( aReq
);
2771 OUString aScriptURL
;
2773 aScriptURL
= static_cast<const SfxStringItem
*>(pRet
)->GetValue();
2774 if ( !aScriptURL
.isEmpty() )
2778 OUString aModuleName
;
2779 OUString aMacroName
;
2781 Reference
< XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
2782 Reference
< css::uri::XUriReferenceFactory
> xFactory
=
2783 css::uri::UriReferenceFactory::create( xContext
);
2784 Reference
< css::uri::XVndSunStarScriptUrl
> xUrl( xFactory
->parse( aScriptURL
), UNO_QUERY
);
2788 const OUString aName
= xUrl
->getName();
2789 const sal_Unicode cTok
= '.';
2790 sal_Int32 nIndex
= 0;
2791 aLibName
= aName
.getToken( 0, cTok
, nIndex
);
2793 aModuleName
= aName
.getToken( 0, cTok
, nIndex
);
2795 aMacroName
= aName
.getToken( 0, cTok
, nIndex
);
2798 aLocation
= xUrl
->getParameter( "location" );
2801 BasicManager
* pBasMgr
= nullptr;
2802 if ( aLocation
== "application" )
2804 // application basic
2805 pBasMgr
= SfxApplication::GetBasicManager();
2807 else if ( aLocation
== "document" )
2809 pBasMgr
= GetObjectShell()->GetBasicManager();
2815 StarBASIC
* pBasic
= pBasMgr
->GetLib( aLibName
);
2818 SbModule
* pModule
= pBasic
->FindModule( aModuleName
);
2819 SbMethod
* pMethod
= pModule
? pModule
->FindMethod(aMacroName
, SbxClassType::Method
) : nullptr;
2822 aOUSource
= pModule
->GetSource32();
2823 sal_uInt16 nStart
, nEnd
;
2824 pMethod
->GetLineRange( nStart
, nEnd
);
2825 sal_uInt16 nlStart
= nStart
;
2826 sal_uInt16 nlEnd
= nEnd
;
2827 CutLines( aOUSource
, nlStart
-1, nlEnd
-nlStart
+1 );
2832 // open lib container and break operation if it couldn't be opened
2833 css::uno::Reference
< css::script::XLibraryContainer
> xLibCont
;
2834 if ( aLocation
== "application" )
2836 xLibCont
= SfxGetpApp()->GetBasicContainer();
2838 else if ( aLocation
== "document" )
2840 xLibCont
= GetObjectShell()->GetBasicContainer();
2845 SAL_WARN("sfx.view", "couldn't get access to the basic lib container. Adding of macro isn't possible.");
2849 // get LibraryContainer
2850 css::uno::Any aTemp
;
2852 css::uno::Reference
< css::container::XNameAccess
> xLib
;
2853 if(xLibCont
->hasByName(aLibName
))
2855 // library must be loaded
2856 aTemp
= xLibCont
->getByName(aLibName
);
2857 xLibCont
->loadLibrary(aLibName
);
2862 xLib
= xLibCont
->createLibrary(aLibName
);
2865 // pack the macro as direct usable "sub" routine
2866 OUStringBuffer
sRoutine(10000);
2867 bool bReplace
= false;
2870 if(xLib
->hasByName(aModuleName
))
2872 if ( !aOUSource
.isEmpty() )
2874 sRoutine
.append( aOUSource
);
2879 aTemp
= xLib
->getByName(aModuleName
);
2881 sRoutine
.append( sCode
);
2887 // append new method
2888 sRoutine
.append( "\nsub " );
2889 sRoutine
.append(aMacroName
);
2890 sRoutine
.append( "\n" );
2891 sRoutine
.append(sMacro
);
2892 sRoutine
.append( "\nend sub\n" );
2894 // create the module inside the library and insert the macro routine
2895 aTemp
<<= sRoutine
.makeStringAndClear();
2898 css::uno::Reference
< css::container::XNameContainer
> xModulCont(
2900 css::uno::UNO_QUERY
);
2901 xModulCont
->replaceByName(aModuleName
,aTemp
);
2905 css::uno::Reference
< css::container::XNameContainer
> xModulCont(
2907 css::uno::UNO_QUERY
);
2908 xModulCont
->insertByName(aModuleName
,aTemp
);
2911 // #i17355# update the Basic IDE
2912 for ( SfxViewShell
* pViewShell
= SfxViewShell::GetFirst(); pViewShell
; pViewShell
= SfxViewShell::GetNext( *pViewShell
) )
2914 if ( pViewShell
->GetName() == "BasicIDE" )
2916 SfxViewFrame
* pViewFrame
= pViewShell
->GetViewFrame();
2917 SfxDispatcher
* pDispat
= pViewFrame
? pViewFrame
->GetDispatcher() : nullptr;
2920 SfxMacroInfoItem
aInfoItem( SID_BASICIDE_ARG_MACROINFO
, pBasMgr
, aLibName
, aModuleName
, OUString(), OUString() );
2921 pDispat
->ExecuteList(SID_BASICIDE_UPDATEMODULESOURCE
,
2922 SfxCallMode::SYNCHRON
, { &aInfoItem
});
2929 // add code for "session only" macro
2934 void SfxViewFrame::MiscExec_Impl( SfxRequest
& rReq
)
2936 switch ( rReq
.GetSlot() )
2938 case SID_STOP_RECORDING
:
2939 case SID_RECORDMACRO
:
2941 // try to find any active recorder on this frame
2942 static const OUStringLiteral
sProperty(u
"DispatchRecorderSupplier");
2943 css::uno::Reference
< css::frame::XFrame
> xFrame
=
2944 GetFrame().GetFrameInterface();
2946 css::uno::Reference
< css::beans::XPropertySet
> xSet(xFrame
,css::uno::UNO_QUERY
);
2947 css::uno::Any aProp
= xSet
->getPropertyValue(sProperty
);
2948 css::uno::Reference
< css::frame::XDispatchRecorderSupplier
> xSupplier
;
2949 aProp
>>= xSupplier
;
2950 css::uno::Reference
< css::frame::XDispatchRecorder
> xRecorder
;
2952 xRecorder
= xSupplier
->getDispatchRecorder();
2954 bool bIsRecording
= xRecorder
.is();
2955 const SfxBoolItem
* pItem
= rReq
.GetArg
<SfxBoolItem
>(SID_RECORDMACRO
);
2956 if ( pItem
&& pItem
->GetValue() == bIsRecording
)
2959 if ( xRecorder
.is() )
2961 // disable active recording
2962 aProp
<<= css::uno::Reference
< css::frame::XDispatchRecorderSupplier
>();
2963 xSet
->setPropertyValue(sProperty
,aProp
);
2965 const SfxBoolItem
* pRecordItem
= rReq
.GetArg
<SfxBoolItem
>(FN_PARAM_1
);
2966 if ( !pRecordItem
|| !pRecordItem
->GetValue() )
2967 // insert script into basic library container of application
2968 AddDispatchMacroToBasic_Impl(xRecorder
->getRecordedMacro());
2970 xRecorder
->endRecording();
2971 xRecorder
= nullptr;
2972 GetBindings().SetRecorder_Impl( xRecorder
);
2974 SetChildWindow( SID_RECORDING_FLOATWINDOW
, false );
2975 if ( rReq
.GetSlot() != SID_RECORDMACRO
)
2976 GetBindings().Invalidate( SID_RECORDMACRO
);
2978 else if ( rReq
.GetSlot() == SID_RECORDMACRO
)
2981 css::uno::Reference
< css::uno::XComponentContext
> xContext(
2982 ::comphelper::getProcessComponentContext());
2984 xRecorder
= css::frame::DispatchRecorder::create( xContext
);
2986 xSupplier
= css::frame::DispatchRecorderSupplier::create( xContext
);
2988 xSupplier
->setDispatchRecorder(xRecorder
);
2989 xRecorder
->startRecording(xFrame
);
2990 aProp
<<= xSupplier
;
2991 xSet
->setPropertyValue(sProperty
,aProp
);
2992 GetBindings().SetRecorder_Impl( xRecorder
);
2993 SetChildWindow( SID_RECORDING_FLOATWINDOW
, true );
3000 case SID_TOGGLESTATUSBAR
:
3002 if ( auto xLayoutManager
= getLayoutManager(GetFrame()) )
3004 static const OUStringLiteral
aStatusbarResString( u
"private:resource/statusbar/statusbar" );
3005 // Evaluate parameter.
3006 const SfxBoolItem
* pShowItem
= rReq
.GetArg
<SfxBoolItem
>(rReq
.GetSlot());
3009 bShow
= xLayoutManager
->isElementVisible( aStatusbarResString
);
3011 bShow
= pShowItem
->GetValue();
3015 xLayoutManager
->createElement( aStatusbarResString
);
3016 xLayoutManager
->showElement( aStatusbarResString
);
3019 xLayoutManager
->hideElement( aStatusbarResString
);
3022 rReq
.AppendItem( SfxBoolItem( SID_TOGGLESTATUSBAR
, bShow
) );
3027 case SID_COMMAND_POPUP
:
3029 tools::Rectangle
aRectangle(Point(0,0), GetWindow().GetSizePixel());
3030 weld::Window
* pParent
= weld::GetPopupParent(GetWindow(), aRectangle
);
3031 m_pCommandPopupHandler
->showPopup(pParent
, GetFrame().GetFrameInterface());
3036 case SID_WIN_FULLSCREEN
:
3038 const SfxBoolItem
* pItem
= rReq
.GetArg
<SfxBoolItem
>(rReq
.GetSlot());
3039 SfxViewFrame
*pTop
= GetTopViewFrame();
3042 WorkWindow
* pWork
= static_cast<WorkWindow
*>( pTop
->GetFrame().GetTopWindow_Impl() );
3045 Reference
< css::frame::XLayoutManager
> xLayoutManager
= getLayoutManager(GetFrame());
3046 bool bNewFullScreenMode
= pItem
? pItem
->GetValue() : !pWork
->IsFullScreenMode();
3047 if ( bNewFullScreenMode
!= pWork
->IsFullScreenMode() )
3049 if ( bNewFullScreenMode
)
3050 sfx2::SfxNotebookBar::LockNotebookBar();
3052 sfx2::SfxNotebookBar::UnlockNotebookBar();
3054 Reference
< css::beans::XPropertySet
> xLMPropSet( xLayoutManager
, UNO_QUERY
);
3055 if ( xLMPropSet
.is() )
3059 xLMPropSet
->setPropertyValue(
3061 makeAny( bNewFullScreenMode
));
3063 catch ( css::beans::UnknownPropertyException
& )
3067 pWork
->ShowFullScreenMode( bNewFullScreenMode
);
3068 pWork
->SetMenuBarMode( bNewFullScreenMode
? MenuBarMode::Hide
: MenuBarMode::Normal
);
3069 GetFrame().GetWorkWindow_Impl()->SetFullScreen_Impl( bNewFullScreenMode
);
3071 rReq
.AppendItem( SfxBoolItem( SID_WIN_FULLSCREEN
, bNewFullScreenMode
) );
3081 GetDispatcher()->Update_Impl( true );
3087 void SfxViewFrame::MiscState_Impl(SfxItemSet
&rSet
)
3089 const WhichRangesContainer
& pRanges
= rSet
.GetRanges();
3090 DBG_ASSERT(!pRanges
.empty(), "Set without range");
3091 for ( auto const & pRange
: pRanges
)
3093 for(sal_uInt16 nWhich
= pRange
.first
; nWhich
<= pRange
.second
; ++nWhich
)
3097 case SID_CURRENT_URL
:
3099 rSet
.Put( SfxStringItem( nWhich
, GetActualPresentationURL_Impl() ) );
3103 case SID_RECORDMACRO
:
3105 SvtMiscOptions aMiscOptions
;
3106 const OUString
& sName
{GetObjectShell()->GetFactory().GetFactoryName()};
3107 bool bMacrosDisabled
= officecfg::Office::Common::Security::Scripting::DisableMacrosExecution::get();
3108 if (bMacrosDisabled
||
3109 !officecfg::Office::Common::Misc::MacroRecorderMode::get() ||
3110 ( sName
!="swriter" && sName
!="scalc" ) )
3112 rSet
.DisableItem( nWhich
);
3113 rSet
.Put(SfxVisibilityItem(nWhich
, false));
3117 css::uno::Reference
< css::beans::XPropertySet
> xSet(
3118 GetFrame().GetFrameInterface(),
3119 css::uno::UNO_QUERY
);
3121 css::uno::Any aProp
= xSet
->getPropertyValue("DispatchRecorderSupplier");
3122 css::uno::Reference
< css::frame::XDispatchRecorderSupplier
> xSupplier
;
3123 if ( aProp
>>= xSupplier
)
3124 rSet
.Put( SfxBoolItem( nWhich
, xSupplier
.is() ) );
3126 rSet
.DisableItem( nWhich
);
3130 case SID_STOP_RECORDING
:
3132 SvtMiscOptions aMiscOptions
;
3133 const OUString
& sName
{GetObjectShell()->GetFactory().GetFactoryName()};
3134 if ( !officecfg::Office::Common::Misc::MacroRecorderMode::get() ||
3135 ( sName
!="swriter" && sName
!="scalc" ) )
3137 rSet
.DisableItem( nWhich
);
3141 css::uno::Reference
< css::beans::XPropertySet
> xSet(
3142 GetFrame().GetFrameInterface(),
3143 css::uno::UNO_QUERY
);
3145 css::uno::Any aProp
= xSet
->getPropertyValue("DispatchRecorderSupplier");
3146 css::uno::Reference
< css::frame::XDispatchRecorderSupplier
> xSupplier
;
3147 if ( !(aProp
>>= xSupplier
) || !xSupplier
.is() )
3148 rSet
.DisableItem( nWhich
);
3152 case SID_TOGGLESTATUSBAR
:
3154 css::uno::Reference
< css::frame::XLayoutManager
> xLayoutManager
;
3155 css::uno::Reference
< css::beans::XPropertySet
> xSet(
3156 GetFrame().GetFrameInterface(),
3157 css::uno::UNO_QUERY
);
3158 css::uno::Any aProp
= xSet
->getPropertyValue( "LayoutManager" );
3160 if ( !( aProp
>>= xLayoutManager
))
3161 rSet
.Put( SfxBoolItem( nWhich
, false ));
3164 bool bShow
= xLayoutManager
->isElementVisible( "private:resource/statusbar/statusbar" );
3165 rSet
.Put( SfxBoolItem( nWhich
, bShow
));
3170 case SID_WIN_FULLSCREEN
:
3172 SfxViewFrame
* pTop
= GetTopViewFrame();
3175 WorkWindow
* pWork
= static_cast<WorkWindow
*>( pTop
->GetFrame().GetTopWindow_Impl() );
3178 rSet
.Put( SfxBoolItem( nWhich
, pWork
->IsFullScreenMode() ) );
3183 rSet
.DisableItem( nWhich
);
3196 This method can be included in the Execute method for the on- and off-
3197 switching of ChildWindows, to implement this and API-bindings.
3199 Simply include as 'ExecuteMethod' in the IDL.
3201 void SfxViewFrame::ChildWindowExecute( SfxRequest
&rReq
)
3203 // Evaluate Parameter
3204 sal_uInt16 nSID
= rReq
.GetSlot();
3206 if (nSID
== SID_SIDEBAR_DECK
)
3208 const SfxStringItem
* pDeckIdItem
= rReq
.GetArg
<SfxStringItem
>(SID_SIDEBAR_DECK
);
3211 const OUString
aDeckId(pDeckIdItem
->GetValue());
3212 ::sfx2::sidebar::Sidebar::ToggleDeck(aDeckId
, this);
3218 const SfxBoolItem
* pShowItem
= rReq
.GetArg
<SfxBoolItem
>(nSID
);
3219 if ( nSID
== SID_VIEW_DATA_SOURCE_BROWSER
)
3221 if (!SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::EModule::DATABASE
))
3223 Reference
< XFrame
> xFrame
= GetFrame().GetFrameInterface();
3224 Reference
< XFrame
> xBeamer( xFrame
->findFrame( "_beamer", FrameSearchFlag::CHILDREN
) );
3225 bool bHasChild
= xBeamer
.is();
3226 bool bShow
= pShowItem
? pShowItem
->GetValue() : !bHasChild
;
3229 if( bShow
== bHasChild
)
3233 rReq
.AppendItem( SfxBoolItem( nSID
, bShow
) );
3237 SetChildWindow( SID_BROWSER
, false );
3241 css::util::URL aTargetURL
;
3242 aTargetURL
.Complete
= ".component:DB/DataSourceBrowser";
3243 Reference
< css::util::XURLTransformer
> xTrans(
3244 css::util::URLTransformer::create(
3245 ::comphelper::getProcessComponentContext() ) );
3246 xTrans
->parseStrict( aTargetURL
);
3248 Reference
< XDispatchProvider
> xProv( xFrame
, UNO_QUERY
);
3249 Reference
< css::frame::XDispatch
> xDisp
;
3251 xDisp
= xProv
->queryDispatch( aTargetURL
, "_beamer", 31 );
3254 Sequence
< css::beans::PropertyValue
> aArgs(1);
3255 css::beans::PropertyValue
* pArg
= aArgs
.getArray();
3256 pArg
[0].Name
= "Referer";
3257 pArg
[0].Value
<<= OUString("private:user");
3258 xDisp
->dispatch( aTargetURL
, aArgs
);
3265 if (nSID
== SID_STYLE_DESIGNER
)
3267 // First make sure that the sidebar is visible
3268 ShowChildWindow(SID_SIDEBAR
);
3270 ::sfx2::sidebar::Sidebar::ShowPanel(u
"StyleListPanel",
3271 GetFrame().GetFrameInterface(), true);
3276 bool bHasChild
= HasChildWindow(nSID
);
3277 bool bShow
= pShowItem
? pShowItem
->GetValue() : !bHasChild
;
3278 GetDispatcher()->Update_Impl( true );
3281 if ( !pShowItem
|| bShow
!= bHasChild
)
3282 ToggleChildWindow( nSID
);
3284 GetBindings().Invalidate( nSID
);
3286 // Record if possible.
3287 if ( nSID
== SID_HYPERLINK_DIALOG
|| nSID
== SID_SEARCH_DLG
)
3293 rReq
.AppendItem( SfxBoolItem( nSID
, bShow
) );
3300 This method can be used in the state method for the on and off-state
3301 of child-windows, in order to implement this.
3303 Just register the IDL as 'StateMethod'.
3305 void SfxViewFrame::ChildWindowState( SfxItemSet
& rState
)
3307 SfxWhichIter
aIter( rState
);
3308 for ( sal_uInt16 nSID
= aIter
.FirstWhich(); nSID
; nSID
= aIter
.NextWhich() )
3310 if ( nSID
== SID_VIEW_DATA_SOURCE_BROWSER
)
3312 rState
.Put( SfxBoolItem( nSID
, HasChildWindow( SID_BROWSER
) ) );
3314 else if ( nSID
== SID_HYPERLINK_DIALOG
)
3316 const SfxPoolItem
* pDummy
= nullptr;
3317 SfxItemState eState
= GetDispatcher()->QueryState( SID_HYPERLINK_SETLINK
, pDummy
);
3318 if ( SfxItemState::DISABLED
== eState
)
3319 rState
.DisableItem(nSID
);
3322 if ( KnowsChildWindow(nSID
) )
3323 rState
.Put( SfxBoolItem( nSID
, HasChildWindow(nSID
)) );
3325 rState
.DisableItem(nSID
);
3328 else if ( nSID
== SID_BROWSER
)
3330 Reference
< XFrame
> xFrame
= GetFrame().GetFrameInterface()->
3331 findFrame( "_beamer", FrameSearchFlag::CHILDREN
);
3333 rState
.DisableItem( nSID
);
3334 else if ( KnowsChildWindow(nSID
) )
3335 rState
.Put( SfxBoolItem( nSID
, HasChildWindow(nSID
) ) );
3337 else if ( nSID
== SID_SIDEBAR
)
3339 if ( !KnowsChildWindow( nSID
) )
3341 SAL_INFO("sfx.view", "SID_SIDEBAR state requested, but no task pane child window exists for this ID!");
3342 rState
.DisableItem( nSID
);
3346 rState
.Put( SfxBoolItem( nSID
, HasChildWindow( nSID
) ) );
3349 else if ( KnowsChildWindow(nSID
) )
3350 rState
.Put( SfxBoolItem( nSID
, HasChildWindow(nSID
) ) );
3352 rState
.DisableItem(nSID
);
3356 SfxWorkWindow
* SfxViewFrame::GetWorkWindow_Impl()
3358 SfxWorkWindow
* pWork
= GetFrame().GetWorkWindow_Impl();
3362 void SfxViewFrame::SetChildWindow(sal_uInt16 nId
, bool bOn
, bool bSetFocus
)
3364 SfxWorkWindow
* pWork
= GetWorkWindow_Impl();
3366 pWork
->SetChildWindow_Impl( nId
, bOn
, bSetFocus
);
3369 void SfxViewFrame::ToggleChildWindow(sal_uInt16 nId
)
3371 SfxWorkWindow
* pWork
= GetWorkWindow_Impl();
3373 pWork
->ToggleChildWindow_Impl( nId
, true );
3376 bool SfxViewFrame::HasChildWindow( sal_uInt16 nId
)
3378 SfxWorkWindow
* pWork
= GetWorkWindow_Impl();
3379 return pWork
&& pWork
->HasChildWindow_Impl(nId
);
3382 bool SfxViewFrame::KnowsChildWindow( sal_uInt16 nId
)
3384 SfxWorkWindow
* pWork
= GetWorkWindow_Impl();
3385 return pWork
&& pWork
->KnowsChildWindow_Impl(nId
);
3388 void SfxViewFrame::ShowChildWindow( sal_uInt16 nId
, bool bVisible
)
3390 SfxWorkWindow
* pWork
= GetWorkWindow_Impl();
3393 GetDispatcher()->Update_Impl(true);
3394 pWork
->ShowChildWindow_Impl(nId
, bVisible
, true );
3398 SfxChildWindow
* SfxViewFrame::GetChildWindow(sal_uInt16 nId
)
3400 SfxWorkWindow
* pWork
= GetWorkWindow_Impl();
3401 return pWork
? pWork
->GetChildWindow_Impl(nId
) : nullptr;
3404 void SfxViewFrame::UpdateDocument_Impl()
3406 SfxObjectShell
* pDoc
= GetObjectShell();
3407 if ( pDoc
->IsLoadingFinished() )
3408 pDoc
->CheckSecurityOnLoading_Impl();
3410 // check if document depends on a template
3411 pDoc
->UpdateFromTemplate_Impl();
3414 void SfxViewFrame::SetViewFrame( SfxViewFrame
* pFrame
)
3417 SetSVHelpData(pFrame
->m_pHelpData
);
3419 SetSVWinData(pFrame
? pFrame
->m_pWinData
: nullptr);
3421 SfxGetpApp()->SetViewFrame_Impl( pFrame
);
3424 VclPtr
<SfxInfoBarWindow
> SfxViewFrame::AppendInfoBar(const OUString
& sId
,
3425 const OUString
& sPrimaryMessage
,
3426 const OUString
& sSecondaryMessage
,
3427 InfobarType aInfobarType
, bool bShowCloseButton
)
3429 SfxChildWindow
* pChild
= GetChildWindow(SfxInfoBarContainerChild::GetChildWindowId());
3433 if (HasInfoBarWithID(sId
))
3436 SfxInfoBarContainerWindow
* pInfoBarContainer
= static_cast<SfxInfoBarContainerWindow
*>(pChild
->GetWindow());
3437 auto pInfoBar
= pInfoBarContainer
->appendInfoBar(sId
, sPrimaryMessage
, sSecondaryMessage
,
3438 aInfobarType
, bShowCloseButton
);
3439 ShowChildWindow(SfxInfoBarContainerChild::GetChildWindowId());
3443 void SfxViewFrame::UpdateInfoBar(std::u16string_view sId
, const OUString
& sPrimaryMessage
,
3444 const OUString
& sSecondaryMessage
, InfobarType eType
)
3446 const sal_uInt16 nId
= SfxInfoBarContainerChild::GetChildWindowId();
3448 // Make sure the InfoBar container is visible
3449 if (!HasChildWindow(nId
))
3450 ToggleChildWindow(nId
);
3452 SfxChildWindow
* pChild
= GetChildWindow(nId
);
3455 SfxInfoBarContainerWindow
* pInfoBarContainer
= static_cast<SfxInfoBarContainerWindow
*>(pChild
->GetWindow());
3456 auto pInfoBar
= pInfoBarContainer
->getInfoBar(sId
);
3459 pInfoBar
->Update(sPrimaryMessage
, sSecondaryMessage
, eType
);
3463 void SfxViewFrame::RemoveInfoBar( std::u16string_view sId
)
3465 const sal_uInt16 nId
= SfxInfoBarContainerChild::GetChildWindowId();
3467 // Make sure the InfoBar container is visible
3468 if (!HasChildWindow(nId
))
3469 ToggleChildWindow(nId
);
3471 SfxChildWindow
* pChild
= GetChildWindow(nId
);
3474 SfxInfoBarContainerWindow
* pInfoBarContainer
= static_cast<SfxInfoBarContainerWindow
*>(pChild
->GetWindow());
3475 auto pInfoBar
= pInfoBarContainer
->getInfoBar(sId
);
3476 pInfoBarContainer
->removeInfoBar(pInfoBar
);
3477 ShowChildWindow(nId
);
3481 bool SfxViewFrame::HasInfoBarWithID( std::u16string_view sId
)
3483 const sal_uInt16 nId
= SfxInfoBarContainerChild::GetChildWindowId();
3485 SfxChildWindow
* pChild
= GetChildWindow(nId
);
3488 SfxInfoBarContainerWindow
* pInfoBarContainer
= static_cast<SfxInfoBarContainerWindow
*>(pChild
->GetWindow());
3489 return pInfoBarContainer
->hasInfoBarWithID(sId
);
3495 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */