File: | home/maarten/src/libreoffice/core/include/tools/ref.hxx |
Warning: | line 97, column 56 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | ||||
96 | using namespace ::com::sun::star; | |||
97 | using namespace ::com::sun::star::uno; | |||
98 | using namespace ::com::sun::star::ucb; | |||
99 | using namespace ::com::sun::star::frame; | |||
100 | using namespace ::com::sun::star::lang; | |||
101 | using ::com::sun::star::awt::XWindow; | |||
102 | using ::com::sun::star::beans::PropertyValue; | |||
103 | using ::com::sun::star::document::XViewDataSupplier; | |||
104 | using ::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 | ||||
138 | SFX_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 | ||||
140 | void 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 | ||||
150 | namespace { | |||
151 | /// Asks the user if editing a read-only document is really wanted. | |||
152 | class SfxEditDocumentDialog : public weld::MessageDialogController | |||
153 | { | |||
154 | private: | |||
155 | std::unique_ptr<weld::Button> m_xEditDocument; | |||
156 | std::unique_ptr<weld::Button> m_xCancel; | |||
157 | ||||
158 | public: | |||
159 | SfxEditDocumentDialog(weld::Widget* pParent); | |||
160 | }; | |||
161 | ||||
162 | SfxEditDocumentDialog::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 | ||||
170 | class SfxQueryOpenAsTemplate | |||
171 | { | |||
172 | private: | |||
173 | std::unique_ptr<weld::MessageDialog> m_xQueryBox; | |||
174 | public: | |||
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 | ||||
190 | private: | |||
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 | ||||
217 | bool AskPasswordToModify_Impl( const uno::Reference< task::XInteractionHandler >& xHandler, const OUString& aPath, const std::shared_ptr<const SfxFilter>& pFilter, sal_uInt32 nPasswordHash, const uno::Sequence< beans::PropertyValue >& aInfo ) | |||
218 | { | |||
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 | ||||
267 | void 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; | |||
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 | ||||
893 | void 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 | ||||
953 | void 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 | ||||
999 | void 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 | ||||
1063 | void 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 | */ | |||
1097 | void 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 | ||||
1148 | void 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 | ||||
1168 | void SfxViewFrame::DoActivate( bool bUI ) | |||
1169 | { | |||
1170 | m_pDispatcher->DoActivate_Impl( bUI ); | |||
1171 | } | |||
1172 | ||||
1173 | void SfxViewFrame::DoDeactivate(bool bUI, SfxViewFrame const * pNewFrame ) | |||
1174 | { | |||
1175 | m_pDispatcher->DoDeactivate_Impl( bUI, pNewFrame ); | |||
1176 | } | |||
1177 | ||||
1178 | void 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 | ||||
1196 | void 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 | ||||
1235 | const SvBorder& SfxViewFrame::GetBorderPixelImpl() const | |||
1236 | { | |||
1237 | return m_pImpl->aBorder; | |||
1238 | } | |||
1239 | ||||
1240 | void 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 | ||||
1286 | void 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 | ||||
1534 | IMPL_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 | ||||
1539 | IMPL_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 | ||||
1544 | IMPL_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 | ||||
1549 | IMPL_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 | ||||
1560 | IMPL_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 | ||||
1565 | void 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 | */ | |||
1618 | SfxViewFrame::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 | ||||
1640 | SfxViewFrame::~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. | |||
1678 | void 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 | ||||
1694 | SfxViewFrame* 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. | |||
1701 | SfxViewFrame* 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. | |||
1726 | SfxViewFrame* 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 | ||||
1757 | SfxProgress* SfxViewFrame::GetProgress() const | |||
1758 | { | |||
1759 | SfxObjectShell *pObjSh = m_xObjSh.get(); | |||
1760 | return pObjSh ? pObjSh->GetProgress() : nullptr; | |||
1761 | } | |||
1762 | ||||
1763 | void 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 | ||||
1784 | bool SfxViewFrameItem::operator==( const SfxPoolItem &rItem ) const | |||
1785 | { | |||
1786 | return SfxPoolItem::operator==(rItem) && | |||
1787 | static_cast<const SfxViewFrameItem&>(rItem).pFrame == pFrame; | |||
1788 | } | |||
1789 | ||||
1790 | SfxViewFrameItem* SfxViewFrameItem::Clone( SfxItemPool *) const | |||
1791 | { | |||
1792 | return new SfxViewFrameItem( *this ); | |||
1793 | } | |||
1794 | ||||
1795 | void 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 | ||||
1809 | void SfxViewFrame::ForceOuterResize_Impl() | |||
1810 | { | |||
1811 | m_pImpl->bResizeInToOut = true; | |||
1812 | } | |||
1813 | ||||
1814 | void 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 | ||||
1821 | void 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 | */ | |||
1856 | void 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 | ||||
1883 | bool SfxViewFrame::IsVisible() const | |||
1884 | { | |||
1885 | return m_pImpl->bObjLocked; | |||
1886 | } | |||
1887 | ||||
1888 | ||||
1889 | void 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 | ||||
1899 | void 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 | ||||
1939 | SfxObjectShell* SfxViewFrame::GetObjectShell() | |||
1940 | { | |||
1941 | return m_xObjSh.get(); | |||
1942 | } | |||
1943 | ||||
1944 | const Size& SfxViewFrame::GetMargin_Impl() const | |||
1945 | { | |||
1946 | return m_pImpl->aMargin; | |||
1947 | } | |||
1948 | ||||
1949 | SfxViewFrame* 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 | ||||
2019 | SfxViewShell* 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 | ||||
2044 | SfxViewFrame* SfxViewFrame::LoadHiddenDocument( SfxObjectShell const & i_rDoc, SfxInterfaceId i_nViewId ) | |||
2045 | { | |||
2046 | return LoadViewIntoFrame_Impl_NoThrow( i_rDoc, Reference< XFrame >(), i_nViewId, true ); | |||
2047 | } | |||
2048 | ||||
2049 | SfxViewFrame* SfxViewFrame::LoadDocument( SfxObjectShell const & i_rDoc, SfxInterfaceId i_nViewId ) | |||
2050 | { | |||
2051 | return LoadViewIntoFrame_Impl_NoThrow( i_rDoc, Reference< XFrame >(), i_nViewId, false ); | |||
2052 | } | |||
2053 | ||||
2054 | SfxViewFrame* 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 | ||||
2059 | SfxViewFrame* 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 | ||||
2064 | SfxViewFrame* 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 | ||||
2077 | SfxViewFrame* 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 | ||||
2109 | void 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 | */ | |||
2190 | bool 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 | ||||
2263 | void SfxViewFrame::SetCurViewId_Impl( const SfxInterfaceId i_nID ) | |||
2264 | { | |||
2265 | m_pImpl->nCurViewId = i_nID; | |||
2266 | } | |||
2267 | ||||
2268 | SfxInterfaceId 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 | */ | |||
2278 | void 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 | */ | |||
2377 | static 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 | */ | |||
2430 | void 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 | ||||
2493 | void SfxViewFrame::ToTop() | |||
2494 | { | |||
2495 | GetFrame().Appear(); | |||
2496 | } | |||
2497 | ||||
2498 | ||||
2499 | /* [Description] | |||
2500 | ||||
2501 | GetFrame returns the Frame, in which the ViewFrame is located. | |||
2502 | */ | |||
2503 | SfxFrame& SfxViewFrame::GetFrame() const | |||
2504 | { | |||
2505 | return m_pImpl->rFrame; | |||
2506 | } | |||
2507 | ||||
2508 | SfxViewFrame* SfxViewFrame::GetTopViewFrame() const | |||
2509 | { | |||
2510 | return GetFrame().GetCurrentViewFrame(); | |||
2511 | } | |||
2512 | ||||
2513 | vcl::Window& SfxViewFrame::GetWindow() const | |||
2514 | { | |||
2515 | return m_pImpl->pWindow ? *m_pImpl->pWindow : GetFrame().GetWindow(); | |||
2516 | } | |||
2517 | ||||
2518 | bool SfxViewFrame::DoClose() | |||
2519 | { | |||
2520 | return GetFrame().DoClose(); | |||
2521 | } | |||
2522 | ||||
2523 | OUString SfxViewFrame::GetActualPresentationURL_Impl() const | |||
2524 | { | |||
2525 | if ( m_xObjSh.is() ) | |||
2526 | return m_xObjSh->GetMedium()->GetName(); | |||
2527 | return OUString(); | |||
2528 | } | |||
2529 | ||||
2530 | void 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 | ||||
2546 | bool SfxViewFrame::IsInModalMode() const | |||
2547 | { | |||
2548 | return m_pImpl->bModal || GetFrame().GetWindow().IsInModalMode(); | |||
2549 | } | |||
2550 | ||||
2551 | void 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 | ||||
2577 | static 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 | */ | |||
2625 | void 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 | ||||
2809 | void 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 | ||||
2988 | void 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 | */ | |||
3103 | void 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 | */ | |||
3195 | void 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 | ||||
3246 | SfxWorkWindow* SfxViewFrame::GetWorkWindow_Impl() | |||
3247 | { | |||
3248 | SfxWorkWindow* pWork = GetFrame().GetWorkWindow_Impl(); | |||
3249 | return pWork; | |||
3250 | } | |||
3251 | ||||
3252 | void 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 | ||||
3259 | void SfxViewFrame::ToggleChildWindow(sal_uInt16 nId) | |||
3260 | { | |||
3261 | SfxWorkWindow* pWork = GetWorkWindow_Impl(); | |||
3262 | if ( pWork ) | |||
3263 | pWork->ToggleChildWindow_Impl( nId, true ); | |||
3264 | } | |||
3265 | ||||
3266 | bool SfxViewFrame::HasChildWindow( sal_uInt16 nId ) | |||
3267 | { | |||
3268 | SfxWorkWindow* pWork = GetWorkWindow_Impl(); | |||
3269 | return pWork && pWork->HasChildWindow_Impl(nId); | |||
3270 | } | |||
3271 | ||||
3272 | bool SfxViewFrame::KnowsChildWindow( sal_uInt16 nId ) | |||
3273 | { | |||
3274 | SfxWorkWindow* pWork = GetWorkWindow_Impl(); | |||
3275 | return pWork && pWork->KnowsChildWindow_Impl(nId); | |||
3276 | } | |||
3277 | ||||
3278 | void 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 | ||||
3288 | SfxChildWindow* SfxViewFrame::GetChildWindow(sal_uInt16 nId) | |||
3289 | { | |||
3290 | SfxWorkWindow* pWork = GetWorkWindow_Impl(); | |||
3291 | return pWork ? pWork->GetChildWindow_Impl(nId) : nullptr; | |||
3292 | } | |||
3293 | ||||
3294 | void 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 | ||||
3304 | void 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 | ||||
3314 | VclPtr<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 | ||||
3333 | void 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 | ||||
3353 | void 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 | ||||
3371 | bool 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: */ |
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 | #ifndef INCLUDED_TOOLS_REF_HXX | |||
20 | #define INCLUDED_TOOLS_REF_HXX | |||
21 | ||||
22 | #include <sal/config.h> | |||
23 | #include <cassert> | |||
24 | #include <tools/toolsdllapi.h> | |||
25 | #include <utility> | |||
26 | ||||
27 | /** | |||
28 | This implements similar functionality to boost::intrusive_ptr | |||
29 | */ | |||
30 | ||||
31 | namespace tools { | |||
32 | ||||
33 | /** T must be a class that extends SvRefBase */ | |||
34 | template<typename T> class SAL_DLLPUBLIC_RTTI__attribute__ ((type_visibility("default"))) SvRef final { | |||
35 | public: | |||
36 | SvRef(): pObj(nullptr) {} | |||
37 | ||||
38 | SvRef(SvRef&& rObj) noexcept | |||
39 | { | |||
40 | pObj = rObj.pObj; | |||
41 | rObj.pObj = nullptr; | |||
42 | } | |||
43 | ||||
44 | SvRef(SvRef const & rObj): pObj(rObj.pObj) | |||
45 | { | |||
46 | if (pObj != nullptr) pObj->AddNextRef(); | |||
47 | } | |||
48 | ||||
49 | SvRef(T * pObjP): pObj(pObjP) | |||
50 | { | |||
51 | if (pObj != nullptr) pObj->AddFirstRef(); | |||
52 | } | |||
53 | ||||
54 | ~SvRef() | |||
55 | { | |||
56 | if (pObj != nullptr) pObj->ReleaseRef(); | |||
57 | } | |||
58 | ||||
59 | void clear() | |||
60 | { | |||
61 | if (pObj != nullptr) { | |||
62 | T * pRefObj = pObj; | |||
63 | pObj = nullptr; | |||
64 | pRefObj->ReleaseRef(); | |||
65 | } | |||
66 | } | |||
67 | ||||
68 | SvRef & operator =(SvRef const & rObj) | |||
69 | { | |||
70 | if (rObj.pObj != nullptr) { | |||
71 | rObj.pObj->AddNextRef(); | |||
72 | } | |||
73 | T * pRefObj = pObj; | |||
74 | pObj = rObj.pObj; | |||
75 | if (pRefObj != nullptr) { | |||
76 | pRefObj->ReleaseRef(); | |||
77 | } | |||
78 | return *this; | |||
79 | } | |||
80 | ||||
81 | SvRef & operator =(SvRef && rObj) | |||
82 | { | |||
83 | if (pObj != nullptr) { | |||
84 | pObj->ReleaseRef(); | |||
85 | } | |||
86 | pObj = rObj.pObj; | |||
87 | rObj.pObj = nullptr; | |||
88 | return *this; | |||
89 | } | |||
90 | ||||
91 | bool is() const { return pObj != nullptr; } | |||
92 | ||||
93 | explicit operator bool() const { return is(); } | |||
94 | ||||
95 | T * get() const { return pObj; } | |||
96 | ||||
97 | T * operator ->() const { assert(pObj != nullptr)(static_cast <bool> (pObj != nullptr) ? void (0) : __assert_fail ("pObj != nullptr", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx" , 97, __extension__ __PRETTY_FUNCTION__)); return pObj; } | |||
| ||||
98 | ||||
99 | T & operator *() const { assert(pObj != nullptr)(static_cast <bool> (pObj != nullptr) ? void (0) : __assert_fail ("pObj != nullptr", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx" , 99, __extension__ __PRETTY_FUNCTION__)); return *pObj; } | |||
100 | ||||
101 | bool operator ==(const SvRef<T> &rhs) const { return pObj == rhs.pObj; } | |||
102 | bool operator !=(const SvRef<T> &rhs) const { return !(*this == rhs); } | |||
103 | ||||
104 | private: | |||
105 | T * pObj; | |||
106 | }; | |||
107 | ||||
108 | /** | |||
109 | * This implements similar functionality to std::make_shared. | |||
110 | */ | |||
111 | template<typename T, typename... Args> | |||
112 | SvRef<T> make_ref(Args&& ... args) | |||
113 | { | |||
114 | return SvRef<T>(new T(std::forward<Args>(args)...)); | |||
115 | } | |||
116 | ||||
117 | } | |||
118 | ||||
119 | /** Classes that want to be referenced-counted via SvRef<T>, should extend this base class */ | |||
120 | class TOOLS_DLLPUBLIC__attribute__ ((visibility("default"))) SvRefBase | |||
121 | { | |||
122 | // work around a clang 3.5 optimization bug: if the bNoDelete is *first* | |||
123 | // it mis-compiles "if (--nRefCount == 0)" and never deletes any object | |||
124 | unsigned int nRefCount : 31; | |||
125 | // the only reason this is not bool is because MSVC cannot handle mixed type bitfields | |||
126 | unsigned int bNoDelete : 1; | |||
127 | ||||
128 | protected: | |||
129 | virtual ~SvRefBase() COVERITY_NOEXCEPT_FALSE; | |||
130 | ||||
131 | public: | |||
132 | SvRefBase() : nRefCount(0), bNoDelete(1) {} | |||
133 | SvRefBase(const SvRefBase &) : nRefCount(0), bNoDelete(1) {} | |||
134 | ||||
135 | SvRefBase & operator=(const SvRefBase &) { return *this; } | |||
136 | ||||
137 | void RestoreNoDelete() | |||
138 | { bNoDelete = 1; } | |||
139 | ||||
140 | void AddNextRef() | |||
141 | { | |||
142 | assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" )(static_cast <bool> (nRefCount < (1 << 30) && "Do not add refs to dead objects") ? void (0) : __assert_fail ("nRefCount < (1 << 30) && \"Do not add refs to dead objects\"" , "/home/maarten/src/libreoffice/core/include/tools/ref.hxx", 142, __extension__ __PRETTY_FUNCTION__)); | |||
143 | ++nRefCount; | |||
144 | } | |||
145 | ||||
146 | void AddFirstRef() | |||
147 | { | |||
148 | assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" )(static_cast <bool> (nRefCount < (1 << 30) && "Do not add refs to dead objects") ? void (0) : __assert_fail ("nRefCount < (1 << 30) && \"Do not add refs to dead objects\"" , "/home/maarten/src/libreoffice/core/include/tools/ref.hxx", 148, __extension__ __PRETTY_FUNCTION__)); | |||
149 | if( bNoDelete ) | |||
150 | bNoDelete = 0; | |||
151 | ++nRefCount; | |||
152 | } | |||
153 | ||||
154 | void ReleaseRef() | |||
155 | { | |||
156 | assert( nRefCount >= 1)(static_cast <bool> (nRefCount >= 1) ? void (0) : __assert_fail ("nRefCount >= 1", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx" , 156, __extension__ __PRETTY_FUNCTION__)); | |||
157 | if( --nRefCount == 0 && !bNoDelete) | |||
158 | { | |||
159 | // I'm not sure about the original purpose of this line, but right now | |||
160 | // it serves the purpose that anything that attempts to do an AddRef() | |||
161 | // after an object is deleted will trip an assert. | |||
162 | nRefCount = 1 << 30; | |||
163 | delete this; | |||
164 | } | |||
165 | } | |||
166 | ||||
167 | unsigned int GetRefCount() const | |||
168 | { return nRefCount; } | |||
169 | }; | |||
170 | ||||
171 | template<typename T> | |||
172 | class SvCompatWeakBase; | |||
173 | ||||
174 | /** SvCompatWeakHdl acts as an intermediary between SvCompatWeakRef<T> and T. | |||
175 | */ | |||
176 | template<typename T> | |||
177 | class SvCompatWeakHdl final : public SvRefBase | |||
178 | { | |||
179 | friend class SvCompatWeakBase<T>; | |||
180 | T* _pObj; | |||
181 | ||||
182 | SvCompatWeakHdl( T* pObj ) : _pObj( pObj ) {} | |||
183 | ||||
184 | public: | |||
185 | void ResetWeakBase( ) { _pObj = nullptr; } | |||
186 | T* GetObj() { return _pObj; } | |||
187 | }; | |||
188 | ||||
189 | /** We only have one place that extends this, in include/sfx2/frame.hxx, class SfxFrame. | |||
190 | Its function is to notify the SvCompatWeakHdl when an SfxFrame object is deleted. | |||
191 | */ | |||
192 | template<typename T> | |||
193 | class SvCompatWeakBase | |||
194 | { | |||
195 | tools::SvRef< SvCompatWeakHdl<T> > _xHdl; | |||
196 | ||||
197 | public: | |||
198 | /** Does not use initializer due to compiler warnings, | |||
199 | because the lifetime of the _xHdl object can exceed the lifetime of this class. | |||
200 | */ | |||
201 | SvCompatWeakBase( T* pObj ) { _xHdl = new SvCompatWeakHdl<T>( pObj ); } | |||
202 | ||||
203 | ~SvCompatWeakBase() { _xHdl->ResetWeakBase(); } | |||
204 | ||||
205 | SvCompatWeakHdl<T>* GetHdl() { return _xHdl.get(); } | |||
206 | }; | |||
207 | ||||
208 | /** We only have one weak reference in LO, in include/sfx2/frame.hxx, class SfxFrameWeak. | |||
209 | */ | |||
210 | template<typename T> | |||
211 | class SAL_WARN_UNUSED__attribute__((warn_unused)) SvCompatWeakRef | |||
212 | { | |||
213 | tools::SvRef< SvCompatWeakHdl<T> > _xHdl; | |||
214 | public: | |||
215 | SvCompatWeakRef( ) {} | |||
216 | SvCompatWeakRef( T* pObj ) | |||
217 | { if( pObj ) _xHdl = pObj->GetHdl(); } | |||
218 | #if defined(__COVERITY__) | |||
219 | ~SvCompatWeakRef() COVERITY_NOEXCEPT_FALSE {} | |||
220 | #endif | |||
221 | SvCompatWeakRef& operator = ( T * pObj ) | |||
222 | { _xHdl = pObj ? pObj->GetHdl() : nullptr; return *this; } | |||
223 | bool is() const | |||
224 | { return _xHdl.is() && _xHdl->GetObj(); } | |||
225 | explicit operator bool() const { return is(); } | |||
226 | T* operator -> () const | |||
227 | { return _xHdl.is() ? _xHdl->GetObj() : nullptr; } | |||
228 | operator T* () const | |||
229 | { return _xHdl.is() ? _xHdl->GetObj() : nullptr; } | |||
230 | }; | |||
231 | ||||
232 | #endif | |||
233 | ||||
234 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |