Bug Summary

File:home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx
Warning:line 437, column 17
Value stored to 'bNeedsReload' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name viewfrm.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SFX2_DLLIMPLEMENTATION -D ENABLE_CUPS -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/liborcus/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/liborcus/include -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sfx2/inc -I /home/maarten/src/libreoffice/core/sfx2/source/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sfx2/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <config_feature_desktop.h>
21#include <osl/file.hxx>
22#include <sfx2/docfilt.hxx>
23#include <sfx2/infobar.hxx>
24#include <sfx2/sfxsids.hrc>
25#include <sfx2/viewfrm.hxx>
26#include <sfx2/classificationhelper.hxx>
27#include <sfx2/notebookbar/SfxNotebookBar.hxx>
28#include <com/sun/star/document/MacroExecMode.hpp>
29#include <com/sun/star/frame/Desktop.hpp>
30#include <com/sun/star/frame/DispatchRecorder.hpp>
31#include <com/sun/star/frame/DispatchRecorderSupplier.hpp>
32#include <com/sun/star/frame/XLoadable.hpp>
33#include <com/sun/star/frame/XLayoutManager.hpp>
34#include <com/sun/star/frame/XComponentLoader.hpp>
35#include <com/sun/star/drawing/XShapes.hpp>
36#include <officecfg/Office/Common.hxx>
37#include <officecfg/Setup.hxx>
38#include <toolkit/helper/vclunohelper.hxx>
39#include <vcl/button.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 <svtools/miscopt.hxx>
51#include <tools/diagnose_ex.h>
52#include <com/sun/star/container/XIndexAccess.hpp>
53#include <com/sun/star/frame/XFramesSupplier.hpp>
54#include <com/sun/star/frame/FrameSearchFlag.hpp>
55#include <com/sun/star/frame/XFrame.hpp>
56#include <com/sun/star/awt/XWindow.hpp>
57#include <com/sun/star/frame/XController.hpp>
58#include <com/sun/star/util/URLTransformer.hpp>
59#include <com/sun/star/util/XURLTransformer.hpp>
60#include <com/sun/star/util/XCloseable.hpp>
61#include <com/sun/star/frame/XDispatchRecorderSupplier.hpp>
62#include <com/sun/star/document/UpdateDocMode.hpp>
63#include <com/sun/star/beans/XPropertySet.hpp>
64#include <com/sun/star/uri/UriReferenceFactory.hpp>
65#include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
66#include <com/sun/star/document/XViewDataSupplier.hpp>
67#include <com/sun/star/container/XIndexContainer.hpp>
68#include <com/sun/star/task/InteractionHandler.hpp>
69#include <com/sun/star/drawing/XDrawView.hpp>
70#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
71#include <rtl/ustrbuf.hxx>
72#include <sal/log.hxx>
73
74#include <unotools/ucbhelper.hxx>
75#include <comphelper/lok.hxx>
76#include <comphelper/processfactory.hxx>
77#include <comphelper/namedvaluecollection.hxx>
78#include <comphelper/docpasswordrequest.hxx>
79#include <comphelper/docpasswordhelper.hxx>
80
81#include <com/sun/star/uno/Reference.h>
82
83#include <basic/basmgr.hxx>
84#include <basic/sbmod.hxx>
85#include <basic/sbmeth.hxx>
86#include <svtools/strings.hrc>
87#include <svtools/svtresid.hxx>
88#include <framework/framelistanalyzer.hxx>
89#include <shellimpl.hxx>
90
91#include <optional>
92
93#include <unotools/configmgr.hxx>
94#include <comphelper/sequenceashashmap.hxx>
95
96using namespace ::com::sun::star;
97using namespace ::com::sun::star::uno;
98using namespace ::com::sun::star::ucb;
99using namespace ::com::sun::star::frame;
100using namespace ::com::sun::star::lang;
101using ::com::sun::star::awt::XWindow;
102using ::com::sun::star::beans::PropertyValue;
103using ::com::sun::star::document::XViewDataSupplier;
104using ::com::sun::star::container::XIndexContainer;
105
106// Due to ViewFrame::Current
107#include <appdata.hxx>
108#include <sfx2/app.hxx>
109#include <sfx2/objface.hxx>
110#include <openflag.hxx>
111#include <objshimp.hxx>
112#include <sfx2/viewsh.hxx>
113#include <sfx2/objsh.hxx>
114#include <sfx2/bindings.hxx>
115#include <sfx2/dispatch.hxx>
116#include <sfx2/request.hxx>
117#include <sfx2/docfac.hxx>
118#include <sfx2/ipclient.hxx>
119#include <sfx2/sfxresid.hxx>
120#include <sfx2/viewfac.hxx>
121#include <sfx2/event.hxx>
122#include <sfx2/fcontnr.hxx>
123#include <sfx2/docfile.hxx>
124#include <sfx2/module.hxx>
125#include <sfx2/sfxuno.hxx>
126#include <sfx2/progress.hxx>
127#include <sfx2/sidebar/Sidebar.hxx>
128#include <workwin.hxx>
129#include <sfx2/minfitem.hxx>
130#include <sfx2/strings.hrc>
131#include "impviewframe.hxx"
132#include <vcl/commandinfoprovider.hxx>
133#include <vcl/svapp.hxx>
134
135#define ShellClass_SfxViewFrame
136#include <sfxslots.hxx>
137
138SFX_IMPL_SUPERCLASS_INTERFACE(SfxViewFrame,SfxShell)SfxInterface* SfxViewFrame::pInterface = nullptr; SfxInterface
* SfxViewFrame::GetStaticInterface() { if ( !pInterface ) { pInterface
= new SfxInterface( "SfxViewFrame", true, GetInterfaceId(), SfxShell
::GetStaticInterface(), aSfxViewFrameSlots_Impl[0], sal_uInt16
(sizeof(aSfxViewFrameSlots_Impl) / sizeof(SfxSlot) ) ); InitInterface_Impl
(); } return pInterface; } SfxInterface* SfxViewFrame::GetInterface
() const { return GetStaticInterface(); } void SfxViewFrame::
RegisterInterface(const SfxModule* pMod) { GetStaticInterface
()->Register(pMod); }
139
140void SfxViewFrame::InitInterface_Impl()
141{
142 GetStaticInterface()->RegisterChildWindow(SID_BROWSER(5000 + 1318));
143 GetStaticInterface()->RegisterChildWindow(SID_RECORDING_FLOATWINDOW(5000 + 800));
144#if HAVE_FEATURE_DESKTOP1
145 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_FULLSCREEN4, SfxVisibilityFlags::FullScreen, ToolbarId::FullScreenToolbox);
146 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_APPLICATION0, SfxVisibilityFlags::Standard, ToolbarId::EnvToolbox);
147#endif
148}
149
150namespace {
151/// Asks the user if editing a read-only document is really wanted.
152class SfxEditDocumentDialog : public weld::MessageDialogController
153{
154private:
155 std::unique_ptr<weld::Button> m_xEditDocument;
156 std::unique_ptr<weld::Button> m_xCancel;
157
158public:
159 SfxEditDocumentDialog(weld::Widget* pParent);
160};
161
162SfxEditDocumentDialog::SfxEditDocumentDialog(weld::Widget* pParent)
163 : MessageDialogController(pParent, "sfx/ui/editdocumentdialog.ui",
164 "EditDocumentDialog")
165 , m_xEditDocument(m_xBuilder->weld_button("edit"))
166 , m_xCancel(m_xBuilder->weld_button("cancel"))
167{
168}
169
170class SfxQueryOpenAsTemplate
171{
172private:
173 std::unique_ptr<weld::MessageDialog> m_xQueryBox;
174public:
175 SfxQueryOpenAsTemplate(weld::Window* pParent, bool bAllowIgnoreLock, LockFileEntry& rLockData)
176 : m_xQueryBox(Application::CreateMessageDialog(pParent, VclMessageType::Question,
177 VclButtonsType::NONE, ""))
178 {
179 m_xQueryBox->add_button(SfxResId(STR_QUERY_OPENASTEMPLATE_OPENCOPY_BTNreinterpret_cast<char const *>("STR_QUERY_OPENASTEMPLATE_OPENCOPY_BTN"
"\004" u8"Open ~Copy")
), RET_YES);
180 bAllowIgnoreLock
181 = bAllowIgnoreLock && officecfg::Office::Common::Misc::AllowOverrideLocking::get();
182 if (bAllowIgnoreLock)
183 m_xQueryBox->add_button(SfxResId(STR_QUERY_OPENASTEMPLATE_OPEN_BTNreinterpret_cast<char const *>("STR_QUERY_OPENASTEMPLATE_OPEN_BTN"
"\004" u8"~Open")
), RET_IGNORE);
184 m_xQueryBox->add_button(GetStandardText( StandardButtonType::Cancel ), RET_CANCEL);
185 m_xQueryBox->set_primary_text(QueryString(bAllowIgnoreLock, rLockData));
186 m_xQueryBox->set_default_response(RET_YES);
187 }
188 short run() { return m_xQueryBox->run(); }
189
190private:
191 static OUString QueryString(bool bAllowIgnoreLock, LockFileEntry& rLockData)
192 {
193 OUString sLockUserData;
194 if (!rLockData[LockFileComponent::OOOUSERNAME].isEmpty())
195 sLockUserData = rLockData[LockFileComponent::OOOUSERNAME];
196 else
197 sLockUserData = rLockData[LockFileComponent::SYSUSERNAME];
198
199 if (!sLockUserData.isEmpty() && !rLockData[LockFileComponent::EDITTIME].isEmpty())
200 sLockUserData += " ( " + rLockData[LockFileComponent::EDITTIME] + " )";
201
202 if (!sLockUserData.isEmpty())
203 sLockUserData = "\n\n" + sLockUserData + "\n";
204
205 const bool bUseLockStr = bAllowIgnoreLock || !sLockUserData.isEmpty();
206
207 OUString sMsg(
208 SfxResId(bUseLockStr ? STR_QUERY_OPENASTEMPLATE_LOCKEDreinterpret_cast<char const *>("STR_QUERY_OPENASTEMPLATE_LOCKED"
"\004" u8"This document cannot be edited, because it is locked in another session.%LOCKINFO\nDo you want to edit a copy of the document?"
)
: STR_QUERY_OPENASTEMPLATEreinterpret_cast<char const *>("STR_QUERY_OPENASTEMPLATE"
"\004" u8"This document cannot be edited, possibly due to missing access rights. Do you want to edit a copy of the document?"
)
));
209
210 if (bAllowIgnoreLock)
211 sMsg += "\n\n" + SfxResId(STR_QUERY_OPENASTEMPLATE_ALLOW_IGNOREreinterpret_cast<char const *>("STR_QUERY_OPENASTEMPLATE_ALLOW_IGNORE"
"\004" u8"You can also try to ignore the lock and open the file for editing."
)
);
212
213 return sMsg.replaceFirst("%LOCKINFO", sLockUserData);
214 }
215};
216
217bool AskPasswordToModify_Impl( const uno::Reference< task::XInteractionHandler >& xHandler, const OUString& aPath, const std::shared_ptr<const SfxFilter>& pFilter, sal_uInt32 nPasswordHash, const uno::Sequence< beans::PropertyValue >& aInfo )
218{
219 // TODO/LATER: In future the info should replace the direct hash completely
220 bool bResult = ( !nPasswordHash && !aInfo.hasElements() );
221
222 SAL_WARN_IF( !(pFilter && ( pFilter->GetFilterFlags() & SfxFilterFlags::PASSWORDTOMODIFY )), "sfx.view",do { if (true && (!(pFilter && ( pFilter->
GetFilterFlags() & SfxFilterFlags::PASSWORDTOMODIFY )))) {
switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN, "sfx.view"
)) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "PasswordToModify feature is active for a filter that does not support it!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "223" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "PasswordToModify feature is active for a filter that does not support it!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "PasswordToModify feature is active for a filter that does not support it!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "223" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "PasswordToModify feature is active for a filter that does not support it!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "223" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "PasswordToModify feature is active for a filter that does not support it!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "PasswordToModify feature is active for a filter that does not support it!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "223" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
223 "PasswordToModify feature is active for a filter that does not support it!")do { if (true && (!(pFilter && ( pFilter->
GetFilterFlags() & SfxFilterFlags::PASSWORDTOMODIFY )))) {
switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN, "sfx.view"
)) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "PasswordToModify feature is active for a filter that does not support it!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "223" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "PasswordToModify feature is active for a filter that does not support it!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "PasswordToModify feature is active for a filter that does not support it!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "223" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "PasswordToModify feature is active for a filter that does not support it!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "223" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "PasswordToModify feature is active for a filter that does not support it!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "PasswordToModify feature is active for a filter that does not support it!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "223" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
224
225 if ( pFilter && xHandler.is() )
226 {
227 bool bCancel = false;
228 bool bFirstTime = true;
229
230 while ( !bResult && !bCancel )
231 {
232 bool bMSType = !pFilter->IsOwnFormat();
233
234 ::rtl::Reference< ::comphelper::DocPasswordRequest > pPasswordRequest(
235 new ::comphelper::DocPasswordRequest(
236 bMSType ? ::comphelper::DocPasswordRequestType::MS : ::comphelper::DocPasswordRequestType::Standard,
237 bFirstTime ? css::task::PasswordRequestMode_PASSWORD_ENTER : css::task::PasswordRequestMode_PASSWORD_REENTER,
238 aPath,
239 true ) );
240
241 uno::Reference< css::task::XInteractionRequest > rRequest( pPasswordRequest.get() );
242 xHandler->handle( rRequest );
243
244 if ( pPasswordRequest->isPassword() )
245 {
246 if ( aInfo.hasElements() )
247 {
248 bResult = ::comphelper::DocPasswordHelper::IsModifyPasswordCorrect( pPasswordRequest->getPasswordToModify(), aInfo );
249 }
250 else
251 {
252 // the binary format
253 bResult = ( SfxMedium::CreatePasswordToModifyHash( pPasswordRequest->getPasswordToModify(), pFilter->GetServiceName()=="com.sun.star.text.TextDocument" ) == nPasswordHash );
254 }
255 }
256 else
257 bCancel = true;
258
259 bFirstTime = false;
260 }
261 }
262
263 return bResult;
264}
265}
266
267void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq )
268{
269 SfxObjectShell* pSh = GetObjectShell();
270 switch ( rReq.GetSlot() )
271 {
272 case SID_EDITDOC(5000 + 1312):
273 case SID_READONLYDOC(5000 + 1314):
274 {
275 // Due to Double occupancy in toolboxes (with or without Ctrl),
276 // it is also possible that the slot is enabled, but Ctrl-click
277 // despite this is not!
278 if( !pSh || !pSh->HasName() || !(pSh->Get_Impl()->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT ))
279 break;
280
281 if (pSh->isEditDocLocked())
282 break;
283
284 // Only change read-only UI and remove info bar when we succeed
285 struct ReadOnlyUIGuard
286 {
287 SfxViewFrame* m_pFrame;
288 SfxObjectShell* m_pSh;
289 SfxMedium* m_pMed = nullptr;
290 bool m_bSetRO;
291 ReadOnlyUIGuard(SfxViewFrame* pFrame, SfxObjectShell* p_Sh)
292 : m_pFrame(pFrame), m_pSh(p_Sh), m_bSetRO(p_Sh->IsReadOnlyUI())
293 {}
294 ~ReadOnlyUIGuard() COVERITY_NOEXCEPT_FALSE
295 {
296 if (m_bSetRO != m_pSh->IsReadOnlyUI())
297 {
298 m_pSh->SetReadOnlyUI(m_bSetRO);
299 if (!m_bSetRO)
300 m_pFrame->RemoveInfoBar("readonly");
301 if (m_pMed)
302 {
303 // tdf#116066: DoSaveCompleted should be called after SetReadOnlyUI
304 m_pSh->DoSaveCompleted(m_pMed);
305 m_pSh->Broadcast(SfxHint(SfxHintId::ModeChanged));
306 }
307 }
308 }
309 } aReadOnlyUIGuard(this, pSh);
310
311 SfxMedium* pMed = pSh->GetMedium();
312
313 const SfxBoolItem* pItem = SfxItemSet::GetItem<SfxBoolItem>(pSh->GetMedium()->GetItemSet(), SID_VIEWONLY(5000 + 1682), false);
314 if ( pItem && pItem->GetValue() )
315 {
316 SfxApplication* pApp = SfxGetpApp();
317 SfxAllItemSet aSet( pApp->GetPool() );
318 aSet.Put( SfxStringItem( SID_FILE_NAME(5000 + 507), pMed->GetURLObject().GetMainURL(INetURLObject::DecodeMechanism::NONE) ) );
319 aSet.Put( SfxBoolItem( SID_TEMPLATE(5000 + 1519), true ) );
320 aSet.Put( SfxStringItem( SID_TARGETNAME(5000 + 560), "_blank" ) );
321 const SfxStringItem* pReferer = SfxItemSet::GetItem<SfxStringItem>(pMed->GetItemSet(), SID_REFERER(5000 + 654), false);
322 if ( pReferer )
323 aSet.Put( *pReferer );
324 const SfxInt16Item* pVersionItem = SfxItemSet::GetItem<SfxInt16Item>(pSh->GetMedium()->GetItemSet(), SID_VERSION(5000 + 1583), false);
325 if ( pVersionItem )
326 aSet.Put( *pVersionItem );
327
328 if( pMed->GetFilter() )
329 {
330 aSet.Put( SfxStringItem( SID_FILTER_NAME(5000 + 530), pMed->GetFilter()->GetFilterName() ) );
331 const SfxStringItem* pOptions = SfxItemSet::GetItem<SfxStringItem>(pMed->GetItemSet(), SID_FILE_FILTEROPTIONS(5000 + 527), false);
332 if ( pOptions )
333 aSet.Put( *pOptions );
334 }
335
336 GetDispatcher()->Execute( SID_OPENDOC(5000 + 501), SfxCallMode::ASYNCHRON, aSet );
337 return;
338 }
339
340 StreamMode nOpenMode;
341 bool bNeedsReload = false;
342 if ( !pSh->IsReadOnly() )
343 {
344 // Save and reload Readonly
345 if( pSh->IsModified() )
346 {
347 if ( pSh->PrepareClose() )
348 {
349 // the storing could let the medium be changed
350 pMed = pSh->GetMedium();
351 bNeedsReload = true;
352 }
353 else
354 {
355 rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), false ) );
356 return;
357 }
358 }
359 nOpenMode = SFX_STREAM_READONLY(StreamMode::READ | StreamMode::SHARE_DENYWRITE);
360 aReadOnlyUIGuard.m_bSetRO = true;
361 }
362 else
363 {
364 if ( pSh->IsReadOnlyMedium()
365 && ( pSh->GetModifyPasswordHash() || pSh->GetModifyPasswordInfo().hasElements() )
366 && !pSh->IsModifyPasswordEntered() )
367 {
368 const OUString aDocumentName = INetURLObject( pMed->GetOrigURL() ).GetMainURL( INetURLObject::DecodeMechanism::WithCharset );
369 if( !AskPasswordToModify_Impl( pMed->GetInteractionHandler(), aDocumentName, pMed->GetFilter(), pSh->GetModifyPasswordHash(), pSh->GetModifyPasswordInfo() ) )
370 {
371 // this is a read-only document, if it has "Password to modify"
372 // the user should enter password before he can edit the document
373 rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), false ) );
374 return;
375 }
376
377 pSh->SetModifyPasswordEntered();
378 }
379
380 nOpenMode = pSh->IsOriginallyReadOnlyMedium() ? SFX_STREAM_READONLY(StreamMode::READ | StreamMode::SHARE_DENYWRITE) : SFX_STREAM_READWRITE(StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE);
381 aReadOnlyUIGuard.m_bSetRO = false;
382
383 // if only the view was in the readonly mode then there is no need to do the reload
384 if ( !pSh->IsReadOnlyMedium() )
385 {
386 // SetReadOnlyUI causes recomputation of window title, using
387 // open mode among other things, so call SetOpenMode before
388 // SetReadOnlyUI:
389 pMed->SetOpenMode( nOpenMode );
390 return;
391 }
392 }
393
394 if ( rReq.IsAPI() )
395 {
396 // Control through API if r/w or r/o
397 const SfxBoolItem* pEditItem = rReq.GetArg<SfxBoolItem>(SID_EDITDOC(5000 + 1312));
398 if ( pEditItem )
399 nOpenMode = pEditItem->GetValue() ? SFX_STREAM_READWRITE(StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE) : SFX_STREAM_READONLY(StreamMode::READ | StreamMode::SHARE_DENYWRITE);
400 }
401
402 // doing
403
404 OUString sTemp;
405 osl::FileBase::getFileURLFromSystemPath( pMed->GetPhysicalName(), sTemp );
406 INetURLObject aPhysObj( sTemp );
407 const SfxInt16Item* pVersionItem = SfxItemSet::GetItem<SfxInt16Item>(pSh->GetMedium()->GetItemSet(), SID_VERSION(5000 + 1583), false);
408
409 INetURLObject aMedObj( pMed->GetName() );
410
411 // -> tdf#82744
412 // the logic below is following:
413 // if the document seems not to need to be reloaded
414 // and the physical name is different to the logical one,
415 // then on file system it can be checked that the copy is still newer than the original and no document reload is required.
416 // Did some semplification to enhance readability of the 'if' expression
417 //
418 // when the 'http/https' protocol is active, the bool bPhysObjIsYounger relies upon the getlastmodified Property of a WebDAV resource.
419 // Said property should be implemented, but sometimes it's not.
420 // implemented. On this case the reload activated here will not work properly.
421 // TODO: change the check age method for WebDAV to etag (entity-tag) property value, need some rethinking, since the
422 // etag tells that the cache representation (e.g. in LO) is different from the one on the server,
423 // but tells nothing about the age
424 // Details at this link: http://tools.ietf.org/html/rfc4918#section-15, section 15.7
425 bool bPhysObjIsYounger = ::utl::UCBContentHelper::IsYounger( aMedObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ),
426 aPhysObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
427 bool bIsWebDAV = aMedObj.isAnyKnownWebDAVScheme();
428
429 if ( ( !bNeedsReload && ( ( aMedObj.GetProtocol() == INetProtocol::File &&
430 aMedObj.getFSysPath( FSysStyle::Detect ) != aPhysObj.getFSysPath( FSysStyle::Detect ) &&
431 !bPhysObjIsYounger )
432 || ( bIsWebDAV && !bPhysObjIsYounger )
433 || ( pMed->IsRemote() && !bIsWebDAV ) ) )
434 || pVersionItem )
435 // <- tdf#82744
436 {
437 bNeedsReload = true;
Value stored to 'bNeedsReload' is never read
438
439 bool bOK = false;
440 bool bRetryIgnoringLock = false;
441 bool bOpenTemplate = false;
442 std::optional<bool> aOrigROVal;
443 if (!pVersionItem)
444 {
445 auto pRO = pMed->GetItemSet()->GetItem<SfxBoolItem>(SID_DOC_READONLY(5000 + 590), false);
446 if (pRO)
447 aOrigROVal = pRO->GetValue();
448 }
449 do {
450 LockFileEntry aLockData;
451 if ( !pVersionItem )
452 {
453 if (bRetryIgnoringLock)
454 pMed->ResetError();
455
456 bool bHasStorage = pMed->HasStorage_Impl();
457 // switching edit mode could be possible without reload
458 if ( bHasStorage && pMed->GetStorage() == pSh->GetStorage() )
459 {
460 // TODO/LATER: faster creation of copy
461 if ( !pSh->ConnectTmpStorage_Impl( pMed->GetStorage(), pMed ) )
462 return;
463 }
464
465 pMed->CloseAndRelease();
466 pMed->SetOpenMode( nOpenMode );
467 // We need to clear the SID_DOC_READONLY item from the set, to allow
468 // MediaDescriptor::impl_openStreamWithURL (called indirectly by
469 // SfxMedium::CompleteReOpen) to properly fill input stream of the
470 // descriptor, even when the file can't be open in read-write mode.
471 // Only then can following call to SfxMedium::LockOrigFileOnDemand
472 // return proper information about who has locked the file, to show
473 // in the SfxQueryOpenAsTemplate box below; otherwise it exits right
474 // after call to SfxMedium::GetMedium_Impl. This mimics what happens
475 // when the file is opened initially, when filter detection code also
476 // calls MediaDescriptor::impl_openStreamWithURL without the item set.
477 pMed->GetItemSet()->ClearItem(SID_DOC_READONLY(5000 + 590));
478 pMed->CompleteReOpen();
479 pMed->GetItemSet()->Put(
480 SfxBoolItem(SID_DOC_READONLY(5000 + 590), !(nOpenMode & StreamMode::WRITE)));
481 if ( nOpenMode & StreamMode::WRITE )
482 {
483 auto eResult = pMed->LockOrigFileOnDemand(
484 true, true, bRetryIgnoringLock, &aLockData);
485 bRetryIgnoringLock
486 = eResult == SfxMedium::LockFileResult::FailedLockFile;
487 }
488
489 // LockOrigFileOnDemand might set the readonly flag itself, it should be set back
490 pMed->GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY(5000 + 590), !( nOpenMode & StreamMode::WRITE ) ) );
491
492 if ( !pMed->GetErrorCode() )
493 bOK = true;
494 }
495
496 if( !bOK )
497 {
498 if (nOpenMode == SFX_STREAM_READWRITE(StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE) && !rReq.IsAPI())
499 {
500 // css::sdbcx::User offering to open it as a template
501 SfxQueryOpenAsTemplate aBox(GetWindow().GetFrameWeld(),
502 bRetryIgnoringLock, aLockData);
503
504 short nUserAnswer = aBox.run();
505 bOpenTemplate = RET_YES == nUserAnswer;
506 // Always reset this here to avoid infinite loop
507 bRetryIgnoringLock = RET_IGNORE == nUserAnswer;
508 }
509 else
510 bRetryIgnoringLock = false;
511 }
512 }
513 while ( !bOK && bRetryIgnoringLock );
514
515 if( !bOK )
516 {
517 ErrCode nErr = pMed->GetErrorCode();
518 if ( pVersionItem )
519 nErr = ERRCODE_IO_ACCESSDENIEDErrCode( ErrCodeArea::Io, ErrCodeClass::Access, 7 );
520 else
521 {
522 pMed->ResetError();
523 pMed->SetOpenMode( SFX_STREAM_READONLY(StreamMode::READ | StreamMode::SHARE_DENYWRITE) );
524 if (aOrigROVal)
525 pMed->GetItemSet()->Put(SfxBoolItem(SID_DOC_READONLY(5000 + 590), *aOrigROVal));
526 else
527 pMed->GetItemSet()->ClearItem(SID_DOC_READONLY(5000 + 590));
528 pMed->ReOpen();
529 pSh->DoSaveCompleted( pMed );
530 }
531
532 // Readonly document can not be switched to edit mode?
533 rReq.Done();
534
535 if ( nOpenMode == SFX_STREAM_READWRITE(StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE) && !rReq.IsAPI() )
536 {
537 if ( bOpenTemplate )
538 {
539 SfxApplication* pApp = SfxGetpApp();
540 SfxAllItemSet aSet( pApp->GetPool() );
541 aSet.Put( SfxStringItem( SID_FILE_NAME(5000 + 507), pMed->GetName() ) );
542 const SfxStringItem* pReferer = SfxItemSet::GetItem<SfxStringItem>(pMed->GetItemSet(), SID_REFERER(5000 + 654), false);
543 if ( pReferer )
544 aSet.Put( *pReferer );
545 aSet.Put( SfxBoolItem( SID_TEMPLATE(5000 + 1519), true ) );
546 if ( pVersionItem )
547 aSet.Put( *pVersionItem );
548
549 if( pMed->GetFilter() )
550 {
551 aSet.Put( SfxStringItem( SID_FILTER_NAME(5000 + 530), pMed->GetFilter()->GetFilterName() ) );
552 const SfxStringItem* pOptions = SfxItemSet::GetItem<SfxStringItem>(pMed->GetItemSet(), SID_FILE_FILTEROPTIONS(5000 + 527), false);
553 if ( pOptions )
554 aSet.Put( *pOptions );
555 }
556
557 GetDispatcher()->Execute( SID_OPENDOC(5000 + 501), SfxCallMode::ASYNCHRON, aSet );
558 return;
559 }
560
561 nErr = ERRCODE_NONEErrCode(0);
562 }
563
564 // Keep the read-only UI
565 aReadOnlyUIGuard.m_bSetRO = true;
566
567 ErrorHandler::HandleError( nErr );
568 rReq.SetReturnValue(
569 SfxBoolItem( rReq.GetSlot(), false ) );
570 return;
571 }
572 else
573 {
574 aReadOnlyUIGuard.m_pMed = pMed;
575 rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), true ) );
576 rReq.Done( true );
577 return;
578 }
579 }
580
581 rReq.AppendItem( SfxBoolItem( SID_FORCERELOAD(5000 + 1502), bNeedsReload) );
582 rReq.AppendItem( SfxBoolItem( SID_SILENT(5000 + 528), true ));
583
584 [[fallthrough]]; //TODO ???
585 }
586
587 case SID_RELOAD(5000 + 508):
588 {
589 // Due to Double occupancy in toolboxes (with or without Ctrl),
590 // it is also possible that the slot is enabled, but Ctrl-click
591 // despite this is not!
592 if ( !pSh || !pSh->CanReload_Impl() )
593 break;
594 SfxApplication* pApp = SfxGetpApp();
595 const SfxBoolItem* pForceReloadItem = rReq.GetArg<SfxBoolItem>(SID_FORCERELOAD(5000 + 1502));
596 if( pForceReloadItem && !pForceReloadItem->GetValue() &&
597 !pSh->GetMedium()->IsExpired() )
598 return;
599 if( m_pImpl->bReloading || pSh->IsInModalMode() )
600 return;
601
602 // AutoLoad is prohibited if possible
603 const SfxBoolItem* pAutoLoadItem = rReq.GetArg<SfxBoolItem>(SID_AUTOLOAD(5000 + 1509));
604 if ( pAutoLoadItem && pAutoLoadItem->GetValue() &&
605 GetFrame().IsAutoLoadLocked_Impl() )
606 return;
607
608 SfxObjectShellLock xOldObj( pSh );
609 m_pImpl->bReloading = true;
610 const SfxStringItem* pURLItem = rReq.GetArg<SfxStringItem>(SID_FILE_NAME(5000 + 507));
611 // Open as editable?
612 bool bForEdit = !pSh->IsReadOnly();
613
614 // If possible ask the User
615 bool bDo = GetViewShell()->PrepareClose();
616 const SfxBoolItem* pSilentItem = rReq.GetArg<SfxBoolItem>(SID_SILENT(5000 + 528));
617 if ( bDo && GetFrame().DocIsModified_Impl() &&
618 !rReq.IsAPI() && ( !pSilentItem || !pSilentItem->GetValue() ) )
619 {
620 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetWindow().GetFrameWeld(),
621 VclMessageType::Question, VclButtonsType::YesNo,
622 SfxResId(STR_QUERY_LASTVERSIONreinterpret_cast<char const *>("STR_QUERY_LASTVERSION" "\004"
u8"Cancel all changes?")
)));
623 bDo = RET_YES == xBox->run();
624 }
625
626 if ( bDo )
627 {
628 SfxMedium *pMedium = xOldObj->GetMedium();
629
630 bool bHandsOff =
631 ( pMedium->GetURLObject().GetProtocol() == INetProtocol::File && !xOldObj->IsDocShared() );
632
633 // Empty existing SfxMDIFrames for this Document
634 // in native format or R/O, open it now for editing?
635 SfxObjectShellLock xNewObj;
636
637 // collect the views of the document
638 // TODO: when UNO ViewFactories are available for SFX-based documents, the below code should
639 // be UNOized, too
640 typedef ::std::pair< Reference< XFrame >, SfxInterfaceId > ViewDescriptor;
641 ::std::vector< ViewDescriptor > aViewFrames;
642 SfxViewFrame *pView = GetFirst( xOldObj );
643 while ( pView )
644 {
645 Reference< XFrame > xFrame( pView->GetFrame().GetFrameInterface() );
646 SAL_WARN_IF( !xFrame.is(), "sfx.view", "SfxViewFrame::ExecReload_Impl: no XFrame?!")do { if (true && (!xFrame.is())) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_WARN, "sfx.view")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "SfxViewFrame::ExecReload_Impl: no XFrame?!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "646" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "SfxViewFrame::ExecReload_Impl: no XFrame?!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxViewFrame::ExecReload_Impl: no XFrame?!"; ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"), (
"/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "646" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SfxViewFrame::ExecReload_Impl: no XFrame?!") == 1
) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "646" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "SfxViewFrame::ExecReload_Impl: no XFrame?!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxViewFrame::ExecReload_Impl: no XFrame?!"; ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"), (
"/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "646" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
647 aViewFrames.emplace_back( xFrame, pView->GetCurViewId() );
648
649 pView = GetNext( *pView, xOldObj );
650 }
651
652 xOldObj->Get_Impl()->pReloadTimer.reset();
653
654 std::unique_ptr<SfxItemSet> pNewSet;
655 std::shared_ptr<const SfxFilter> pFilter = pMedium->GetFilter();
656 if( pURLItem )
657 {
658 pNewSet.reset(new SfxAllItemSet( pApp->GetPool() ));
659 pNewSet->Put( *pURLItem );
660
661 // Filter Detection
662 OUString referer;
663 const SfxStringItem* refererItem = rReq.GetArg<SfxStringItem>(SID_REFERER(5000 + 654));
664 if (refererItem != nullptr) {
665 referer = refererItem->GetValue();
666 }
667 SfxMedium aMedium( pURLItem->GetValue(), referer, SFX_STREAM_READWRITE(StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE) );
668 SfxFilterMatcher().GuessFilter( aMedium, pFilter );
669 if ( pFilter )
670 pNewSet->Put( SfxStringItem( SID_FILTER_NAME(5000 + 530), pFilter->GetName() ) );
671 pNewSet->Put( *aMedium.GetItemSet() );
672 }
673 else
674 {
675 pNewSet.reset(new SfxAllItemSet( *pMedium->GetItemSet() ));
676 pNewSet->ClearItem( SID_VIEW_ID(5000 + 523) );
677 pNewSet->ClearItem( SID_STREAM(5000 + 1699) );
678 pNewSet->ClearItem( SID_INPUTSTREAM(5000 + 1648) );
679 pNewSet->Put( SfxStringItem( SID_FILTER_NAME(5000 + 530), pMedium->GetFilter()->GetName() ) );
680
681 // let the current security settings be checked again
682 pNewSet->Put( SfxUInt16Item( SID_MACROEXECMODE(5000 + 1319), document::MacroExecMode::USE_CONFIG ) );
683
684 if ( pSh->IsOriginallyReadOnlyMedium()
685 || pSh->IsOriginallyLoadedReadOnlyMedium() )
686 // edit mode is switched or reload of readonly document
687 pNewSet->Put( SfxBoolItem( SID_DOC_READONLY(5000 + 590), true ) );
688 else
689 // Reload of file opened for writing
690 pNewSet->ClearItem( SID_DOC_READONLY(5000 + 590) );
691 }
692
693 // If a salvaged file is present, do not enclose the OrigURL
694 // again, since the Template is invalid after reload.
695 const SfxStringItem* pSalvageItem = SfxItemSet::GetItem<SfxStringItem>(pNewSet.get(), SID_DOC_SALVAGE(5000 + 531), false);
696 if( pSalvageItem )
697 {
698 pNewSet->ClearItem( SID_DOC_SALVAGE(5000 + 531) );
699 }
700
701#if HAVE_FEATURE_MULTIUSER_ENVIRONMENT1
702 // TODO/LATER: Temporary solution, the SfxMedium must know the original URL as aLogicName
703 // SfxMedium::Transfer_Impl() will be forbidden then.
704 if ( xOldObj->IsDocShared() )
705 pNewSet->Put( SfxStringItem( SID_FILE_NAME(5000 + 507), xOldObj->GetSharedFileURL() ) );
706#endif
707 if ( pURLItem )
708 pNewSet->Put( SfxStringItem( SID_REFERER(5000 + 654), pMedium->GetName() ) );
709 else
710 pNewSet->Put( SfxStringItem( SID_REFERER(5000 + 654), OUString() ) );
711
712 xOldObj->CancelTransfers();
713
714
715 if ( pSilentItem && pSilentItem->GetValue() )
716 pNewSet->Put( SfxBoolItem( SID_SILENT(5000 + 528), true ) );
717
718 const SfxUnoAnyItem* pInteractionItem = SfxItemSet::GetItem<SfxUnoAnyItem>(pNewSet.get(), SID_INTERACTIONHANDLER(5000 + 1675), false);
719 const SfxUInt16Item* pMacroExecItem = SfxItemSet::GetItem<SfxUInt16Item>(pNewSet.get(), SID_MACROEXECMODE(5000 + 1319), false);
720 const SfxUInt16Item* pDocTemplateItem = SfxItemSet::GetItem<SfxUInt16Item>(pNewSet.get(), SID_UPDATEDOCMODE(5000 + 1668), false);
721
722 if (!pInteractionItem)
723 {
724 Reference < task::XInteractionHandler2 > xHdl = task::InteractionHandler::createWithParent( ::comphelper::getProcessComponentContext(), nullptr );
725 if (xHdl.is())
726 pNewSet->Put( SfxUnoAnyItem(SID_INTERACTIONHANDLER(5000 + 1675),css::uno::makeAny(xHdl)) );
727 }
728
729 if (!pMacroExecItem)
730 pNewSet->Put( SfxUInt16Item(SID_MACROEXECMODE(5000 + 1319),css::document::MacroExecMode::USE_CONFIG) );
731 if (!pDocTemplateItem)
732 pNewSet->Put( SfxUInt16Item(SID_UPDATEDOCMODE(5000 + 1668),css::document::UpdateDocMode::ACCORDING_TO_CONFIG) );
733
734 xOldObj->SetModified( false );
735 // Do not cache the old Document! Is invalid when loading
736 // another document.
737
738 const SfxStringItem* pSavedOptions = SfxItemSet::GetItem<SfxStringItem>(pMedium->GetItemSet(), SID_FILE_FILTEROPTIONS(5000 + 527), false);
739 const SfxStringItem* pSavedReferer = SfxItemSet::GetItem<SfxStringItem>(pMedium->GetItemSet(), SID_REFERER(5000 + 654), false);
740
741 bool bHasStorage = pMedium->HasStorage_Impl();
742 if( bHandsOff )
743 {
744 if ( bHasStorage && pMedium->GetStorage() == xOldObj->GetStorage() )
745 {
746 // TODO/LATER: faster creation of copy
747 if ( !xOldObj->ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium ) )
748 return;
749 }
750
751 pMedium->CloseAndRelease();
752 }
753
754 xNewObj = SfxObjectShell::CreateObject( pFilter->GetServiceName() );
755
756 if ( xOldObj->IsModifyPasswordEntered() )
757 xNewObj->SetModifyPasswordEntered();
758
759 uno::Sequence < beans::PropertyValue > aLoadArgs;
760 TransformItems( SID_OPENDOC(5000 + 501), *pNewSet, aLoadArgs );
761 try
762 {
763 uno::Reference < frame::XLoadable > xLoad( xNewObj->GetModel(), uno::UNO_QUERY );
764 xLoad->load( aLoadArgs );
765 }
766 catch ( uno::Exception& )
767 {
768 xNewObj->DoClose();
769 xNewObj = nullptr;
770 }
771
772 pNewSet.reset();
773
774 if( !xNewObj.Is() )
775 {
776 if( bHandsOff )
777 {
778 // back to old medium
779 pMedium->ReOpen();
780 pMedium->LockOrigFileOnDemand( false, true );
781
782 xOldObj->DoSaveCompleted( pMedium );
783 }
784
785 // r/o-Doc couldn't be switched to writing mode
786 if ( bForEdit && ( SID_EDITDOC(5000 + 1312) == rReq.GetSlot() || SID_READONLYDOC(5000 + 1314) == rReq.GetSlot() ) )
787 {
788 // ask user for opening as template
789 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetWindow().GetFrameWeld(),
790 VclMessageType::Question, VclButtonsType::YesNo,
791 SfxResId(STR_QUERY_OPENASTEMPLATEreinterpret_cast<char const *>("STR_QUERY_OPENASTEMPLATE"
"\004" u8"This document cannot be edited, possibly due to missing access rights. Do you want to edit a copy of the document?"
)
)));
792 if (RET_YES == xBox->run())
793 {
794 SfxAllItemSet aSet( pApp->GetPool() );
795 aSet.Put( SfxStringItem( SID_FILE_NAME(5000 + 507), pMedium->GetName() ) );
796 aSet.Put( SfxStringItem( SID_TARGETNAME(5000 + 560), "_blank" ) );
797 if ( pSavedOptions )
798 aSet.Put( *pSavedOptions );
799 if ( pSavedReferer )
800 aSet.Put( *pSavedReferer );
801 aSet.Put( SfxBoolItem( SID_TEMPLATE(5000 + 1519), true ) );
802 if( pFilter )
803 aSet.Put( SfxStringItem( SID_FILTER_NAME(5000 + 530), pFilter->GetFilterName() ) );
804 GetDispatcher()->Execute( SID_OPENDOC(5000 + 501), SfxCallMode::ASYNCHRON, aSet );
805 }
806 }
807 }
808 else
809 {
810 if ( xNewObj->GetModifyPasswordHash() && xNewObj->GetModifyPasswordHash() != xOldObj->GetModifyPasswordHash() )
811 {
812 xNewObj->SetModifyPasswordEntered( false );
813 xNewObj->SetReadOnly();
814 }
815 else if ( rReq.GetSlot() == SID_EDITDOC(5000 + 1312) || rReq.GetSlot() == SID_READONLYDOC(5000 + 1314) )
816 {
817 xNewObj->SetReadOnlyUI( !bForEdit );
818 }
819
820#if HAVE_FEATURE_MULTIUSER_ENVIRONMENT1
821 if ( xNewObj->IsDocShared() )
822 {
823 // the file is shared but the closing can change the sharing control file
824 xOldObj->DoNotCleanShareControlFile();
825 }
826#endif
827 // the Reload and Silent items were only temporary, remove them
828 xNewObj->GetMedium()->GetItemSet()->ClearItem( SID_RELOAD(5000 + 508) );
829 xNewObj->GetMedium()->GetItemSet()->ClearItem( SID_SILENT(5000 + 528) );
830 TransformItems( SID_OPENDOC(5000 + 501), *xNewObj->GetMedium()->GetItemSet(), aLoadArgs );
831
832 UpdateDocument_Impl();
833
834 if (vcl::CommandInfoProvider::GetModuleIdentifier(GetFrame().GetFrameInterface()) == "com.sun.star.text.TextDocument")
835 sfx2::SfxNotebookBar::ReloadNotebookBar("modules/swriter/ui/");
836
837 try
838 {
839 for (auto const& viewFrame : aViewFrames)
840 {
841 LoadViewIntoFrame_Impl( *xNewObj, viewFrame.first, aLoadArgs, viewFrame.second, false );
842 }
843 aViewFrames.clear();
844 }
845 catch( const Exception& )
846 {
847 // close the remaining frames
848 // Don't catch exceptions herein, if this fails, then we're left in an indetermined state, and
849 // crashing is better than trying to proceed
850 for (auto const& viewFrame : aViewFrames)
851 {
852 Reference< util::XCloseable > xClose( viewFrame.first, UNO_QUERY_THROW );
853 xClose->close( true );
854 }
855 aViewFrames.clear();
856 }
857
858 const SfxInt32Item* pPageNumber = rReq.GetArg<SfxInt32Item>(SID_PAGE_NUMBER(5000 + 655));
859 if (pPageNumber && pPageNumber->GetValue() >= 0)
860 {
861 // Restore current page after reload.
862 uno::Reference<drawing::XDrawView> xController(
863 xNewObj->GetModel()->getCurrentController(), uno::UNO_QUERY);
864 uno::Reference<drawing::XDrawPagesSupplier> xSupplier(xNewObj->GetModel(),
865 uno::UNO_QUERY);
866 uno::Reference<drawing::XDrawPages> xDrawPages = xSupplier->getDrawPages();
867 uno::Reference<drawing::XDrawPage> xDrawPage(
868 xDrawPages->getByIndex(pPageNumber->GetValue()), uno::UNO_QUERY);
869 xController->setCurrentPage(xDrawPage);
870 }
871
872 // Propagate document closure.
873 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::CloseDoc, GlobalEventConfig::GetEventName( GlobalEventId::CLOSEDOC ), xOldObj ) );
874 }
875
876 // Record as done
877 rReq.Done( true );
878 rReq.SetReturnValue(SfxBoolItem(rReq.GetSlot(), true));
879 return;
880 }
881 else
882 {
883 // Record as not done
884 rReq.Done();
885 rReq.SetReturnValue(SfxBoolItem(rReq.GetSlot(), false));
886 m_pImpl->bReloading = false;
887 return;
888 }
889 }
890 }
891}
892
893void SfxViewFrame::StateReload_Impl( SfxItemSet& rSet )
894{
895 SfxObjectShell* pSh = GetObjectShell();
896 if ( !pSh )
897 {
898 // I'm just on reload and am yielding myself ...
899 return;
900 }
901
902 SfxWhichIter aIter( rSet );
903 for ( sal_uInt16 nWhich = aIter.FirstWhich(); nWhich; nWhich = aIter.NextWhich() )
904 {
905 switch ( nWhich )
906 {
907 case SID_EDITDOC(5000 + 1312):
908 case SID_READONLYDOC(5000 + 1314):
909 {
910 const SfxViewShell *pVSh;
911 const SfxShell *pFSh;
912 if ( !pSh->HasName() ||
913 !( pSh->Get_Impl()->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT ) ||
914 (pSh->isEditDocLocked()) ||
915 ( pSh->GetCreateMode() == SfxObjectCreateMode::EMBEDDED &&
916 ( !(pVSh = pSh->GetViewShell()) ||
917 !(pFSh = pVSh->GetFormShell()) ||
918 !pFSh->IsDesignMode())))
919 rSet.DisableItem( nWhich );
920 else
921 {
922 const SfxBoolItem* pItem = SfxItemSet::GetItem<SfxBoolItem>(pSh->GetMedium()->GetItemSet(), SID_EDITDOC(5000 + 1312), false);
923 if ( pItem && !pItem->GetValue() )
924 rSet.DisableItem( nWhich );
925 else
926 {
927 if (nWhich==SID_EDITDOC(5000 + 1312))
928 rSet.Put( SfxBoolItem( nWhich, !pSh->IsReadOnly() ) );
929 else if (nWhich==SID_READONLYDOC(5000 + 1314))
930 rSet.Put( SfxBoolItem( nWhich, pSh->IsReadOnly() ) );
931 }
932 }
933 break;
934 }
935
936 case SID_RELOAD(5000 + 508):
937 {
938 if ( !pSh->CanReload_Impl() || pSh->GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
939 rSet.DisableItem(nWhich);
940 else
941 {
942 // If any ChildFrame is reloadable, the slot is enabled,
943 // so you can perform CTRL-Reload
944 rSet.Put( SfxBoolItem( nWhich, false));
945 }
946
947 break;
948 }
949 }
950 }
951}
952
953void SfxViewFrame::ExecHistory_Impl( SfxRequest &rReq )
954{
955 // Is there an Undo-Manager on the top Shell?
956 SfxShell *pSh = GetDispatcher()->GetShell(0);
957 SfxUndoManager* pShUndoMgr = pSh->GetUndoManager();
958 bool bOK = false;
959 if ( pShUndoMgr )
960 {
961 switch ( rReq.GetSlot() )
962 {
963 case SID_CLEARHISTORY(5000 + 703):
964 pShUndoMgr->Clear();
965 bOK = true;
966 break;
967
968 case SID_UNDO(5000 + 701):
969 pShUndoMgr->Undo();
970 GetBindings().InvalidateAll(false);
971 bOK = true;
972 break;
973
974 case SID_REDO(5000 + 700):
975 pShUndoMgr->Redo();
976 GetBindings().InvalidateAll(false);
977 bOK = true;
978 break;
979
980 case SID_REPEAT(5000 + 702):
981 if ( pSh->GetRepeatTarget() )
982 pShUndoMgr->Repeat( *pSh->GetRepeatTarget() );
983 bOK = true;
984 break;
985 }
986 }
987 else if ( GetViewShell() )
988 {
989 // The SW has its own undo in the View
990 const SfxPoolItem *pRet = GetViewShell()->ExecuteSlot( rReq );
991 if ( pRet )
992 bOK = static_cast<const SfxBoolItem*>(pRet)->GetValue();
993 }
994
995 rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bOK ) );
996 rReq.Done();
997}
998
999void SfxViewFrame::StateHistory_Impl( SfxItemSet &rSet )
1000{
1001 // Search for Undo-Manager
1002 SfxShell *pSh = GetDispatcher()->GetShell(0);
1003 if ( !pSh )
1004 // I'm just on reload and am yielding myself ...
1005 return;
1006
1007 SfxUndoManager *pShUndoMgr = pSh->GetUndoManager();
1008 if ( !pShUndoMgr )
1009 {
1010 // The SW has its own undo in the View
1011 SfxWhichIter aIter( rSet );
1012 SfxViewShell *pViewSh = GetViewShell();
1013 if( !pViewSh ) return;
1014 for ( sal_uInt16 nSID = aIter.FirstWhich(); nSID; nSID = aIter.NextWhich() )
1015 pViewSh->GetSlotState( nSID, nullptr, &rSet );
1016 return;
1017 }
1018
1019 if ( pShUndoMgr->GetUndoActionCount() == 0 &&
1020 pShUndoMgr->GetRedoActionCount() == 0 &&
1021 pShUndoMgr->GetRepeatActionCount() == 0 )
1022 rSet.DisableItem( SID_CLEARHISTORY(5000 + 703) );
1023
1024 if (pShUndoMgr->GetUndoActionCount())
1025 {
1026 const SfxUndoAction* pAction = pShUndoMgr->GetUndoAction();
1027 SfxViewShell *pViewSh = GetViewShell();
1028 if (pViewSh && pAction->GetViewShellId() != pViewSh->GetViewShellId())
1029 {
1030 rSet.Put(SfxUInt32Item(SID_UNDO(5000 + 701), static_cast<sal_uInt32>(SID_REPAIRPACKAGE(5000 + 1683))));
1031 }
1032 else
1033 {
1034 rSet.Put( SfxStringItem( SID_UNDO(5000 + 701), SvtResId(STR_UNDOreinterpret_cast<char const *>("STR_UNDO" "\004" u8"Undo: "
)
)+pShUndoMgr->GetUndoActionComment() ) );
1035 }
1036 }
1037 else
1038 rSet.DisableItem( SID_UNDO(5000 + 701) );
1039
1040 if (pShUndoMgr->GetRedoActionCount())
1041 {
1042 const SfxUndoAction* pAction = pShUndoMgr->GetRedoAction();
1043 SfxViewShell *pViewSh = GetViewShell();
1044 if (pViewSh && pAction->GetViewShellId() != pViewSh->GetViewShellId())
1045 {
1046 rSet.Put(SfxUInt32Item(SID_REDO(5000 + 700), static_cast<sal_uInt32>(SID_REPAIRPACKAGE(5000 + 1683))));
1047 }
1048 else
1049 {
1050 rSet.Put(SfxStringItem(SID_REDO(5000 + 700), SvtResId(STR_REDOreinterpret_cast<char const *>("STR_REDO" "\004" u8"Redo: "
)
) + pShUndoMgr->GetRedoActionComment()));
1051 }
1052 }
1053 else
1054 rSet.DisableItem( SID_REDO(5000 + 700) );
1055
1056 SfxRepeatTarget *pTarget = pSh->GetRepeatTarget();
1057 if (pTarget && pShUndoMgr->GetRepeatActionCount() && pShUndoMgr->CanRepeat(*pTarget))
1058 rSet.Put( SfxStringItem( SID_REPEAT(5000 + 702), SvtResId(STR_REPEATreinterpret_cast<char const *>("STR_REPEAT" "\004" u8"~Repeat: "
)
)+pShUndoMgr->GetRepeatActionComment(*pTarget) ) );
1059 else
1060 rSet.DisableItem( SID_REPEAT(5000 + 702) );
1061}
1062
1063void SfxViewFrame::PopShellAndSubShells_Impl( SfxViewShell& i_rViewShell )
1064{
1065 i_rViewShell.PopSubShells_Impl();
1066 sal_uInt16 nLevel = m_pDispatcher->GetShellLevel( i_rViewShell );
1067 if ( nLevel != USHRT_MAX(32767 *2 +1) )
1068 {
1069 if ( nLevel )
1070 {
1071 // more sub shells on the stack, which were not affected by PopSubShells_Impl
1072 SfxShell *pSubShell = m_pDispatcher->GetShell( nLevel-1 );
1073 m_pDispatcher->Pop( *pSubShell, SfxDispatcherPopFlags::POP_UNTIL | SfxDispatcherPopFlags::POP_DELETE );
1074 }
1075 m_pDispatcher->Pop( i_rViewShell );
1076 m_pDispatcher->Flush();
1077 }
1078
1079}
1080
1081/* [Description]
1082
1083 This method empties the SfxViewFrame, i.e. takes the <SfxObjectShell>
1084 from the dispatcher and ends its <SfxListener> Relationship to this
1085 SfxObjectShell (by which they may even destroy themselves).
1086
1087 Thus, by invoking ReleaseObjectShell() and SetObjectShell() the
1088 SfxObjectShell can be replaced.
1089
1090 Between ReleaseObjectShell() and SetObjectShell() the control cannot
1091 be handed over to the system.
1092
1093 [Cross-reference]
1094
1095 <SfxViewFrame::SetObjectShell(SfxObjectShell&)>
1096*/
1097void SfxViewFrame::ReleaseObjectShell_Impl()
1098{
1099 DBG_ASSERT( m_xObjSh.is(), "no SfxObjectShell to release!" )do { if (true && (!(m_xObjSh.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "1099" ": "), "%s", "no SfxObjectShell to release!"); } }
while (false)
;
1100
1101 GetFrame().ReleasingComponent_Impl();
1102 if ( GetWindow().HasChildPathFocus( true ) )
1103 {
1104 GetWindow().GrabFocus();
1105 }
1106
1107 SfxViewShell *pDyingViewSh = GetViewShell();
1108 if ( pDyingViewSh )
1109 {
1110 PopShellAndSubShells_Impl( *pDyingViewSh );
1111 pDyingViewSh->DisconnectAllClients();
1112 SetViewShell_Impl(nullptr);
1113 delete pDyingViewSh;
1114 }
1115#ifdef DBG_UTIL
1116 else
1117 OSL_FAIL("No Shell")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "1117" ": "), "%s", "No Shell"); } } while (false)
;
1118#endif
1119
1120 if ( m_xObjSh.is() )
1121 {
1122 m_pDispatcher->Pop( *m_xObjSh );
1123 SfxModule* pModule = m_xObjSh->GetModule();
1124 if( pModule )
1125 m_pDispatcher->RemoveShell_Impl( *pModule );
1126 m_pDispatcher->Flush();
1127 EndListening( *m_xObjSh );
1128
1129 Notify( *m_xObjSh, SfxHint(SfxHintId::TitleChanged) );
1130 Notify( *m_xObjSh, SfxHint(SfxHintId::DocChanged) );
1131
1132 if ( 1 == m_xObjSh->GetOwnerLockCount() && m_pImpl->bObjLocked && m_xObjSh->GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
1133 m_xObjSh->DoClose();
1134 SfxObjectShellRef xDyingObjSh = m_xObjSh;
1135 m_xObjSh.clear();
1136 if( GetFrame().GetHasTitle() && m_pImpl->nDocViewNo )
1137 xDyingObjSh->GetNoSet_Impl().ReleaseIndex(m_pImpl->nDocViewNo-1);
1138 if ( m_pImpl->bObjLocked )
1139 {
1140 xDyingObjSh->OwnerLock( false );
1141 m_pImpl->bObjLocked = false;
1142 }
1143 }
1144
1145 GetDispatcher()->SetDisableFlags( SfxDisableFlags::NONE );
1146}
1147
1148void SfxViewFrame::Close()
1149{
1150
1151 DBG_ASSERT( GetFrame().IsClosing_Impl() || !GetFrame().GetFrameInterface().is(), "ViewFrame closed too early!" )do { if (true && (!(GetFrame().IsClosing_Impl() || !GetFrame
().GetFrameInterface().is()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "1151" ": "), "%s", "ViewFrame closed too early!"); } } while
(false)
;
1152
1153 // If no saving have been made up until now, then embedded Objects should
1154 // not be saved automatically anymore.
1155 if ( GetViewShell() )
1156 GetViewShell()->DisconnectAllClients();
1157 Broadcast( SfxHint( SfxHintId::Dying ) );
1158
1159 if (SfxViewFrame::Current() == this)
1160 SfxViewFrame::SetViewFrame( nullptr );
1161
1162 // Since the Dispatcher is emptied, it can not be used in any reasonable
1163 // manner, thus it is better to let the dispatcher be.
1164 GetDispatcher()->Lock(true);
1165 delete this;
1166}
1167
1168void SfxViewFrame::DoActivate( bool bUI )
1169{
1170 m_pDispatcher->DoActivate_Impl( bUI );
1171}
1172
1173void SfxViewFrame::DoDeactivate(bool bUI, SfxViewFrame const * pNewFrame )
1174{
1175 m_pDispatcher->DoDeactivate_Impl( bUI, pNewFrame );
1176}
1177
1178void SfxViewFrame::InvalidateBorderImpl( const SfxViewShell* pSh )
1179{
1180 if( !pSh || m_nAdjustPosPixelLock )
1181 return;
1182
1183 if ( GetViewShell() && GetWindow().IsVisible() )
1184 {
1185 if ( GetFrame().IsInPlace() )
1186 {
1187 return;
1188 }
1189
1190 DoAdjustPosSizePixel( GetViewShell(), Point(),
1191 GetWindow().GetOutputSizePixel(),
1192 false );
1193 }
1194}
1195
1196void SfxViewFrame::SetBorderPixelImpl
1197(
1198 const SfxViewShell* pVSh,
1199 const SvBorder& rBorder
1200)
1201
1202{
1203 m_pImpl->aBorder = rBorder;
1204
1205 if ( m_pImpl->bResizeInToOut && !GetFrame().IsInPlace() )
1206 {
1207 Size aSize = pVSh->GetWindow()->GetOutputSizePixel();
1208 if ( aSize.Width() && aSize.Height() )
1209 {
1210 aSize.AdjustWidth(rBorder.Left() + rBorder.Right() );
1211 aSize.AdjustHeight(rBorder.Top() + rBorder.Bottom() );
1212
1213 Size aOldSize = GetWindow().GetOutputSizePixel();
1214 GetWindow().SetOutputSizePixel( aSize );
1215 vcl::Window* pParent = &GetWindow();
1216 while ( pParent->GetParent() )
1217 pParent = pParent->GetParent();
1218 Size aOuterSize = pParent->GetOutputSizePixel();
1219 aOuterSize.AdjustWidth( aSize.Width() - aOldSize.Width() );
1220 aOuterSize.AdjustHeight( aSize.Height() - aOldSize.Height() );
1221 pParent->SetOutputSizePixel( aOuterSize );
1222 }
1223 }
1224 else
1225 {
1226 tools::Rectangle aEditArea( Point(), GetWindow().GetOutputSizePixel() );
1227 aEditArea.AdjustLeft(rBorder.Left() );
1228 aEditArea.AdjustRight( -(rBorder.Right()) );
1229 aEditArea.AdjustTop(rBorder.Top() );
1230 aEditArea.AdjustBottom( -(rBorder.Bottom()) );
1231 pVSh->GetWindow()->SetPosSizePixel( aEditArea.TopLeft(), aEditArea.GetSize() );
1232 }
1233}
1234
1235const SvBorder& SfxViewFrame::GetBorderPixelImpl() const
1236{
1237 return m_pImpl->aBorder;
1238}
1239
1240void SfxViewFrame::AppendReadOnlyInfobar()
1241{
1242 bool bSignPDF = m_xObjSh->IsSignPDF();
1243 bool bSignWithCert = false;
1244 if (bSignPDF)
1245 {
1246 SfxObjectShell* pObjectShell = GetObjectShell();
1247 uno::Reference<security::XCertificate> xCertificate = pObjectShell->GetSignPDFCertificate();
1248 bSignWithCert = xCertificate.is();
1249 }
1250
1251 auto pInfoBar = AppendInfoBar("readonly", "",
1252 SfxResId(bSignPDF ? STR_READONLY_PDFreinterpret_cast<char const *>("STR_READONLY_PDF" "\004"
u8"This PDF is open in read-only mode to allow signing the existing file."
)
: STR_READONLY_DOCUMENTreinterpret_cast<char const *>("STR_READONLY_DOCUMENT" "\004"
u8"This document is open in read-only mode.")
),
1253 InfobarType::INFO);
1254 if (!pInfoBar)
1255 return;
1256
1257 if (bSignPDF)
1258 {
1259 // SID_SIGNPDF opened a read-write PDF
1260 // read-only for signing purposes.
1261 weld::Button& rSignButton = pInfoBar->addButton();
1262 if (bSignWithCert)
1263 {
1264 rSignButton.set_label(SfxResId(STR_READONLY_FINISH_SIGNreinterpret_cast<char const *>("STR_READONLY_FINISH_SIGN"
"\004" u8"Finish Signing")
));
1265 }
1266 else
1267 {
1268 rSignButton.set_label(SfxResId(STR_READONLY_SIGNreinterpret_cast<char const *>("STR_READONLY_SIGN" "\004"
u8"Sign Document")
));
1269 }
1270
1271 rSignButton.connect_clicked(LINK(this, SfxViewFrame, SignDocumentHandler)::tools::detail::makeLink( ::tools::detail::castTo<SfxViewFrame
*>(this), &SfxViewFrame::LinkStubSignDocumentHandler)
);
1272 }
1273
1274 bool showEditDocumentButton = true;
1275 if (m_xObjSh->isEditDocLocked())
1276 showEditDocumentButton = false;
1277
1278 if (showEditDocumentButton)
1279 {
1280 weld::Button& rBtn = pInfoBar->addButton();
1281 rBtn.set_label(SfxResId(STR_READONLY_EDITreinterpret_cast<char const *>("STR_READONLY_EDIT" "\004"
u8"Edit Document")
));
1282 rBtn.connect_clicked(LINK(this, SfxViewFrame, SwitchReadOnlyHandler)::tools::detail::makeLink( ::tools::detail::castTo<SfxViewFrame
*>(this), &SfxViewFrame::LinkStubSwitchReadOnlyHandler
)
);
1283 }
1284}
1285
1286void SfxViewFrame::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
1287{
1288 if(m_pImpl->bIsDowning)
1289 return;
1290
1291 // we know only SfxEventHint or simple SfxHint
1292 if (const SfxEventHint* pEventHint = dynamic_cast<const SfxEventHint*>(&rHint))
1293 {
1294 // When the Document is loaded asynchronously, was the Dispatcher
1295 // set as ReadOnly, to what must be returned when the document itself
1296 // is not read only, and the loading is finished.
1297 switch ( pEventHint->GetEventId() )
1298 {
1299 case SfxEventHintId::ModifyChanged:
1300 {
1301 SfxBindings& rBind = GetBindings();
1302 rBind.Invalidate( SID_DOC_MODIFIED(5000 + 584) );
1303 rBind.Invalidate( SID_RELOAD(5000 + 508) );
1304 rBind.Invalidate( SID_EDITDOC(5000 + 1312) );
1305 break;
1306 }
1307
1308 case SfxEventHintId::OpenDoc:
1309 case SfxEventHintId::CreateDoc:
1310 {
1311 if ( !m_xObjSh.is() )
1312 break;
1313
1314 SfxBindings& rBind = GetBindings();
1315 rBind.Invalidate( SID_RELOAD(5000 + 508) );
1316 rBind.Invalidate( SID_EDITDOC(5000 + 1312) );
1317
1318 const auto t0 = std::chrono::system_clock::now().time_since_epoch();
1319
1320 bool bIsUITest = false; //uitest.uicheck fails when the dialog is open
1321 for( sal_uInt16 i = 0; i < Application::GetCommandLineParamCount(); i++ )
1322 {
1323 if( Application::GetCommandLineParam(i) == "--nologo" )
1324 bIsUITest = true;
1325 }
1326
1327 //what's new infobar
1328 OUString sSetupVersion = utl::ConfigManager::getProductVersion();
1329 sal_Int32 iCurrent = sSetupVersion.getToken(0,'.').toInt32() * 10 + sSetupVersion.getToken(1,'.').toInt32();
1330 OUString sLastVersion
1331 = officecfg::Setup::Product::ooSetupLastVersion::get().value_or("0.0");
1332 sal_Int32 iLast = sLastVersion.getToken(0,'.').toInt32() * 10 + sLastVersion.getToken(1,'.').toInt32();
1333 if ((iCurrent > iLast) && !Application::IsHeadlessModeEnabled() && !bIsUITest)
1334 {
1335 VclPtr<SfxInfoBarWindow> pInfoBar = AppendInfoBar("whatsnew", "", SfxResId(STR_WHATSNEW_TEXTreinterpret_cast<char const *>("STR_WHATSNEW" "\004" u8"You are running version %PRODUCTVERSION of %PRODUCTNAME for the first time. Do you want to learn what's new?"
)
), InfobarType::INFO);
1336 if (pInfoBar)
1337 {
1338 weld::Button& rWhatsNewButton = pInfoBar->addButton();
1339 rWhatsNewButton.set_label(SfxResId(STR_WHATSNEW_BUTTONreinterpret_cast<char const *>("STR_WHATSNEW_BUTTON" "\004"
u8"Release Notes")
));
1340 rWhatsNewButton.connect_clicked(LINK(this, SfxViewFrame, WhatsNewHandler)::tools::detail::makeLink( ::tools::detail::castTo<SfxViewFrame
*>(this), &SfxViewFrame::LinkStubWhatsNewHandler)
);
1341 }
1342 //update lastversion
1343 std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
1344 officecfg::Setup::Product::ooSetupLastVersion::set(sSetupVersion, batch);
1345 batch->commit();
1346 }
1347
1348 // show tip-of-the-day dialog
1349 const bool bShowTipOfTheDay = officecfg::Office::Common::Misc::ShowTipOfTheDay::get();
1350 if (bShowTipOfTheDay && !Application::IsHeadlessModeEnabled() && !bIsUITest) {
1351 const sal_Int32 nLastTipOfTheDay = officecfg::Office::Common::Misc::LastTipOfTheDayShown::get();
1352 const sal_Int32 nDay = std::chrono::duration_cast<std::chrono::hours>(t0).count()/24; // days since 1970-01-01
1353 if (nDay-nLastTipOfTheDay > 0) { //only once per day
1354 // tdf#127946 pass in argument for dialog parent
1355 SfxUnoFrameItem aDocFrame(SID_FILLFRAME(5000 + 1516), GetFrame().GetFrameInterface());
1356 GetDispatcher()->ExecuteList(SID_TIPOFTHEDAY(5000 + 407), SfxCallMode::SLOT, {}, { &aDocFrame });
1357 }
1358 } //bShowTipOfTheDay
1359
1360 // inform about the community involvement
1361 const sal_Int64 nLastGetInvolvedShown = officecfg::Setup::Product::LastTimeGetInvolvedShown::get();
1362 const sal_Int64 nNow = std::chrono::duration_cast<std::chrono::seconds>(t0).count();
1363 const sal_Int64 nPeriodSec(60 * 60 * 24 * 180); // 180 days in seconds
1364 bool bUpdateLastTimeGetInvolvedShown = false;
1365
1366 if (nLastGetInvolvedShown == 0)
1367 bUpdateLastTimeGetInvolvedShown = true;
1368 else if (nPeriodSec < nNow && nLastGetInvolvedShown < (nNow + nPeriodSec/2) - nPeriodSec) // 90d alternating with donation
1369 {
1370 bUpdateLastTimeGetInvolvedShown = true;
1371
1372 VclPtr<SfxInfoBarWindow> pInfoBar = AppendInfoBar("getinvolved", "", SfxResId(STR_GET_INVOLVED_TEXTreinterpret_cast<char const *>("STR_GET_INVOLVED_TEXT" "\004"
u8"Help us make %PRODUCTNAME even better!")
), InfobarType::INFO);
1373
1374 if (pInfoBar)
1375 {
1376 weld::Button& rGetInvolvedButton = pInfoBar->addButton();
1377 rGetInvolvedButton.set_label(SfxResId(STR_GET_INVOLVED_BUTTONreinterpret_cast<char const *>("STR_GET_INVOLVED_BUTTON"
"\004" u8"Get involved")
));
1378 rGetInvolvedButton.connect_clicked(LINK(this, SfxViewFrame, GetInvolvedHandler)::tools::detail::makeLink( ::tools::detail::castTo<SfxViewFrame
*>(this), &SfxViewFrame::LinkStubGetInvolvedHandler)
);
1379 }
1380 }
1381
1382 if (bUpdateLastTimeGetInvolvedShown
1383 && !officecfg::Setup::Product::LastTimeGetInvolvedShown::isReadOnly())
1384 {
1385 std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
1386 officecfg::Setup::Product::LastTimeGetInvolvedShown::set(nNow, batch);
1387 batch->commit();
1388 }
1389
1390 // inform about donations
1391 const sal_Int64 nLastDonateShown = officecfg::Setup::Product::LastTimeDonateShown::get();
1392 bool bUpdateLastTimeDonateShown = false;
1393
1394 if (nLastDonateShown == 0)
1395 bUpdateLastTimeDonateShown = true;
1396 else if (nPeriodSec < nNow && nLastDonateShown < nNow - nPeriodSec) // 90d alternating with getinvolved
1397 {
1398 bUpdateLastTimeDonateShown = true;
1399
1400 VclPtr<SfxInfoBarWindow> pInfoBar = AppendInfoBar("donate", "", SfxResId(STR_DONATE_TEXTreinterpret_cast<char const *>("STR_DONATE_TEXT" "\004"
u8"Your donations support our worldwide community.")
), InfobarType::INFO);
1401 if (pInfoBar)
1402 {
1403 weld::Button& rDonateButton = pInfoBar->addButton();
1404 rDonateButton.set_label(SfxResId(STR_DONATE_BUTTONreinterpret_cast<char const *>("STR_DONATE_BUTTON" "\004"
u8"Donate")
));
1405 rDonateButton.connect_clicked(LINK(this, SfxViewFrame, DonationHandler)::tools::detail::makeLink( ::tools::detail::castTo<SfxViewFrame
*>(this), &SfxViewFrame::LinkStubDonationHandler)
);
1406 }
1407 }
1408
1409 if (bUpdateLastTimeDonateShown
1410 && !officecfg::Setup::Product::LastTimeDonateShown::isReadOnly())
1411 {
1412 std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
1413 officecfg::Setup::Product::LastTimeDonateShown::set(nNow, batch);
1414 batch->commit();
1415 }
1416
1417 // read-only infobar if necessary
1418 const SfxViewShell *pVSh;
1419 const SfxShell *pFSh;
1420 if ( m_xObjSh->IsReadOnly() &&
1421 ! m_xObjSh->IsSecurityOptOpenReadOnly() &&
1422 ( m_xObjSh->GetCreateMode() != SfxObjectCreateMode::EMBEDDED ||
1423 (( pVSh = m_xObjSh->GetViewShell()) && (pFSh = pVSh->GetFormShell()) && pFSh->IsDesignMode())))
1424 {
1425 AppendReadOnlyInfobar();
1426 }
1427
1428 if (vcl::CommandInfoProvider::GetModuleIdentifier(GetFrame().GetFrameInterface()) == "com.sun.star.text.TextDocument")
1429 sfx2::SfxNotebookBar::ReloadNotebookBar("modules/swriter/ui/");
1430
1431 if (SfxClassificationHelper::IsClassified(m_xObjSh->getDocProperties()))
1432 {
1433 // Document has BAILS properties, display an infobar accordingly.
1434 SfxClassificationHelper aHelper(m_xObjSh->getDocProperties());
1435 aHelper.UpdateInfobar(*this);
1436 }
1437
1438 // Add pending infobars
1439 std::vector<InfobarData>& aPendingInfobars = m_xObjSh->getPendingInfobars();
1440 while (!aPendingInfobars.empty())
1441 {
1442 InfobarData& aInfobarData = aPendingInfobars.back();
1443 AppendInfoBar(aInfobarData.msId, aInfobarData.msPrimaryMessage,
1444 aInfobarData.msSecondaryMessage, aInfobarData.maInfobarType,
1445 aInfobarData.mbShowCloseButton);
1446 aPendingInfobars.pop_back();
1447 }
1448
1449 break;
1450 }
1451 default: break;
1452 }
1453 }
1454 else
1455 {
1456 switch( rHint.GetId() )
1457 {
1458 case SfxHintId::ModeChanged:
1459 {
1460 UpdateTitle();
1461
1462 if ( !m_xObjSh.is() )
1463 break;
1464
1465 // Switch r/o?
1466 SfxBindings& rBind = GetBindings();
1467 rBind.Invalidate( SID_RELOAD(5000 + 508) );
1468 SfxDispatcher *pDispat = GetDispatcher();
1469 bool bWasReadOnly = pDispat->GetReadOnly_Impl();
1470 bool bIsReadOnly = m_xObjSh->IsReadOnly();
1471 if ( bWasReadOnly != bIsReadOnly )
1472 {
1473 // Then also TITLE_CHANGED
1474 UpdateTitle();
1475 rBind.Invalidate( SID_FILE_NAME(5000 + 507) );
1476 rBind.Invalidate( SID_DOCINFO_TITLE(5000 + 557) );
1477 rBind.Invalidate( SID_EDITDOC(5000 + 1312) );
1478
1479 pDispat->GetBindings()->InvalidateAll(true);
1480 pDispat->SetReadOnly_Impl( bIsReadOnly );
1481
1482 // Only force and Dispatcher-Update, if it is done next
1483 // anyway, otherwise flickering or GPF is possible since
1484 // the Writer for example prefers in Resize perform some
1485 // actions which has a SetReadOnlyUI in Dispatcher as a
1486 // result!
1487
1488 if ( pDispat->IsUpdated_Impl() )
1489 pDispat->Update_Impl(true);
1490 }
1491
1492 Enable( !m_xObjSh->IsInModalMode() );
1493 break;
1494 }
1495
1496 case SfxHintId::TitleChanged:
1497 {
1498 UpdateTitle();
1499 SfxBindings& rBind = GetBindings();
1500 rBind.Invalidate( SID_FILE_NAME(5000 + 507) );
1501 rBind.Invalidate( SID_DOCINFO_TITLE(5000 + 557) );
1502 rBind.Invalidate( SID_EDITDOC(5000 + 1312) );
1503 rBind.Invalidate( SID_RELOAD(5000 + 508) );
1504 break;
1505 }
1506
1507 case SfxHintId::DocumentRepair:
1508 {
1509 GetBindings().Invalidate( SID_DOC_REPAIR(5000 + 510) );
1510 break;
1511 }
1512
1513 case SfxHintId::Deinitializing:
1514 {
1515 vcl::Window* pFrameWin = GetWindow().GetFrameWindow();
1516 if (pFrameWin && pFrameWin->GetLOKNotifier())
1517 pFrameWin->ReleaseLOKNotifier();
1518
1519 GetFrame().DoClose();
1520 break;
1521 }
1522 case SfxHintId::Dying:
1523 // when the Object is being deleted, destroy the view too
1524 if ( m_xObjSh.is() )
1525 ReleaseObjectShell_Impl();
1526 else
1527 GetFrame().DoClose();
1528 break;
1529 default: break;
1530 }
1531 }
1532}
1533
1534IMPL_LINK_NOARG(SfxViewFrame, WhatsNewHandler, weld::Button&, void)void SfxViewFrame::LinkStubWhatsNewHandler(void * instance, weld
::Button& data) { return static_cast<SfxViewFrame *>
(instance)->WhatsNewHandler(data); } void SfxViewFrame::WhatsNewHandler
(__attribute__ ((unused)) weld::Button&)
1535{
1536 GetDispatcher()->Execute(SID_WHATSNEW(5000 + 426));
1537}
1538
1539IMPL_LINK_NOARG(SfxViewFrame, GetInvolvedHandler, weld::Button&, void)void SfxViewFrame::LinkStubGetInvolvedHandler(void * instance
, weld::Button& data) { return static_cast<SfxViewFrame
*>(instance)->GetInvolvedHandler(data); } void SfxViewFrame
::GetInvolvedHandler(__attribute__ ((unused)) weld::Button&
)
1540{
1541 GetDispatcher()->Execute(SID_GETINVOLVED(5000 + 425));
1542}
1543
1544IMPL_LINK_NOARG(SfxViewFrame, DonationHandler, weld::Button&, void)void SfxViewFrame::LinkStubDonationHandler(void * instance, weld
::Button& data) { return static_cast<SfxViewFrame *>
(instance)->DonationHandler(data); } void SfxViewFrame::DonationHandler
(__attribute__ ((unused)) weld::Button&)
1545{
1546 GetDispatcher()->Execute(SID_DONATION(5000 + 424));
1547}
1548
1549IMPL_LINK(SfxViewFrame, SwitchReadOnlyHandler, weld::Button&, rButton, void)void SfxViewFrame::LinkStubSwitchReadOnlyHandler(void * instance
, weld::Button& data) { return static_cast<SfxViewFrame
*>(instance)->SwitchReadOnlyHandler(data); } void SfxViewFrame
::SwitchReadOnlyHandler(weld::Button& rButton)
1550{
1551 if (m_xObjSh.is() && m_xObjSh->IsSignPDF())
1552 {
1553 SfxEditDocumentDialog aDialog(&rButton);
1554 if (aDialog.run() != RET_OK)
1555 return;
1556 }
1557 GetDispatcher()->Execute(SID_EDITDOC(5000 + 1312));
1558}
1559
1560IMPL_LINK_NOARG(SfxViewFrame, SignDocumentHandler, weld::Button&, void)void SfxViewFrame::LinkStubSignDocumentHandler(void * instance
, weld::Button& data) { return static_cast<SfxViewFrame
*>(instance)->SignDocumentHandler(data); } void SfxViewFrame
::SignDocumentHandler(__attribute__ ((unused)) weld::Button&
)
1561{
1562 GetDispatcher()->Execute(SID_SIGNATURE(5000 + 1643));
1563}
1564
1565void SfxViewFrame::Construct_Impl( SfxObjectShell *pObjSh )
1566{
1567 m_pImpl->bResizeInToOut = true;
1568 m_pImpl->bObjLocked = false;
1569 m_pImpl->nCurViewId = SFX_INTERFACE_NONE;
1570 m_pImpl->bReloading = false;
1571 m_pImpl->bIsDowning = false;
1572 m_pImpl->bModal = false;
1573 m_pImpl->bEnabled = true;
1574 m_pImpl->nDocViewNo = 0;
1575 m_pImpl->aMargin = Size( -1, -1 );
1576 m_pImpl->pWindow = nullptr;
1577
1578 SetPool( &SfxGetpApp()->GetPool() );
1579 m_pDispatcher.reset( new SfxDispatcher(this) );
1580 if ( !GetBindings().GetDispatcher() )
1581 GetBindings().SetDispatcher( m_pDispatcher.get() );
1582
1583 m_xObjSh = pObjSh;
1584 if ( m_xObjSh.is() && m_xObjSh->IsPreview() )
1585 GetDispatcher()->SetQuietMode_Impl( true );
1586
1587 if ( pObjSh )
1588 {
1589 m_pDispatcher->Push( *SfxGetpApp() );
1590 SfxModule* pModule = m_xObjSh->GetModule();
1591 if( pModule )
1592 m_pDispatcher->Push( *pModule );
1593 m_pDispatcher->Push( *this );
1594 m_pDispatcher->Push( *pObjSh );
1595 m_pDispatcher->Flush();
1596 StartListening( *pObjSh );
1597 Notify( *pObjSh, SfxHint(SfxHintId::TitleChanged) );
1598 Notify( *pObjSh, SfxHint(SfxHintId::DocChanged) );
1599 m_pDispatcher->SetReadOnly_Impl( pObjSh->IsReadOnly() );
1600 }
1601 else
1602 {
1603 m_pDispatcher->Push( *SfxGetpApp() );
1604 m_pDispatcher->Push( *this );
1605 m_pDispatcher->Flush();
1606 }
1607
1608 SfxViewFrameArr_Impl &rViewArr = SfxGetpApp()->GetViewFrames_Impl();
1609 rViewArr.push_back( this );
1610}
1611
1612/* [Description]
1613
1614 Constructor of SfxViewFrame for a <SfxObjectShell> from the Resource.
1615 The 'nViewId' to the created <SfxViewShell> can be returned.
1616 (default is the SfxViewShell-Subclass that was registered first).
1617*/
1618SfxViewFrame::SfxViewFrame
1619(
1620 SfxFrame& rFrame,
1621 SfxObjectShell* pObjShell
1622)
1623 : m_pImpl( new SfxViewFrame_Impl( rFrame ) )
1624 , m_pBindings( new SfxBindings )
1625 , m_pHelpData(CreateSVHelpData())
1626 , m_pWinData(CreateSVWinData())
1627 , m_nAdjustPosPixelLock( 0 )
1628{
1629
1630 rFrame.SetCurrentViewFrame_Impl( this );
1631 rFrame.SetHasTitle( true );
1632 Construct_Impl( pObjShell );
1633
1634 m_pImpl->pWindow = VclPtr<SfxFrameViewWindow_Impl>::Create( this, rFrame.GetWindow() );
1635 m_pImpl->pWindow->SetSizePixel( rFrame.GetWindow().GetOutputSizePixel() );
1636 rFrame.SetOwnsBindings_Impl( true );
1637 rFrame.CreateWorkWindow_Impl();
1638}
1639
1640SfxViewFrame::~SfxViewFrame()
1641{
1642 m_pImpl->bIsDowning = true;
1643
1644 if ( SfxViewFrame::Current() == this )
1645 SfxViewFrame::SetViewFrame( nullptr );
1646
1647 ReleaseObjectShell_Impl();
1648
1649 if ( GetFrame().OwnsBindings_Impl() )
1650 // The Bindings delete the Frame!
1651 KillDispatcher_Impl();
1652
1653 m_pImpl->pWindow.disposeAndClear();
1654
1655 if ( GetFrame().GetCurrentViewFrame() == this )
1656 GetFrame().SetCurrentViewFrame_Impl( nullptr );
1657
1658 // Unregister from the Frame List.
1659 SfxApplication *pSfxApp = SfxApplication::Get();
1660 if (pSfxApp)
1661 {
1662 SfxViewFrameArr_Impl &rFrames = pSfxApp->GetViewFrames_Impl();
1663 SfxViewFrameArr_Impl::iterator it = std::find( rFrames.begin(), rFrames.end(), this );
1664 rFrames.erase( it );
1665 }
1666
1667 // Delete Member
1668 KillDispatcher_Impl();
1669
1670 DestroySVHelpData(m_pHelpData);
1671 m_pHelpData = nullptr;
1672
1673 DestroySVWinData(m_pWinData);
1674 m_pWinData = nullptr;
1675}
1676
1677// Remove and delete the Dispatcher.
1678void SfxViewFrame::KillDispatcher_Impl()
1679{
1680
1681 SfxModule* pModule = m_xObjSh.is() ? m_xObjSh->GetModule() : nullptr;
1682 if ( m_xObjSh.is() )
1683 ReleaseObjectShell_Impl();
1684 if ( m_pDispatcher )
1685 {
1686 if( pModule )
1687 m_pDispatcher->Pop( *pModule, SfxDispatcherPopFlags::POP_UNTIL );
1688 else
1689 m_pDispatcher->Pop( *this );
1690 m_pDispatcher.reset();
1691 }
1692}
1693
1694SfxViewFrame* SfxViewFrame::Current()
1695{
1696 SfxApplication* pApp = SfxApplication::Get();
1697 return pApp ? pApp->Get_Impl()->pViewFrame : nullptr;
1698}
1699
1700// returns the first window of spec. type viewing the specified doc.
1701SfxViewFrame* SfxViewFrame::GetFirst
1702(
1703 const SfxObjectShell* pDoc,
1704 bool bOnlyIfVisible
1705)
1706{
1707 SfxApplication *pSfxApp = SfxApplication::Get();
1708 if (!pSfxApp)
1709 return nullptr;
1710
1711 SfxViewFrameArr_Impl &rFrames = pSfxApp->GetViewFrames_Impl();
1712
1713 // search for a SfxDocument of the specified type
1714 for (SfxViewFrame* pFrame : rFrames)
1715 {
1716 if ( ( !pDoc || pDoc == pFrame->GetObjectShell() )
1717 && ( !bOnlyIfVisible || pFrame->IsVisible() )
1718 )
1719 return pFrame;
1720 }
1721
1722 return nullptr;
1723}
1724
1725// returns the next window of spec. type viewing the specified doc.
1726SfxViewFrame* SfxViewFrame::GetNext
1727(
1728 const SfxViewFrame& rPrev,
1729 const SfxObjectShell* pDoc,
1730 bool bOnlyIfVisible
1731)
1732{
1733 SfxApplication *pSfxApp = SfxApplication::Get();
1734 if (!pSfxApp)
1735 return nullptr;
1736
1737 SfxViewFrameArr_Impl &rFrames = pSfxApp->GetViewFrames_Impl();
1738
1739 // refind the specified predecessor
1740 size_t nPos;
1741 for ( nPos = 0; nPos < rFrames.size(); ++nPos )
1742 if ( rFrames[nPos] == &rPrev )
1743 break;
1744
1745 // search for a Frame of the specified type
1746 for ( ++nPos; nPos < rFrames.size(); ++nPos )
1747 {
1748 SfxViewFrame *pFrame = rFrames[nPos];
1749 if ( ( !pDoc || pDoc == pFrame->GetObjectShell() )
1750 && ( !bOnlyIfVisible || pFrame->IsVisible() )
1751 )
1752 return pFrame;
1753 }
1754 return nullptr;
1755}
1756
1757SfxProgress* SfxViewFrame::GetProgress() const
1758{
1759 SfxObjectShell *pObjSh = m_xObjSh.get();
1760 return pObjSh ? pObjSh->GetProgress() : nullptr;
1761}
1762
1763void SfxViewFrame::DoAdjustPosSizePixel //! divide on Inner.../Outer...
1764(
1765 SfxViewShell* pSh,
1766 const Point& rPos,
1767 const Size& rSize,
1768 bool inplaceEditModeChange
1769)
1770{
1771
1772 // Components do not use this Method!
1773 if( pSh && pSh->GetWindow() && !m_nAdjustPosPixelLock )
1774 {
1775 m_nAdjustPosPixelLock++;
1776 if ( m_pImpl->bResizeInToOut )
1777 pSh->InnerResizePixel( rPos, rSize, inplaceEditModeChange );
1778 else
1779 pSh->OuterResizePixel( rPos, rSize );
1780 m_nAdjustPosPixelLock--;
1781 }
1782}
1783
1784bool SfxViewFrameItem::operator==( const SfxPoolItem &rItem ) const
1785{
1786 return SfxPoolItem::operator==(rItem) &&
1787 static_cast<const SfxViewFrameItem&>(rItem).pFrame == pFrame;
1788}
1789
1790SfxViewFrameItem* SfxViewFrameItem::Clone( SfxItemPool *) const
1791{
1792 return new SfxViewFrameItem( *this );
1793}
1794
1795void SfxViewFrame::SetViewShell_Impl( SfxViewShell *pVSh )
1796/* [Description]
1797
1798 Internal Method to set the current <SfxViewShell> Instance,
1799 that is active int this SfxViewFrame at the moment.
1800*/
1801{
1802 SfxShell::SetViewShell_Impl( pVSh );
1803
1804 // Hack: InPlaceMode
1805 if ( pVSh )
1806 m_pImpl->bResizeInToOut = false;
1807}
1808
1809void SfxViewFrame::ForceOuterResize_Impl()
1810{
1811 m_pImpl->bResizeInToOut = true;
1812}
1813
1814void SfxViewFrame::GetDocNumber_Impl()
1815{
1816 DBG_ASSERT( GetObjectShell(), "No Document!" )do { if (true && (!(GetObjectShell()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "1816" ": "), "%s", "No Document!"); } } while (false)
;
1817 GetObjectShell()->SetNamedVisibility_Impl();
1818 m_pImpl->nDocViewNo = GetObjectShell()->GetNoSet_Impl().GetFreeIndex()+1;
1819}
1820
1821void SfxViewFrame::Enable( bool bEnable )
1822{
1823 if ( bEnable == m_pImpl->bEnabled )
1824 return;
1825
1826 m_pImpl->bEnabled = bEnable;
1827
1828 vcl::Window *pWindow = &GetFrame().GetWindow();
1829 if ( !bEnable )
1830 m_pImpl->bWindowWasEnabled = pWindow->IsInputEnabled();
1831 if ( !bEnable || m_pImpl->bWindowWasEnabled )
1832 pWindow->EnableInput( bEnable );
1833
1834 // cursor and focus
1835 SfxViewShell* pViewSh = GetViewShell();
1836 if ( bEnable )
1837 {
1838 // show cursor
1839 if ( pViewSh )
1840 pViewSh->ShowCursor();
1841 }
1842 else
1843 {
1844 // hide cursor
1845 if ( pViewSh )
1846 pViewSh->ShowCursor(false);
1847 }
1848}
1849
1850/* [Description]
1851
1852 This method makes the Frame-Window visible and before transmits the
1853 window name. In addition, the document is held. In general one can never
1854 show the window directly!
1855*/
1856void SfxViewFrame::Show()
1857{
1858 // First lock the objectShell so that UpdateTitle() is valid:
1859 // IsVisible() == true (:#)
1860 if ( m_xObjSh.is() )
1861 {
1862 m_xObjSh->GetMedium()->GetItemSet()->ClearItem( SID_HIDDEN(5000 + 534) );
1863 if ( !m_pImpl->bObjLocked )
1864 LockObjectShell_Impl();
1865
1866 // Adjust Doc-Shell title number, get unique view-no
1867 if ( 0 == m_pImpl->nDocViewNo )
1868 {
1869 GetDocNumber_Impl();
1870 UpdateTitle();
1871 }
1872 }
1873 else
1874 UpdateTitle();
1875
1876 // Display Frame-window, but only if the ViewFrame has no window of its
1877 // own or if it does not contain a Component
1878 GetWindow().Show();
1879 GetFrame().GetWindow().Show();
1880}
1881
1882
1883bool SfxViewFrame::IsVisible() const
1884{
1885 return m_pImpl->bObjLocked;
1886}
1887
1888
1889void SfxViewFrame::LockObjectShell_Impl()
1890{
1891 DBG_ASSERT( !m_pImpl->bObjLocked, "Wrong Locked status!" )do { if (true && (!(!m_pImpl->bObjLocked))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "1891" ": "), "%s", "Wrong Locked status!"); } } while (
false)
;
1892
1893 DBG_ASSERT( GetObjectShell(), "No Document!" )do { if (true && (!(GetObjectShell()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "1893" ": "), "%s", "No Document!"); } } while (false)
;
1894 GetObjectShell()->OwnerLock(true);
1895 m_pImpl->bObjLocked = true;
1896}
1897
1898
1899void SfxViewFrame::MakeActive_Impl( bool bGrabFocus )
1900{
1901 if ( !GetViewShell() || GetFrame().IsClosing_Impl() )
1902 return;
1903
1904 if ( !IsVisible() )
1905 return;
1906
1907 bool bPreview = false;
1908 if (GetObjectShell()->IsPreview())
1909 {
1910 bPreview = true;
1911 }
1912
1913 css::uno::Reference<css::frame::XFrame> xFrame = GetFrame().GetFrameInterface();
1914 if (!bPreview)
1915 {
1916 SetViewFrame(this);
1917 GetBindings().SetActiveFrame(css::uno::Reference<css::frame::XFrame>());
1918 uno::Reference<frame::XFramesSupplier> xSupp(xFrame, uno::UNO_QUERY);
1919 if (xSupp.is())
1920 xSupp->setActiveFrame(uno::Reference<frame::XFrame>());
1921
1922 css::uno::Reference< css::awt::XWindow > xContainerWindow = xFrame->getContainerWindow();
1923 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(xContainerWindow);
1924 if (pWindow && pWindow->HasChildPathFocus() && bGrabFocus)
1925 {
1926 SfxInPlaceClient *pCli = GetViewShell()->GetUIActiveClient();
1927 if (!pCli || !pCli->IsObjectUIActive())
1928 GetFrame().GrabFocusOnComponent_Impl();
1929 }
1930 }
1931 else
1932 {
1933 GetBindings().SetDispatcher(GetDispatcher());
1934 GetBindings().SetActiveFrame(css::uno::Reference<css::frame::XFrame>());
1935 GetDispatcher()->Update_Impl();
1936 }
1937}
1938
1939SfxObjectShell* SfxViewFrame::GetObjectShell()
1940{
1941 return m_xObjSh.get();
1942}
1943
1944const Size& SfxViewFrame::GetMargin_Impl() const
1945{
1946 return m_pImpl->aMargin;
1947}
1948
1949SfxViewFrame* SfxViewFrame::LoadViewIntoFrame_Impl_NoThrow( const SfxObjectShell& i_rDoc, const Reference< XFrame >& i_rFrame,
1950 const SfxInterfaceId i_nViewId, const bool i_bHidden )
1951{
1952 Reference< XFrame > xFrame( i_rFrame );
1953 bool bOwnFrame = false;
1954 SfxViewShell* pSuccessView = nullptr;
1955 try
1956 {
1957 if ( !xFrame.is() )
1958 {
1959 Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
1960
1961 if ( !i_bHidden )
1962 {
1963 try
1964 {
1965 // if there is a backing component, use it
1966 ::framework::FrameListAnalyzer aAnalyzer( xDesktop, Reference< XFrame >(), FrameAnalyzerFlags::BackingComponent );
1967
1968 if ( aAnalyzer.m_xBackingComponent.is() )
1969 xFrame = aAnalyzer.m_xBackingComponent;
1970 }
1971 catch( uno::Exception& )
1972 {}
1973 }
1974
1975 if ( !xFrame.is() )
1976 xFrame.set( xDesktop->findFrame( "_blank", 0 ), UNO_SET_THROW );
1977
1978 bOwnFrame = true;
1979 }
1980
1981 pSuccessView = LoadViewIntoFrame_Impl(
1982 i_rDoc,
1983 xFrame,
1984 Sequence< PropertyValue >(), // means "reuse existing model's args"
1985 i_nViewId,
1986 i_bHidden
1987 );
1988
1989 if ( bOwnFrame && !i_bHidden )
1990 {
1991 // ensure the frame/window is visible
1992 Reference< XWindow > xContainerWindow( xFrame->getContainerWindow(), UNO_SET_THROW );
1993 xContainerWindow->setVisible( true );
1994 }
1995 }
1996 catch( const Exception& )
1997 {
1998 DBG_UNHANDLED_EXCEPTION("sfx.view")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "1998" ": ", "sfx.view" );
;
1999 }
2000
2001 if ( pSuccessView )
2002 return pSuccessView->GetViewFrame();
2003
2004 if ( bOwnFrame )
2005 {
2006 try
2007 {
2008 xFrame->dispose();
2009 }
2010 catch( const Exception& )
2011 {
2012 DBG_UNHANDLED_EXCEPTION("sfx.view")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "2012" ": ", "sfx.view" );
;
2013 }
2014 }
2015
2016 return nullptr;
2017}
2018
2019SfxViewShell* SfxViewFrame::LoadViewIntoFrame_Impl( const SfxObjectShell& i_rDoc, const Reference< XFrame >& i_rFrame,
2020 const Sequence< PropertyValue >& i_rLoadArgs, const SfxInterfaceId i_nViewId,
2021 const bool i_bHidden )
2022{
2023 Reference< XModel > xDocument( i_rDoc.GetModel(), UNO_SET_THROW );
2024
2025 ::comphelper::NamedValueCollection aTransformLoadArgs( i_rLoadArgs.hasElements() ? i_rLoadArgs : xDocument->getArgs() );
2026 aTransformLoadArgs.put( "Model", xDocument );
2027 if ( i_nViewId )
2028 aTransformLoadArgs.put( "ViewId", sal_uInt16( i_nViewId ) );
2029 if ( i_bHidden )
2030 aTransformLoadArgs.put( "Hidden", i_bHidden );
2031 else
2032 aTransformLoadArgs.remove( "Hidden" );
2033
2034 Reference< XComponentLoader > xLoader( i_rFrame, UNO_QUERY_THROW );
2035 xLoader->loadComponentFromURL( "private:object", "_self", 0,
2036 aTransformLoadArgs.getPropertyValues() );
2037
2038 SfxViewShell* pViewShell = SfxViewShell::Get( i_rFrame->getController() );
2039 ENSURE_OR_THROW( pViewShell,if( !(pViewShell) ){ do { if (true && (!(pViewShell))
) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "2040" ": "), "%s", "SfxViewFrame::LoadViewIntoFrame_Impl: loading an SFX doc into a frame resulted in a non-SFX view - quite impossible"
); } } while (false); throw css::uno::RuntimeException( __func__
+ OUStringLiteral(u",\n" "SfxViewFrame::LoadViewIntoFrame_Impl: loading an SFX doc into a frame resulted in a non-SFX view - quite impossible"
), css::uno::Reference< css::uno::XInterface >() ); }
2040 "SfxViewFrame::LoadViewIntoFrame_Impl: loading an SFX doc into a frame resulted in a non-SFX view - quite impossible" )if( !(pViewShell) ){ do { if (true && (!(pViewShell))
) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "2040" ": "), "%s", "SfxViewFrame::LoadViewIntoFrame_Impl: loading an SFX doc into a frame resulted in a non-SFX view - quite impossible"
); } } while (false); throw css::uno::RuntimeException( __func__
+ OUStringLiteral(u",\n" "SfxViewFrame::LoadViewIntoFrame_Impl: loading an SFX doc into a frame resulted in a non-SFX view - quite impossible"
), css::uno::Reference< css::uno::XInterface >() ); }
;
2041 return pViewShell;
2042}
2043
2044SfxViewFrame* SfxViewFrame::LoadHiddenDocument( SfxObjectShell const & i_rDoc, SfxInterfaceId i_nViewId )
2045{
2046 return LoadViewIntoFrame_Impl_NoThrow( i_rDoc, Reference< XFrame >(), i_nViewId, true );
2047}
2048
2049SfxViewFrame* SfxViewFrame::LoadDocument( SfxObjectShell const & i_rDoc, SfxInterfaceId i_nViewId )
2050{
2051 return LoadViewIntoFrame_Impl_NoThrow( i_rDoc, Reference< XFrame >(), i_nViewId, false );
2052}
2053
2054SfxViewFrame* SfxViewFrame::LoadDocumentIntoFrame( SfxObjectShell const & i_rDoc, const Reference< XFrame >& i_rTargetFrame )
2055{
2056 return LoadViewIntoFrame_Impl_NoThrow( i_rDoc, i_rTargetFrame, SFX_INTERFACE_NONE, false );
2057}
2058
2059SfxViewFrame* SfxViewFrame::LoadDocumentIntoFrame( SfxObjectShell const & i_rDoc, const SfxFrameItem* i_pFrameItem, SfxInterfaceId i_nViewId )
2060{
2061 return LoadViewIntoFrame_Impl_NoThrow( i_rDoc, i_pFrameItem && i_pFrameItem->GetFrame() ? i_pFrameItem->GetFrame()->GetFrameInterface() : nullptr, i_nViewId, false );
2062}
2063
2064SfxViewFrame* SfxViewFrame::DisplayNewDocument( SfxObjectShell const & i_rDoc, const SfxRequest& i_rCreateDocRequest )
2065{
2066 const SfxUnoFrameItem* pFrameItem = i_rCreateDocRequest.GetArg<SfxUnoFrameItem>(SID_FILLFRAME(5000 + 1516));
2067 const SfxBoolItem* pHiddenItem = i_rCreateDocRequest.GetArg<SfxBoolItem>(SID_HIDDEN(5000 + 534));
2068
2069 return LoadViewIntoFrame_Impl_NoThrow(
2070 i_rDoc,
2071 pFrameItem ? pFrameItem->GetFrame() : nullptr,
2072 SFX_INTERFACE_NONE,
2073 pHiddenItem && pHiddenItem->GetValue()
2074 );
2075}
2076
2077SfxViewFrame* SfxViewFrame::Get( const Reference< XController>& i_rController, const SfxObjectShell* i_pDoc )
2078{
2079 if ( !i_rController.is() )
2080 return nullptr;
2081
2082 const SfxObjectShell* pDoc = i_pDoc;
2083 if ( !pDoc )
2084 {
2085 Reference< XModel > xDocument( i_rController->getModel() );
2086 for ( pDoc = SfxObjectShell::GetFirst( nullptr, false );
2087 pDoc;
2088 pDoc = SfxObjectShell::GetNext( *pDoc, nullptr, false )
2089 )
2090 {
2091 if ( pDoc->GetModel() == xDocument )
2092 break;
2093 }
2094 }
2095
2096 SfxViewFrame* pViewFrame = nullptr;
2097 for ( pViewFrame = SfxViewFrame::GetFirst( pDoc, false );
2098 pViewFrame;
2099 pViewFrame = SfxViewFrame::GetNext( *pViewFrame, pDoc, false )
2100 )
2101 {
2102 if ( pViewFrame->GetViewShell()->GetController() == i_rController )
2103 break;
2104 }
2105
2106 return pViewFrame;
2107}
2108
2109void SfxViewFrame::SaveCurrentViewData_Impl( const SfxInterfaceId i_nNewViewId )
2110{
2111 SfxViewShell* pCurrentShell = GetViewShell();
2112 ENSURE_OR_RETURN_VOID( pCurrentShell != nullptr, "SfxViewFrame::SaveCurrentViewData_Impl: no current view shell -> no current view data!" )if( !(pCurrentShell != nullptr) ) { do { if (true && (
!(pCurrentShell != nullptr))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "2112" ": "), "%s", "SfxViewFrame::SaveCurrentViewData_Impl: no current view shell -> no current view data!"
); } } while (false); return; }
;
2113
2114 // determine the logical (API) view name
2115 const SfxObjectFactory& rDocFactory( pCurrentShell->GetObjectShell()->GetFactory() );
2116 const sal_uInt16 nCurViewNo = rDocFactory.GetViewNo_Impl( GetCurViewId(), 0 );
2117 const OUString sCurrentViewName = rDocFactory.GetViewFactory( nCurViewNo ).GetAPIViewName();
2118 const sal_uInt16 nNewViewNo = rDocFactory.GetViewNo_Impl( i_nNewViewId, 0 );
2119 const OUString sNewViewName = rDocFactory.GetViewFactory( nNewViewNo ).GetAPIViewName();
2120 if ( sCurrentViewName.isEmpty() || sNewViewName.isEmpty() )
2121 {
2122 // can't say anything about the view, the respective application did not yet migrate its code to
2123 // named view factories => bail out
2124 OSL_FAIL( "SfxViewFrame::SaveCurrentViewData_Impl: views without API names? Shouldn't happen anymore?" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "2124" ": "), "%s", "SfxViewFrame::SaveCurrentViewData_Impl: views without API names? Shouldn't happen anymore?"
); } } while (false)
;
2125 return;
2126 }
2127 SAL_WARN_IF(sNewViewName == sCurrentViewName, "sfx.view", "SfxViewFrame::SaveCurrentViewData_Impl: suspicious: new and old view name are identical!")do { if (true && (sNewViewName == sCurrentViewName)) {
switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN, "sfx.view"
)) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SfxViewFrame::SaveCurrentViewData_Impl: suspicious: new and old view name are identical!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "2127" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxViewFrame::SaveCurrentViewData_Impl: suspicious: new and old view name are identical!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxViewFrame::SaveCurrentViewData_Impl: suspicious: new and old view name are identical!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "2127" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SfxViewFrame::SaveCurrentViewData_Impl: suspicious: new and old view name are identical!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "2127" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SfxViewFrame::SaveCurrentViewData_Impl: suspicious: new and old view name are identical!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxViewFrame::SaveCurrentViewData_Impl: suspicious: new and old view name are identical!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "2127" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2128
2129 // save the view data only when we're moving from a non-print-preview to the print-preview view
2130 if ( sNewViewName != "PrintPreview" )
2131 return;
2132
2133 // retrieve the view data from the view
2134 Sequence< PropertyValue > aViewData;
2135 pCurrentShell->WriteUserDataSequence( aViewData );
2136
2137 try
2138 {
2139 // retrieve view data (for *all* views) from the model
2140 const Reference< XController > xController( pCurrentShell->GetController(), UNO_SET_THROW );
2141 const Reference< XViewDataSupplier > xViewDataSupplier( xController->getModel(), UNO_QUERY_THROW );
2142 const Reference< XIndexContainer > xViewData( xViewDataSupplier->getViewData(), UNO_QUERY_THROW );
2143
2144 // look up the one view data item which corresponds to our current view, and remove it
2145 const sal_Int32 nCount = xViewData->getCount();
2146 for ( sal_Int32 i=0; i<nCount; ++i )
2147 {
2148 const ::comphelper::NamedValueCollection aCurViewData( xViewData->getByIndex(i) );
2149 const OUString sViewId( aCurViewData.getOrDefault( "ViewId", OUString() ) );
2150 if ( sViewId.isEmpty() )
2151 continue;
2152
2153 const SfxViewFactory* pViewFactory = rDocFactory.GetViewFactoryByViewName( sViewId );
2154 if ( pViewFactory == nullptr )
2155 continue;
2156
2157 if ( pViewFactory->GetOrdinal() == GetCurViewId() )
2158 {
2159 xViewData->removeByIndex(i);
2160 break;
2161 }
2162 }
2163
2164 // then replace it with the most recent view data we just obtained
2165 xViewData->insertByIndex( 0, makeAny( aViewData ) );
2166 }
2167 catch( const Exception& )
2168 {
2169 DBG_UNHANDLED_EXCEPTION("sfx.view")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "2169" ": ", "sfx.view" );
;
2170 }
2171}
2172
2173/* [Description]
2174
2175 Internal Method for switching to another <SfxViewShell> subclass,
2176 which should be created in this SfxMDIFrame. If no SfxViewShell exist
2177 in this SfxMDIFrame, then one will first be created.
2178
2179
2180 [Return Value]
2181
2182 bool true
2183 requested SfxViewShell was created and a
2184 possibly existing one deleted
2185
2186 false
2187 SfxViewShell requested could not be created,
2188 the existing SfxViewShell thus continue to exist
2189*/
2190bool SfxViewFrame::SwitchToViewShell_Impl
2191(
2192 sal_uInt16 nViewIdOrNo, /* > 0
2193 Registration-Id of the View, to which the
2194 method should switch, for example the one
2195 that will be created.
2196
2197 == 0
2198 First use the Default view. */
2199
2200 bool bIsIndex /* true
2201 'nViewIdOrNo' is no Registration-Id instead
2202 an Index of <SfxViewFrame> in <SfxObjectShell>.
2203 */
2204)
2205{
2206 try
2207 {
2208 ENSURE_OR_THROW( GetObjectShell() != nullptr, "not possible without a document" )if( !(GetObjectShell() != nullptr) ){ do { if (true &&
(!(GetObjectShell() != nullptr))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "2208" ": "), "%s", "not possible without a document"); }
} while (false); throw css::uno::RuntimeException( __func__ +
OUStringLiteral(u",\n" "not possible without a document"), css
::uno::Reference< css::uno::XInterface >() ); }
;
2209
2210 // if we already have a view shell, remove it
2211 SfxViewShell* pOldSh = GetViewShell();
2212 OSL_PRECOND( pOldSh, "SfxViewFrame::SwitchToViewShell_Impl: that's called *switch* (not for *initial-load*) for a reason" )do { if (true && (!(pOldSh))) { sal_detail_logFormat(
(SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "2212" ": "), "%s", "SfxViewFrame::SwitchToViewShell_Impl: that's called *switch* (not for *initial-load*) for a reason"
); } } while (false)
;
2213 if ( pOldSh )
2214 {
2215 // ask whether it can be closed
2216 if ( !pOldSh->PrepareClose() )
2217 return false;
2218
2219 // remove sub shells from Dispatcher before switching to new ViewShell
2220 PopShellAndSubShells_Impl( *pOldSh );
2221 }
2222
2223 GetBindings().ENTERREGISTRATIONS()EnterRegistrations();
2224 LockAdjustPosSizePixel();
2225
2226 // ID of the new view
2227 SfxObjectFactory& rDocFact = GetObjectShell()->GetFactory();
2228 const SfxInterfaceId nViewId = ( bIsIndex || !nViewIdOrNo ) ? rDocFact.GetViewFactory( nViewIdOrNo ).GetOrdinal() : SfxInterfaceId(nViewIdOrNo);
2229
2230 // save the view data of the old view, so it can be restored later on (when needed)
2231 SaveCurrentViewData_Impl( nViewId );
2232
2233 // create and load new ViewShell
2234 SfxViewShell* pNewSh = LoadViewIntoFrame_Impl(
2235 *GetObjectShell(),
2236 GetFrame().GetFrameInterface(),
2237 Sequence< PropertyValue >(), // means "reuse existing model's args"
2238 nViewId,
2239 false
2240 );
2241
2242 // allow resize events to be processed
2243 UnlockAdjustPosSizePixel();
2244
2245 if ( GetWindow().IsReallyVisible() )
2246 DoAdjustPosSizePixel( pNewSh, Point(), GetWindow().GetOutputSizePixel(), false );
2247
2248 GetBindings().LEAVEREGISTRATIONS()LeaveRegistrations();
2249 delete pOldSh;
2250 }
2251 catch ( const css::uno::Exception& )
2252 {
2253 // the SfxCode is not able to cope with exceptions thrown while creating views
2254 // the code will crash in the stack unwinding procedure, so we shouldn't let exceptions go through here
2255 DBG_UNHANDLED_EXCEPTION("sfx.view")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "2255" ": ", "sfx.view" );
;
2256 return false;
2257 }
2258
2259 DBG_ASSERT( SfxGetpApp()->GetViewFrames_Impl().size() == SfxGetpApp()->GetViewShells_Impl().size(), "Inconsistent view arrays!" )do { if (true && (!(SfxGetpApp()->GetViewFrames_Impl
().size() == SfxGetpApp()->GetViewShells_Impl().size()))) {
sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "2259" ": "), "%s", "Inconsistent view arrays!"); } } while
(false)
;
2260 return true;
2261}
2262
2263void SfxViewFrame::SetCurViewId_Impl( const SfxInterfaceId i_nID )
2264{
2265 m_pImpl->nCurViewId = i_nID;
2266}
2267
2268SfxInterfaceId SfxViewFrame::GetCurViewId() const
2269{
2270 return m_pImpl->nCurViewId;
2271}
2272
2273/* [Description]
2274
2275 Internal method to run the slot for the <SfxShell> Subclass in the
2276 SfxViewFrame <SVIDL> described slots.
2277*/
2278void SfxViewFrame::ExecView_Impl
2279(
2280 SfxRequest& rReq // The executable <SfxRequest>
2281)
2282{
2283
2284 // If the Shells are just being replaced...
2285 if ( !GetObjectShell() || !GetViewShell() )
2286 return;
2287
2288 switch ( rReq.GetSlot() )
2289 {
2290 case SID_TERMINATE_INPLACEACTIVATION(5000 + 1702) :
2291 {
2292 SfxInPlaceClient* pClient = GetViewShell()->GetUIActiveClient();
2293 if ( pClient )
2294 pClient->DeactivateObject();
2295 break;
2296 }
2297
2298 case SID_VIEWSHELL(5000 + 623):
2299 {
2300 const SfxPoolItem *pItem = nullptr;
2301 if ( rReq.GetArgs()
2302 && SfxItemState::SET == rReq.GetArgs()->GetItemState( SID_VIEWSHELL(5000 + 623), false, &pItem )
2303 )
2304 {
2305 const sal_uInt16 nViewId = static_cast< const SfxUInt16Item* >( pItem )->GetValue();
2306 bool bSuccess = SwitchToViewShell_Impl( nViewId );
2307 rReq.SetReturnValue( SfxBoolItem( 0, bSuccess ) );
2308 }
2309 break;
2310 }
2311
2312 case SID_VIEWSHELL0(5000 + 630):
2313 case SID_VIEWSHELL1(5000 + 631):
2314 case SID_VIEWSHELL2(5000 + 632):
2315 case SID_VIEWSHELL3(5000 + 633):
2316 case SID_VIEWSHELL4(5000 + 634):
2317 {
2318 const sal_uInt16 nViewNo = rReq.GetSlot() - SID_VIEWSHELL0(5000 + 630);
2319 bool bSuccess = SwitchToViewShell_Impl( nViewNo, true );
2320 rReq.SetReturnValue( SfxBoolItem( 0, bSuccess ) );
2321 break;
2322 }
2323
2324 case SID_NEWWINDOW(5000 + 620):
2325 {
2326 // Hack. at the moment a virtual Function
2327 if ( !GetViewShell()->NewWindowAllowed() )
2328 {
2329 OSL_FAIL( "You should have disabled the 'Window/New Window' slot!" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "2329" ": "), "%s", "You should have disabled the 'Window/New Window' slot!"
); } } while (false)
;
2330 return;
2331 }
2332
2333 // Get ViewData of FrameSets recursively.
2334 GetFrame().GetViewData_Impl();
2335 SfxMedium* pMed = GetObjectShell()->GetMedium();
2336
2337 // do not open the new window hidden
2338 pMed->GetItemSet()->ClearItem( SID_HIDDEN(5000 + 534) );
2339
2340 // the view ID (optional arg. TODO: this is currently not supported in the slot definition ...)
2341 const SfxUInt16Item* pViewIdItem = rReq.GetArg<SfxUInt16Item>(SID_VIEW_ID(5000 + 523));
2342 const SfxInterfaceId nViewId = pViewIdItem ? SfxInterfaceId(pViewIdItem->GetValue()) : GetCurViewId();
2343
2344 Reference < XFrame > xFrame;
2345 // the frame (optional arg. TODO: this is currently not supported in the slot definition ...)
2346 const SfxUnoFrameItem* pFrameItem = rReq.GetArg<SfxUnoFrameItem>(SID_FILLFRAME(5000 + 1516));
2347 if ( pFrameItem )
2348 xFrame = pFrameItem->GetFrame();
2349
2350 LoadViewIntoFrame_Impl_NoThrow( *GetObjectShell(), xFrame, nViewId, false );
2351
2352 rReq.Done();
2353 break;
2354 }
2355
2356 case SID_OBJECT(5000 + 575):
2357 {
2358 const SfxInt16Item* pItem = rReq.GetArg<SfxInt16Item>(SID_OBJECT(5000 + 575));
2359
2360 if (pItem)
2361 {
2362 GetViewShell()->DoVerb( pItem->GetValue() );
2363 rReq.Done();
2364 break;
2365 }
2366 }
2367 }
2368}
2369
2370/* TODO as96863:
2371 This method try to collect information about the count of currently open documents.
2372 But the algorithm is implemented very simple ...
2373 E.g. hidden documents should be ignored here ... but they are counted.
2374 TODO: export special helper "framework::FrameListAnalyzer" within the framework module
2375 and use it here.
2376*/
2377static bool impl_maxOpenDocCountReached()
2378{
2379 css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2380 std::optional<sal_Int32> x(officecfg::Office::Common::Misc::MaxOpenDocuments::get(xContext));
2381 // NIL means: count of allowed documents = infinite !
2382 if (!x)
2383 return false;
2384 sal_Int32 nMaxDocs(*x);
2385 sal_Int32 nOpenDocs = 0;
2386
2387 css::uno::Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create(xContext);
2388 css::uno::Reference< css::container::XIndexAccess > xCont(xDesktop->getFrames(), css::uno::UNO_QUERY_THROW);
2389
2390 sal_Int32 c = xCont->getCount();
2391 sal_Int32 i = 0;
2392
2393 for (i=0; i<c; ++i)
2394 {
2395 try
2396 {
2397 css::uno::Reference< css::frame::XFrame > xFrame;
2398 xCont->getByIndex(i) >>= xFrame;
2399 if ( ! xFrame.is())
2400 continue;
2401
2402 // a) do not count the help window
2403 if ( xFrame->getName() == "OFFICE_HELP_TASK" )
2404 continue;
2405
2406 // b) count all other frames
2407 ++nOpenDocs;
2408 }
2409 catch(const css::uno::Exception&)
2410 // An IndexOutOfBoundsException can happen in multithreaded
2411 // environments, where any other thread can change this
2412 // container !
2413 { continue; }
2414 }
2415
2416 return (nOpenDocs >= nMaxDocs);
2417}
2418
2419/* [Description]
2420
2421 This internal method returns in 'rSet' the Status for the <SfxShell>
2422 Subclass SfxViewFrame in the <SVIDL> described <Slots>.
2423
2424 Thus exactly those Slots-IDs that are recognized as being invalid by Sfx
2425 are included as Which-ranges in 'rSet'. If there exists a mapping for
2426 single slot-IDs of the <SfxItemPool> set in the shell, then the respective
2427 Which-IDs are used so that items can be replaced directly with a working
2428 Core::sun::com::star::script::Engine of the Which-IDs if possible. .
2429*/
2430void SfxViewFrame::StateView_Impl
2431(
2432 SfxItemSet& rSet /* empty <SfxItemSet> with <Which-Ranges>,
2433 which describes the Slot Ids */
2434)
2435{
2436
2437 SfxObjectShell *pDocSh = GetObjectShell();
2438
2439 if ( !pDocSh )
2440 // I'm just on reload and am yielding myself ...
2441 return;
2442
2443 const sal_uInt16 *pRanges = rSet.GetRanges();
2444 assert(pRanges && "Set with no Range")(static_cast <bool> (pRanges && "Set with no Range"
) ? void (0) : __assert_fail ("pRanges && \"Set with no Range\""
, "/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
, 2444, __extension__ __PRETTY_FUNCTION__))
;
2445 while ( *pRanges )
2446 {
2447 sal_uInt16 nStartWhich = *pRanges++;
2448 sal_uInt16 nEndWhich = *pRanges++;
2449 for ( sal_uInt16 nWhich = nStartWhich; nWhich <= nEndWhich; ++nWhich )
2450 {
2451 switch(nWhich)
2452 {
2453 case SID_VIEWSHELL(5000 + 623):
2454 {
2455 rSet.Put( SfxUInt16Item( nWhich, sal_uInt16(m_pImpl->nCurViewId )) );
2456 break;
2457 }
2458
2459 case SID_VIEWSHELL0(5000 + 630):
2460 case SID_VIEWSHELL1(5000 + 631):
2461 case SID_VIEWSHELL2(5000 + 632):
2462 case SID_VIEWSHELL3(5000 + 633):
2463 case SID_VIEWSHELL4(5000 + 634):
2464 {
2465 sal_uInt16 nViewNo = nWhich - SID_VIEWSHELL0(5000 + 630);
2466 if ( GetObjectShell()->GetFactory().GetViewFactoryCount() >
2467 nViewNo && !GetObjectShell()->IsInPlaceActive() )
2468 {
2469 SfxViewFactory &rViewFactory =
2470 GetObjectShell()->GetFactory().GetViewFactory(nViewNo);
2471 rSet.Put( SfxBoolItem(
2472 nWhich, m_pImpl->nCurViewId == rViewFactory.GetOrdinal() ) );
2473 }
2474 else
2475 rSet.DisableItem( nWhich );
2476 break;
2477 }
2478
2479 case SID_NEWWINDOW(5000 + 620):
2480 {
2481 if ( !GetViewShell()->NewWindowAllowed()
2482 || impl_maxOpenDocCountReached()
2483 )
2484 rSet.DisableItem( nWhich );
2485 break;
2486 }
2487 }
2488 }
2489 }
2490}
2491
2492
2493void SfxViewFrame::ToTop()
2494{
2495 GetFrame().Appear();
2496}
2497
2498
2499/* [Description]
2500
2501 GetFrame returns the Frame, in which the ViewFrame is located.
2502*/
2503SfxFrame& SfxViewFrame::GetFrame() const
2504{
2505 return m_pImpl->rFrame;
2506}
2507
2508SfxViewFrame* SfxViewFrame::GetTopViewFrame() const
2509{
2510 return GetFrame().GetCurrentViewFrame();
2511}
2512
2513vcl::Window& SfxViewFrame::GetWindow() const
2514{
2515 return m_pImpl->pWindow ? *m_pImpl->pWindow : GetFrame().GetWindow();
2516}
2517
2518bool SfxViewFrame::DoClose()
2519{
2520 return GetFrame().DoClose();
2521}
2522
2523OUString SfxViewFrame::GetActualPresentationURL_Impl() const
2524{
2525 if ( m_xObjSh.is() )
2526 return m_xObjSh->GetMedium()->GetName();
2527 return OUString();
2528}
2529
2530void SfxViewFrame::SetModalMode( bool bModal )
2531{
2532 // no real modality for LOK
2533 if (comphelper::LibreOfficeKit::isActive())
2534 return;
2535
2536 m_pImpl->bModal = bModal;
2537 if ( m_xObjSh.is() )
2538 {
2539 for ( SfxViewFrame* pFrame = SfxViewFrame::GetFirst( m_xObjSh.get() );
2540 !bModal && pFrame; pFrame = SfxViewFrame::GetNext( *pFrame, m_xObjSh.get() ) )
2541 bModal = pFrame->m_pImpl->bModal;
2542 m_xObjSh->SetModalMode_Impl( bModal );
2543 }
2544}
2545
2546bool SfxViewFrame::IsInModalMode() const
2547{
2548 return m_pImpl->bModal || GetFrame().GetWindow().IsInModalMode();
2549}
2550
2551void SfxViewFrame::Resize( bool bForce )
2552{
2553 Size aSize = GetWindow().GetOutputSizePixel();
2554 if ( !bForce && aSize == m_pImpl->aSize )
2555 return;
2556
2557 m_pImpl->aSize = aSize;
2558 SfxViewShell *pShell = GetViewShell();
2559 if ( pShell )
2560 {
2561 if ( GetFrame().IsInPlace() )
2562 {
2563 Point aPoint = GetWindow().GetPosPixel();
2564 DoAdjustPosSizePixel( pShell, aPoint, aSize, true );
2565 }
2566 else
2567 {
2568 DoAdjustPosSizePixel( pShell, Point(), aSize, false );
2569 }
2570 }
2571}
2572
2573#if HAVE_FEATURE_SCRIPTING1
2574
2575#define LINE_SEP0x0A 0x0A
2576
2577static void CutLines( OUString& rStr, sal_Int32 nStartLine, sal_Int32 nLines )
2578{
2579 sal_Int32 nStartPos = 0;
2580 sal_Int32 nLine = 0;
2581 while ( nLine < nStartLine )
2582 {
2583 nStartPos = rStr.indexOf( LINE_SEP0x0A, nStartPos );
2584 if( nStartPos == -1 )
2585 break;
2586 nStartPos++; // not the \n.
2587 nLine++;
2588 }
2589
2590 SAL_WARN_IF(nStartPos == -1, "sfx.view", "CutLines: Start row not found!")do { if (true && (nStartPos == -1)) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_WARN, "sfx.view")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "CutLines: Start row not found!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "2590" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "CutLines: Start row not found!"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "CutLines: Start row not found!"; ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "2590" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "CutLines: Start row not found!") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "2590" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "CutLines: Start row not found!"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "CutLines: Start row not found!"; ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "2590" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2591
2592 if ( nStartPos != -1 )
2593 {
2594 sal_Int32 nEndPos = nStartPos;
2595 for ( sal_Int32 i = 0; i < nLines; i++ )
2596 nEndPos = rStr.indexOf( LINE_SEP0x0A, nEndPos+1 );
2597
2598 if ( nEndPos == -1 ) // Can happen at the last row.
2599 nEndPos = rStr.getLength();
2600 else
2601 nEndPos++;
2602
2603 rStr = rStr.copy( 0, nStartPos ) + rStr.copy( nEndPos );
2604 }
2605 // erase trailing lines
2606 if ( nStartPos != -1 )
2607 {
2608 sal_Int32 n = nStartPos;
2609 sal_Int32 nLen = rStr.getLength();
2610 while ( ( n < nLen ) && ( rStr[ n ] == LINE_SEP0x0A ) )
2611 n++;
2612
2613 if ( n > nStartPos )
2614 rStr = rStr.copy( 0, nStartPos ) + rStr.copy( n );
2615 }
2616}
2617
2618#endif
2619
2620/*
2621 add new recorded dispatch macro script into the application global basic
2622 lib container. It generates a new unique id for it and insert the macro
2623 by using this number as name for the module
2624 */
2625void SfxViewFrame::AddDispatchMacroToBasic_Impl( const OUString& sMacro )
2626{
2627#if !HAVE_FEATURE_SCRIPTING1
2628 (void) sMacro;
2629#else
2630 if ( sMacro.isEmpty() )
2631 return;
2632
2633 SfxApplication* pSfxApp = SfxGetpApp();
2634 SfxItemPool& rPool = pSfxApp->GetPool();
2635 SfxRequest aReq(SID_BASICCHOOSER(5000 + 959), SfxCallMode::SYNCHRON, rPool);
2636
2637 //seen in tdf#122598, no parent for subsequent dialog
2638 SfxAllItemSet aSet(rPool);
2639 css::uno::Reference< css::frame::XFrame > xFrame =
2640 GetFrame().GetFrameInterface();
2641 aSet.Put(SfxUnoFrameItem(SID_FILLFRAME(5000 + 1516), xFrame));
2642 aReq.SetInternalArgs_Impl(aSet);
2643
2644 aReq.AppendItem( SfxBoolItem(SID_RECORDMACRO(5000 + 1669),true) );
2645 const SfxPoolItem* pRet = SfxGetpApp()->ExecuteSlot( aReq );
2646 OUString aScriptURL;
2647 if ( pRet )
2648 aScriptURL = static_cast<const SfxStringItem*>(pRet)->GetValue();
2649 if ( !aScriptURL.isEmpty() )
2650 {
2651 // parse scriptURL
2652 OUString aLibName;
2653 OUString aModuleName;
2654 OUString aMacroName;
2655 OUString aLocation;
2656 Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2657 Reference< css::uri::XUriReferenceFactory > xFactory =
2658 css::uri::UriReferenceFactory::create( xContext );
2659 Reference< css::uri::XVndSunStarScriptUrl > xUrl( xFactory->parse( aScriptURL ), UNO_QUERY );
2660 if ( xUrl.is() )
2661 {
2662 // get name
2663 const OUString aName = xUrl->getName();
2664 const sal_Unicode cTok = '.';
2665 sal_Int32 nIndex = 0;
2666 aLibName = aName.getToken( 0, cTok, nIndex );
2667 if ( nIndex != -1 )
2668 aModuleName = aName.getToken( 0, cTok, nIndex );
2669 if ( nIndex != -1 )
2670 aMacroName = aName.getToken( 0, cTok, nIndex );
2671
2672 // get location
2673 aLocation = xUrl->getParameter( "location" );
2674 }
2675
2676 BasicManager* pBasMgr = nullptr;
2677 if ( aLocation == "application" )
2678 {
2679 // application basic
2680 pBasMgr = SfxApplication::GetBasicManager();
2681 }
2682 else if ( aLocation == "document" )
2683 {
2684 pBasMgr = GetObjectShell()->GetBasicManager();
2685 }
2686
2687 OUString aOUSource;
2688 if ( pBasMgr)
2689 {
2690 StarBASIC* pBasic = pBasMgr->GetLib( aLibName );
2691 if ( pBasic )
2692 {
2693 SbModule* pModule = pBasic->FindModule( aModuleName );
2694 SbMethod* pMethod = pModule ? pModule->FindMethod(aMacroName, SbxClassType::Method) : nullptr;
2695 if (pMethod)
2696 {
2697 aOUSource = pModule->GetSource32();
2698 sal_uInt16 nStart, nEnd;
2699 pMethod->GetLineRange( nStart, nEnd );
2700 sal_uInt16 nlStart = nStart;
2701 sal_uInt16 nlEnd = nEnd;
2702 CutLines( aOUSource, nlStart-1, nlEnd-nlStart+1 );
2703 }
2704 }
2705 }
2706
2707 // open lib container and break operation if it couldn't be opened
2708 css::uno::Reference< css::script::XLibraryContainer > xLibCont;
2709 if ( aLocation == "application" )
2710 {
2711 xLibCont = SfxGetpApp()->GetBasicContainer();
2712 }
2713 else if ( aLocation == "document" )
2714 {
2715 xLibCont = GetObjectShell()->GetBasicContainer();
2716 }
2717
2718 if(!xLibCont.is())
2719 {
2720 SAL_WARN("sfx.view", "couldn't get access to the basic lib container. Adding of macro isn't possible.")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.view")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "couldn't get access to the basic lib container. Adding of macro isn't possible."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "2720" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "couldn't get access to the basic lib container. Adding of macro isn't possible."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "couldn't get access to the basic lib container. Adding of macro isn't possible."
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "2720" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "couldn't get access to the basic lib container. Adding of macro isn't possible."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "2720" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "couldn't get access to the basic lib container. Adding of macro isn't possible."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "couldn't get access to the basic lib container. Adding of macro isn't possible."
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "2720" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2721 return;
2722 }
2723
2724 // get LibraryContainer
2725 css::uno::Any aTemp;
2726
2727 css::uno::Reference< css::container::XNameAccess > xLib;
2728 if(xLibCont->hasByName(aLibName))
2729 {
2730 // library must be loaded
2731 aTemp = xLibCont->getByName(aLibName);
2732 xLibCont->loadLibrary(aLibName);
2733 aTemp >>= xLib;
2734 }
2735 else
2736 {
2737 xLib = xLibCont->createLibrary(aLibName);
2738 }
2739
2740 // pack the macro as direct usable "sub" routine
2741 OUStringBuffer sRoutine(10000);
2742 bool bReplace = false;
2743
2744 // get module
2745 if(xLib->hasByName(aModuleName))
2746 {
2747 if ( !aOUSource.isEmpty() )
2748 {
2749 sRoutine.append( aOUSource );
2750 }
2751 else
2752 {
2753 OUString sCode;
2754 aTemp = xLib->getByName(aModuleName);
2755 aTemp >>= sCode;
2756 sRoutine.append( sCode );
2757 }
2758
2759 bReplace = true;
2760 }
2761
2762 // append new method
2763 sRoutine.append( "\nsub " );
2764 sRoutine.append(aMacroName);
2765 sRoutine.append( "\n" );
2766 sRoutine.append(sMacro);
2767 sRoutine.append( "\nend sub\n" );
2768
2769 // create the module inside the library and insert the macro routine
2770 aTemp <<= sRoutine.makeStringAndClear();
2771 if ( bReplace )
2772 {
2773 css::uno::Reference< css::container::XNameContainer > xModulCont(
2774 xLib,
2775 css::uno::UNO_QUERY);
2776 xModulCont->replaceByName(aModuleName,aTemp);
2777 }
2778 else
2779 {
2780 css::uno::Reference< css::container::XNameContainer > xModulCont(
2781 xLib,
2782 css::uno::UNO_QUERY);
2783 xModulCont->insertByName(aModuleName,aTemp);
2784 }
2785
2786 // #i17355# update the Basic IDE
2787 for ( SfxViewShell* pViewShell = SfxViewShell::GetFirst(); pViewShell; pViewShell = SfxViewShell::GetNext( *pViewShell ) )
2788 {
2789 if ( pViewShell->GetName() == "BasicIDE" )
2790 {
2791 SfxViewFrame* pViewFrame = pViewShell->GetViewFrame();
2792 SfxDispatcher* pDispat = pViewFrame ? pViewFrame->GetDispatcher() : nullptr;
2793 if ( pDispat )
2794 {
2795 SfxMacroInfoItem aInfoItem( SID_BASICIDE_ARG_MACROINFOTypedWhichId<SfxMacroInfoItem>( (30000 + 768) + 32 ), pBasMgr, aLibName, aModuleName, OUString(), OUString() );
2796 pDispat->ExecuteList(SID_BASICIDE_UPDATEMODULESOURCE( (30000 + 768) + 12 ),
2797 SfxCallMode::SYNCHRON, { &aInfoItem });
2798 }
2799 }
2800 }
2801 }
2802 else
2803 {
2804 // add code for "session only" macro
2805 }
2806#endif
2807}
2808
2809void SfxViewFrame::MiscExec_Impl( SfxRequest& rReq )
2810{
2811 switch ( rReq.GetSlot() )
2812 {
2813 case SID_STOP_RECORDING(5000 + 1671) :
2814 case SID_RECORDMACRO(5000 + 1669) :
2815 {
2816 // try to find any active recorder on this frame
2817 const OUString sProperty("DispatchRecorderSupplier");
2818 css::uno::Reference< css::frame::XFrame > xFrame =
2819 GetFrame().GetFrameInterface();
2820
2821 css::uno::Reference< css::beans::XPropertySet > xSet(xFrame,css::uno::UNO_QUERY);
2822 css::uno::Any aProp = xSet->getPropertyValue(sProperty);
2823 css::uno::Reference< css::frame::XDispatchRecorderSupplier > xSupplier;
2824 aProp >>= xSupplier;
2825 css::uno::Reference< css::frame::XDispatchRecorder > xRecorder;
2826 if (xSupplier.is())
2827 xRecorder = xSupplier->getDispatchRecorder();
2828
2829 bool bIsRecording = xRecorder.is();
2830 const SfxBoolItem* pItem = rReq.GetArg<SfxBoolItem>(SID_RECORDMACRO(5000 + 1669));
2831 if ( pItem && pItem->GetValue() == bIsRecording )
2832 return;
2833
2834 if ( xRecorder.is() )
2835 {
2836 // disable active recording
2837 aProp <<= css::uno::Reference< css::frame::XDispatchRecorderSupplier >();
2838 xSet->setPropertyValue(sProperty,aProp);
2839
2840 const SfxBoolItem* pRecordItem = rReq.GetArg<SfxBoolItem>(FN_PARAM_1((20000 + 1100)+60));
2841 if ( !pRecordItem || !pRecordItem->GetValue() )
2842 // insert script into basic library container of application
2843 AddDispatchMacroToBasic_Impl(xRecorder->getRecordedMacro());
2844
2845 xRecorder->endRecording();
2846 xRecorder = nullptr;
2847 GetBindings().SetRecorder_Impl( xRecorder );
2848
2849 SetChildWindow( SID_RECORDING_FLOATWINDOW(5000 + 800), false );
2850 if ( rReq.GetSlot() != SID_RECORDMACRO(5000 + 1669) )
2851 GetBindings().Invalidate( SID_RECORDMACRO(5000 + 1669) );
2852 }
2853 else if ( rReq.GetSlot() == SID_RECORDMACRO(5000 + 1669) )
2854 {
2855 // enable recording
2856 css::uno::Reference< css::uno::XComponentContext > xContext(
2857 ::comphelper::getProcessComponentContext());
2858
2859 xRecorder = css::frame::DispatchRecorder::create( xContext );
2860
2861 xSupplier = css::frame::DispatchRecorderSupplier::create( xContext );
2862
2863 xSupplier->setDispatchRecorder(xRecorder);
2864 xRecorder->startRecording(xFrame);
2865 aProp <<= xSupplier;
2866 xSet->setPropertyValue(sProperty,aProp);
2867 GetBindings().SetRecorder_Impl( xRecorder );
2868 SetChildWindow( SID_RECORDING_FLOATWINDOW(5000 + 800), true );
2869 }
2870
2871 rReq.Done();
2872 break;
2873 }
2874
2875 case SID_TOGGLESTATUSBAR(5000 + 920):
2876 {
2877 css::uno::Reference< css::frame::XFrame > xFrame =
2878 GetFrame().GetFrameInterface();
2879
2880 Reference< css::beans::XPropertySet > xPropSet( xFrame, UNO_QUERY );
2881 Reference< css::frame::XLayoutManager > xLayoutManager;
2882 if ( xPropSet.is() )
2883 {
2884 try
2885 {
2886 Any aValue = xPropSet->getPropertyValue("LayoutManager");
2887 aValue >>= xLayoutManager;
2888 }
2889 catch ( Exception& )
2890 {
2891 }
2892 }
2893
2894 if ( xLayoutManager.is() )
2895 {
2896 const OUString aStatusbarResString( "private:resource/statusbar/statusbar" );
2897 // Evaluate parameter.
2898 const SfxBoolItem* pShowItem = rReq.GetArg<SfxBoolItem>(rReq.GetSlot());
2899 bool bShow( true );
2900 if ( !pShowItem )
2901 bShow = xLayoutManager->isElementVisible( aStatusbarResString );
2902 else
2903 bShow = pShowItem->GetValue();
2904
2905 if ( bShow )
2906 {
2907 xLayoutManager->createElement( aStatusbarResString );
2908 xLayoutManager->showElement( aStatusbarResString );
2909 }
2910 else
2911 xLayoutManager->hideElement( aStatusbarResString );
2912
2913 if ( !pShowItem )
2914 rReq.AppendItem( SfxBoolItem( SID_TOGGLESTATUSBAR(5000 + 920), bShow ) );
2915 }
2916 rReq.Done();
2917 break;
2918 }
2919
2920 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2921 case SID_WIN_FULLSCREEN(5000 + 627):
2922 {
2923 const SfxBoolItem* pItem = rReq.GetArg<SfxBoolItem>(rReq.GetSlot());
2924 SfxViewFrame *pTop = GetTopViewFrame();
2925 if ( pTop )
2926 {
2927 WorkWindow* pWork = static_cast<WorkWindow*>( pTop->GetFrame().GetTopWindow_Impl() );
2928 if ( pWork )
2929 {
2930 css::uno::Reference< css::frame::XFrame > xFrame =
2931 GetFrame().GetFrameInterface();
2932
2933 Reference< css::beans::XPropertySet > xPropSet( xFrame, UNO_QUERY );
2934 Reference< css::frame::XLayoutManager > xLayoutManager;
2935 if ( xPropSet.is() )
2936 {
2937 try
2938 {
2939 Any aValue = xPropSet->getPropertyValue("LayoutManager");
2940 aValue >>= xLayoutManager;
2941 }
2942 catch ( Exception& )
2943 {
2944 }
2945 }
2946
2947 bool bNewFullScreenMode = pItem ? pItem->GetValue() : !pWork->IsFullScreenMode();
2948 if ( bNewFullScreenMode != pWork->IsFullScreenMode() )
2949 {
2950 if ( bNewFullScreenMode )
2951 sfx2::SfxNotebookBar::LockNotebookBar();
2952 else
2953 sfx2::SfxNotebookBar::UnlockNotebookBar();
2954
2955 Reference< css::beans::XPropertySet > xLMPropSet( xLayoutManager, UNO_QUERY );
2956 if ( xLMPropSet.is() )
2957 {
2958 try
2959 {
2960 xLMPropSet->setPropertyValue(
2961 "HideCurrentUI",
2962 makeAny( bNewFullScreenMode ));
2963 }
2964 catch ( css::beans::UnknownPropertyException& )
2965 {
2966 }
2967 }
2968 pWork->ShowFullScreenMode( bNewFullScreenMode );
2969 pWork->SetMenuBarMode( bNewFullScreenMode ? MenuBarMode::Hide : MenuBarMode::Normal );
2970 GetFrame().GetWorkWindow_Impl()->SetFullScreen_Impl( bNewFullScreenMode );
2971 if ( !pItem )
2972 rReq.AppendItem( SfxBoolItem( SID_WIN_FULLSCREEN(5000 + 627), bNewFullScreenMode ) );
2973 rReq.Done();
2974 }
2975 else
2976 rReq.Ignore();
2977 }
2978 }
2979 else
2980 rReq.Ignore();
2981
2982 GetDispatcher()->Update_Impl( true );
2983 break;
2984 }
2985 }
2986}
2987
2988void SfxViewFrame::MiscState_Impl(SfxItemSet &rSet)
2989{
2990 const sal_uInt16 *pRanges = rSet.GetRanges();
2991 DBG_ASSERT(pRanges && *pRanges, "Set without range")do { if (true && (!(pRanges && *pRanges))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "2991" ": "), "%s", "Set without range"); } } while (false
)
;
2992 while ( *pRanges )
2993 {
2994 for(sal_uInt16 nWhich = *pRanges++; nWhich <= *pRanges; ++nWhich)
2995 {
2996 switch(nWhich)
2997 {
2998 case SID_CURRENT_URL(5000 + 1613):
2999 {
3000 rSet.Put( SfxStringItem( nWhich, GetActualPresentationURL_Impl() ) );
3001 break;
3002 }
3003
3004 case SID_RECORDMACRO(5000 + 1669) :
3005 {
3006 SvtMiscOptions aMiscOptions;
3007 const OUString& sName{GetObjectShell()->GetFactory().GetFactoryName()};
3008 bool bMacrosDisabled = officecfg::Office::Common::Security::Scripting::DisableMacrosExecution::get();
3009 if (bMacrosDisabled || !aMiscOptions.IsMacroRecorderMode() ||
3010 ( sName!="swriter" && sName!="scalc" ) )
3011 {
3012 rSet.DisableItem( nWhich );
3013 rSet.Put(SfxVisibilityItem(nWhich, false));
3014 break;
3015 }
3016
3017 css::uno::Reference< css::beans::XPropertySet > xSet(
3018 GetFrame().GetFrameInterface(),
3019 css::uno::UNO_QUERY);
3020
3021 css::uno::Any aProp = xSet->getPropertyValue("DispatchRecorderSupplier");
3022 css::uno::Reference< css::frame::XDispatchRecorderSupplier > xSupplier;
3023 if ( aProp >>= xSupplier )
3024 rSet.Put( SfxBoolItem( nWhich, xSupplier.is() ) );
3025 else
3026 rSet.DisableItem( nWhich );
3027 break;
3028 }
3029
3030 case SID_STOP_RECORDING(5000 + 1671) :
3031 {
3032 SvtMiscOptions aMiscOptions;
3033 const OUString& sName{GetObjectShell()->GetFactory().GetFactoryName()};
3034 if ( !aMiscOptions.IsMacroRecorderMode() ||
3035 ( sName!="swriter" && sName!="scalc" ) )
3036 {
3037 rSet.DisableItem( nWhich );
3038 break;
3039 }
3040
3041 css::uno::Reference< css::beans::XPropertySet > xSet(
3042 GetFrame().GetFrameInterface(),
3043 css::uno::UNO_QUERY);
3044
3045 css::uno::Any aProp = xSet->getPropertyValue("DispatchRecorderSupplier");
3046 css::uno::Reference< css::frame::XDispatchRecorderSupplier > xSupplier;
3047 if ( !(aProp >>= xSupplier) || !xSupplier.is() )
3048 rSet.DisableItem( nWhich );
3049 break;
3050 }
3051
3052 case SID_TOGGLESTATUSBAR(5000 + 920):
3053 {
3054 css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
3055 css::uno::Reference< css::beans::XPropertySet > xSet(
3056 GetFrame().GetFrameInterface(),
3057 css::uno::UNO_QUERY);
3058 css::uno::Any aProp = xSet->getPropertyValue( "LayoutManager" );
3059
3060 if ( !( aProp >>= xLayoutManager ))
3061 rSet.Put( SfxBoolItem( nWhich, false ));
3062 else
3063 {
3064 bool bShow = xLayoutManager->isElementVisible( "private:resource/statusbar/statusbar" );
3065 rSet.Put( SfxBoolItem( nWhich, bShow ));
3066 }
3067 break;
3068 }
3069
3070 case SID_WIN_FULLSCREEN(5000 + 627):
3071 {
3072 SfxViewFrame* pTop = GetTopViewFrame();
3073 if ( pTop )
3074 {
3075 WorkWindow* pWork = static_cast<WorkWindow*>( pTop->GetFrame().GetTopWindow_Impl() );
3076 if ( pWork )
3077 {
3078 rSet.Put( SfxBoolItem( nWhich, pWork->IsFullScreenMode() ) );
3079 break;
3080 }
3081 }
3082
3083 rSet.DisableItem( nWhich );
3084 break;
3085 }
3086
3087 default:
3088 break;
3089 }
3090 }
3091
3092 ++pRanges;
3093 }
3094}
3095
3096/* [Description]
3097
3098 This method can be included in the Execute method for the on- and off-
3099 switching of ChildWindows, to implement this and API-bindings.
3100
3101 Simply include as 'ExecuteMethod' in the IDL.
3102*/
3103void SfxViewFrame::ChildWindowExecute( SfxRequest &rReq )
3104{
3105 // Evaluate Parameter
3106 sal_uInt16 nSID = rReq.GetSlot();
3107
3108 const SfxBoolItem* pShowItem = rReq.GetArg<SfxBoolItem>(nSID);
3109 if ( nSID == SID_VIEW_DATA_SOURCE_BROWSER(5000 + 1660) )
3110 {
3111 if (!SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::EModule::DATABASE))
3112 return;
3113 Reference < XFrame > xFrame = GetFrame().GetFrameInterface();
3114 Reference < XFrame > xBeamer( xFrame->findFrame( "_beamer", FrameSearchFlag::CHILDREN ) );
3115 bool bHasChild = xBeamer.is();
3116 bool bShow = pShowItem ? pShowItem->GetValue() : !bHasChild;
3117 if ( pShowItem )
3118 {
3119 if( bShow == bHasChild )
3120 return;
3121 }
3122 else
3123 rReq.AppendItem( SfxBoolItem( nSID, bShow ) );
3124
3125 if ( !bShow )
3126 {
3127 SetChildWindow( SID_BROWSER(5000 + 1318), false );
3128 }
3129 else
3130 {
3131 css::util::URL aTargetURL;
3132 aTargetURL.Complete = ".component:DB/DataSourceBrowser";
3133 Reference < css::util::XURLTransformer > xTrans(
3134 css::util::URLTransformer::create(
3135 ::comphelper::getProcessComponentContext() ) );
3136 xTrans->parseStrict( aTargetURL );
3137
3138 Reference < XDispatchProvider > xProv( xFrame, UNO_QUERY );
3139 Reference < css::frame::XDispatch > xDisp;
3140 if ( xProv.is() )
3141 xDisp = xProv->queryDispatch( aTargetURL, "_beamer", 31 );
3142 if ( xDisp.is() )
3143 {
3144 Sequence < css::beans::PropertyValue > aArgs(1);
3145 css::beans::PropertyValue* pArg = aArgs.getArray();
3146 pArg[0].Name = "Referer";
3147 pArg[0].Value <<= OUString("private:user");
3148 xDisp->dispatch( aTargetURL, aArgs );
3149 }
3150 }
3151
3152 rReq.Done();
3153 return;
3154 }
3155 if (nSID == SID_STYLE_DESIGNER(5000 + 539))
3156 {
3157 // First make sure that the sidebar is visible
3158 ShowChildWindow(SID_SIDEBAR(10000 + 336));
3159
3160 ::sfx2::sidebar::Sidebar::ShowPanel("StyleListPanel",
3161 GetFrame().GetFrameInterface(), true);
3162 rReq.Done();
3163 return;
3164 }
3165
3166 bool bHasChild = HasChildWindow(nSID);
3167 bool bShow = pShowItem ? pShowItem->GetValue() : !bHasChild;
3168 GetDispatcher()->Update_Impl( true );
3169
3170 // Perform action.
3171 if ( !pShowItem || bShow != bHasChild )
3172 ToggleChildWindow( nSID );
3173
3174 GetBindings().Invalidate( nSID );
3175
3176 // Record if possible.
3177 if ( nSID == SID_HYPERLINK_DIALOG(5000 + 678) || nSID == SID_SEARCH_DLG(5000 + 961) )
3178 {
3179 rReq.Ignore();
3180 }
3181 else
3182 {
3183 rReq.AppendItem( SfxBoolItem( nSID, bShow ) );
3184 rReq.Done();
3185 }
3186}
3187
3188/* [Description]
3189
3190 This method can be used in the state method for the on and off-state
3191 of child-windows, in order to implement this.
3192
3193 Just register the IDL as 'StateMethod'.
3194*/
3195void SfxViewFrame::ChildWindowState( SfxItemSet& rState )
3196{
3197 SfxWhichIter aIter( rState );
3198 for ( sal_uInt16 nSID = aIter.FirstWhich(); nSID; nSID = aIter.NextWhich() )
3199 {
3200 if ( nSID == SID_VIEW_DATA_SOURCE_BROWSER(5000 + 1660) )
3201 {
3202 rState.Put( SfxBoolItem( nSID, HasChildWindow( SID_BROWSER(5000 + 1318) ) ) );
3203 }
3204 else if ( nSID == SID_HYPERLINK_DIALOG(5000 + 678) )
3205 {
3206 const SfxPoolItem* pDummy = nullptr;
3207 SfxItemState eState = GetDispatcher()->QueryState( SID_HYPERLINK_SETLINKTypedWhichId<SvxHyperlinkItem>(10000 + 362), pDummy );
3208 if ( SfxItemState::DISABLED == eState )
3209 rState.DisableItem(nSID);
3210 else
3211 {
3212 if ( KnowsChildWindow(nSID) )
3213 rState.Put( SfxBoolItem( nSID, HasChildWindow(nSID)) );
3214 else
3215 rState.DisableItem(nSID);
3216 }
3217 }
3218 else if ( nSID == SID_BROWSER(5000 + 1318) )
3219 {
3220 Reference < XFrame > xFrame = GetFrame().GetFrameInterface()->
3221 findFrame( "_beamer", FrameSearchFlag::CHILDREN );
3222 if ( !xFrame.is() )
3223 rState.DisableItem( nSID );
3224 else if ( KnowsChildWindow(nSID) )
3225 rState.Put( SfxBoolItem( nSID, HasChildWindow(nSID) ) );
3226 }
3227 else if ( nSID == SID_SIDEBAR(10000 + 336) )
3228 {
3229 if ( !KnowsChildWindow( nSID ) )
3230 {
3231 SAL_INFO("sfx.view", "SID_SIDEBAR state requested, but no task pane child window exists for this ID!")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "sfx.view")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "SID_SIDEBAR state requested, but no task pane child window exists for this ID!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "3231" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SID_SIDEBAR state requested, but no task pane child window exists for this ID!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SID_SIDEBAR state requested, but no task pane child window exists for this ID!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "3231" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SID_SIDEBAR state requested, but no task pane child window exists for this ID!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "3231" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "SID_SIDEBAR state requested, but no task pane child window exists for this ID!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SID_SIDEBAR state requested, but no task pane child window exists for this ID!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.view"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx"
":" "3231" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
3232 rState.DisableItem( nSID );
3233 }
3234 else
3235 {
3236 rState.Put( SfxBoolItem( nSID, HasChildWindow( nSID ) ) );
3237 }
3238 }
3239 else if ( KnowsChildWindow(nSID) )
3240 rState.Put( SfxBoolItem( nSID, HasChildWindow(nSID) ) );
3241 else
3242 rState.DisableItem(nSID);
3243 }
3244}
3245
3246SfxWorkWindow* SfxViewFrame::GetWorkWindow_Impl()
3247{
3248 SfxWorkWindow* pWork = GetFrame().GetWorkWindow_Impl();
3249 return pWork;
3250}
3251
3252void SfxViewFrame::SetChildWindow(sal_uInt16 nId, bool bOn, bool bSetFocus )
3253{
3254 SfxWorkWindow* pWork = GetWorkWindow_Impl();
3255 if ( pWork )
3256 pWork->SetChildWindow_Impl( nId, bOn, bSetFocus );
3257}
3258
3259void SfxViewFrame::ToggleChildWindow(sal_uInt16 nId)
3260{
3261 SfxWorkWindow* pWork = GetWorkWindow_Impl();
3262 if ( pWork )
3263 pWork->ToggleChildWindow_Impl( nId, true );
3264}
3265
3266bool SfxViewFrame::HasChildWindow( sal_uInt16 nId )
3267{
3268 SfxWorkWindow* pWork = GetWorkWindow_Impl();
3269 return pWork && pWork->HasChildWindow_Impl(nId);
3270}
3271
3272bool SfxViewFrame::KnowsChildWindow( sal_uInt16 nId )
3273{
3274 SfxWorkWindow* pWork = GetWorkWindow_Impl();
3275 return pWork && pWork->KnowsChildWindow_Impl(nId);
3276}
3277
3278void SfxViewFrame::ShowChildWindow( sal_uInt16 nId, bool bVisible )
3279{
3280 SfxWorkWindow* pWork = GetWorkWindow_Impl();
3281 if ( pWork )
3282 {
3283 GetDispatcher()->Update_Impl(true);
3284 pWork->ShowChildWindow_Impl(nId, bVisible, true );
3285 }
3286}
3287
3288SfxChildWindow* SfxViewFrame::GetChildWindow(sal_uInt16 nId)
3289{
3290 SfxWorkWindow* pWork = GetWorkWindow_Impl();
3291 return pWork ? pWork->GetChildWindow_Impl(nId) : nullptr;
3292}
3293
3294void SfxViewFrame::UpdateDocument_Impl()
3295{
3296 SfxObjectShell* pDoc = GetObjectShell();
3297 if ( pDoc->IsLoadingFinished() )
3298 pDoc->CheckSecurityOnLoading_Impl();
3299
3300 // check if document depends on a template
3301 pDoc->UpdateFromTemplate_Impl();
3302}
3303
3304void SfxViewFrame::SetViewFrame( SfxViewFrame* pFrame )
3305{
3306 if(pFrame)
3307 SetSVHelpData(pFrame->m_pHelpData);
3308
3309 SetSVWinData(pFrame ? pFrame->m_pWinData : nullptr);
3310
3311 SfxGetpApp()->SetViewFrame_Impl( pFrame );
3312}
3313
3314VclPtr<SfxInfoBarWindow> SfxViewFrame::AppendInfoBar(const OUString& sId,
3315 const OUString& sPrimaryMessage,
3316 const OUString& sSecondaryMessage,
3317 InfobarType aInfobarType, bool bShowCloseButton)
3318{
3319 SfxChildWindow* pChild = GetChildWindow(SfxInfoBarContainerChild::GetChildWindowId());
3320 if (!pChild)
3321 return nullptr;
3322
3323 if (HasInfoBarWithID(sId))
3324 return nullptr;
3325
3326 SfxInfoBarContainerWindow* pInfoBarContainer = static_cast<SfxInfoBarContainerWindow*>(pChild->GetWindow());
3327 auto pInfoBar = pInfoBarContainer->appendInfoBar(sId, sPrimaryMessage, sSecondaryMessage,
3328 aInfobarType, bShowCloseButton);
3329 ShowChildWindow(SfxInfoBarContainerChild::GetChildWindowId());
3330 return pInfoBar;
3331}
3332
3333void SfxViewFrame::UpdateInfoBar(const OUString& sId, const OUString& sPrimaryMessage,
3334 const OUString& sSecondaryMessage, InfobarType eType)
3335{
3336 const sal_uInt16 nId = SfxInfoBarContainerChild::GetChildWindowId();
3337
3338 // Make sure the InfoBar container is visible
3339 if (!HasChildWindow(nId))
3340 ToggleChildWindow(nId);
3341
3342 SfxChildWindow* pChild = GetChildWindow(nId);
3343 if (pChild)
3344 {
3345 SfxInfoBarContainerWindow* pInfoBarContainer = static_cast<SfxInfoBarContainerWindow*>(pChild->GetWindow());
3346 auto pInfoBar = pInfoBarContainer->getInfoBar(sId);
3347
3348 if (pInfoBar)
3349 pInfoBar->Update(sPrimaryMessage, sSecondaryMessage, eType);
3350 }
3351}
3352
3353void SfxViewFrame::RemoveInfoBar( const OUString& sId )
3354{
3355 const sal_uInt16 nId = SfxInfoBarContainerChild::GetChildWindowId();
3356
3357 // Make sure the InfoBar container is visible
3358 if (!HasChildWindow(nId))
3359 ToggleChildWindow(nId);
3360
3361 SfxChildWindow* pChild = GetChildWindow(nId);
3362 if (pChild)
3363 {
3364 SfxInfoBarContainerWindow* pInfoBarContainer = static_cast<SfxInfoBarContainerWindow*>(pChild->GetWindow());
3365 auto pInfoBar = pInfoBarContainer->getInfoBar(sId);
3366 pInfoBarContainer->removeInfoBar(pInfoBar);
3367 ShowChildWindow(nId);
3368 }
3369}
3370
3371bool SfxViewFrame::HasInfoBarWithID( const OUString& sId )
3372{
3373 const sal_uInt16 nId = SfxInfoBarContainerChild::GetChildWindowId();
3374
3375 SfxChildWindow* pChild = GetChildWindow(nId);
3376 if (pChild)
3377 {
3378 SfxInfoBarContainerWindow* pInfoBarContainer = static_cast<SfxInfoBarContainerWindow*>(pChild->GetWindow());
3379 return pInfoBarContainer->hasInfoBarWithID(sId);
3380 }
3381
3382 return false;
3383}
3384
3385/* vim:set shiftwidth=4 softtabstop=4 expandtab: */