/src/libreoffice/sfx2/source/doc/objmisc.cxx
Line | Count | Source |
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_features.h> |
21 | | |
22 | | #include <tools/debug.hxx> |
23 | | #include <tools/inetmsg.hxx> |
24 | | #include <comphelper/diagnose_ex.hxx> |
25 | | #include <svl/eitem.hxx> |
26 | | #include <svl/stritem.hxx> |
27 | | #include <svl/intitem.hxx> |
28 | | #include <svtools/svparser.hxx> |
29 | | #include <cppuhelper/exc_hlp.hxx> |
30 | | #include <sal/log.hxx> |
31 | | #include <o3tl/string_view.hxx> |
32 | | |
33 | | #include <com/sun/star/awt/XTopWindow.hpp> |
34 | | #include <com/sun/star/beans/XPropertySet.hpp> |
35 | | #include <com/sun/star/container/XChild.hpp> |
36 | | #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> |
37 | | #include <com/sun/star/document/XDocumentProperties.hpp> |
38 | | #include <com/sun/star/document/MacroExecMode.hpp> |
39 | | #include <com/sun/star/document/XScriptInvocationContext.hpp> |
40 | | #include <com/sun/star/embed/EmbedStates.hpp> |
41 | | #include <com/sun/star/embed/XEmbeddedObject.hpp> |
42 | | #include <com/sun/star/script/provider/theMasterScriptProviderFactory.hpp> |
43 | | #include <com/sun/star/script/provider/XScript.hpp> |
44 | | #include <com/sun/star/script/provider/XScriptProvider.hpp> |
45 | | #include <com/sun/star/script/provider/XScriptProviderSupplier.hpp> |
46 | | #include <com/sun/star/uri/UriReferenceFactory.hpp> |
47 | | #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp> |
48 | | #include <com/sun/star/util/XModifiable.hpp> |
49 | | |
50 | | #include <com/sun/star/uno/Reference.h> |
51 | | #include <com/sun/star/uno/Any.h> |
52 | | #include <com/sun/star/task/ErrorCodeRequest2.hpp> |
53 | | |
54 | | #include <comphelper/lok.hxx> |
55 | | #include <LibreOfficeKit/LibreOfficeKitEnums.h> |
56 | | #include <comphelper/processfactory.hxx> |
57 | | #include <comphelper/sequenceashashmap.hxx> |
58 | | #include <comphelper/string.hxx> |
59 | | |
60 | | #include <com/sun/star/security/DocumentDigitalSignatures.hpp> |
61 | | #include <com/sun/star/task/DocumentMacroConfirmationRequest.hpp> |
62 | | #include <com/sun/star/task/InteractionClassification.hpp> |
63 | | #include <com/sun/star/task/XInteractionHandler.hpp> |
64 | | #include <com/sun/star/frame/XModel.hpp> |
65 | | |
66 | | #include <basic/basmgr.hxx> |
67 | | #include <basic/sberrors.hxx> |
68 | | #include <utility> |
69 | | #include <vcl/weld/MessageDialog.hxx> |
70 | | #include <vcl/weld/weld.hxx> |
71 | | #include <basic/sbx.hxx> |
72 | | #include <svtools/sfxecode.hxx> |
73 | | |
74 | | #include <unotools/ucbhelper.hxx> |
75 | | #include <tools/urlobj.hxx> |
76 | | #include <svl/sharecontrolfile.hxx> |
77 | | #include <rtl/uri.hxx> |
78 | | #include <vcl/svapp.hxx> |
79 | | #include <framework/interaction.hxx> |
80 | | #include <framework/documentundoguard.hxx> |
81 | | #include <comphelper/interaction.hxx> |
82 | | #include <comphelper/storagehelper.hxx> |
83 | | #include <comphelper/documentconstants.hxx> |
84 | | #include <comphelper/namedvaluecollection.hxx> |
85 | | #include <ucbhelper/simpleinteractionrequest.hxx> |
86 | | #include <officecfg/Office/Common.hxx> |
87 | | |
88 | | #include <sfx2/brokenpackageint.hxx> |
89 | | #include <sfx2/signaturestate.hxx> |
90 | | #include <sfx2/app.hxx> |
91 | | #include <appdata.hxx> |
92 | | #include <sfx2/request.hxx> |
93 | | #include <sfx2/bindings.hxx> |
94 | | #include <sfx2/sfxresid.hxx> |
95 | | #include <sfx2/docfile.hxx> |
96 | | #include <sfx2/objsh.hxx> |
97 | | #include <objshimp.hxx> |
98 | | #include <sfx2/event.hxx> |
99 | | #include <sfx2/viewfrm.hxx> |
100 | | #include <sfx2/sfxuno.hxx> |
101 | | #include <sfx2/module.hxx> |
102 | | #include <sfx2/docfac.hxx> |
103 | | #include <sfx2/sfxsids.hrc> |
104 | | #include <sfx2/strings.hrc> |
105 | | #include <workwin.hxx> |
106 | | #include <sfx2/sfxdlg.hxx> |
107 | | #include <sfx2/infobar.hxx> |
108 | | #include <sfx2/lokhelper.hxx> |
109 | | #include <sfx2/sfxbasemodel.hxx> |
110 | | #include <openflag.hxx> |
111 | | #include "objstor.hxx" |
112 | | #include <appopen.hxx> |
113 | | #include <sfx2/viewsh.hxx> |
114 | | |
115 | | #include <memory> |
116 | | |
117 | | using namespace ::com::sun::star; |
118 | | using namespace ::com::sun::star::uno; |
119 | | using namespace ::com::sun::star::ucb; |
120 | | using namespace ::com::sun::star::document; |
121 | | using namespace ::com::sun::star::frame; |
122 | | using namespace ::com::sun::star::script; |
123 | | using namespace ::com::sun::star::script::provider; |
124 | | |
125 | | // class SfxHeaderAttributes_Impl ---------------------------------------- |
126 | | |
127 | | namespace { |
128 | | |
129 | | class SfxHeaderAttributes_Impl : public SvKeyValueIterator |
130 | | { |
131 | | private: |
132 | | SfxObjectShell* pDoc; |
133 | | SvKeyValueIteratorRef xIter; |
134 | | bool bAlert; |
135 | | |
136 | | public: |
137 | | explicit SfxHeaderAttributes_Impl( SfxObjectShell* pSh ) : |
138 | 14.4k | pDoc( pSh ), |
139 | 14.4k | xIter( pSh->GetMedium()->GetHeaderAttributes_Impl() ), |
140 | 14.4k | bAlert( false ) {} |
141 | | |
142 | 21.3k | virtual bool GetFirst( SvKeyValue& rKV ) override { return xIter->GetFirst( rKV ); } |
143 | 1.95k | virtual bool GetNext( SvKeyValue& rKV ) override { return xIter->GetNext( rKV ); } |
144 | | virtual void Append( const SvKeyValue& rKV ) override; |
145 | | |
146 | 0 | void ClearForSourceView() { xIter = new SvKeyValueIterator; bAlert = false; } |
147 | | void SetAttributes(); |
148 | | void SetAttribute( const SvKeyValue& rKV ); |
149 | | }; |
150 | | |
151 | | } |
152 | | |
153 | | sal_uInt16 const aTitleMap_Impl[3][2] = |
154 | | { |
155 | | // local remote |
156 | | /* SFX_TITLE_CAPTION */ { SFX_TITLE_FILENAME, SFX_TITLE_TITLE }, |
157 | | /* SFX_TITLE_PICKLIST */ { 32, SFX_TITLE_FULLNAME }, |
158 | | /* SFX_TITLE_HISTORY */ { 32, SFX_TITLE_FULLNAME } |
159 | | }; |
160 | | |
161 | | |
162 | | bool SfxObjectShell::IsAbortingImport() const |
163 | 2.96M | { |
164 | 2.96M | return pImpl->bIsAbortingImport; |
165 | 2.96M | } |
166 | | |
167 | | |
168 | | uno::Reference<document::XDocumentProperties> |
169 | | SfxObjectShell::getDocProperties() const |
170 | 108k | { |
171 | 108k | uno::Reference<document::XDocumentPropertiesSupplier> xDPS( |
172 | 108k | GetModel(), uno::UNO_QUERY_THROW); |
173 | 108k | uno::Reference<document::XDocumentProperties> xDocProps( |
174 | 108k | xDPS->getDocumentProperties()); |
175 | 108k | DBG_ASSERT(xDocProps.is(), |
176 | 108k | "SfxObjectShell: model has no DocumentProperties"); |
177 | 108k | return xDocProps; |
178 | 108k | } |
179 | | |
180 | | |
181 | | void SfxObjectShell::DoFlushDocInfo() |
182 | 17.3k | { |
183 | 17.3k | } |
184 | | |
185 | | |
186 | | // Note: the only thing that calls this is the modification event handler |
187 | | // that is installed at the XDocumentProperties |
188 | | void SfxObjectShell::FlushDocInfo() |
189 | 120k | { |
190 | 120k | if ( IsLoading() ) |
191 | 53.2k | return; |
192 | | |
193 | 67.4k | SetModified(); |
194 | 67.4k | uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties()); |
195 | 67.4k | DoFlushDocInfo(); // call template method |
196 | 67.4k | const OUString url(xDocProps->getAutoloadURL()); |
197 | 67.4k | sal_Int32 delay(xDocProps->getAutoloadSecs()); |
198 | 67.4k | SetAutoLoad( INetURLObject(url), delay * 1000, |
199 | 67.4k | (delay > 0) || !url.isEmpty() ); |
200 | 67.4k | } |
201 | | |
202 | | void SfxObjectShell::AppendInfoBarWhenReady(const OUString& sId, const OUString& sPrimaryMessage, |
203 | | const OUString& sSecondaryMessage, |
204 | | InfobarType aInfobarType, bool bShowCloseButton) |
205 | 0 | { |
206 | 0 | InfobarData aInfobarData; |
207 | 0 | aInfobarData.msId = sId; |
208 | 0 | aInfobarData.msPrimaryMessage = sPrimaryMessage; |
209 | 0 | aInfobarData.msSecondaryMessage = sSecondaryMessage; |
210 | 0 | aInfobarData.maInfobarType = aInfobarType; |
211 | 0 | aInfobarData.mbShowCloseButton = bShowCloseButton; |
212 | 0 | Get_Impl()->m_aPendingInfobars.emplace_back(aInfobarData); |
213 | 0 | } |
214 | | |
215 | | std::vector<InfobarData>& SfxObjectShell::getPendingInfobars() |
216 | 0 | { |
217 | 0 | return Get_Impl()->m_aPendingInfobars; |
218 | 0 | } |
219 | | |
220 | | void SfxObjectShell::SetError(const ErrCodeMsg& lErr) |
221 | 37 | { |
222 | 37 | if (pImpl->lErr == ERRCODE_NONE || (pImpl->lErr.IsWarning() && lErr.IsError())) |
223 | 37 | { |
224 | 37 | pImpl->lErr=lErr; |
225 | 37 | } |
226 | 37 | } |
227 | | |
228 | | ErrCodeMsg SfxObjectShell::GetErrorIgnoreWarning() const |
229 | 8.19k | { |
230 | 8.19k | return GetErrorCode().IgnoreWarning(); |
231 | 8.19k | } |
232 | | |
233 | | ErrCodeMsg SfxObjectShell::GetErrorCode() const |
234 | 16.2k | { |
235 | 16.2k | ErrCodeMsg lError=pImpl->lErr; |
236 | 16.2k | if(!lError && GetMedium()) |
237 | 16.2k | lError=GetMedium()->GetErrorCode(); |
238 | 16.2k | return lError; |
239 | 16.2k | } |
240 | | |
241 | | void SfxObjectShell::ResetError() |
242 | 8.19k | { |
243 | 8.19k | pImpl->lErr=ERRCODE_NONE; |
244 | 8.19k | SfxMedium * pMed = GetMedium(); |
245 | 8.19k | if( pMed ) |
246 | 8.19k | pMed->ResetError(); |
247 | 8.19k | } |
248 | | |
249 | | void SfxObjectShell::EnableSetModified( bool bEnable ) |
250 | 209k | { |
251 | 209k | SAL_INFO_IF( bEnable == pImpl->m_bEnableSetModified, "sfx", "SFX_PERSIST: EnableSetModified 2x called with the same value" ); |
252 | 209k | pImpl->m_bEnableSetModified = bEnable; |
253 | 209k | } |
254 | | |
255 | | |
256 | | bool SfxObjectShell::IsEnableSetModified() const |
257 | 83.2M | { |
258 | | // tdf#146547 read-only does not prevent modified, instead try to prevent |
259 | | // setting "internal" documents that may be displayed in some dialog but |
260 | | // which the user didn't load or activate to modified. |
261 | 83.2M | return pImpl->m_bEnableSetModified && !IsPreview() |
262 | 83.1M | && eCreateMode != SfxObjectCreateMode::ORGANIZER |
263 | 83.1M | && eCreateMode != SfxObjectCreateMode::INTERNAL |
264 | | // tdf#157931 form documents only in design mode |
265 | 39.3M | && ((pImpl->pBaseModel |
266 | 39.3M | && !pImpl->pBaseModel->impl_isDisposed() |
267 | 38.4M | && pImpl->pBaseModel->IsInitialized() |
268 | 38.2M | && pImpl->pBaseModel->getIdentifier() != "com.sun.star.sdb.FormDesign") |
269 | 1.02M | || !IsReadOnly()); |
270 | 83.2M | } |
271 | | |
272 | | |
273 | | bool SfxObjectShell::IsModified() const |
274 | 9.62M | { |
275 | 9.62M | if ( pImpl->m_bIsModified ) |
276 | 9.43M | return true; |
277 | | |
278 | 187k | if ( !pImpl->m_xDocStorage.is() || IsReadOnly() ) |
279 | 32.1k | { |
280 | | // if the document still has no storage and is not set to be modified explicitly it is not modified |
281 | | // a readonly document is also not modified |
282 | | |
283 | 32.1k | return false; |
284 | 32.1k | } |
285 | | |
286 | 155k | if (pImpl->mxObjectContainer) |
287 | 0 | { |
288 | 0 | const uno::Sequence < OUString > aNames = GetEmbeddedObjectContainer().GetObjectNames(); |
289 | 0 | for ( const auto& rName : aNames ) |
290 | 0 | { |
291 | 0 | uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObjectContainer().GetEmbeddedObject( rName ); |
292 | 0 | OSL_ENSURE( xObj.is(), "An empty entry in the embedded objects list!" ); |
293 | 0 | if ( xObj.is() ) |
294 | 0 | { |
295 | 0 | try |
296 | 0 | { |
297 | 0 | sal_Int32 nState = xObj->getCurrentState(); |
298 | 0 | if ( nState != embed::EmbedStates::LOADED ) |
299 | 0 | { |
300 | 0 | uno::Reference< util::XModifiable > xModifiable( xObj->getComponent(), uno::UNO_QUERY ); |
301 | 0 | if ( xModifiable.is() && xModifiable->isModified() ) |
302 | 0 | return true; |
303 | 0 | } |
304 | 0 | } |
305 | 0 | catch( uno::Exception& ) |
306 | 0 | {} |
307 | 0 | } |
308 | 0 | } |
309 | 0 | } |
310 | | |
311 | 155k | return false; |
312 | 155k | } |
313 | | |
314 | | |
315 | | void SfxObjectShell::SetModified( bool bModifiedP ) |
316 | 9.69M | { |
317 | 9.69M | SAL_INFO_IF( !bModifiedP && !IsEnableSetModified(), "sfx", |
318 | 9.69M | "SFX_PERSIST: SetModified( sal_False ), although IsEnableSetModified() == sal_False" ); |
319 | | |
320 | 9.69M | if( !IsEnableSetModified() ) |
321 | 13.7k | return; |
322 | | |
323 | 9.68M | if( pImpl->m_bIsModified != bModifiedP ) |
324 | 217k | { |
325 | 217k | pImpl->m_bIsModified = bModifiedP; |
326 | 217k | ModifyChanged(); |
327 | 217k | } |
328 | 9.68M | } |
329 | | |
330 | | |
331 | | void SfxObjectShell::ModifyChanged() |
332 | 217k | { |
333 | 217k | if ( pImpl->bClosing ) |
334 | | // SetModified dispose of the models! |
335 | 13.1k | return; |
336 | | |
337 | 204k | SfxViewFrame* pViewFrame = SfxViewFrame::Current(); |
338 | 204k | if ( pViewFrame ) |
339 | 0 | pViewFrame->GetBindings().Invalidate( SID_SAVEDOCS ); |
340 | | |
341 | 204k | Invalidate( SID_SIGNATURE ); |
342 | 204k | Invalidate( SID_MACRO_SIGNATURE ); |
343 | 204k | Broadcast( SfxHint( SfxHintId::TitleChanged ) ); // xmlsec05, signed state might change in title... |
344 | | |
345 | 204k | SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::ModifyChanged, GlobalEventConfig::GetEventName(GlobalEventId::MODIFYCHANGED), this ) ); |
346 | | |
347 | | // Don't wait to get this important state via binding notification timeout. |
348 | 204k | if ( comphelper::LibreOfficeKit::isActive() ) |
349 | 0 | { |
350 | 0 | OString aStatus = ".uno:ModifiedStatus="_ostr; |
351 | 0 | aStatus += IsModified() ? "true" : "false"; |
352 | 0 | SfxLokHelper::notifyAllViews(LOK_CALLBACK_STATE_CHANGED, aStatus); |
353 | 0 | } |
354 | 204k | } |
355 | | |
356 | | |
357 | | bool SfxObjectShell::IsReadOnlyUI() const |
358 | | |
359 | | /* [Description] |
360 | | |
361 | | Returns sal_True if the document for the UI is treated as r/o. This is |
362 | | regardless of the actual r/o, which can be checked with <IsReadOnly()>. |
363 | | */ |
364 | | |
365 | 277k | { |
366 | 277k | return pImpl->bReadOnlyUI || SfxViewShell::IsCurrentLokViewReadOnly(); |
367 | 277k | } |
368 | | |
369 | | |
370 | | bool SfxObjectShell::IsReadOnlyMedium() const |
371 | | |
372 | | /* [Description] |
373 | | |
374 | | Returns sal_True when the medium is r/o, for instance when opened as r/o. |
375 | | */ |
376 | | |
377 | 0 | { |
378 | 0 | if ( !pMedium ) |
379 | 0 | return true; |
380 | 0 | return pMedium->IsReadOnly(); |
381 | 0 | } |
382 | | |
383 | | bool SfxObjectShell::IsOriginallyReadOnlyMedium() const |
384 | 0 | { |
385 | 0 | return pMedium == nullptr || pMedium->IsOriginallyReadOnly(); |
386 | 0 | } |
387 | | |
388 | | bool SfxObjectShell::IsOriginallyLoadedReadOnlyMedium() const |
389 | 0 | { |
390 | 0 | return pMedium != nullptr && pMedium->IsOriginallyLoadedReadOnly(); |
391 | 0 | } |
392 | | |
393 | | |
394 | | void SfxObjectShell::SetReadOnlyUI( bool bReadOnly ) |
395 | | |
396 | | /* [Description] |
397 | | |
398 | | Turns the document in a r/o and r/w state respectively without reloading |
399 | | it and without changing the open mode of the medium. |
400 | | */ |
401 | | |
402 | 10.7k | { |
403 | 10.7k | if ( bReadOnly != pImpl->bReadOnlyUI ) |
404 | 10.7k | { |
405 | 10.7k | pImpl->bReadOnlyUI = bReadOnly; |
406 | 10.7k | Broadcast( SfxHint(SfxHintId::ModeChanged) ); |
407 | 10.7k | } |
408 | 10.7k | } |
409 | | |
410 | | |
411 | | void SfxObjectShell::SetReadOnly() |
412 | 0 | { |
413 | | // Let the document be completely readonly, means that the |
414 | | // medium open mode is adjusted accordingly, and the write lock |
415 | | // on the file is removed. |
416 | |
|
417 | 0 | if ( !pMedium || IsReadOnlyMedium() ) |
418 | 0 | return; |
419 | | |
420 | 0 | bool bWasROUI = IsReadOnly(); |
421 | |
|
422 | 0 | pMedium->UnlockFile( false ); |
423 | | |
424 | | // the storage-based mediums are already based on the temporary file |
425 | | // so UnlockFile has already closed the locking stream |
426 | 0 | if ( !pMedium->HasStorage_Impl() && IsLoadingFinished() ) |
427 | 0 | pMedium->CloseInStream(); |
428 | |
|
429 | 0 | pMedium->SetOpenMode( SFX_STREAM_READONLY, true ); |
430 | 0 | pMedium->GetItemSet().Put( SfxBoolItem( SID_DOC_READONLY, true ) ); |
431 | |
|
432 | 0 | if ( !bWasROUI ) |
433 | 0 | Broadcast( SfxHint(SfxHintId::ModeChanged) ); |
434 | 0 | } |
435 | | |
436 | | |
437 | | bool SfxObjectShell::IsReadOnly() const |
438 | 1.47M | { |
439 | 1.47M | return pImpl->bReadOnlyUI || pMedium == nullptr || pMedium->HasRestrictedFonts(); |
440 | 1.47M | } |
441 | | |
442 | | |
443 | | bool SfxObjectShell::IsInModalMode() const |
444 | 0 | { |
445 | 0 | return pImpl->bModalMode || pImpl->bRunningMacro; |
446 | 0 | } |
447 | | |
448 | | bool SfxObjectShell::AcceptStateUpdate() const |
449 | 0 | { |
450 | 0 | return !IsInModalMode(); |
451 | 0 | } |
452 | | |
453 | | |
454 | | void SfxObjectShell::SetMacroMode_Impl( bool bModal ) |
455 | 0 | { |
456 | 0 | if ( !pImpl->bRunningMacro != !bModal ) |
457 | 0 | { |
458 | 0 | pImpl->bRunningMacro = bModal; |
459 | 0 | Broadcast( SfxHint( SfxHintId::ModeChanged ) ); |
460 | 0 | } |
461 | 0 | } |
462 | | |
463 | | |
464 | | void SfxObjectShell::SetModalMode_Impl( bool bModal ) |
465 | 0 | { |
466 | | // Broadcast only if modified, or otherwise it will possibly go into |
467 | | // an endless loop |
468 | 0 | if ( pImpl->bModalMode == bModal ) |
469 | 0 | return; |
470 | | |
471 | | // Central count |
472 | 0 | sal_uInt16 &rDocModalCount = SfxGetpApp()->Get_Impl()->nDocModalMode; |
473 | 0 | if ( bModal ) |
474 | 0 | ++rDocModalCount; |
475 | 0 | else |
476 | 0 | --rDocModalCount; |
477 | | |
478 | | // Switch |
479 | 0 | pImpl->bModalMode = bModal; |
480 | 0 | Broadcast( SfxHint( SfxHintId::ModeChanged ) ); |
481 | 0 | } |
482 | | |
483 | | #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT |
484 | | |
485 | | bool SfxObjectShell::SwitchToShared( bool bShared, bool bSave ) |
486 | | { |
487 | | bool bResult = true; |
488 | | |
489 | | if ( bShared != IsDocShared() ) |
490 | | { |
491 | | OUString aOrigURL = GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE ); |
492 | | |
493 | | if ( aOrigURL.isEmpty() && bSave ) |
494 | | { |
495 | | // this is a new document, let it be stored before switching to the shared mode; |
496 | | // the storing should be done without shared flag, since it is possible that the |
497 | | // target location does not allow to create sharing control file; |
498 | | // the shared flag will be set later after creation of sharing control file |
499 | | SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst( this ); |
500 | | |
501 | | if ( pViewFrame ) |
502 | | { |
503 | | // TODO/LATER: currently the application guards against the reentrance problem |
504 | | const SfxPoolItemHolder aItem(pViewFrame->GetBindings().ExecuteSynchron( HasName() ? SID_SAVEDOC : SID_SAVEASDOC )); |
505 | | const SfxBoolItem* pResult(dynamic_cast<const SfxBoolItem*>(aItem.getItem())); |
506 | | bResult = ( pResult && pResult->GetValue() ); |
507 | | if ( bResult ) |
508 | | aOrigURL = GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE ); |
509 | | } |
510 | | } |
511 | | |
512 | | bool bOldValue = HasSharedXMLFlagSet(); |
513 | | SetSharedXMLFlag( bShared ); |
514 | | |
515 | | bool bRemoveEntryOnError = false; |
516 | | if ( bResult && bShared ) |
517 | | { |
518 | | try |
519 | | { |
520 | | ::svt::ShareControlFile aControlFile( aOrigURL ); |
521 | | aControlFile.InsertOwnEntry(); |
522 | | bRemoveEntryOnError = true; |
523 | | } |
524 | | catch( uno::Exception& ) |
525 | | { |
526 | | bResult = false; |
527 | | } |
528 | | } |
529 | | |
530 | | if ( bResult && bSave ) |
531 | | { |
532 | | SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst( this ); |
533 | | |
534 | | if ( pViewFrame ) |
535 | | { |
536 | | // TODO/LATER: currently the application guards against the reentrance problem |
537 | | SetModified(); // the modified flag has to be set to let the document be stored with the shared flag |
538 | | try |
539 | | { |
540 | | // Do *not* use dispatch mechanism in this place - we don't want others (extensions etc.) to intercept this. |
541 | | pImpl->pBaseModel->store(); |
542 | | bResult = true; |
543 | | } |
544 | | catch (...) |
545 | | { |
546 | | bResult = false; |
547 | | } |
548 | | } |
549 | | } |
550 | | |
551 | | if ( bResult ) |
552 | | { |
553 | | // TODO/LATER: Is it possible that the following calls fail? |
554 | | if ( bShared ) |
555 | | { |
556 | | pImpl->m_aSharedFileURL = aOrigURL; |
557 | | GetMedium()->SwitchDocumentToTempFile(); |
558 | | } |
559 | | else |
560 | | { |
561 | | const OUString aTempFileURL = pMedium->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE ); |
562 | | GetMedium()->SwitchDocumentToFile( GetSharedFileURL() ); |
563 | | pImpl->m_aSharedFileURL.clear(); |
564 | | |
565 | | // now remove the temporary file the document was based on |
566 | | ::utl::UCBContentHelper::Kill( aTempFileURL ); |
567 | | |
568 | | try |
569 | | { |
570 | | // aOrigURL can not be used since it contains an old value |
571 | | ::svt::ShareControlFile aControlFile( GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE ) ); |
572 | | aControlFile.RemoveFile(); |
573 | | } |
574 | | catch( uno::Exception& ) |
575 | | { |
576 | | } |
577 | | } |
578 | | } |
579 | | else |
580 | | { |
581 | | // the saving has failed! |
582 | | if ( bRemoveEntryOnError ) |
583 | | { |
584 | | try |
585 | | { |
586 | | ::svt::ShareControlFile aControlFile( aOrigURL ); |
587 | | aControlFile.RemoveEntry(); |
588 | | } |
589 | | catch( uno::Exception& ) |
590 | | {} |
591 | | } |
592 | | |
593 | | SetSharedXMLFlag( bOldValue ); |
594 | | } |
595 | | } |
596 | | else |
597 | | bResult = false; // the second switch to the same mode |
598 | | |
599 | | if ( bResult ) |
600 | | SetTitle( u""_ustr ); |
601 | | |
602 | | return bResult; |
603 | | } |
604 | | |
605 | | |
606 | | void SfxObjectShell::FreeSharedFile( const OUString& aTempFileURL ) |
607 | | { |
608 | | SetSharedXMLFlag( false ); |
609 | | |
610 | | if ( !IsDocShared() || aTempFileURL.isEmpty() |
611 | | || ::utl::UCBContentHelper::EqualURLs( aTempFileURL, GetSharedFileURL() ) ) |
612 | | return; |
613 | | |
614 | | if ( pImpl->m_bAllowShareControlFileClean ) |
615 | | { |
616 | | try |
617 | | { |
618 | | ::svt::ShareControlFile aControlFile( GetSharedFileURL() ); |
619 | | aControlFile.RemoveEntry(); |
620 | | } |
621 | | catch( uno::Exception& ) |
622 | | { |
623 | | } |
624 | | } |
625 | | |
626 | | // the cleaning is forbidden only once |
627 | | pImpl->m_bAllowShareControlFileClean = true; |
628 | | |
629 | | // now remove the temporary file the document is based currently on |
630 | | ::utl::UCBContentHelper::Kill( aTempFileURL ); |
631 | | |
632 | | pImpl->m_aSharedFileURL.clear(); |
633 | | } |
634 | | |
635 | | |
636 | | void SfxObjectShell::DoNotCleanShareControlFile() |
637 | | { |
638 | | pImpl->m_bAllowShareControlFileClean = false; |
639 | | } |
640 | | |
641 | | |
642 | | void SfxObjectShell::SetSharedXMLFlag( bool bFlag ) const |
643 | | { |
644 | | pImpl->m_bSharedXMLFlag = bFlag; |
645 | | } |
646 | | |
647 | | |
648 | | bool SfxObjectShell::HasSharedXMLFlagSet() const |
649 | | { |
650 | | return pImpl->m_bSharedXMLFlag; |
651 | | } |
652 | | |
653 | | #endif |
654 | | |
655 | | bool SfxObjectShell::IsDocShared() const |
656 | 134k | { |
657 | | #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT |
658 | | return ( !pImpl->m_aSharedFileURL.isEmpty() ); |
659 | | #else |
660 | 134k | return false; |
661 | 134k | #endif |
662 | 134k | } |
663 | | |
664 | | |
665 | | OUString SfxObjectShell::GetSharedFileURL() const |
666 | 0 | { |
667 | | #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT |
668 | | return pImpl->m_aSharedFileURL; |
669 | | #else |
670 | 0 | return OUString(); |
671 | 0 | #endif |
672 | 0 | } |
673 | | |
674 | | Size SfxObjectShell::GetFirstPageSize() const |
675 | 0 | { |
676 | 0 | return GetVisArea(ASPECT_THUMBNAIL).GetSize(); |
677 | 0 | } |
678 | | |
679 | | |
680 | | IndexBitSet& SfxObjectShell::GetNoSet_Impl() |
681 | 8.16k | { |
682 | 8.16k | return pImpl->aBitSet; |
683 | 8.16k | } |
684 | | |
685 | | |
686 | | // changes the title of the document |
687 | | |
688 | | void SfxObjectShell::SetTitle |
689 | | ( |
690 | | const OUString& rTitle // the new Document Title |
691 | | ) |
692 | | |
693 | | /* [Description] |
694 | | |
695 | | With this method, the title of the document can be set. |
696 | | This corresponds initially to the full file name. A setting of the |
697 | | title does not affect the file name, but it will be shown in the |
698 | | Caption-Bars of the MDI-window. |
699 | | */ |
700 | | |
701 | 122k | { |
702 | | |
703 | | // Nothing to do? |
704 | 122k | if ( ( ( HasName() && pImpl->aTitle == rTitle ) |
705 | 122k | || ( !HasName() && GetTitle() == rTitle ) ) |
706 | 116k | && !IsDocShared() ) |
707 | 116k | return; |
708 | | |
709 | 6.22k | SfxApplication *pSfxApp = SfxGetpApp(); |
710 | | |
711 | | // If possible release the unnamed number. |
712 | 6.22k | if ( pImpl->bIsNamedVisible && USHRT_MAX != pImpl->nVisualDocumentNumber ) |
713 | 0 | { |
714 | 0 | pSfxApp->ReleaseIndex(pImpl->nVisualDocumentNumber); |
715 | 0 | pImpl->bIsNamedVisible = false; |
716 | 0 | } |
717 | | |
718 | | // Set Title |
719 | 6.22k | pImpl->aTitle = rTitle; |
720 | | |
721 | | // Notification |
722 | 6.22k | if ( GetMedium() ) |
723 | 6.22k | { |
724 | 6.22k | SfxShell::SetName( GetTitle(SFX_TITLE_APINAME) ); |
725 | 6.22k | Broadcast( SfxHint(SfxHintId::TitleChanged) ); |
726 | 6.22k | } |
727 | 6.22k | } |
728 | | |
729 | | |
730 | | |
731 | | OUString SfxObjectShell::GetTitle( sal_uInt16 nMaxLength ) const |
732 | | |
733 | | /* [Description] |
734 | | |
735 | | Returns the title or logical file name of the document, depending on the |
736 | | 'nMaxLength'. |
737 | | |
738 | | If the file name with path is used, the Name shortened by replacing one or |
739 | | more directory names with "...", URLs are currently always returned |
740 | | in complete form. |
741 | | */ |
742 | | |
743 | 829k | { |
744 | 829k | SfxMedium *pMed = GetMedium(); |
745 | 829k | if ( IsLoading() ) |
746 | 129k | return OUString(); |
747 | | |
748 | | // Create Title? |
749 | 699k | if ( SFX_TITLE_DETECT == nMaxLength && pImpl->aTitle.isEmpty() ) |
750 | 195k | { |
751 | 195k | static bool bRecur = false; |
752 | 195k | if ( bRecur ) |
753 | 0 | return u"-not available-"_ustr; |
754 | 195k | bRecur = true; |
755 | | |
756 | 195k | OUString aTitle; |
757 | | |
758 | 195k | if ( pMed ) |
759 | 195k | { |
760 | 195k | const SfxStringItem* pNameItem = pMed->GetItemSet().GetItem(SID_DOCINFO_TITLE, false); |
761 | 195k | if ( pNameItem ) |
762 | 0 | aTitle = pNameItem->GetValue(); |
763 | 195k | } |
764 | | |
765 | 195k | if ( aTitle.isEmpty() ) |
766 | 195k | aTitle = GetTitle( SFX_TITLE_FILENAME ); |
767 | | |
768 | 195k | bRecur = false; |
769 | 195k | return aTitle; |
770 | 195k | } |
771 | | |
772 | 504k | if (SFX_TITLE_APINAME == nMaxLength ) |
773 | 10.3k | return GetAPIName(); |
774 | | |
775 | | // Picklist/Caption is mapped |
776 | 493k | if ( pMed && ( nMaxLength == SFX_TITLE_CAPTION || nMaxLength == SFX_TITLE_PICKLIST ) ) |
777 | 0 | { |
778 | | // If a specific title was given at open: |
779 | | // important for URLs: use INetProtocol::File for which the set title is not |
780 | | // considered. (See below, analysis of aTitleMap_Impl) |
781 | 0 | const SfxStringItem* pNameItem = pMed->GetItemSet().GetItem(SID_DOCINFO_TITLE, false); |
782 | 0 | if ( pNameItem ) |
783 | 0 | return pNameItem->GetValue(); |
784 | 0 | } |
785 | | |
786 | | // Still unnamed? |
787 | 493k | DBG_ASSERT( !HasName() || pMed, "HasName() but no Medium?!?" ); |
788 | 493k | if ( !HasName() || !pMed ) |
789 | 493k | { |
790 | | // Title already set? |
791 | 493k | if ( !pImpl->aTitle.isEmpty() ) |
792 | 18.8k | return pImpl->aTitle; |
793 | | |
794 | | // must it be numbered? |
795 | 474k | const OUString aNoName(SfxResId(STR_NONAME)); |
796 | 474k | if (pImpl->bIsNamedVisible) |
797 | 36.7k | { |
798 | | // Append number |
799 | 36.7k | return aNoName + " " + OUString::number(pImpl->nVisualDocumentNumber); |
800 | 36.7k | } |
801 | | |
802 | | // Document called "Untitled" for the time being |
803 | 438k | return aNoName; |
804 | 474k | } |
805 | 493k | assert(pMed); |
806 | |
|
807 | 0 | const INetURLObject aURL( IsDocShared() ? GetSharedFileURL() : GetMedium()->GetName() ); |
808 | 0 | if ( nMaxLength > SFX_TITLE_CAPTION && nMaxLength <= SFX_TITLE_HISTORY ) |
809 | 0 | { |
810 | 0 | sal_uInt16 nRemote; |
811 | 0 | if (aURL.GetProtocol() == INetProtocol::File) |
812 | 0 | nRemote = 0; |
813 | 0 | else |
814 | 0 | nRemote = 1; |
815 | 0 | nMaxLength = aTitleMap_Impl[nMaxLength-SFX_TITLE_CAPTION][nRemote]; |
816 | 0 | } |
817 | | |
818 | | // Local file? |
819 | 0 | if ( aURL.GetProtocol() == INetProtocol::File ) |
820 | 0 | { |
821 | 0 | if ( nMaxLength == SFX_TITLE_FULLNAME ) |
822 | 0 | return aURL.HasMark() ? INetURLObject( aURL.GetURLNoMark() ).PathToFileName() : aURL.PathToFileName(); |
823 | 0 | if ( nMaxLength == SFX_TITLE_FILENAME ) |
824 | 0 | return aURL.getName(INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset); |
825 | 0 | if ( pImpl->aTitle.isEmpty() ) |
826 | 0 | pImpl->aTitle = aURL.getBase( INetURLObject::LAST_SEGMENT, |
827 | 0 | true, INetURLObject::DecodeMechanism::WithCharset ); |
828 | 0 | } |
829 | 0 | else |
830 | 0 | { |
831 | 0 | if ( nMaxLength >= SFX_TITLE_MAXLEN ) |
832 | 0 | { |
833 | 0 | const OUString aComplete( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) ); |
834 | 0 | if( aComplete.getLength() > nMaxLength ) |
835 | 0 | return OUString::Concat("...") + aComplete.subView( aComplete.getLength() - nMaxLength + 3, nMaxLength - 3 ); |
836 | 0 | return aComplete; |
837 | 0 | } |
838 | 0 | if ( nMaxLength == SFX_TITLE_FILENAME ) |
839 | 0 | { |
840 | 0 | const OUString aName = INetURLObject::decode( aURL.GetBase(), INetURLObject::DecodeMechanism::WithCharset ); |
841 | 0 | return aName.isEmpty() ? aURL.GetURLNoPass() : aName; |
842 | 0 | } |
843 | 0 | if ( nMaxLength == SFX_TITLE_FULLNAME ) |
844 | 0 | return aURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri ); |
845 | | |
846 | | // Generate Title from file name if possible |
847 | 0 | if ( pImpl->aTitle.isEmpty() ) |
848 | 0 | pImpl->aTitle = aURL.GetBase(); |
849 | | |
850 | | // workaround for the case when the name can not be retrieved from URL by INetURLObject |
851 | 0 | if ( pImpl->aTitle.isEmpty() ) |
852 | 0 | pImpl->aTitle = aURL.GetMainURL( INetURLObject::DecodeMechanism::WithCharset ); |
853 | 0 | } |
854 | | |
855 | | // Complete Title |
856 | 0 | return pImpl->aTitle; |
857 | 0 | } |
858 | | |
859 | | |
860 | | void SfxObjectShell::InvalidateName() |
861 | | |
862 | | /* [Description] |
863 | | |
864 | | Returns the title of the new document, DocInfo-Title or |
865 | | File name. Is required for loading from template or SaveAs. |
866 | | */ |
867 | | |
868 | 0 | { |
869 | 0 | pImpl->aTitle.clear(); |
870 | |
|
871 | 0 | OUString sOldName = GetName(); |
872 | 0 | OUString sNewName = GetTitle(SFX_TITLE_APINAME); |
873 | 0 | if (sOldName != sNewName) |
874 | 0 | { |
875 | 0 | SetName(sNewName); |
876 | 0 | Broadcast(SfxHint(SfxHintId::TitleChanged)); |
877 | 0 | } |
878 | 0 | } |
879 | | |
880 | | |
881 | | void SfxObjectShell::SetNamedVisibility_Impl() |
882 | 4.08k | { |
883 | 4.08k | if ( !pImpl->bIsNamedVisible ) |
884 | 4.08k | { |
885 | 4.08k | pImpl->bIsNamedVisible = true; |
886 | 4.08k | if ( !HasName() && USHRT_MAX == pImpl->nVisualDocumentNumber && pImpl->aTitle.isEmpty() ) |
887 | 4.08k | { |
888 | 4.08k | pImpl->nVisualDocumentNumber = SfxGetpApp()->GetFreeIndex(); |
889 | 4.08k | Broadcast( SfxHint(SfxHintId::TitleChanged) ); |
890 | 4.08k | } |
891 | 4.08k | } |
892 | | |
893 | 4.08k | SetName( GetTitle(SFX_TITLE_APINAME) ); |
894 | 4.08k | } |
895 | | |
896 | | void SfxObjectShell::SetNoName() |
897 | 0 | { |
898 | 0 | bHasName = false; |
899 | 0 | GetModel()->attachResource( OUString(), GetModel()->getArgs() ); |
900 | 0 | } |
901 | | |
902 | | |
903 | | SfxProgress* SfxObjectShell::GetProgress() const |
904 | 321k | { |
905 | 321k | return pImpl->pProgress; |
906 | 321k | } |
907 | | |
908 | | |
909 | | void SfxObjectShell::SetProgress_Impl |
910 | | ( |
911 | | SfxProgress *pProgress /* to started <SfxProgress> or 0, |
912 | | if the progress is to be reset */ |
913 | | ) |
914 | | |
915 | | /* [Description] |
916 | | |
917 | | Internal method to set or reset the Progress modes for |
918 | | SfxObjectShell. |
919 | | */ |
920 | | |
921 | 94.1k | { |
922 | 94.1k | DBG_ASSERT( ( !pImpl->pProgress && pProgress ) || |
923 | 94.1k | ( pImpl->pProgress && !pProgress ), |
924 | 94.1k | "Progress activation/deactivation mismatch" ); |
925 | 94.1k | pImpl->pProgress = pProgress; |
926 | 94.1k | } |
927 | | |
928 | | |
929 | | void SfxObjectShell::PostActivateEvent_Impl( SfxViewFrame const * pFrame ) |
930 | 4.08k | { |
931 | 4.08k | SfxApplication* pSfxApp = SfxGetpApp(); |
932 | 4.08k | if ( pSfxApp->IsDowning() || IsLoading() || !pFrame || pFrame->GetFrame().IsClosing_Impl() ) |
933 | 0 | return; |
934 | | |
935 | 4.08k | const SfxBoolItem* pHiddenItem = pMedium ? pMedium->GetItemSet().GetItem(SID_HIDDEN, false) : nullptr; |
936 | 4.08k | if ( !pHiddenItem || !pHiddenItem->GetValue() ) |
937 | 4.08k | { |
938 | 4.08k | SfxEventHintId nId = pImpl->nEventId; |
939 | 4.08k | pImpl->nEventId = SfxEventHintId::NONE; |
940 | 4.08k | if ( nId == SfxEventHintId::OpenDoc ) |
941 | 0 | pSfxApp->NotifyEvent(SfxViewEventHint( nId, GlobalEventConfig::GetEventName(GlobalEventId::OPENDOC), this, pFrame->GetFrame().GetController() ), false); |
942 | 4.08k | else if (nId == SfxEventHintId::CreateDoc ) |
943 | 0 | pSfxApp->NotifyEvent(SfxViewEventHint( nId, GlobalEventConfig::GetEventName(GlobalEventId::CREATEDOC), this, pFrame->GetFrame().GetController() ), false); |
944 | 4.08k | } |
945 | 4.08k | } |
946 | | |
947 | | |
948 | | void SfxObjectShell::SetActivateEvent_Impl(SfxEventHintId nId ) |
949 | 0 | { |
950 | 0 | pImpl->nEventId = nId; |
951 | 0 | } |
952 | | |
953 | | bool SfxObjectShell::IsAutoLoadLocked() const |
954 | | |
955 | | /* Returns whether an Autoload is allowed to be executed. Before the |
956 | | surrounding FrameSet of the AutoLoad is also taken into account as well. |
957 | | */ |
958 | | |
959 | 0 | { |
960 | 0 | return !IsReadOnly(); |
961 | 0 | } |
962 | | |
963 | | |
964 | | void SfxObjectShell::BreakMacroSign_Impl( bool bBreakMacroSign ) |
965 | 6.59k | { |
966 | 6.59k | pImpl->m_bMacroSignBroken = bBreakMacroSign; |
967 | 6.59k | } |
968 | | |
969 | | |
970 | | void SfxObjectShell::CheckSecurityOnLoading_Impl() |
971 | 4.08k | { |
972 | 4.08k | if (GetErrorCode() == ERRCODE_IO_BROKENPACKAGE) |
973 | 0 | { // safety first: don't run any macros from broken package. |
974 | 0 | pImpl->aMacroMode.disallowMacroExecution(); |
975 | 0 | return; // do not get signature status - needs to be done after RepairPackage |
976 | 0 | } |
977 | | |
978 | | // make sure LO evaluates the macro signatures, so it can be preserved |
979 | 4.08k | GetScriptingSignatureState(); |
980 | | |
981 | 4.08k | uno::Reference< task::XInteractionHandler > xInteraction; |
982 | 4.08k | if ( GetMedium() ) |
983 | 4.08k | xInteraction = GetMedium()->GetInteractionHandler(); |
984 | | |
985 | | // check if there is a broken signature... |
986 | 4.08k | CheckForBrokenDocSignatures_Impl(); |
987 | | |
988 | 4.08k | CheckEncryption_Impl( xInteraction ); |
989 | | |
990 | | // check macro security |
991 | 4.08k | const bool bHasValidContentSignature = HasValidSignatures(); |
992 | 4.08k | const bool bHasMacros = pImpl->aMacroMode.hasMacros(); |
993 | 4.08k | pImpl->aMacroMode.checkMacrosOnLoading( xInteraction, bHasValidContentSignature, bHasMacros ); |
994 | 4.08k | pImpl->m_bHadCheckedMacrosOnLoad = bHasMacros; |
995 | 4.08k | } |
996 | | |
997 | | bool SfxObjectShell::GetHadCheckedMacrosOnLoad() const |
998 | 0 | { |
999 | 0 | return pImpl->m_bHadCheckedMacrosOnLoad; |
1000 | 0 | } |
1001 | | |
1002 | | bool SfxObjectShell::AllowedLinkProtocolFromDocument(const OUString& rUrl, SfxObjectShell* pObjShell, weld::Window* pDialogParent) |
1003 | 0 | { |
1004 | 0 | if (!INetURLObject(rUrl).IsExoticProtocol()) |
1005 | 0 | return true; |
1006 | | // Default to ignoring exotic protocols |
1007 | 0 | bool bAllow = false; |
1008 | 0 | if (pObjShell) |
1009 | 0 | { |
1010 | | // If the document had macros when loaded then follow the allowed macro-mode |
1011 | 0 | if (pObjShell->GetHadCheckedMacrosOnLoad()) |
1012 | 0 | bAllow = pObjShell->AdjustMacroMode(); |
1013 | 0 | else // otherwise ask the user, defaulting to cancel |
1014 | 0 | { |
1015 | | //Reuse URITools::onOpenURI warning string |
1016 | 0 | std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(pDialogParent, |
1017 | 0 | VclMessageType::Warning, VclButtonsType::YesNo, |
1018 | 0 | SfxResId(STR_DANGEROUS_TO_OPEN))); |
1019 | 0 | xQueryBox->set_primary_text(xQueryBox->get_primary_text().replaceFirst("$(ARG1)", |
1020 | 0 | INetURLObject::decode(rUrl, INetURLObject::DecodeMechanism::Unambiguous))); |
1021 | 0 | xQueryBox->set_default_response(RET_NO); |
1022 | 0 | bAllow = xQueryBox->run() == RET_YES; |
1023 | 0 | } |
1024 | 0 | } |
1025 | 0 | SAL_WARN_IF(!bAllow, "sfx.appl", "SfxObjectShell::AllowedLinkProtocolFromDocument ignoring: " << rUrl); |
1026 | 0 | return bAllow; |
1027 | 0 | } |
1028 | | |
1029 | | void SfxObjectShell::CheckEncryption_Impl( const uno::Reference< task::XInteractionHandler >& xHandler ) |
1030 | 4.08k | { |
1031 | 4.08k | OUString aVersion; |
1032 | 4.08k | bool bIsEncrypted = false; |
1033 | 4.08k | bool bHasNonEncrypted = false; |
1034 | | |
1035 | 4.08k | try |
1036 | 4.08k | { |
1037 | 4.08k | uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW ); |
1038 | 4.08k | xPropSet->getPropertyValue(u"Version"_ustr) >>= aVersion; |
1039 | 4.08k | xPropSet->getPropertyValue(u"HasEncryptedEntries"_ustr) >>= bIsEncrypted; |
1040 | 4.08k | xPropSet->getPropertyValue(u"HasNonEncryptedEntries"_ustr) >>= bHasNonEncrypted; |
1041 | 4.08k | } |
1042 | 4.08k | catch( uno::Exception& ) |
1043 | 4.08k | { |
1044 | 0 | } |
1045 | | |
1046 | 4.08k | if ( aVersion.compareTo( ODFVER_012_TEXT ) < 0 ) |
1047 | 0 | return; |
1048 | | |
1049 | | // this is ODF1.2 or later |
1050 | 4.08k | if ( !(bIsEncrypted && bHasNonEncrypted) ) |
1051 | 4.08k | return; |
1052 | | |
1053 | 0 | if ( !pImpl->m_bIncomplEncrWarnShown ) |
1054 | 0 | { |
1055 | | // this is an encrypted document with nonencrypted streams inside, show the warning |
1056 | 0 | css::task::ErrorCodeRequest aErrorCode; |
1057 | 0 | aErrorCode.ErrCode = sal_uInt32(ERRCODE_SFX_INCOMPLETE_ENCRYPTION); |
1058 | |
|
1059 | 0 | SfxMedium::CallApproveHandler( xHandler, uno::Any( aErrorCode ), false ); |
1060 | 0 | pImpl->m_bIncomplEncrWarnShown = true; |
1061 | 0 | } |
1062 | | |
1063 | | // broken signatures imply no macro execution at all |
1064 | 0 | pImpl->aMacroMode.disallowMacroExecution(); |
1065 | 0 | } |
1066 | | |
1067 | | |
1068 | | void SfxObjectShell::CheckForBrokenDocSignatures_Impl() |
1069 | 4.08k | { |
1070 | 4.08k | SignatureState nSignatureState = GetDocumentSignatureState(); |
1071 | 4.08k | bool bSignatureBroken = ( nSignatureState == SignatureState::BROKEN ); |
1072 | 4.08k | if ( !bSignatureBroken ) |
1073 | 4.08k | return; |
1074 | | |
1075 | | // broken signatures imply no macro execution at all |
1076 | 0 | pImpl->aMacroMode.disallowMacroExecution(); |
1077 | 0 | } |
1078 | | |
1079 | | |
1080 | | void SfxObjectShell::SetAutoLoad( |
1081 | | const INetURLObject& rUrl, sal_uInt32 nTime, bool bReload ) |
1082 | 67.4k | { |
1083 | 67.4k | pImpl->pReloadTimer.reset(); |
1084 | 67.4k | if ( bReload ) |
1085 | 0 | { |
1086 | 0 | pImpl->pReloadTimer.reset(new AutoReloadTimer_Impl( |
1087 | 0 | rUrl.GetMainURL( INetURLObject::DecodeMechanism::ToIUri ), |
1088 | 0 | nTime, this )); |
1089 | 0 | pImpl->pReloadTimer->Start(); |
1090 | 0 | } |
1091 | 67.4k | } |
1092 | | |
1093 | | void SfxObjectShell::SetLoading(SfxLoadedFlags nFlags) |
1094 | 240k | { |
1095 | 240k | pImpl->nLoadedFlags = nFlags; |
1096 | 240k | } |
1097 | | |
1098 | | bool SfxObjectShell::IsLoadingFinished() const |
1099 | 4.08k | { |
1100 | 4.08k | return ( pImpl->nLoadedFlags == SfxLoadedFlags::ALL ); |
1101 | 4.08k | } |
1102 | | |
1103 | | void SfxObjectShell::InitOwnModel_Impl() |
1104 | 0 | { |
1105 | 0 | if ( pImpl->bModelInitialized ) |
1106 | 0 | return; |
1107 | | |
1108 | 0 | const SfxStringItem* pSalvageItem = pMedium->GetItemSet().GetItem(SID_DOC_SALVAGE, false); |
1109 | 0 | if ( pSalvageItem ) |
1110 | 0 | { |
1111 | 0 | pImpl->aTempName = pMedium->GetPhysicalName(); |
1112 | 0 | pMedium->GetItemSet().ClearItem( SID_DOC_SALVAGE ); |
1113 | 0 | pMedium->GetItemSet().ClearItem( SID_FILE_NAME ); |
1114 | 0 | pMedium->GetItemSet().Put( SfxStringItem( SID_FILE_NAME, pMedium->GetOrigURL() ) ); |
1115 | 0 | } |
1116 | 0 | else |
1117 | 0 | { |
1118 | 0 | pMedium->GetItemSet().ClearItem( SID_PROGRESS_STATUSBAR_CONTROL ); |
1119 | 0 | pMedium->GetItemSet().ClearItem( SID_DOCUMENT ); |
1120 | 0 | } |
1121 | |
|
1122 | 0 | pMedium->GetItemSet().ClearItem( SID_REFERER ); |
1123 | 0 | uno::Reference< frame::XModel > xModel = GetModel(); |
1124 | 0 | if ( xModel.is() ) |
1125 | 0 | { |
1126 | 0 | SfxItemSet& rSet = GetMedium()->GetItemSet(); |
1127 | 0 | if ( !GetMedium()->IsReadOnly() ) |
1128 | 0 | rSet.ClearItem( SID_INPUTSTREAM ); |
1129 | 0 | comphelper::SequenceAsHashMap aArgs = TransformItems(SID_OPENDOC, rSet); |
1130 | 0 | xModel->attachResource(GetMedium()->GetOrigURL(), aArgs.getAsConstPropertyValueList()); |
1131 | 0 | impl_addToModelCollection(xModel); |
1132 | 0 | } |
1133 | |
|
1134 | 0 | pImpl->bModelInitialized = true; |
1135 | 0 | } |
1136 | | |
1137 | | void SfxObjectShell::FinishedLoading( SfxLoadedFlags nFlags ) |
1138 | 0 | { |
1139 | 0 | bool bSetModifiedTRUE = false; |
1140 | 0 | const SfxStringItem* pSalvageItem = pMedium->GetItemSet().GetItem(SID_DOC_SALVAGE, false); |
1141 | 0 | if( ( nFlags & SfxLoadedFlags::MAINDOCUMENT ) && !(pImpl->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT ) |
1142 | 0 | && !(pImpl->nFlagsInProgress & SfxLoadedFlags::MAINDOCUMENT )) |
1143 | 0 | { |
1144 | 0 | pImpl->nFlagsInProgress |= SfxLoadedFlags::MAINDOCUMENT; |
1145 | 0 | static_cast<SfxHeaderAttributes_Impl*>(GetHeaderAttributes())->SetAttributes(); |
1146 | |
|
1147 | 0 | pMedium->activateEmbeddedFonts(); |
1148 | |
|
1149 | 0 | if ( ( GetModifyPasswordHash() || GetModifyPasswordInfo().hasElements() ) && !IsModifyPasswordEntered() ) |
1150 | 0 | SetReadOnly(); |
1151 | | |
1152 | | // Salvage |
1153 | 0 | if ( pSalvageItem ) |
1154 | 0 | bSetModifiedTRUE = true; |
1155 | |
|
1156 | 0 | if ( !IsEnableSetModified() ) |
1157 | 0 | EnableSetModified(); |
1158 | |
|
1159 | 0 | if( !bSetModifiedTRUE && IsEnableSetModified() ) |
1160 | 0 | SetModified( false ); |
1161 | |
|
1162 | 0 | CheckSecurityOnLoading_Impl(); |
1163 | |
|
1164 | 0 | bHasName = true; // the document is loaded, so the name should already available |
1165 | 0 | GetTitle( SFX_TITLE_DETECT ); |
1166 | 0 | InitOwnModel_Impl(); |
1167 | |
|
1168 | 0 | if (IsLoadReadonly()) |
1169 | 0 | { |
1170 | 0 | OUString aFilterName; |
1171 | 0 | if (const SfxStringItem* pFilterNameItem = |
1172 | 0 | pMedium->GetItemSet().GetItem(SID_FILTER_NAME, false)) |
1173 | 0 | aFilterName = pFilterNameItem->GetValue(); |
1174 | |
|
1175 | 0 | OUString aFileName; |
1176 | 0 | if (const SfxStringItem* pFileNameItem = |
1177 | 0 | pMedium->GetItemSet().GetItem(SID_FILE_NAME, false)) |
1178 | 0 | { |
1179 | 0 | const INetURLObject aURL(pFileNameItem->GetValue()); |
1180 | 0 | aFileName = aURL.getBase(INetURLObject::LAST_SEGMENT, true, |
1181 | 0 | INetURLObject::DecodeMechanism::WithCharset); |
1182 | 0 | } |
1183 | |
|
1184 | 0 | bool bSilent = false; |
1185 | 0 | if (const SfxBoolItem* pSilentNameItem = |
1186 | 0 | pMedium->GetItemSet().GetItem(SID_SILENT, false)) |
1187 | 0 | bSilent = pSilentNameItem->GetValue(); |
1188 | |
|
1189 | 0 | if (!bSilent && aFilterName.indexOf("Excel") != -1) |
1190 | 0 | { |
1191 | 0 | Reference<task::XInteractionHandler> xHandler(pMedium->GetInteractionHandler()); |
1192 | 0 | if (xHandler.is()) |
1193 | 0 | { |
1194 | 0 | beans::NamedValue aLoadReadOnlyRequest; |
1195 | 0 | aLoadReadOnlyRequest.Name = "LoadReadOnlyRequest"; |
1196 | 0 | aLoadReadOnlyRequest.Value <<= aFileName; |
1197 | |
|
1198 | 0 | Any aRequest(aLoadReadOnlyRequest); |
1199 | 0 | rtl::Reference<ucbhelper::SimpleInteractionRequest> xRequest |
1200 | 0 | = new ucbhelper::SimpleInteractionRequest(aRequest, |
1201 | 0 | ContinuationFlags::Approve | |
1202 | 0 | ContinuationFlags::Disapprove); |
1203 | |
|
1204 | 0 | xHandler->handle(xRequest); |
1205 | |
|
1206 | 0 | if (xRequest->getResponse() == ContinuationFlags::Disapprove) |
1207 | 0 | { |
1208 | 0 | SetSecurityOptOpenReadOnly(false); |
1209 | 0 | pMedium->GetItemSet().Put(SfxBoolItem(SID_DOC_READONLY, false)); |
1210 | 0 | } |
1211 | 0 | } |
1212 | 0 | } |
1213 | 0 | } |
1214 | |
|
1215 | 0 | pImpl->nFlagsInProgress &= ~SfxLoadedFlags::MAINDOCUMENT; |
1216 | 0 | } |
1217 | |
|
1218 | 0 | if( ( nFlags & SfxLoadedFlags::IMAGES ) && !(pImpl->nLoadedFlags & SfxLoadedFlags::IMAGES ) |
1219 | 0 | && !(pImpl->nFlagsInProgress & SfxLoadedFlags::IMAGES )) |
1220 | 0 | { |
1221 | 0 | pImpl->nFlagsInProgress |= SfxLoadedFlags::IMAGES; |
1222 | 0 | uno::Reference<document::XDocumentProperties> xDocProps( |
1223 | 0 | getDocProperties()); |
1224 | 0 | const OUString url(xDocProps->getAutoloadURL()); |
1225 | 0 | sal_Int32 delay(xDocProps->getAutoloadSecs()); |
1226 | 0 | SetAutoLoad( INetURLObject(url), delay * 1000, |
1227 | 0 | (delay > 0) || !url.isEmpty() ); |
1228 | 0 | if( !bSetModifiedTRUE && IsEnableSetModified() ) |
1229 | 0 | SetModified( false ); |
1230 | 0 | Invalidate( SID_SAVEASDOC ); |
1231 | 0 | pImpl->nFlagsInProgress &= ~SfxLoadedFlags::IMAGES; |
1232 | 0 | } |
1233 | |
|
1234 | 0 | pImpl->nLoadedFlags |= nFlags; |
1235 | |
|
1236 | 0 | if ( pImpl->nFlagsInProgress != SfxLoadedFlags::NONE ) |
1237 | 0 | return; |
1238 | | |
1239 | | // in case of reentrance calls the first called FinishedLoading() call on the stack |
1240 | | // should do the notification, in result the notification is done when all the FinishedLoading() calls are finished |
1241 | | |
1242 | 0 | if ( bSetModifiedTRUE ) |
1243 | 0 | SetModified(); |
1244 | 0 | else |
1245 | 0 | SetModified( false ); |
1246 | |
|
1247 | 0 | if ( (pImpl->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT ) && (pImpl->nLoadedFlags & SfxLoadedFlags::IMAGES ) ) |
1248 | 0 | { |
1249 | 0 | const SfxBoolItem* pTemplateItem = pMedium->GetItemSet().GetItem(SID_TEMPLATE, false); |
1250 | 0 | bool bTemplate = pTemplateItem && pTemplateItem->GetValue(); |
1251 | | |
1252 | | // closing the streams on loading should be under control of SFX! |
1253 | 0 | DBG_ASSERT( pMedium->IsOpen(), "Don't close the medium when loading documents!" ); |
1254 | |
|
1255 | 0 | if ( bTemplate ) |
1256 | 0 | { |
1257 | 0 | TemplateDisconnectionAfterLoad(); |
1258 | 0 | } |
1259 | 0 | else |
1260 | 0 | { |
1261 | | // if a readonly medium has storage then it's stream is already based on temporary file |
1262 | 0 | if( !(pMedium->GetOpenMode() & StreamMode::WRITE) && !pMedium->HasStorage_Impl() ) |
1263 | | // don't lock file opened read only |
1264 | 0 | pMedium->CloseInStream(); |
1265 | 0 | } |
1266 | 0 | } |
1267 | |
|
1268 | 0 | SetInitialized_Impl( false ); |
1269 | | |
1270 | | // Title is not available until loading has finished |
1271 | 0 | Broadcast( SfxHint( SfxHintId::TitleChanged ) ); |
1272 | 0 | if ( pImpl->nEventId != SfxEventHintId::NONE ) |
1273 | 0 | PostActivateEvent_Impl(SfxViewFrame::GetFirst(this)); |
1274 | 0 | } |
1275 | | |
1276 | | void SfxObjectShell::TemplateDisconnectionAfterLoad() |
1277 | 0 | { |
1278 | | // document is created from a template |
1279 | | //TODO/LATER: should the templates always be XML docs! |
1280 | |
|
1281 | 0 | SfxMedium* pTmpMedium = pMedium; |
1282 | 0 | if ( !pTmpMedium ) |
1283 | 0 | return; |
1284 | | |
1285 | 0 | const OUString aName( pTmpMedium->GetName() ); |
1286 | 0 | const SfxStringItem* pTemplNamItem = pTmpMedium->GetItemSet().GetItem(SID_TEMPLATE_NAME, false); |
1287 | 0 | OUString aTemplateName; |
1288 | 0 | if ( pTemplNamItem ) |
1289 | 0 | aTemplateName = pTemplNamItem->GetValue(); |
1290 | 0 | else |
1291 | 0 | { |
1292 | | // !TODO/LATER: what's this?! |
1293 | | // Interactive ( DClick, Contextmenu ) no long name is included |
1294 | 0 | aTemplateName = getDocProperties()->getTitle(); |
1295 | 0 | if ( aTemplateName.isEmpty() ) |
1296 | 0 | { |
1297 | 0 | INetURLObject aURL( aName ); |
1298 | 0 | aURL.CutExtension(); |
1299 | 0 | aTemplateName = aURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset ); |
1300 | 0 | } |
1301 | 0 | } |
1302 | | |
1303 | | // tdf#165348: release the lock on the original file before clearing the URL, otherwise |
1304 | | // UnlockFile (called later from Close) won't know which lock file to remove. |
1305 | 0 | pTmpMedium->UnlockFile(false); |
1306 | | |
1307 | | // set medium to noname |
1308 | 0 | pTmpMedium->SetName( OUString(), true ); |
1309 | 0 | pTmpMedium->Init_Impl(); |
1310 | | |
1311 | | // drop resource |
1312 | 0 | SetNoName(); |
1313 | 0 | InvalidateName(); |
1314 | |
|
1315 | 0 | if( IsPackageStorageFormat_Impl( *pTmpMedium ) ) |
1316 | 0 | { |
1317 | | // untitled document must be based on temporary storage |
1318 | | // the medium should not dispose the storage in this case |
1319 | 0 | uno::Reference < embed::XStorage > xTmpStor = ::comphelper::OStorageHelper::GetTemporaryStorage(); |
1320 | 0 | GetStorage()->copyToStorage( xTmpStor ); |
1321 | | |
1322 | | // the medium should disconnect from the original location |
1323 | | // the storage should not be disposed since the document is still |
1324 | | // based on it, but in DoSaveCompleted it will be disposed |
1325 | 0 | pTmpMedium->CanDisposeStorage_Impl( false ); |
1326 | 0 | pTmpMedium->Close(); |
1327 | | |
1328 | | // setting the new storage the medium will be based on |
1329 | 0 | pTmpMedium->SetStorage_Impl( xTmpStor ); |
1330 | |
|
1331 | 0 | pMedium = nullptr; |
1332 | 0 | bool ok = DoSaveCompleted( pTmpMedium ); |
1333 | 0 | assert(pMedium != nullptr); |
1334 | 0 | if( ok ) |
1335 | 0 | { |
1336 | 0 | const SfxStringItem* pSalvageItem = pMedium->GetItemSet().GetItem(SID_DOC_SALVAGE, false); |
1337 | 0 | bool bSalvage = pSalvageItem != nullptr; |
1338 | |
|
1339 | 0 | if ( !bSalvage ) |
1340 | 0 | { |
1341 | | // some further initializations for templates |
1342 | 0 | SetTemplate_Impl( aName, aTemplateName, this ); |
1343 | 0 | } |
1344 | | |
1345 | | // the medium should not dispose the storage, DoSaveCompleted() has let it to do so |
1346 | 0 | pTmpMedium->CanDisposeStorage_Impl( false ); |
1347 | 0 | } |
1348 | 0 | else |
1349 | 0 | { |
1350 | 0 | SetError(ERRCODE_IO_GENERAL); |
1351 | 0 | } |
1352 | 0 | } |
1353 | 0 | else |
1354 | 0 | { |
1355 | | // some further initializations for templates |
1356 | 0 | SetTemplate_Impl( aName, aTemplateName, this ); |
1357 | 0 | pTmpMedium->CreateTempFile(); |
1358 | 0 | } |
1359 | | |
1360 | | // templates are never readonly |
1361 | 0 | pTmpMedium->GetItemSet().ClearItem( SID_DOC_READONLY ); |
1362 | 0 | pTmpMedium->SetOpenMode( SFX_STREAM_READWRITE, true ); |
1363 | | |
1364 | | // notifications about possible changes in readonly state and document info |
1365 | 0 | Broadcast( SfxHint(SfxHintId::ModeChanged) ); |
1366 | | |
1367 | | // created untitled document can't be modified |
1368 | 0 | SetModified( false ); |
1369 | 0 | } |
1370 | | |
1371 | | |
1372 | | bool SfxObjectShell::IsLoading() const |
1373 | | /* [Description] |
1374 | | |
1375 | | Has FinishedLoading been called? |
1376 | | */ |
1377 | 13.9M | { |
1378 | 13.9M | return !( pImpl->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT ); |
1379 | 13.9M | } |
1380 | | |
1381 | | |
1382 | | void SfxObjectShell::CancelTransfers() |
1383 | | /* [Description] |
1384 | | |
1385 | | Here can Transfers get canceled, which were not registered |
1386 | | by RegisterTransfer. |
1387 | | */ |
1388 | 4.08k | { |
1389 | 4.08k | if( ( pImpl->nLoadedFlags & SfxLoadedFlags::ALL ) != SfxLoadedFlags::ALL ) |
1390 | 0 | { |
1391 | 0 | pImpl->bIsAbortingImport = true; |
1392 | 0 | if( IsLoading() ) |
1393 | 0 | FinishedLoading(); |
1394 | 0 | } |
1395 | 4.08k | } |
1396 | | |
1397 | | |
1398 | | AutoReloadTimer_Impl::AutoReloadTimer_Impl( |
1399 | | OUString _aURL, sal_uInt32 nTime, SfxObjectShell* pSh ) |
1400 | 0 | : Timer("sfx2 AutoReloadTimer_Impl"), aUrl(std::move( _aURL )), pObjSh( pSh ) |
1401 | 0 | { |
1402 | 0 | SetTimeout( nTime ); |
1403 | 0 | } |
1404 | | |
1405 | | |
1406 | | void AutoReloadTimer_Impl::Invoke() |
1407 | 0 | { |
1408 | 0 | SfxViewFrame *pFrame = SfxViewFrame::GetFirst( pObjSh ); |
1409 | |
|
1410 | 0 | if ( pFrame ) |
1411 | 0 | { |
1412 | | // Not possible/meaningful at the moment? |
1413 | 0 | if ( !pObjSh->CanReload_Impl() || pObjSh->IsAutoLoadLocked() || Application::IsUICaptured() ) |
1414 | 0 | { |
1415 | | // Allow a retry |
1416 | 0 | Start(); |
1417 | 0 | return; |
1418 | 0 | } |
1419 | | |
1420 | 0 | SfxAllItemSet aSet( SfxGetpApp()->GetPool() ); |
1421 | 0 | aSet.Put( SfxBoolItem( SID_AUTOLOAD, true ) ); |
1422 | 0 | if ( !aUrl.isEmpty() ) |
1423 | 0 | aSet.Put( SfxStringItem( SID_FILE_NAME, aUrl ) ); |
1424 | 0 | if (pObjSh->HasName()) { |
1425 | 0 | aSet.Put( |
1426 | 0 | SfxStringItem(SID_REFERER, pObjSh->GetMedium()->GetName())); |
1427 | 0 | } |
1428 | 0 | SfxRequest aReq( SID_RELOAD, SfxCallMode::SLOT, aSet ); |
1429 | | // this will delete this |
1430 | 0 | pObjSh->Get_Impl()->pReloadTimer.reset(); |
1431 | 0 | pFrame->ExecReload_Impl( aReq ); |
1432 | 0 | return; |
1433 | 0 | } |
1434 | | |
1435 | | // this will delete this |
1436 | 0 | pObjSh->Get_Impl()->pReloadTimer.reset(); |
1437 | 0 | } |
1438 | | |
1439 | | SfxModule* SfxObjectShell::GetModule() const |
1440 | 146k | { |
1441 | 146k | return GetFactory().GetModule(); |
1442 | 146k | } |
1443 | | |
1444 | | ErrCode SfxObjectShell::CallBasic( std::u16string_view rMacro, |
1445 | | std::u16string_view rBasic, SbxArray* pArgs, |
1446 | | SbxValue* pRet ) |
1447 | 0 | { |
1448 | 0 | SfxApplication* pApp = SfxGetpApp(); |
1449 | 0 | if( pApp->GetName() != rBasic ) |
1450 | 0 | { |
1451 | 0 | if ( !AdjustMacroMode() ) |
1452 | 0 | return ERRCODE_IO_ACCESSDENIED; |
1453 | 0 | } |
1454 | | |
1455 | 0 | BasicManager *pMgr = GetBasicManager(); |
1456 | 0 | if( pApp->GetName() == rBasic ) |
1457 | 0 | pMgr = SfxApplication::GetBasicManager(); |
1458 | 0 | ErrCode nRet = SfxApplication::CallBasic( OUString(rMacro), pMgr, pArgs, pRet ); |
1459 | 0 | return nRet; |
1460 | 0 | } |
1461 | | |
1462 | | bool SfxObjectShell::isScriptAccessAllowed( const Reference< XInterface >& _rxScriptContext ) |
1463 | 0 | { |
1464 | 0 | try |
1465 | 0 | { |
1466 | 0 | Reference< XEmbeddedScripts > xScripts( _rxScriptContext, UNO_QUERY ); |
1467 | 0 | if ( !xScripts.is() ) |
1468 | 0 | { |
1469 | 0 | Reference< XScriptInvocationContext > xContext( _rxScriptContext, UNO_QUERY_THROW ); |
1470 | 0 | xScripts.set( xContext->getScriptContainer(), UNO_SET_THROW ); |
1471 | 0 | } |
1472 | |
|
1473 | 0 | return xScripts->getAllowMacroExecution(); |
1474 | 0 | } |
1475 | 0 | catch( const Exception& ) |
1476 | 0 | { |
1477 | 0 | DBG_UNHANDLED_EXCEPTION("sfx.doc"); |
1478 | 0 | } |
1479 | 0 | return false; |
1480 | 0 | } |
1481 | | |
1482 | | // don't allow LibreLogo to be used with our mouseover/etc dom-alike events |
1483 | | bool SfxObjectShell::UnTrustedScript(const OUString& rScriptURL) |
1484 | 0 | { |
1485 | 0 | if (!rScriptURL.startsWith("vnd.sun.star.script:")) |
1486 | 0 | return false; |
1487 | | |
1488 | | // ensure URL Escape Codes are decoded |
1489 | 0 | css::uno::Reference<css::uri::XUriReference> uri( |
1490 | 0 | css::uri::UriReferenceFactory::create(comphelper::getProcessComponentContext())->parse(rScriptURL)); |
1491 | 0 | css::uno::Reference<css::uri::XVndSunStarScriptUrl> sfUri(uri, css::uno::UNO_QUERY); |
1492 | |
|
1493 | 0 | if (!sfUri.is()) |
1494 | 0 | return false; |
1495 | | |
1496 | | // pyuno encodes path separator as | |
1497 | 0 | OUString sScript = sfUri->getName().replace('|', '/'); |
1498 | | |
1499 | | // check if any path portion matches LibreLogo and ban it if it does |
1500 | 0 | sal_Int32 nIndex = 0; |
1501 | 0 | do |
1502 | 0 | { |
1503 | 0 | OUString aToken = sScript.getToken(0, '/', nIndex); |
1504 | 0 | if (aToken.startsWithIgnoreAsciiCase("LibreLogo") || aToken.indexOf('~') != -1) |
1505 | 0 | { |
1506 | 0 | return true; |
1507 | 0 | } |
1508 | 0 | } |
1509 | 0 | while (nIndex >= 0); |
1510 | | |
1511 | 0 | return false; |
1512 | 0 | } |
1513 | | |
1514 | | ErrCode SfxObjectShell::CallXScript( const Reference< XInterface >& _rxScriptContext, const OUString& _rScriptURL, |
1515 | | const Sequence< Any >& aParams, Any& aRet, Sequence< sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam, bool bRaiseError, const css::uno::Any* pCaller ) |
1516 | 0 | { |
1517 | 0 | SAL_INFO("sfx", "in CallXScript" ); |
1518 | 0 | ErrCode nErr = ERRCODE_NONE; |
1519 | |
|
1520 | 0 | bool bCaughtException = false; |
1521 | 0 | Any aException; |
1522 | 0 | try |
1523 | 0 | { |
1524 | 0 | if (!isScriptAccessAllowed(_rxScriptContext)) |
1525 | 0 | return ERRCODE_IO_ACCESSDENIED; |
1526 | | |
1527 | 0 | if ( UnTrustedScript(_rScriptURL) ) |
1528 | 0 | return ERRCODE_IO_ACCESSDENIED; |
1529 | | |
1530 | | // obtain/create a script provider |
1531 | 0 | Reference< provider::XScriptProvider > xScriptProvider; |
1532 | 0 | Reference< provider::XScriptProviderSupplier > xSPS( _rxScriptContext, UNO_QUERY ); |
1533 | 0 | if ( xSPS.is() ) |
1534 | 0 | xScriptProvider.set( xSPS->getScriptProvider() ); |
1535 | |
|
1536 | 0 | if ( !xScriptProvider.is() ) |
1537 | 0 | { |
1538 | 0 | Reference< provider::XScriptProviderFactory > xScriptProviderFactory = |
1539 | 0 | provider::theMasterScriptProviderFactory::get( ::comphelper::getProcessComponentContext() ); |
1540 | 0 | xScriptProvider.set( xScriptProviderFactory->createScriptProvider( Any( _rxScriptContext ) ), UNO_SET_THROW ); |
1541 | 0 | } |
1542 | | |
1543 | | // ry to protect the invocation context's undo manager (if present), just in case the script tampers with it |
1544 | 0 | ::framework::DocumentUndoGuard aUndoGuard( _rxScriptContext ); |
1545 | | |
1546 | | // obtain the script, and execute it |
1547 | 0 | Reference< provider::XScript > xScript( xScriptProvider->getScript( _rScriptURL ), UNO_SET_THROW ); |
1548 | 0 | if ( pCaller && pCaller->hasValue() ) |
1549 | 0 | { |
1550 | 0 | Reference< beans::XPropertySet > xProps( xScript, uno::UNO_QUERY ); |
1551 | 0 | if ( xProps.is() ) |
1552 | 0 | { |
1553 | 0 | Sequence< uno::Any > aArgs{ *pCaller }; |
1554 | 0 | xProps->setPropertyValue(u"Caller"_ustr, uno::Any( aArgs ) ); |
1555 | 0 | } |
1556 | 0 | } |
1557 | 0 | aRet = xScript->invoke( aParams, aOutParamIndex, aOutParam ); |
1558 | 0 | } |
1559 | 0 | catch ( const uno::Exception& ) |
1560 | 0 | { |
1561 | 0 | aException = ::cppu::getCaughtException(); |
1562 | 0 | bCaughtException = true; |
1563 | 0 | nErr = ERRCODE_BASIC_INTERNAL_ERROR; |
1564 | 0 | } |
1565 | | |
1566 | 0 | if ( bCaughtException && bRaiseError ) |
1567 | 0 | { |
1568 | 0 | SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); |
1569 | 0 | pFact->ShowAsyncScriptErrorDialog( nullptr, aException ); |
1570 | 0 | } |
1571 | |
|
1572 | 0 | SAL_INFO("sfx", "leaving CallXScript" ); |
1573 | 0 | return nErr; |
1574 | 0 | } |
1575 | | |
1576 | | // perhaps rename to CallScript once we get rid of the existing CallScript |
1577 | | // and Call, CallBasic, CallStarBasic methods |
1578 | | ErrCode SfxObjectShell::CallXScript( const OUString& rScriptURL, |
1579 | | const css::uno::Sequence< css::uno::Any >& aParams, |
1580 | | css::uno::Any& aRet, |
1581 | | css::uno::Sequence< sal_Int16 >& aOutParamIndex, |
1582 | | css::uno::Sequence< css::uno::Any >& aOutParam, |
1583 | | bool bRaiseError, |
1584 | | const css::uno::Any* pCaller ) |
1585 | 0 | { |
1586 | 0 | return CallXScript( GetModel(), rScriptURL, aParams, aRet, aOutParamIndex, aOutParam, bRaiseError, pCaller ); |
1587 | 0 | } |
1588 | | |
1589 | | void SfxHeaderAttributes_Impl::SetAttributes() |
1590 | 0 | { |
1591 | 0 | bAlert = true; |
1592 | 0 | SvKeyValue aPair; |
1593 | 0 | for( bool bCont = xIter->GetFirst( aPair ); bCont; |
1594 | 0 | bCont = xIter->GetNext( aPair ) ) |
1595 | 0 | SetAttribute( aPair ); |
1596 | 0 | } |
1597 | | |
1598 | | void SfxHeaderAttributes_Impl::SetAttribute( const SvKeyValue& rKV ) |
1599 | 0 | { |
1600 | 0 | const OUString& aValue = rKV.GetValue(); |
1601 | 0 | if( rKV.GetKey().equalsIgnoreAsciiCase("refresh") && !rKV.GetValue().isEmpty() ) |
1602 | 0 | { |
1603 | 0 | sal_Int32 nIdx{ 0 }; |
1604 | 0 | const sal_Int32 nTime{ o3tl::toInt32(o3tl::getToken(aValue, 0, ';', nIdx )) }; |
1605 | 0 | const OUString aURL{ comphelper::string::strip(o3tl::getToken(aValue, 0, ';', nIdx ), ' ') }; |
1606 | 0 | uno::Reference<document::XDocumentProperties> xDocProps( |
1607 | 0 | pDoc->getDocProperties()); |
1608 | 0 | if( aURL.startsWithIgnoreAsciiCase( "url=" ) ) |
1609 | 0 | { |
1610 | 0 | try { |
1611 | 0 | xDocProps->setAutoloadURL( |
1612 | 0 | rtl::Uri::convertRelToAbs(pDoc->GetMedium()->GetName(), aURL.copy( 4 )) ); |
1613 | 0 | } catch (rtl::MalformedUriException &) { |
1614 | 0 | TOOLS_WARN_EXCEPTION("sfx", ""); |
1615 | 0 | } |
1616 | 0 | } |
1617 | 0 | try |
1618 | 0 | { |
1619 | 0 | xDocProps->setAutoloadSecs( nTime ); |
1620 | 0 | } |
1621 | 0 | catch (lang::IllegalArgumentException &) |
1622 | 0 | { |
1623 | | // ignore |
1624 | 0 | } |
1625 | 0 | } |
1626 | 0 | else if( rKV.GetKey().equalsIgnoreAsciiCase( "expires" ) ) |
1627 | 0 | { |
1628 | 0 | DateTime aDateTime( DateTime::EMPTY ); |
1629 | 0 | if( INetMIMEMessage::ParseDateField( rKV.GetValue(), aDateTime ) ) |
1630 | 0 | { |
1631 | 0 | aDateTime.ConvertToLocalTime(); |
1632 | 0 | pDoc->GetMedium()->SetExpired_Impl( aDateTime ); |
1633 | 0 | } |
1634 | 0 | else |
1635 | 0 | { |
1636 | 0 | pDoc->GetMedium()->SetExpired_Impl( DateTime(Date( 1, 1, 1970 )) ); |
1637 | 0 | } |
1638 | 0 | } |
1639 | 0 | } |
1640 | | |
1641 | | void SfxHeaderAttributes_Impl::Append( const SvKeyValue& rKV ) |
1642 | 5.13k | { |
1643 | 5.13k | xIter->Append( rKV ); |
1644 | 5.13k | if( bAlert ) SetAttribute( rKV ); |
1645 | 5.13k | } |
1646 | | |
1647 | | SvKeyValueIterator* SfxObjectShell::GetHeaderAttributes() |
1648 | 160k | { |
1649 | 160k | if( !pImpl->xHeaderAttributes.is() ) |
1650 | 14.4k | { |
1651 | 14.4k | DBG_ASSERT( pMedium, "No Medium" ); |
1652 | 14.4k | pImpl->xHeaderAttributes = new SfxHeaderAttributes_Impl( this ); |
1653 | 14.4k | } |
1654 | 160k | return pImpl->xHeaderAttributes.get(); |
1655 | 160k | } |
1656 | | |
1657 | | void SfxObjectShell::ClearHeaderAttributesForSourceViewHack() |
1658 | 0 | { |
1659 | 0 | static_cast<SfxHeaderAttributes_Impl*>(GetHeaderAttributes()) |
1660 | 0 | ->ClearForSourceView(); |
1661 | 0 | } |
1662 | | |
1663 | | |
1664 | | void SfxObjectShell::SetHeaderAttributesForSourceViewHack() |
1665 | 0 | { |
1666 | 0 | static_cast<SfxHeaderAttributes_Impl*>(GetHeaderAttributes()) |
1667 | 0 | ->SetAttributes(); |
1668 | 0 | } |
1669 | | |
1670 | | bool SfxObjectShell::IsPreview() const |
1671 | 83.5M | { |
1672 | 83.5M | if ( !pMedium ) |
1673 | 246k | return false; |
1674 | | |
1675 | 83.2M | bool bPreview = false; |
1676 | 83.2M | const SfxStringItem* pFlags = pMedium->GetItemSet().GetItem(SID_OPTIONS, false); |
1677 | 83.2M | if ( pFlags ) |
1678 | 0 | { |
1679 | | // Distributed values among individual items |
1680 | 0 | const OUString aFileFlags = pFlags->GetValue().toAsciiUpperCase(); |
1681 | 0 | if ( -1 != aFileFlags.indexOf( 'B' ) ) |
1682 | 0 | bPreview = true; |
1683 | 0 | } |
1684 | | |
1685 | 83.2M | if ( !bPreview ) |
1686 | 83.2M | { |
1687 | 83.2M | const SfxBoolItem* pItem = pMedium->GetItemSet().GetItem(SID_PREVIEW, false); |
1688 | 83.2M | if ( pItem ) |
1689 | 0 | bPreview = pItem->GetValue(); |
1690 | 83.2M | } |
1691 | | |
1692 | 83.2M | return bPreview; |
1693 | 83.5M | } |
1694 | | |
1695 | | void SfxObjectShell::SetWaitCursor( bool bSet ) const |
1696 | 52.3k | { |
1697 | 52.3k | for( SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this ); pFrame; pFrame = SfxViewFrame::GetNext( *pFrame, this ) ) |
1698 | 0 | { |
1699 | 0 | if ( bSet ) |
1700 | 0 | pFrame->GetFrame().GetWindow().EnterWait(); |
1701 | 0 | else |
1702 | 0 | pFrame->GetFrame().GetWindow().LeaveWait(); |
1703 | 0 | } |
1704 | 52.3k | } |
1705 | | |
1706 | | OUString SfxObjectShell::GetAPIName() const |
1707 | 10.3k | { |
1708 | 10.3k | INetURLObject aURL( IsDocShared() ? GetSharedFileURL() : GetMedium()->GetName() ); |
1709 | 10.3k | OUString aName( aURL.GetBase() ); |
1710 | 10.3k | if( aName.isEmpty() ) |
1711 | 10.3k | aName = aURL.GetURLNoPass(); |
1712 | 10.3k | if ( aName.isEmpty() ) |
1713 | 10.3k | aName = GetTitle( SFX_TITLE_DETECT ); |
1714 | 10.3k | return aName; |
1715 | 10.3k | } |
1716 | | |
1717 | | void SfxObjectShell::Invalidate( sal_uInt16 nId ) |
1718 | 409k | { |
1719 | 409k | for( SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this ); pFrame; pFrame = SfxViewFrame::GetNext( *pFrame, this ) ) |
1720 | 0 | Invalidate_Impl( pFrame->GetBindings(), nId ); |
1721 | 409k | } |
1722 | | |
1723 | | bool SfxObjectShell::AdjustMacroMode() |
1724 | 0 | { |
1725 | 0 | uno::Reference< task::XInteractionHandler > xInteraction; |
1726 | 0 | if ( pMedium ) |
1727 | 0 | xInteraction = pMedium->GetInteractionHandler(); |
1728 | |
|
1729 | 0 | CheckForBrokenDocSignatures_Impl(); |
1730 | |
|
1731 | 0 | CheckEncryption_Impl( xInteraction ); |
1732 | |
|
1733 | 0 | return pImpl->aMacroMode.adjustMacroMode( xInteraction ); |
1734 | 0 | } |
1735 | | |
1736 | | css::uno::Reference<css::awt::XWindow> SfxObjectShell::GetDialogParent( SfxMedium const * pLoadingMedium ) |
1737 | 0 | { |
1738 | 0 | css::uno::Reference<css::awt::XWindow> xWindow; |
1739 | 0 | SfxItemSet& rSet = pLoadingMedium ? pLoadingMedium->GetItemSet() : GetMedium()->GetItemSet(); |
1740 | 0 | const SfxUnoFrameItem* pUnoItem = rSet.GetItem(SID_FILLFRAME, false); |
1741 | 0 | if ( pUnoItem ) |
1742 | 0 | { |
1743 | 0 | const uno::Reference < frame::XFrame >& xFrame( pUnoItem->GetFrame() ); |
1744 | 0 | xWindow = xFrame->getContainerWindow(); |
1745 | 0 | } |
1746 | |
|
1747 | 0 | if (!xWindow) |
1748 | 0 | { |
1749 | 0 | SfxFrame* pFrame = nullptr; |
1750 | 0 | const SfxFrameItem* pFrameItem = rSet.GetItem<SfxFrameItem>(SID_DOCFRAME, false); |
1751 | 0 | if( pFrameItem && pFrameItem->GetFrame() ) |
1752 | | // get target frame from ItemSet |
1753 | 0 | pFrame = pFrameItem->GetFrame(); |
1754 | 0 | else |
1755 | 0 | { |
1756 | | // try the current frame |
1757 | 0 | SfxViewFrame* pView = SfxViewFrame::Current(); |
1758 | 0 | if ( !pView || pView->GetObjectShell() != this ) |
1759 | | // get any visible frame |
1760 | 0 | pView = SfxViewFrame::GetFirst(this); |
1761 | 0 | if ( pView ) |
1762 | 0 | pFrame = &pView->GetFrame(); |
1763 | 0 | } |
1764 | |
|
1765 | 0 | if ( pFrame ) |
1766 | 0 | { |
1767 | | // get topmost window |
1768 | 0 | xWindow = pFrame->GetFrameInterface()->getContainerWindow(); |
1769 | 0 | } |
1770 | 0 | } |
1771 | |
|
1772 | 0 | if (xWindow) |
1773 | 0 | { |
1774 | | // this frame may be invisible, show it if it is allowed |
1775 | 0 | const SfxBoolItem* pHiddenItem = rSet.GetItem(SID_HIDDEN, false); |
1776 | 0 | if ( !pHiddenItem || !pHiddenItem->GetValue() ) |
1777 | 0 | { |
1778 | 0 | xWindow->setVisible(true); |
1779 | 0 | css::uno::Reference<css::awt::XTopWindow> xTopWindow(xWindow, uno::UNO_QUERY); |
1780 | 0 | SAL_WARN_IF(!xTopWindow, "sfx.appl", "XTopWindow not available from XWindow"); |
1781 | 0 | if (xTopWindow) |
1782 | 0 | xTopWindow->toFront(); |
1783 | 0 | } |
1784 | 0 | } |
1785 | | |
1786 | 0 | return xWindow; |
1787 | 0 | } |
1788 | | |
1789 | | void SfxObjectShell::SetCreateMode_Impl( SfxObjectCreateMode nMode ) |
1790 | 0 | { |
1791 | 0 | eCreateMode = nMode; |
1792 | 0 | } |
1793 | | |
1794 | | bool SfxObjectShell::IsInPlaceActive() const |
1795 | 48.5k | { |
1796 | 48.5k | if ( eCreateMode != SfxObjectCreateMode::EMBEDDED ) |
1797 | 20.4k | return false; |
1798 | | |
1799 | 28.1k | SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this ); |
1800 | 28.1k | return pFrame && pFrame->GetFrame().IsInPlace(); |
1801 | 48.5k | } |
1802 | | |
1803 | | bool SfxObjectShell::IsUIActive() const |
1804 | 0 | { |
1805 | 0 | if ( eCreateMode != SfxObjectCreateMode::EMBEDDED ) |
1806 | 0 | return false; |
1807 | | |
1808 | 0 | SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this ); |
1809 | 0 | return pFrame && pFrame->GetFrame().IsInPlace() && pFrame->GetFrame().GetWorkWindow_Impl()->IsVisible_Impl(); |
1810 | 0 | } |
1811 | | |
1812 | | bool SfxObjectShell::UseInteractionToHandleError( |
1813 | | const uno::Reference< task::XInteractionHandler >& xHandler, |
1814 | | const ErrCodeMsg& nError ) |
1815 | 0 | { |
1816 | 0 | bool bResult = false; |
1817 | |
|
1818 | 0 | if ( xHandler.is() ) |
1819 | 0 | { |
1820 | 0 | try |
1821 | 0 | { |
1822 | 0 | uno::Any aInteraction; |
1823 | 0 | rtl::Reference<::comphelper::OInteractionAbort> pAbort = new ::comphelper::OInteractionAbort(); |
1824 | 0 | rtl::Reference<::comphelper::OInteractionApprove> pApprove = new ::comphelper::OInteractionApprove(); |
1825 | 0 | uno::Sequence< uno::Reference< task::XInteractionContinuation > > lContinuations{ |
1826 | 0 | pAbort, pApprove |
1827 | 0 | }; |
1828 | |
|
1829 | 0 | task::ErrorCodeRequest2 aErrorCode(OUString(), uno::Reference<XInterface>(), |
1830 | 0 | sal_Int32(sal_uInt32(nError.GetCode())), nError.GetArg1(), nError.GetArg2(), |
1831 | 0 | static_cast<sal_Int16>(nError.GetDialogMask())); |
1832 | 0 | aInteraction <<= aErrorCode; |
1833 | 0 | xHandler->handle(::framework::InteractionRequest::CreateRequest (aInteraction,lContinuations)); |
1834 | 0 | bResult = pAbort->wasSelected(); |
1835 | 0 | } |
1836 | 0 | catch( uno::Exception& ) |
1837 | 0 | {} |
1838 | 0 | } |
1839 | |
|
1840 | 0 | return bResult; |
1841 | 0 | } |
1842 | | |
1843 | | sal_Int16 SfxObjectShell_Impl::getCurrentMacroExecMode() const |
1844 | 0 | { |
1845 | 0 | sal_Int16 nImposedExecMode( MacroExecMode::NEVER_EXECUTE ); |
1846 | |
|
1847 | 0 | const SfxMedium* pMedium( rDocShell.GetMedium() ); |
1848 | 0 | OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getCurrentMacroExecMode: no medium!" ); |
1849 | 0 | if ( pMedium ) |
1850 | 0 | { |
1851 | 0 | const SfxUInt16Item* pMacroModeItem = pMedium->GetItemSet().GetItem(SID_MACROEXECMODE, false); |
1852 | 0 | if ( pMacroModeItem ) |
1853 | 0 | nImposedExecMode = pMacroModeItem->GetValue(); |
1854 | 0 | } |
1855 | 0 | return nImposedExecMode; |
1856 | 0 | } |
1857 | | |
1858 | | void SfxObjectShell_Impl::setCurrentMacroExecMode( sal_uInt16 nMacroMode ) |
1859 | 195k | { |
1860 | 195k | const SfxMedium* pMedium( rDocShell.GetMedium() ); |
1861 | 195k | OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getCurrentMacroExecMode: no medium!" ); |
1862 | 195k | if ( pMedium ) |
1863 | 195k | { |
1864 | 195k | pMedium->GetItemSet().Put( SfxUInt16Item( SID_MACROEXECMODE, nMacroMode ) ); |
1865 | 195k | } |
1866 | 195k | } |
1867 | | |
1868 | | OUString SfxObjectShell_Impl::getDocumentLocation() const |
1869 | 0 | { |
1870 | 0 | OUString sLocation; |
1871 | |
|
1872 | 0 | const SfxMedium* pMedium( rDocShell.GetMedium() ); |
1873 | 0 | OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getDocumentLocation: no medium!" ); |
1874 | 0 | if ( pMedium ) |
1875 | 0 | { |
1876 | 0 | sLocation = pMedium->GetName(); |
1877 | 0 | if ( sLocation.isEmpty() ) |
1878 | 0 | { |
1879 | | // for documents made from a template: get the name of the template |
1880 | 0 | sLocation = rDocShell.getDocProperties()->getTemplateURL(); |
1881 | 0 | } |
1882 | | |
1883 | | // tdf#128006 take document base url as location |
1884 | 0 | if (sLocation.isEmpty()) |
1885 | 0 | sLocation = rDocShell.getDocumentBaseURL(); |
1886 | 0 | } |
1887 | |
|
1888 | 0 | return sLocation; |
1889 | 0 | } |
1890 | | |
1891 | | bool SfxObjectShell_Impl::documentStorageHasMacros() const |
1892 | 4.08k | { |
1893 | 4.08k | return ::sfx2::DocumentMacroMode::storageHasMacros( m_xDocStorage ); |
1894 | 4.08k | } |
1895 | | |
1896 | | bool SfxObjectShell_Impl::macroCallsSeenWhileLoading() const |
1897 | 4.08k | { |
1898 | 4.08k | return rDocShell.GetMacroCallsSeenWhileLoading(); |
1899 | 4.08k | } |
1900 | | |
1901 | | Reference< XEmbeddedScripts > SfxObjectShell_Impl::getEmbeddedDocumentScripts() const |
1902 | 0 | { |
1903 | 0 | return Reference< XEmbeddedScripts >( rDocShell.GetModel(), UNO_QUERY ); |
1904 | 0 | } |
1905 | | |
1906 | | SignatureState SfxObjectShell_Impl::getScriptingSignatureState() |
1907 | 0 | { |
1908 | 0 | SignatureState nSignatureState( rDocShell.GetScriptingSignatureState() ); |
1909 | |
|
1910 | 0 | if ( nSignatureState != SignatureState::NOSIGNATURES && m_bMacroSignBroken ) |
1911 | 0 | { |
1912 | | // if there is a macro signature it must be handled as broken |
1913 | 0 | nSignatureState = SignatureState::BROKEN; |
1914 | 0 | } |
1915 | |
|
1916 | 0 | return nSignatureState; |
1917 | 0 | } |
1918 | | |
1919 | | bool SfxObjectShell_Impl::hasTrustedScriptingSignature( |
1920 | | const css::uno::Reference<css::task::XInteractionHandler>& _rxInteraction) |
1921 | 0 | { |
1922 | 0 | bool bResult = false; |
1923 | |
|
1924 | 0 | try |
1925 | 0 | { |
1926 | 0 | if ( nScriptingSignatureState == SignatureState::UNKNOWN |
1927 | 0 | || nScriptingSignatureState == SignatureState::OK |
1928 | 0 | || nScriptingSignatureState == SignatureState::NOTVALIDATED ) |
1929 | 0 | { |
1930 | 0 | OUString aVersion; |
1931 | 0 | try |
1932 | 0 | { |
1933 | 0 | uno::Reference < beans::XPropertySet > xPropSet( rDocShell.GetStorage(), uno::UNO_QUERY_THROW ); |
1934 | 0 | xPropSet->getPropertyValue(u"Version"_ustr) >>= aVersion; |
1935 | 0 | } |
1936 | 0 | catch( uno::Exception& ) |
1937 | 0 | { |
1938 | 0 | } |
1939 | |
|
1940 | 0 | uno::Reference< security::XDocumentDigitalSignatures > xSigner( security::DocumentDigitalSignatures::createWithVersion(comphelper::getProcessComponentContext(), aVersion) ); |
1941 | |
|
1942 | 0 | uno::Sequence<security::DocumentSignatureInformation> aInfo = rDocShell.GetDocumentSignatureInformation( true, xSigner ); |
1943 | |
|
1944 | 0 | if ( aInfo.hasElements() ) |
1945 | 0 | { |
1946 | 0 | if ( nScriptingSignatureState == SignatureState::UNKNOWN ) |
1947 | 0 | nScriptingSignatureState = DocumentSignatures::getSignatureState(aInfo); |
1948 | |
|
1949 | 0 | if ( nScriptingSignatureState == SignatureState::OK |
1950 | 0 | || nScriptingSignatureState == SignatureState::NOTVALIDATED ) |
1951 | 0 | { |
1952 | 0 | bResult = std::any_of(aInfo.begin(), aInfo.end(), |
1953 | 0 | [&xSigner](const security::DocumentSignatureInformation& rInfo) { |
1954 | 0 | return xSigner->isAuthorTrusted( rInfo.Signer ); }); |
1955 | |
|
1956 | 0 | if (!bResult && _rxInteraction) |
1957 | 0 | { |
1958 | 0 | task::DocumentMacroConfirmationRequest aRequest; |
1959 | 0 | aRequest.DocumentURL = getDocumentLocation(); |
1960 | 0 | aRequest.DocumentStorage = rDocShell.GetMedium()->GetScriptingStorageToSign_Impl(); |
1961 | 0 | aRequest.DocumentSignatureInformation = std::move(aInfo); |
1962 | 0 | aRequest.DocumentVersion = aVersion; |
1963 | 0 | aRequest.Classification = task::InteractionClassification_QUERY; |
1964 | 0 | bResult = SfxMedium::CallApproveHandler( _rxInteraction, uno::Any( aRequest ), true ); |
1965 | 0 | } |
1966 | 0 | } |
1967 | 0 | } |
1968 | 0 | } |
1969 | 0 | } |
1970 | 0 | catch( uno::Exception& ) |
1971 | 0 | {} |
1972 | |
|
1973 | 0 | return bResult; |
1974 | 0 | } |
1975 | | |
1976 | | bool SfxObjectShell::IsContinueImportOnFilterExceptions() |
1977 | 913 | { |
1978 | 913 | if (mbContinueImportOnFilterExceptions == undefined) |
1979 | 895 | { |
1980 | 895 | if (!pMedium) |
1981 | 0 | { |
1982 | 0 | mbContinueImportOnFilterExceptions = no; |
1983 | 0 | return false; |
1984 | 0 | } |
1985 | | |
1986 | 895 | if (!pMedium->GetArgs().getUnpackedValueOrDefault(u"RepairAllowed"_ustr, true)) |
1987 | 0 | { |
1988 | 0 | mbContinueImportOnFilterExceptions = no; |
1989 | 0 | return false; |
1990 | 0 | } |
1991 | | |
1992 | 895 | if (pMedium->IsRepairPackage()) |
1993 | 0 | { |
1994 | 0 | mbContinueImportOnFilterExceptions = yes; |
1995 | 0 | return true; |
1996 | 0 | } |
1997 | | |
1998 | 895 | auto xInteractionHandler = pMedium->GetInteractionHandler(); |
1999 | 895 | if (!xInteractionHandler) |
2000 | 895 | { |
2001 | 895 | mbContinueImportOnFilterExceptions = no; |
2002 | 895 | return false; |
2003 | 895 | } |
2004 | | |
2005 | 0 | const OUString aDocName(pMedium->GetURLObject().getName( |
2006 | 0 | INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset)); |
2007 | 0 | RequestPackageReparation aRequest(aDocName); |
2008 | 0 | xInteractionHandler->handle(aRequest.GetRequest()); |
2009 | 0 | if (aRequest.isApproved()) |
2010 | 0 | { |
2011 | 0 | mbContinueImportOnFilterExceptions = yes; |
2012 | | // lok: we want to overwrite file in jail, so don't use template flag |
2013 | 0 | bool bIsLOK = comphelper::LibreOfficeKit::isActive(); |
2014 | | // allow repair |
2015 | 0 | pMedium->GetItemSet().Put(SfxBoolItem(SID_REPAIRPACKAGE, true)); |
2016 | 0 | pMedium->GetItemSet().Put(SfxBoolItem(SID_TEMPLATE, !bIsLOK)); |
2017 | 0 | pMedium->GetItemSet().Put(SfxStringItem(SID_DOCINFO_TITLE, aDocName)); |
2018 | 0 | } |
2019 | 0 | else |
2020 | 0 | mbContinueImportOnFilterExceptions = no; |
2021 | 0 | } |
2022 | 18 | return mbContinueImportOnFilterExceptions == yes; |
2023 | 913 | } |
2024 | | |
2025 | | bool SfxObjectShell::isEditDocLocked() const |
2026 | 0 | { |
2027 | 0 | Reference<XModel3> xModel = GetModel(); |
2028 | 0 | if (!xModel.is()) |
2029 | 0 | return false; |
2030 | 0 | if (officecfg::Office::Common::Misc::ViewerAppMode::get() |
2031 | 0 | || !officecfg::Office::Common::Misc::AllowEditReadonlyDocs::get()) |
2032 | 0 | return true; |
2033 | 0 | try |
2034 | 0 | { |
2035 | 0 | return comphelper::NamedValueCollection::getOrDefault(xModel->getArgs2( { u"LockEditDoc"_ustr } ), u"LockEditDoc", false); |
2036 | 0 | } |
2037 | 0 | catch (const uno::RuntimeException&) |
2038 | 0 | { |
2039 | 0 | TOOLS_WARN_EXCEPTION("sfx.appl", "unexpected RuntimeException"); |
2040 | 0 | } |
2041 | 0 | return false; |
2042 | 0 | } |
2043 | | |
2044 | | bool SfxObjectShell::isContentExtractionLocked() const |
2045 | 0 | { |
2046 | 0 | Reference<XModel3> xModel = GetModel(); |
2047 | 0 | if (!xModel.is()) |
2048 | 0 | return false; |
2049 | 0 | try |
2050 | 0 | { |
2051 | 0 | return comphelper::NamedValueCollection::getOrDefault(xModel->getArgs2( { u"LockContentExtraction"_ustr } ), u"LockContentExtraction", false); |
2052 | 0 | } |
2053 | 0 | catch (const uno::RuntimeException&) |
2054 | 0 | { |
2055 | 0 | TOOLS_WARN_EXCEPTION("sfx.appl", "unexpected RuntimeException"); |
2056 | 0 | } |
2057 | 0 | return false; |
2058 | 0 | } |
2059 | | |
2060 | | bool SfxObjectShell::isExportLocked() const |
2061 | 0 | { |
2062 | 0 | Reference<XModel3> xModel = GetModel(); |
2063 | 0 | if (!xModel.is()) |
2064 | 0 | return false; |
2065 | 0 | try |
2066 | 0 | { |
2067 | 0 | return comphelper::NamedValueCollection::getOrDefault(xModel->getArgs2( { u"LockExport"_ustr } ), u"LockExport", false); |
2068 | 0 | } |
2069 | 0 | catch (const uno::RuntimeException&) |
2070 | 0 | { |
2071 | 0 | TOOLS_WARN_EXCEPTION("sfx.appl", "unexpected RuntimeException"); |
2072 | 0 | } |
2073 | 0 | return false; |
2074 | 0 | } |
2075 | | |
2076 | | bool SfxObjectShell::isPrintLocked() const |
2077 | 0 | { |
2078 | 0 | Reference<XModel3> xModel = GetModel(); |
2079 | 0 | if (!xModel.is()) |
2080 | 0 | return false; |
2081 | 0 | return comphelper::NamedValueCollection::getOrDefault(xModel->getArgs2( { u"LockPrint"_ustr } ), u"LockPrint", false); |
2082 | 0 | } |
2083 | | |
2084 | | bool SfxObjectShell::isSaveLocked() const |
2085 | 0 | { |
2086 | 0 | Reference<XModel3> xModel = GetModel(); |
2087 | 0 | if (!xModel.is()) |
2088 | 0 | return false; |
2089 | 0 | return comphelper::NamedValueCollection::getOrDefault(xModel->getArgs2( { u"LockSave"_ustr } ), u"LockSave", false); |
2090 | 0 | } |
2091 | | |
2092 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |