File: | home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx |
Warning: | line 437, column 17 Value stored to 'bNeedsReload' is never read |
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; |
Value stored to 'bNeedsReload' is never read | |
438 | |
439 | bool bOK = false; |
440 | bool bRetryIgnoringLock = false; |
441 | bool bOpenTemplate = false; |
442 | std::optional<bool> aOrigROVal; |
443 | if (!pVersionItem) |
444 | { |
445 | auto pRO = pMed->GetItemSet()->GetItem<SfxBoolItem>(SID_DOC_READONLY(5000 + 590), false); |
446 | if (pRO) |
447 | aOrigROVal = pRO->GetValue(); |
448 | } |
449 | do { |
450 | LockFileEntry aLockData; |
451 | if ( !pVersionItem ) |
452 | { |
453 | if (bRetryIgnoringLock) |
454 | pMed->ResetError(); |
455 | |
456 | bool bHasStorage = pMed->HasStorage_Impl(); |
457 | // switching edit mode could be possible without reload |
458 | if ( bHasStorage && pMed->GetStorage() == pSh->GetStorage() ) |
459 | { |
460 | // TODO/LATER: faster creation of copy |
461 | if ( !pSh->ConnectTmpStorage_Impl( pMed->GetStorage(), pMed ) ) |
462 | return; |
463 | } |
464 | |
465 | pMed->CloseAndRelease(); |
466 | pMed->SetOpenMode( nOpenMode ); |
467 | // We need to clear the SID_DOC_READONLY item from the set, to allow |
468 | // MediaDescriptor::impl_openStreamWithURL (called indirectly by |
469 | // SfxMedium::CompleteReOpen) to properly fill input stream of the |
470 | // descriptor, even when the file can't be open in read-write mode. |
471 | // Only then can following call to SfxMedium::LockOrigFileOnDemand |
472 | // return proper information about who has locked the file, to show |
473 | // in the SfxQueryOpenAsTemplate box below; otherwise it exits right |
474 | // after call to SfxMedium::GetMedium_Impl. This mimics what happens |
475 | // when the file is opened initially, when filter detection code also |
476 | // calls MediaDescriptor::impl_openStreamWithURL without the item set. |
477 | pMed->GetItemSet()->ClearItem(SID_DOC_READONLY(5000 + 590)); |
478 | pMed->CompleteReOpen(); |
479 | pMed->GetItemSet()->Put( |
480 | SfxBoolItem(SID_DOC_READONLY(5000 + 590), !(nOpenMode & StreamMode::WRITE))); |
481 | if ( nOpenMode & StreamMode::WRITE ) |
482 | { |
483 | auto eResult = pMed->LockOrigFileOnDemand( |
484 | true, true, bRetryIgnoringLock, &aLockData); |
485 | bRetryIgnoringLock |
486 | = eResult == SfxMedium::LockFileResult::FailedLockFile; |
487 | } |
488 | |
489 | // LockOrigFileOnDemand might set the readonly flag itself, it should be set back |
490 | pMed->GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY(5000 + 590), !( nOpenMode & StreamMode::WRITE ) ) ); |
491 | |
492 | if ( !pMed->GetErrorCode() ) |
493 | bOK = true; |
494 | } |
495 | |
496 | if( !bOK ) |
497 | { |
498 | if (nOpenMode == SFX_STREAM_READWRITE(StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE) && !rReq.IsAPI()) |
499 | { |
500 | // css::sdbcx::User offering to open it as a template |
501 | SfxQueryOpenAsTemplate aBox(GetWindow().GetFrameWeld(), |
502 | bRetryIgnoringLock, aLockData); |
503 | |
504 | short nUserAnswer = aBox.run(); |
505 | bOpenTemplate = RET_YES == nUserAnswer; |
506 | // Always reset this here to avoid infinite loop |
507 | bRetryIgnoringLock = RET_IGNORE == nUserAnswer; |
508 | } |
509 | else |
510 | bRetryIgnoringLock = false; |
511 | } |
512 | } |
513 | while ( !bOK && bRetryIgnoringLock ); |
514 | |
515 | if( !bOK ) |
516 | { |
517 | ErrCode nErr = pMed->GetErrorCode(); |
518 | if ( pVersionItem ) |
519 | nErr = ERRCODE_IO_ACCESSDENIEDErrCode( ErrCodeArea::Io, ErrCodeClass::Access, 7 ); |
520 | else |
521 | { |
522 | pMed->ResetError(); |
523 | pMed->SetOpenMode( SFX_STREAM_READONLY(StreamMode::READ | StreamMode::SHARE_DENYWRITE) ); |
524 | if (aOrigROVal) |
525 | pMed->GetItemSet()->Put(SfxBoolItem(SID_DOC_READONLY(5000 + 590), *aOrigROVal)); |
526 | else |
527 | pMed->GetItemSet()->ClearItem(SID_DOC_READONLY(5000 + 590)); |
528 | pMed->ReOpen(); |
529 | pSh->DoSaveCompleted( pMed ); |
530 | } |
531 | |
532 | // Readonly document can not be switched to edit mode? |
533 | rReq.Done(); |
534 | |
535 | if ( nOpenMode == SFX_STREAM_READWRITE(StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE) && !rReq.IsAPI() ) |
536 | { |
537 | if ( bOpenTemplate ) |
538 | { |
539 | SfxApplication* pApp = SfxGetpApp(); |
540 | SfxAllItemSet aSet( pApp->GetPool() ); |
541 | aSet.Put( SfxStringItem( SID_FILE_NAME(5000 + 507), pMed->GetName() ) ); |
542 | const SfxStringItem* pReferer = SfxItemSet::GetItem<SfxStringItem>(pMed->GetItemSet(), SID_REFERER(5000 + 654), false); |
543 | if ( pReferer ) |
544 | aSet.Put( *pReferer ); |
545 | aSet.Put( SfxBoolItem( SID_TEMPLATE(5000 + 1519), true ) ); |
546 | if ( pVersionItem ) |
547 | aSet.Put( *pVersionItem ); |
548 | |
549 | if( pMed->GetFilter() ) |
550 | { |
551 | aSet.Put( SfxStringItem( SID_FILTER_NAME(5000 + 530), pMed->GetFilter()->GetFilterName() ) ); |
552 | const SfxStringItem* pOptions = SfxItemSet::GetItem<SfxStringItem>(pMed->GetItemSet(), SID_FILE_FILTEROPTIONS(5000 + 527), false); |
553 | if ( pOptions ) |
554 | aSet.Put( *pOptions ); |
555 | } |
556 | |
557 | GetDispatcher()->Execute( SID_OPENDOC(5000 + 501), SfxCallMode::ASYNCHRON, aSet ); |
558 | return; |
559 | } |
560 | |
561 | nErr = ERRCODE_NONEErrCode(0); |
562 | } |
563 | |
564 | // Keep the read-only UI |
565 | aReadOnlyUIGuard.m_bSetRO = true; |
566 | |
567 | ErrorHandler::HandleError( nErr ); |
568 | rReq.SetReturnValue( |
569 | SfxBoolItem( rReq.GetSlot(), false ) ); |
570 | return; |
571 | } |
572 | else |
573 | { |
574 | aReadOnlyUIGuard.m_pMed = pMed; |
575 | rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), true ) ); |
576 | rReq.Done( true ); |
577 | return; |
578 | } |
579 | } |
580 | |
581 | rReq.AppendItem( SfxBoolItem( SID_FORCERELOAD(5000 + 1502), bNeedsReload) ); |
582 | rReq.AppendItem( SfxBoolItem( SID_SILENT(5000 + 528), true )); |
583 | |
584 | [[fallthrough]]; //TODO ??? |
585 | } |
586 | |
587 | case SID_RELOAD(5000 + 508): |
588 | { |
589 | // Due to Double occupancy in toolboxes (with or without Ctrl), |
590 | // it is also possible that the slot is enabled, but Ctrl-click |
591 | // despite this is not! |
592 | if ( !pSh || !pSh->CanReload_Impl() ) |
593 | break; |
594 | SfxApplication* pApp = SfxGetpApp(); |
595 | const SfxBoolItem* pForceReloadItem = rReq.GetArg<SfxBoolItem>(SID_FORCERELOAD(5000 + 1502)); |
596 | if( pForceReloadItem && !pForceReloadItem->GetValue() && |
597 | !pSh->GetMedium()->IsExpired() ) |
598 | return; |
599 | if( m_pImpl->bReloading || pSh->IsInModalMode() ) |
600 | return; |
601 | |
602 | // AutoLoad is prohibited if possible |
603 | const SfxBoolItem* pAutoLoadItem = rReq.GetArg<SfxBoolItem>(SID_AUTOLOAD(5000 + 1509)); |
604 | if ( pAutoLoadItem && pAutoLoadItem->GetValue() && |
605 | GetFrame().IsAutoLoadLocked_Impl() ) |
606 | return; |
607 | |
608 | SfxObjectShellLock xOldObj( pSh ); |
609 | m_pImpl->bReloading = true; |
610 | const SfxStringItem* pURLItem = rReq.GetArg<SfxStringItem>(SID_FILE_NAME(5000 + 507)); |
611 | // Open as editable? |
612 | bool bForEdit = !pSh->IsReadOnly(); |
613 | |
614 | // If possible ask the User |
615 | bool bDo = GetViewShell()->PrepareClose(); |
616 | const SfxBoolItem* pSilentItem = rReq.GetArg<SfxBoolItem>(SID_SILENT(5000 + 528)); |
617 | if ( bDo && GetFrame().DocIsModified_Impl() && |
618 | !rReq.IsAPI() && ( !pSilentItem || !pSilentItem->GetValue() ) ) |
619 | { |
620 | std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetWindow().GetFrameWeld(), |
621 | VclMessageType::Question, VclButtonsType::YesNo, |
622 | SfxResId(STR_QUERY_LASTVERSIONreinterpret_cast<char const *>("STR_QUERY_LASTVERSION" "\004" u8"Cancel all changes?")))); |
623 | bDo = RET_YES == xBox->run(); |
624 | } |
625 | |
626 | if ( bDo ) |
627 | { |
628 | SfxMedium *pMedium = xOldObj->GetMedium(); |
629 | |
630 | bool bHandsOff = |
631 | ( pMedium->GetURLObject().GetProtocol() == INetProtocol::File && !xOldObj->IsDocShared() ); |
632 | |
633 | // Empty existing SfxMDIFrames for this Document |
634 | // in native format or R/O, open it now for editing? |
635 | SfxObjectShellLock xNewObj; |
636 | |
637 | // collect the views of the document |
638 | // TODO: when UNO ViewFactories are available for SFX-based documents, the below code should |
639 | // be UNOized, too |
640 | typedef ::std::pair< Reference< XFrame >, SfxInterfaceId > ViewDescriptor; |
641 | ::std::vector< ViewDescriptor > aViewFrames; |
642 | SfxViewFrame *pView = GetFirst( xOldObj ); |
643 | while ( pView ) |
644 | { |
645 | Reference< XFrame > xFrame( pView->GetFrame().GetFrameInterface() ); |
646 | SAL_WARN_IF( !xFrame.is(), "sfx.view", "SfxViewFrame::ExecReload_Impl: no XFrame?!")do { if (true && (!xFrame.is())) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "sfx.view")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "SfxViewFrame::ExecReload_Impl: no XFrame?!" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view" ), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx" ":" "646" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "SfxViewFrame::ExecReload_Impl: no XFrame?!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "SfxViewFrame::ExecReload_Impl: no XFrame?!"; ::sal ::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"), ( "/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx" ":" "646" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "SfxViewFrame::ExecReload_Impl: no XFrame?!") == 1 ) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view" ), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx" ":" "646" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "SfxViewFrame::ExecReload_Impl: no XFrame?!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "SfxViewFrame::ExecReload_Impl: no XFrame?!"; ::sal ::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.view"), ( "/home/maarten/src/libreoffice/core/sfx2/source/view/viewfrm.cxx" ":" "646" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); |
647 | aViewFrames.emplace_back( xFrame, pView->GetCurViewId() ); |
648 | |
649 | pView = GetNext( *pView, xOldObj ); |
650 | } |
651 | |
652 | xOldObj->Get_Impl()->pReloadTimer.reset(); |
653 | |
654 | std::unique_ptr<SfxItemSet> pNewSet; |
655 | std::shared_ptr<const SfxFilter> pFilter = pMedium->GetFilter(); |
656 | if( pURLItem ) |
657 | { |
658 | pNewSet.reset(new SfxAllItemSet( pApp->GetPool() )); |
659 | pNewSet->Put( *pURLItem ); |
660 | |
661 | // Filter Detection |
662 | OUString referer; |
663 | const SfxStringItem* refererItem = rReq.GetArg<SfxStringItem>(SID_REFERER(5000 + 654)); |
664 | if (refererItem != nullptr) { |
665 | referer = refererItem->GetValue(); |
666 | } |
667 | SfxMedium aMedium( pURLItem->GetValue(), referer, SFX_STREAM_READWRITE(StreamMode::READWRITE | StreamMode::SHARE_DENYWRITE) ); |
668 | SfxFilterMatcher().GuessFilter( aMedium, pFilter ); |
669 | if ( pFilter ) |
670 | pNewSet->Put( SfxStringItem( SID_FILTER_NAME(5000 + 530), pFilter->GetName() ) ); |
671 | pNewSet->Put( *aMedium.GetItemSet() ); |
672 | } |
673 | else |
674 | { |
675 | pNewSet.reset(new SfxAllItemSet( *pMedium->GetItemSet() )); |
676 | pNewSet->ClearItem( SID_VIEW_ID(5000 + 523) ); |
677 | pNewSet->ClearItem( SID_STREAM(5000 + 1699) ); |
678 | pNewSet->ClearItem( SID_INPUTSTREAM(5000 + 1648) ); |
679 | pNewSet->Put( SfxStringItem( SID_FILTER_NAME(5000 + 530), pMedium->GetFilter()->GetName() ) ); |
680 | |
681 | // let the current security settings be checked again |
682 | pNewSet->Put( SfxUInt16Item( SID_MACROEXECMODE(5000 + 1319), document::MacroExecMode::USE_CONFIG ) ); |
683 | |
684 | if ( pSh->IsOriginallyReadOnlyMedium() |
685 | || pSh->IsOriginallyLoadedReadOnlyMedium() ) |
686 | // edit mode is switched or reload of readonly document |
687 | pNewSet->Put( SfxBoolItem( SID_DOC_READONLY(5000 + 590), true ) ); |
688 | else |
689 | // Reload of file opened for writing |
690 | pNewSet->ClearItem( SID_DOC_READONLY(5000 + 590) ); |
691 | } |
692 | |
693 | // If a salvaged file is present, do not enclose the OrigURL |
694 | // again, since the Template is invalid after reload. |
695 | const SfxStringItem* pSalvageItem = SfxItemSet::GetItem<SfxStringItem>(pNewSet.get(), SID_DOC_SALVAGE(5000 + 531), false); |
696 | if( pSalvageItem ) |
697 | { |
698 | pNewSet->ClearItem( SID_DOC_SALVAGE(5000 + 531) ); |
699 | } |
700 | |
701 | #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT1 |
702 | // TODO/LATER: Temporary solution, the SfxMedium must know the original URL as aLogicName |
703 | // SfxMedium::Transfer_Impl() will be forbidden then. |
704 | if ( xOldObj->IsDocShared() ) |
705 | pNewSet->Put( SfxStringItem( SID_FILE_NAME(5000 + 507), xOldObj->GetSharedFileURL() ) ); |
706 | #endif |
707 | if ( pURLItem ) |
708 | pNewSet->Put( SfxStringItem( SID_REFERER(5000 + 654), pMedium->GetName() ) ); |
709 | else |
710 | pNewSet->Put( SfxStringItem( SID_REFERER(5000 + 654), OUString() ) ); |
711 | |
712 | xOldObj->CancelTransfers(); |
713 | |
714 | |
715 | if ( pSilentItem && pSilentItem->GetValue() ) |
716 | pNewSet->Put( SfxBoolItem( SID_SILENT(5000 + 528), true ) ); |
717 | |
718 | const SfxUnoAnyItem* pInteractionItem = SfxItemSet::GetItem<SfxUnoAnyItem>(pNewSet.get(), SID_INTERACTIONHANDLER(5000 + 1675), false); |
719 | const SfxUInt16Item* pMacroExecItem = SfxItemSet::GetItem<SfxUInt16Item>(pNewSet.get(), SID_MACROEXECMODE(5000 + 1319), false); |
720 | const SfxUInt16Item* pDocTemplateItem = SfxItemSet::GetItem<SfxUInt16Item>(pNewSet.get(), SID_UPDATEDOCMODE(5000 + 1668), false); |
721 | |
722 | if (!pInteractionItem) |
723 | { |
724 | Reference < task::XInteractionHandler2 > xHdl = task::InteractionHandler::createWithParent( ::comphelper::getProcessComponentContext(), nullptr ); |
725 | if (xHdl.is()) |
726 | pNewSet->Put( SfxUnoAnyItem(SID_INTERACTIONHANDLER(5000 + 1675),css::uno::makeAny(xHdl)) ); |
727 | } |
728 | |
729 | if (!pMacroExecItem) |
730 | pNewSet->Put( SfxUInt16Item(SID_MACROEXECMODE(5000 + 1319),css::document::MacroExecMode::USE_CONFIG) ); |
731 | if (!pDocTemplateItem) |
732 | pNewSet->Put( SfxUInt16Item(SID_UPDATEDOCMODE(5000 + 1668),css::document::UpdateDocMode::ACCORDING_TO_CONFIG) ); |
733 | |
734 | xOldObj->SetModified( false ); |
735 | // Do not cache the old Document! Is invalid when loading |
736 | // another document. |
737 | |
738 | const SfxStringItem* pSavedOptions = SfxItemSet::GetItem<SfxStringItem>(pMedium->GetItemSet(), SID_FILE_FILTEROPTIONS(5000 + 527), false); |
739 | const SfxStringItem* pSavedReferer = SfxItemSet::GetItem<SfxStringItem>(pMedium->GetItemSet(), SID_REFERER(5000 + 654), false); |
740 | |
741 | bool bHasStorage = pMedium->HasStorage_Impl(); |
742 | if( bHandsOff ) |
743 | { |
744 | if ( bHasStorage && pMedium->GetStorage() == xOldObj->GetStorage() ) |
745 | { |
746 | // TODO/LATER: faster creation of copy |
747 | if ( !xOldObj->ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium ) ) |
748 | return; |
749 | } |
750 | |
751 | pMedium->CloseAndRelease(); |
752 | } |
753 | |
754 | xNewObj = SfxObjectShell::CreateObject( pFilter->GetServiceName() ); |
755 | |
756 | if ( xOldObj->IsModifyPasswordEntered() ) |
757 | xNewObj->SetModifyPasswordEntered(); |
758 | |
759 | uno::Sequence < beans::PropertyValue > aLoadArgs; |
760 | TransformItems( SID_OPENDOC(5000 + 501), *pNewSet, aLoadArgs ); |
761 | try |
762 | { |
763 | uno::Reference < frame::XLoadable > xLoad( xNewObj->GetModel(), uno::UNO_QUERY ); |
764 | xLoad->load( aLoadArgs ); |
765 | } |
766 | catch ( uno::Exception& ) |
767 | { |
768 | xNewObj->DoClose(); |
769 | xNewObj = nullptr; |
770 | } |
771 | |
772 | pNewSet.reset(); |
773 | |
774 | if( !xNewObj.Is() ) |
775 | { |
776 | if( bHandsOff ) |
777 | { |
778 | // back to old medium |
779 | pMedium->ReOpen(); |
780 | pMedium->LockOrigFileOnDemand( false, true ); |
781 | |
782 | xOldObj->DoSaveCompleted( pMedium ); |
783 | } |
784 | |
785 | // r/o-Doc couldn't be switched to writing mode |
786 | if ( bForEdit && ( SID_EDITDOC(5000 + 1312) == rReq.GetSlot() || SID_READONLYDOC(5000 + 1314) == rReq.GetSlot() ) ) |
787 | { |
788 | // ask user for opening as template |
789 | std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetWindow().GetFrameWeld(), |
790 | VclMessageType::Question, VclButtonsType::YesNo, |
791 | SfxResId(STR_QUERY_OPENASTEMPLATEreinterpret_cast<char const *>("STR_QUERY_OPENASTEMPLATE" "\004" u8"This document cannot be edited, possibly due to missing access rights. Do you want to edit a copy of the document?" )))); |
792 | if (RET_YES == xBox->run()) |
793 | { |
794 | SfxAllItemSet aSet( pApp->GetPool() ); |
795 | aSet.Put( SfxStringItem( SID_FILE_NAME(5000 + 507), pMedium->GetName() ) ); |
796 | aSet.Put( SfxStringItem( SID_TARGETNAME(5000 + 560), "_blank" ) ); |
797 | if ( pSavedOptions ) |
798 | aSet.Put( *pSavedOptions ); |
799 | if ( pSavedReferer ) |
800 | aSet.Put( *pSavedReferer ); |
801 | aSet.Put( SfxBoolItem( SID_TEMPLATE(5000 + 1519), true ) ); |
802 | if( pFilter ) |
803 | aSet.Put( SfxStringItem( SID_FILTER_NAME(5000 + 530), pFilter->GetFilterName() ) ); |
804 | GetDispatcher()->Execute( SID_OPENDOC(5000 + 501), SfxCallMode::ASYNCHRON, aSet ); |
805 | } |
806 | } |
807 | } |
808 | else |
809 | { |
810 | if ( xNewObj->GetModifyPasswordHash() && xNewObj->GetModifyPasswordHash() != xOldObj->GetModifyPasswordHash() ) |
811 | { |
812 | xNewObj->SetModifyPasswordEntered( false ); |
813 | xNewObj->SetReadOnly(); |
814 | } |
815 | else if ( rReq.GetSlot() == SID_EDITDOC(5000 + 1312) || rReq.GetSlot() == SID_READONLYDOC(5000 + 1314) ) |
816 | { |
817 | xNewObj->SetReadOnlyUI( !bForEdit ); |
818 | } |
819 | |
820 | #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT1 |
821 | if ( xNewObj->IsDocShared() ) |
822 | { |
823 | // the file is shared but the closing can change the sharing control file |
824 | xOldObj->DoNotCleanShareControlFile(); |
825 | } |
826 | #endif |
827 | // the Reload and Silent items were only temporary, remove them |
828 | xNewObj->GetMedium()->GetItemSet()->ClearItem( SID_RELOAD(5000 + 508) ); |
829 | xNewObj->GetMedium()->GetItemSet()->ClearItem( SID_SILENT(5000 + 528) ); |
830 | TransformItems( SID_OPENDOC(5000 + 501), *xNewObj->GetMedium()->GetItemSet(), aLoadArgs ); |
831 | |
832 | UpdateDocument_Impl(); |
833 | |
834 | if (vcl::CommandInfoProvider::GetModuleIdentifier(GetFrame().GetFrameInterface()) == "com.sun.star.text.TextDocument") |
835 | sfx2::SfxNotebookBar::ReloadNotebookBar("modules/swriter/ui/"); |
836 | |
837 | try |
838 | { |
839 | for (auto const& viewFrame : aViewFrames) |
840 | { |
841 | LoadViewIntoFrame_Impl( *xNewObj, viewFrame.first, aLoadArgs, viewFrame.second, false ); |
842 | } |
843 | aViewFrames.clear(); |
844 | } |
845 | catch( const Exception& ) |
846 | { |
847 | // close the remaining frames |
848 | // Don't catch exceptions herein, if this fails, then we're left in an indetermined state, and |
849 | // crashing is better than trying to proceed |
850 | for (auto const& viewFrame : aViewFrames) |
851 | { |
852 | Reference< util::XCloseable > xClose( viewFrame.first, UNO_QUERY_THROW ); |
853 | xClose->close( true ); |
854 | } |
855 | aViewFrames.clear(); |
856 | } |
857 | |
858 | const SfxInt32Item* pPageNumber = rReq.GetArg<SfxInt32Item>(SID_PAGE_NUMBER(5000 + 655)); |
859 | if (pPageNumber && pPageNumber->GetValue() >= 0) |
860 | { |
861 | // Restore current page after reload. |
862 | uno::Reference<drawing::XDrawView> xController( |
863 | xNewObj->GetModel()->getCurrentController(), uno::UNO_QUERY); |
864 | uno::Reference<drawing::XDrawPagesSupplier> xSupplier(xNewObj->GetModel(), |
865 | uno::UNO_QUERY); |
866 | uno::Reference<drawing::XDrawPages> xDrawPages = xSupplier->getDrawPages(); |
867 | uno::Reference<drawing::XDrawPage> xDrawPage( |
868 | xDrawPages->getByIndex(pPageNumber->GetValue()), uno::UNO_QUERY); |
869 | xController->setCurrentPage(xDrawPage); |
870 | } |
871 | |
872 | // Propagate document closure. |
873 | SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::CloseDoc, GlobalEventConfig::GetEventName( GlobalEventId::CLOSEDOC ), xOldObj ) ); |
874 | } |
875 | |
876 | // Record as done |
877 | rReq.Done( true ); |
878 | rReq.SetReturnValue(SfxBoolItem(rReq.GetSlot(), true)); |
879 | return; |
880 | } |
881 | else |
882 | { |
883 | // Record as not done |
884 | rReq.Done(); |
885 | rReq.SetReturnValue(SfxBoolItem(rReq.GetSlot(), false)); |
886 | m_pImpl->bReloading = false; |
887 | return; |
888 | } |
889 | } |
890 | } |
891 | } |
892 | |
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: */ |