Bug Summary

File:home/maarten/src/libreoffice/core/sw/source/uibase/app/docsh.cxx
Warning:line 629, column 9
Potential leak of memory pointed to by 'xStg.pObj'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name docsh.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SW_DLLIMPLEMENTATION -D SWUI_DLL_NAME="libswuilo.so" -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sw/source/core/inc -I /home/maarten/src/libreoffice/core/sw/source/filter/inc -I /home/maarten/src/libreoffice/core/sw/source/uibase/inc -I /home/maarten/src/libreoffice/core/sw/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sw/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/sw/generated -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/oovbaapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sw/source/uibase/app/docsh.cxx
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <config_features.h>
21
22#include <officecfg/Office/Common.hxx>
23#include <vcl/weld.hxx>
24#include <vcl/svapp.hxx>
25#include <vcl/syswin.hxx>
26#include <vcl/jobset.hxx>
27#include <svl/whiter.hxx>
28#include <svl/zforlist.hxx>
29#include <svl/eitem.hxx>
30#include <svl/stritem.hxx>
31#include <svl/PasswordHelper.hxx>
32#include <unotools/moduleoptions.hxx>
33#include <sfx2/bindings.hxx>
34#include <sfx2/docfile.hxx>
35#include <sfx2/docfilt.hxx>
36#include <sfx2/notebookbar/SfxNotebookBar.hxx>
37#include <sfx2/printer.hxx>
38#include <sfx2/linkmgr.hxx>
39#include <editeng/flstitem.hxx>
40#include <comphelper/lok.hxx>
41#include <comphelper/classids.hxx>
42#include <basic/sbmod.hxx>
43#include <node.hxx>
44#include <swwait.hxx>
45#include <printdata.hxx>
46#include <view.hxx>
47#include <edtwin.hxx>
48#include <PostItMgr.hxx>
49#include <wrtsh.hxx>
50#include <docsh.hxx>
51#include <viewopt.hxx>
52#include <wdocsh.hxx>
53#include <swmodule.hxx>
54#include <globdoc.hxx>
55#include <usrpref.hxx>
56#include <shellio.hxx>
57#include <docstyle.hxx>
58#include <doc.hxx>
59#include <docfunc.hxx>
60#include <IDocumentUndoRedo.hxx>
61#include <IDocumentSettingAccess.hxx>
62#include <IDocumentLinksAdministration.hxx>
63#include <IDocumentDeviceAccess.hxx>
64#include <IDocumentDrawModelAccess.hxx>
65#include <IDocumentRedlineAccess.hxx>
66#include <IDocumentStatistics.hxx>
67#include <IDocumentState.hxx>
68#include <pview.hxx>
69#include <srcview.hxx>
70#include <ndindex.hxx>
71#include <ndole.hxx>
72#include <txtftn.hxx>
73#include <ftnidx.hxx>
74#include <fldbas.hxx>
75#include <docary.hxx>
76#include <swerror.h>
77#include <cmdid.h>
78#include <strings.hrc>
79
80#include <unotools/fltrcfg.hxx>
81#include <svtools/htmlcfg.hxx>
82#include <sfx2/viewfrm.hxx>
83#include <sfx2/objface.hxx>
84
85#define ShellClass_SwDocShell
86#include <sfx2/msg.hxx>
87#include <swslots.hxx>
88#include <com/sun/star/document/UpdateDocMode.hpp>
89
90#include <com/sun/star/script/XLibraryContainer.hpp>
91#include <com/sun/star/document/XDocumentProperties.hpp>
92#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
93#include <com/sun/star/sdb/DatabaseContext.hpp>
94#include <com/sun/star/sdb/XDocumentDataSource.hpp>
95#include <com/sun/star/uri/UriReferenceFactory.hpp>
96#include <com/sun/star/uri/VndSunStarPkgUrlReferenceFactory.hpp>
97#include <com/sun/star/frame/XStorable.hpp>
98#include <ooo/vba/XSinkCaller.hpp>
99
100#include <unotextrange.hxx>
101
102#include <dbmgr.hxx>
103#include <iodetect.hxx>
104
105#include <comphelper/processfactory.hxx>
106
107using namespace ::com::sun::star;
108using namespace ::com::sun::star::uno;
109using namespace ::com::sun::star::script;
110using namespace ::com::sun::star::container;
111
112SFX_IMPL_SUPERCLASS_INTERFACE(SwDocShell, SfxObjectShell)SfxInterface* SwDocShell::pInterface = nullptr; SfxInterface*
SwDocShell::GetStaticInterface() { if ( !pInterface ) { pInterface
= new SfxInterface( "SwDocShell", true, GetInterfaceId(), SfxObjectShell
::GetStaticInterface(), aSwDocShellSlots_Impl[0], sal_uInt16(
sizeof(aSwDocShellSlots_Impl) / sizeof(SfxSlot) ) ); InitInterface_Impl
(); } return pInterface; } SfxInterface* SwDocShell::GetInterface
() const { return GetStaticInterface(); } void SwDocShell::RegisterInterface
(const SfxModule* pMod) { GetStaticInterface()->Register(pMod
); }
113
114void SwDocShell::InitInterface_Impl()
115{
116}
117
118
119SFX_IMPL_OBJECTFACTORY(SwDocShell, SvGlobalName(SO3_SW_CLASSID), "swriter" )SfxObjectFactory& SwDocShell::Factory() { static SfxObjectFactory
aObjectFactory(SvGlobalName(0x8BC6B165, 0xB1B2, 0x4EDD, 0xAA
, 0x47, 0xDA, 0xE2, 0xEE, 0x68, 0x9D, 0xD6), "swriter"); return
aObjectFactory; }
120
121bool SwDocShell::InsertGeneratedStream(SfxMedium & rMedium,
122 uno::Reference<text::XTextRange> const& xInsertPosition)
123{
124 SwUnoInternalPaM aPam(*GetDoc()); // must have doc since called from SwView
125 if (!::sw::XTextRangeToSwPaM(aPam, xInsertPosition))
126 return false;
127 // similar to SwView::InsertMedium
128 SwReaderPtr pReader;
129 Reader *const pRead = StartConvertFrom(rMedium, pReader, nullptr, &aPam);
130 if (!pRead)
131 return false;
132 ErrCode const nError = pReader->Read(*pRead);
133 return ERRCODE_NONEErrCode(0) == nError;
134}
135
136// Prepare loading
137Reader* SwDocShell::StartConvertFrom(SfxMedium& rMedium, SwReaderPtr& rpRdr,
138 SwCursorShell const *pCursorShell,
139 SwPaM* pPaM )
140{
141 bool bAPICall = false;
142 const SfxPoolItem* pApiItem;
143 const SfxItemSet* pMedSet;
144 if( nullptr != ( pMedSet = rMedium.GetItemSet() ) && SfxItemState::SET ==
145 pMedSet->GetItemState( FN_API_CALL((20000 + 2200) + 60), true, &pApiItem ) )
146 bAPICall = static_cast<const SfxBoolItem*>(pApiItem)->GetValue();
147
148 std::shared_ptr<const SfxFilter> pFlt = rMedium.GetFilter();
149 if( !pFlt )
150 {
151 if(!bAPICall)
152 {
153 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(nullptr,
154 VclMessageType::Info, VclButtonsType::Ok,
155 SwResId(STR_CANTOPENreinterpret_cast<char const *>("STR_CANTOPEN" "\004" u8"Cannot open document."
)
)));
156 xInfoBox->run();
157 }
158 return nullptr;
159 }
160 OUString aFileName( rMedium.GetName() );
161 Reader* pRead = SwReaderWriter::GetReader( pFlt->GetUserData() );
162 if( !pRead )
163 return nullptr;
164
165 if( rMedium.IsStorage()
166 ? SwReaderType::Storage & pRead->GetReaderType()
167 : SwReaderType::Stream & pRead->GetReaderType() )
168 {
169 if (pPaM)
170 rpRdr.reset(new SwReader( rMedium, aFileName, *pPaM ));
171 else if (pCursorShell)
172 rpRdr.reset(new SwReader( rMedium, aFileName, *pCursorShell->GetCursor() ));
173 else
174 rpRdr.reset(new SwReader( rMedium, aFileName, m_xDoc.get() ));
175 }
176 else
177 return nullptr;
178
179 // #i30171# set the UpdateDocMode at the SwDocShell
180 const SfxUInt16Item* pUpdateDocItem = SfxItemSet::GetItem<SfxUInt16Item>(rMedium.GetItemSet(), SID_UPDATEDOCMODE(5000 + 1668), false);
181 m_nUpdateDocMode = pUpdateDocItem ? pUpdateDocItem->GetValue() : document::UpdateDocMode::NO_UPDATE;
182
183 if (!pFlt->GetDefaultTemplate().isEmpty())
184 pRead->SetTemplateName( pFlt->GetDefaultTemplate() );
185
186 if( pRead == ReadAscii && nullptr != rMedium.GetInStream() &&
187 pFlt->GetUserData() == FILTER_TEXT_DLG"TEXT_DLG" )
188 {
189 SwAsciiOptions aOpt;
190 const SfxItemSet* pSet;
191 const SfxPoolItem* pItem;
192 if( nullptr != ( pSet = rMedium.GetItemSet() ) && SfxItemState::SET ==
193 pSet->GetItemState( SID_FILE_FILTEROPTIONS(5000 + 527), true, &pItem ) )
194 aOpt.ReadUserData( static_cast<const SfxStringItem*>(pItem)->GetValue() );
195
196 pRead->GetReaderOpt().SetASCIIOpts( aOpt );
197 }
198
199 return pRead;
200}
201
202// Loading
203bool SwDocShell::ConvertFrom( SfxMedium& rMedium )
204{
205 SwReaderPtr pRdr;
206 Reader* pRead = StartConvertFrom(rMedium, pRdr);
207 if (!pRead)
208 return false; // #129881# return if no reader is found
209 tools::SvRef<SotStorage> pStg=pRead->getSotStorageRef(); // #i45333# save sot storage ref in case of recursive calls
210
211 m_xDoc->setDocAccTitle(OUString());
212 if (const auto pFrame1 = SfxViewFrame::GetFirst(this))
213 {
214 if (auto pSysWin = pFrame1->GetWindow().GetSystemWindow())
215 {
216 pSysWin->SetAccessibleName(OUString());
217 }
218 }
219 SwWait aWait( *this, true );
220
221 // Suppress SfxProgress, when we are Embedded
222 SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule
::Writer)))
->SetEmbeddedLoadSave(
223 SfxObjectCreateMode::EMBEDDED == GetCreateMode() );
224
225 pRdr->GetDoc().getIDocumentSettingAccess().set(DocumentSettingId::HTML_MODE, dynamic_cast< const SwWebDocShell *>( this ) != nullptr);
226
227 // Restore the pool default if reading a saved document.
228 m_xDoc->RemoveAllFormatLanguageDependencies();
229
230 ErrCode nErr = pRdr->Read( *pRead );
231
232 // Maybe put away one old Doc
233 if (m_xDoc.get() != &pRdr->GetDoc())
234 {
235 RemoveLink();
236 m_xDoc = &pRdr->GetDoc();
237
238 AddLink();
239
240 if (!m_xBasePool.is())
241 m_xBasePool = new SwDocStyleSheetPool( *m_xDoc, SfxObjectCreateMode::ORGANIZER == GetCreateMode() );
242 }
243
244 UpdateFontList();
245 InitDrawModelAndDocShell(this, m_xDoc ? m_xDoc->getIDocumentDrawModelAccess().GetDrawModel() : nullptr);
246
247 pRdr.reset();
248
249 SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule
::Writer)))
->SetEmbeddedLoadSave( false );
250
251 SetError(nErr);
252 bool bOk = !nErr.IsError();
253
254 if (bOk && !m_xDoc->IsInLoadAsynchron())
255 {
256 LoadingFinished();
257 }
258
259 pRead->setSotStorageRef(pStg); // #i45333# save sot storage ref in case of recursive calls
260
261 return bOk;
262}
263
264// Saving the Default-Format, Stg present
265bool SwDocShell::Save()
266{
267 //#i3370# remove quick help to prevent saving of autocorrection suggestions
268 if (m_pView)
269 m_pView->GetEditWin().StopQuickHelp();
270 SwWait aWait( *this, true );
271
272 CalcLayoutForOLEObjects(); // format for OLE objects
273 // #i62875#
274 // reset compatibility flag <DoNotCaptureDrawObjsOnPage>, if possible
275 if (m_pWrtShell && m_xDoc &&
276 m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE) &&
277 docfunc::AllDrawObjsOnPage(*m_xDoc))
278 {
279 m_xDoc->getIDocumentSettingAccess().set(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE, false);
280 }
281
282 ErrCode nErr = ERR_SWG_WRITE_ERRORErrCode(ErrCodeArea::Sw, ErrCodeClass::Write, 30 ), nVBWarning = ERRCODE_NONEErrCode(0);
283 if( SfxObjectShell::Save() )
284 {
285 switch( GetCreateMode() )
286 {
287 case SfxObjectCreateMode::INTERNAL:
288 nErr = ERRCODE_NONEErrCode(0);
289 break;
290
291 case SfxObjectCreateMode::ORGANIZER:
292 {
293 WriterRef xWrt;
294 ::GetXMLWriter(OUString(), GetMedium()->GetBaseURL(true), xWrt);
295 xWrt->SetOrganizerMode( true );
296 SwWriter aWrt( *GetMedium(), *m_xDoc );
297 nErr = aWrt.Write( xWrt );
298 xWrt->SetOrganizerMode( false );
299 }
300 break;
301
302 case SfxObjectCreateMode::EMBEDDED:
303 // Suppress SfxProgress, if we are Embedded
304 SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule
::Writer)))
->SetEmbeddedLoadSave( true );
305 [[fallthrough]];
306
307 case SfxObjectCreateMode::STANDARD:
308 default:
309 {
310 if (m_xDoc->ContainsMSVBasic())
311 {
312 if( SvtFilterOptions::Get().IsLoadWordBasicStorage() )
313 nVBWarning = GetSaveWarningOfMSVBAStorage( static_cast<SfxObjectShell&>(*this) );
314 m_xDoc->SetContainsMSVBasic( false );
315 }
316
317 // End TableBox Edit!
318 if (m_pWrtShell)
319 m_pWrtShell->EndAllTableBoxEdit();
320
321 WriterRef xWrt;
322 ::GetXMLWriter(OUString(), GetMedium()->GetBaseURL(true), xWrt);
323
324 bool bLockedView(false);
325 if (m_pWrtShell)
326 {
327 bLockedView = m_pWrtShell->IsViewLocked();
328 m_pWrtShell->LockView( true ); //lock visible section
329 }
330
331 SwWriter aWrt( *GetMedium(), *m_xDoc );
332 nErr = aWrt.Write( xWrt );
333
334 if (m_pWrtShell)
335 m_pWrtShell->LockView( bLockedView );
336 }
337 break;
338 }
339 SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule
::Writer)))
->SetEmbeddedLoadSave( false );
340 }
341 SetError(nErr ? nErr : nVBWarning);
342
343 SfxViewFrame *const pFrame =
344 m_pWrtShell ? m_pWrtShell->GetView().GetViewFrame() : nullptr;
345 if( pFrame )
346 {
347 pFrame->GetBindings().SetState(SfxBoolItem(SID_DOC_MODIFIED(5000 + 584), false));
348 }
349 return !nErr.IsError();
350}
351
352SwDocShell::LockAllViewsGuard_Impl::LockAllViewsGuard_Impl(SwViewShell* pViewShell)
353{
354 if (!pViewShell)
355 return;
356 for (SwViewShell& rShell : pViewShell->GetRingContainer())
357 {
358 if (!rShell.IsViewLocked())
359 {
360 m_aViewWasUnLocked.push_back(&rShell);
361 rShell.LockView(true);
362 }
363 }
364}
365
366SwDocShell::LockAllViewsGuard_Impl::~LockAllViewsGuard_Impl()
367{
368 for (SwViewShell* pShell : m_aViewWasUnLocked)
369 pShell->LockView(false);
370}
371
372std::unique_ptr<SfxObjectShell::LockAllViewsGuard> SwDocShell::LockAllViews()
373{
374 return std::make_unique<LockAllViewsGuard_Impl>(GetEditShell());
375}
376
377// Save using the Defaultformat
378bool SwDocShell::SaveAs( SfxMedium& rMedium )
379{
380 SwWait aWait( *this, true );
381 //#i3370# remove quick help to prevent saving of autocorrection suggestions
382 if (m_pView)
383 m_pView->GetEditWin().StopQuickHelp();
384
385 //#i91811# mod if we have an active margin window, write back the text
386 if (m_pView &&
387 m_pView->GetPostItMgr() &&
388 m_pView->GetPostItMgr()->HasActiveSidebarWin())
389 {
390 m_pView->GetPostItMgr()->UpdateDataOnActiveSidebarWin();
391 }
392
393 if (m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT) &&
394 !m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT_SAVE_LINKS))
395 RemoveOLEObjects();
396
397 if (GetMedium())
398 {
399 // Task 75666 - is the Document imported by our Microsoft-Filters?
400 std::shared_ptr<const SfxFilter> pOldFilter = GetMedium()->GetFilter();
401 if( pOldFilter &&
402 ( pOldFilter->GetUserData() == FILTER_WW8"CWW8" ||
403 pOldFilter->GetUserData() == "CWW6" ||
404 pOldFilter->GetUserData() == "WW6" ) )
405 {
406 // when saving it in our own fileformat, then remove the template
407 // name from the docinfo.
408 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
409 GetModel(), uno::UNO_QUERY_THROW);
410 uno::Reference<document::XDocumentProperties> xDocProps
411 = xDPS->getDocumentProperties();
412 xDocProps->setTemplateName(OUString());
413 xDocProps->setTemplateURL(OUString());
414 xDocProps->setTemplateDate(::util::DateTime());
415 }
416 }
417
418 CalcLayoutForOLEObjects(); // format for OLE objects
419
420 const bool bURLChanged = GetMedium() && GetMedium()->GetURLObject() != rMedium.GetURLObject();
421 const SwDBManager* const pMgr = m_xDoc->GetDBManager();
422 const bool bHasEmbedded = pMgr && !pMgr->getEmbeddedName().isEmpty();
423 bool bSaveDS = bHasEmbedded && bURLChanged;
424 if (bSaveDS)
425 {
426 // Don't save data source in case a temporary is being saved for preview in MM wizard
427 if (const SfxBoolItem* pNoEmbDS
428 = SfxItemSet::GetItem(rMedium.GetItemSet(), SID_NO_EMBEDDED_DSTypedWhichId<SfxBoolItem>(5000 + 1731), false))
429 bSaveDS = !pNoEmbDS->GetValue();
430 }
431 if (bSaveDS)
432 {
433 // We have an embedded data source definition, need to re-store it,
434 // otherwise relative references will break when the new file is in a
435 // different directory.
436
437 OUString aURL(GetMedium()->GetURLObject().GetMainURL(INetURLObject::DecodeMechanism::NONE));
438 if (aURL.isEmpty())
439 {
440 // No old URL - is this a new document created from a template with embedded DS?
441 // Try to get the template URL to reconstruct the embedded data source URL
442 const css::beans::PropertyValues& rArgs = GetMedium()->GetArgs();
443 const auto aURLIter = std::find_if(rArgs.begin(), rArgs.end(),
444 [](const auto& v) { return v.Name == "URL"; });
445 if (aURLIter != rArgs.end())
446 aURLIter->Value >>= aURL;
447 }
448
449 if (!aURL.isEmpty())
450 {
451 auto xContext(comphelper::getProcessComponentContext());
452 auto xUri = css::uri::UriReferenceFactory::create(xContext)->parse(aURL);
453 assert(xUri.is())(static_cast <bool> (xUri.is()) ? void (0) : __assert_fail
("xUri.is()", "/home/maarten/src/libreoffice/core/sw/source/uibase/app/docsh.cxx"
, 453, __extension__ __PRETTY_FUNCTION__))
;
454 xUri = css::uri::VndSunStarPkgUrlReferenceFactory::create(xContext)
455 ->createVndSunStarPkgUrlReference(xUri);
456 assert(xUri.is())(static_cast <bool> (xUri.is()) ? void (0) : __assert_fail
("xUri.is()", "/home/maarten/src/libreoffice/core/sw/source/uibase/app/docsh.cxx"
, 456, __extension__ __PRETTY_FUNCTION__))
;
457 aURL = xUri->getUriReference() + "/"
458 + INetURLObject::encode(pMgr->getEmbeddedName(), INetURLObject::PART_FPATH,
459 INetURLObject::EncodeMechanism::All);
460
461 bool bCopyTo = GetCreateMode() == SfxObjectCreateMode::EMBEDDED;
462 if (!bCopyTo)
463 {
464 if (const SfxBoolItem* pSaveToItem
465 = SfxItemSet::GetItem(rMedium.GetItemSet(), SID_SAVETOTypedWhichId<SfxBoolItem>(5000 + 1546), false))
466 bCopyTo = pSaveToItem->GetValue();
467 }
468
469 auto xDatabaseContext = sdb::DatabaseContext::create(xContext);
470 uno::Reference<sdb::XDocumentDataSource> xDataSource(xDatabaseContext->getByName(aURL),
471 uno::UNO_QUERY);
472 if (xDataSource)
473 {
474 uno::Reference<frame::XStorable> xStorable(xDataSource->getDatabaseDocument(),
475 uno::UNO_QUERY);
476 SwDBManager::StoreEmbeddedDataSource(xStorable, rMedium.GetOutputStorage(),
477 pMgr->getEmbeddedName(), rMedium.GetName(),
478 bCopyTo);
479 }
480 }
481 }
482
483 // #i62875#
484 // reset compatibility flag <DoNotCaptureDrawObjsOnPage>, if possible
485 if (m_pWrtShell &&
486 m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE) &&
487 docfunc::AllDrawObjsOnPage(*m_xDoc))
488 {
489 m_xDoc->getIDocumentSettingAccess().set(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE, false);
490 }
491
492 ErrCode nErr = ERR_SWG_WRITE_ERRORErrCode(ErrCodeArea::Sw, ErrCodeClass::Write, 30 ), nVBWarning = ERRCODE_NONEErrCode(0);
493 uno::Reference < embed::XStorage > xStor = rMedium.GetOutputStorage();
494 if( SfxObjectShell::SaveAs( rMedium ) )
495 {
496 if( GetDoc()->getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT) && dynamic_cast< const SwGlobalDocShell *>( this ) == nullptr )
497 {
498 // The document is closed explicitly, but using SfxObjectShellLock is still more correct here
499 SfxObjectShellLock xDocSh =
500 new SwGlobalDocShell( SfxObjectCreateMode::INTERNAL );
501 // the global document can not be a template
502 xDocSh->SetupStorage( xStor, SotStorage::GetVersion( xStor ), false );
503 xDocSh->DoClose();
504 }
505
506 if (m_xDoc->ContainsMSVBasic())
507 {
508 if( SvtFilterOptions::Get().IsLoadWordBasicStorage() )
509 nVBWarning = GetSaveWarningOfMSVBAStorage( static_cast<SfxObjectShell&>(*this) );
510 m_xDoc->SetContainsMSVBasic( false );
511 }
512
513 if (m_pWrtShell)
514 {
515 // End TableBox Edit!
516 m_pWrtShell->EndAllTableBoxEdit();
517
518 // Remove invalid signatures.
519 m_pWrtShell->ValidateAllParagraphSignatures(false);
520
521 m_pWrtShell->ClassifyDocPerHighestParagraphClass();
522 }
523
524 // Remember and preserve Modified-Flag without calling the Link
525 // (for OLE; after Statement from MM)
526 const bool bIsModified = m_xDoc->getIDocumentState().IsModified();
527 m_xDoc->GetIDocumentUndoRedo().LockUndoNoModifiedPosition();
528 Link<bool,void> aOldOLELnk( m_xDoc->GetOle2Link() );
529 m_xDoc->SetOle2Link( Link<bool,void>() );
530
531 // Suppress SfxProgress when we are Embedded
532 SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule
::Writer)))
->SetEmbeddedLoadSave(
533 SfxObjectCreateMode::EMBEDDED == GetCreateMode() );
534
535 WriterRef xWrt;
536 ::GetXMLWriter(OUString(), rMedium.GetBaseURL(true), xWrt);
537
538 bool bLockedView(false);
539 if (m_pWrtShell)
540 {
541 bLockedView = m_pWrtShell->IsViewLocked();
542 m_pWrtShell->LockView( true ); //lock visible section
543 }
544
545 SwWriter aWrt( rMedium, *m_xDoc );
546 nErr = aWrt.Write( xWrt );
547
548 if (m_pWrtShell)
549 m_pWrtShell->LockView( bLockedView );
550
551 if( bIsModified )
552 {
553 m_xDoc->getIDocumentState().SetModified();
554 m_xDoc->GetIDocumentUndoRedo().UnLockUndoNoModifiedPosition();
555 }
556 m_xDoc->SetOle2Link( aOldOLELnk );
557
558 SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule
::Writer)))
->SetEmbeddedLoadSave( false );
559
560 // Increase RSID
561 m_xDoc->setRsid( m_xDoc->getRsid() );
562
563 m_xDoc->cleanupUnoCursorTable();
564 }
565 SetError(nErr ? nErr : nVBWarning);
566
567 return !nErr.IsError();
568}
569
570// Save all Formats
571static SwSrcView* lcl_GetSourceView( SwDocShell const * pSh )
572{
573 // are we in SourceView?
574 SfxViewFrame* pVFrame = SfxViewFrame::GetFirst( pSh );
575 SfxViewShell* pViewShell = pVFrame ? pVFrame->GetViewShell() : nullptr;
576 return dynamic_cast<SwSrcView*>( pViewShell );
577}
578
579bool SwDocShell::ConvertTo( SfxMedium& rMedium )
580{
581 std::shared_ptr<const SfxFilter> pFlt = rMedium.GetFilter();
582 if( !pFlt )
1
Taking false branch
583 return false;
584
585 WriterRef xWriter;
586 SwReaderWriter::GetWriter( pFlt->GetUserData(), rMedium.GetBaseURL( true ), xWriter );
587 if( !xWriter.is() )
2
Taking false branch
588 { // Filter not available
589 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(nullptr,
590 VclMessageType::Info, VclButtonsType::Ok,
591 SwResId(STR_DLLNOTFOUNDreinterpret_cast<char const *>("STR_DLLNOTFOUND" "\004"
u8"Filter not found.")
)));
592 xInfoBox->run();
593 return false;
594 }
595
596 //#i3370# remove quick help to prevent saving of autocorrection suggestions
597 if (m_pView)
3
Assuming field 'm_pView' is null
4
Taking false branch
598 m_pView->GetEditWin().StopQuickHelp();
599
600 //#i91811# mod if we have an active margin window, write back the text
601 if (m_pView
4.1
Field 'm_pView' is null
&&
602 m_pView->GetPostItMgr() &&
603 m_pView->GetPostItMgr()->HasActiveSidebarWin())
604 {
605 m_pView->GetPostItMgr()->UpdateDataOnActiveSidebarWin();
606 }
607
608 ErrCode nVBWarning = ERRCODE_NONEErrCode(0);
609
610 if (m_xDoc->ContainsMSVBasic())
5
Assuming the condition is true
6
Taking true branch
611 {
612 bool bSave = pFlt->GetUserData() == "CWW8"
7
Assuming the condition is true
613 && SvtFilterOptions::Get().IsLoadWordBasicStorage();
614
615 if ( bSave )
8
Assuming 'bSave' is true
9
Taking true branch
616 {
617 tools::SvRef<SotStorage> xStg = new SotStorage( rMedium.GetOutStream(), false );
10
Memory is allocated
618 OSL_ENSURE( !xStg->GetError(), "No storage available for storing VBA macros!" )do { if (true && (!(!xStg->GetError()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/app/docsh.cxx"
":" "618" ": "), "%s", "No storage available for storing VBA macros!"
); } } while (false)
;
11
Taking true branch
12
Loop condition is false. Exiting loop
619 if ( !xStg->GetError() )
13
Taking false branch
620 {
621 nVBWarning = SaveOrDelMSVBAStorage( static_cast<SfxObjectShell&>(*this), *xStg, bSave, "Macros" );
622 xStg->Commit();
623 m_xDoc->SetContainsMSVBasic( true );
624 }
625 }
626 }
627
628 // End TableBox Edit!
629 if (m_pWrtShell)
14
Potential leak of memory pointed to by 'xStg.pObj'
630 m_pWrtShell->EndAllTableBoxEdit();
631
632 if( pFlt->GetUserData() == "HTML" )
633 {
634#if HAVE_FEATURE_SCRIPTING1
635 SvxHtmlOptions& rHtmlOpt = SvxHtmlOptions::Get();
636 if( !rHtmlOpt.IsStarBasic() && rHtmlOpt.IsStarBasicWarning() && HasBasic() )
637 {
638 uno::Reference< XLibraryContainer > xLibCont = GetBasicContainer();
639 uno::Reference< XNameAccess > xLib;
640 const Sequence<OUString> aNames = xLibCont->getElementNames();
641 for(const OUString& rName : aNames)
642 {
643 Any aLib = xLibCont->getByName(rName);
644 aLib >>= xLib;
645 if(xLib.is())
646 {
647 Sequence<OUString> aModNames = xLib->getElementNames();
648 if(aModNames.hasElements())
649 {
650 SetError(WARN_SWG_HTML_NO_MACROSErrCode(WarningFlag::Yes, ErrCodeArea::Sw, ErrCodeClass::Write
, 75)
);
651 break;
652 }
653 }
654 }
655 }
656#endif
657 }
658
659 // #i76360# Update document statistics
660 if ( !rMedium.IsSkipImages() )
661 m_xDoc->getIDocumentStatistics().UpdateDocStat( false, true );
662
663 CalcLayoutForOLEObjects(); // format for OLE objects
664 // #i62875#
665 // reset compatibility flag <DoNotCaptureDrawObjsOnPage>, if possible
666 if (m_pWrtShell &&
667 m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE) &&
668 docfunc::AllDrawObjsOnPage(*m_xDoc))
669 {
670 m_xDoc->getIDocumentSettingAccess().set(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE, false);
671 }
672
673 if( xWriter->IsStgWriter() &&
674 ( pFlt->GetUserData() == FILTER_XML"CXML" ||
675 pFlt->GetUserData() == FILTER_XMLV"CXMLV" ||
676 pFlt->GetUserData() == FILTER_XMLVW"CXMLVWEB" ) )
677 {
678 // determine the own Type
679 sal_uInt8 nMyType = 0;
680 if( dynamic_cast< const SwWebDocShell *>( this ) != nullptr )
681 nMyType = 1;
682 else if( dynamic_cast< const SwGlobalDocShell *>( this ) != nullptr )
683 nMyType = 2;
684
685 // determine the desired Type
686 sal_uInt8 nSaveType = 0;
687 SotClipboardFormatId nSaveClipId = pFlt->GetFormat();
688 if( SotClipboardFormatId::STARWRITERWEB_8 == nSaveClipId ||
689 SotClipboardFormatId::STARWRITERWEB_60 == nSaveClipId ||
690 SotClipboardFormatId::STARWRITERWEB_50 == nSaveClipId ||
691 SotClipboardFormatId::STARWRITERWEB_40 == nSaveClipId )
692 nSaveType = 1;
693 else if( SotClipboardFormatId::STARWRITERGLOB_8 == nSaveClipId ||
694 SotClipboardFormatId::STARWRITERGLOB_8_TEMPLATE == nSaveClipId ||
695 SotClipboardFormatId::STARWRITERGLOB_60 == nSaveClipId ||
696 SotClipboardFormatId::STARWRITERGLOB_50 == nSaveClipId ||
697 SotClipboardFormatId::STARWRITERGLOB_40 == nSaveClipId )
698 nSaveType = 2;
699
700 // Change Flags of the Document accordingly
701 bool bIsHTMLModeSave = GetDoc()->getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE);
702 bool bIsGlobalDocSave = GetDoc()->getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT);
703 bool bIsGlblDocSaveLinksSave = GetDoc()->getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT_SAVE_LINKS);
704 if( nMyType != nSaveType )
705 {
706 GetDoc()->getIDocumentSettingAccess().set(DocumentSettingId::HTML_MODE, 1 == nSaveType);
707 GetDoc()->getIDocumentSettingAccess().set(DocumentSettingId::GLOBAL_DOCUMENT, 2 == nSaveType);
708 if( 2 != nSaveType )
709 GetDoc()->getIDocumentSettingAccess().set(DocumentSettingId::GLOBAL_DOCUMENT_SAVE_LINKS, false);
710 }
711
712 // if the target format is storage based, then the output storage must be already created
713 if ( rMedium.IsStorage() )
714 {
715 // set MediaType on target storage
716 // (MediaType will be queried during SaveAs)
717 try
718 {
719 // TODO/MBA: testing
720 uno::Reference < beans::XPropertySet > xSet( rMedium.GetStorage(), uno::UNO_QUERY );
721 if ( xSet.is() )
722 xSet->setPropertyValue("MediaType", uno::makeAny( SotExchange::GetFormatMimeType( nSaveClipId ) ) );
723 }
724 catch (const uno::Exception&)
725 {
726 }
727 }
728
729 // Now normally save the Document
730 bool bRet = SaveAs( rMedium );
731
732 if( nMyType != nSaveType )
733 {
734 GetDoc()->getIDocumentSettingAccess().set(DocumentSettingId::HTML_MODE, bIsHTMLModeSave );
735 GetDoc()->getIDocumentSettingAccess().set(DocumentSettingId::GLOBAL_DOCUMENT, bIsGlobalDocSave);
736 GetDoc()->getIDocumentSettingAccess().set(DocumentSettingId::GLOBAL_DOCUMENT_SAVE_LINKS, bIsGlblDocSaveLinksSave);
737 }
738
739 return bRet;
740 }
741
742 if( pFlt->GetUserData() == FILTER_TEXT_DLG"TEXT_DLG" &&
743 (m_pWrtShell || !::lcl_GetSourceView(this)))
744 {
745 SwAsciiOptions aOpt;
746 OUString sItemOpt;
747 const SfxItemSet* pSet = rMedium.GetItemSet();
748 if( nullptr != pSet )
749 {
750 const SfxPoolItem* pItem;
751 if( SfxItemState::SET == pSet->GetItemState( SID_FILE_FILTEROPTIONS(5000 + 527),
752 true, &pItem ) )
753 sItemOpt = static_cast<const SfxStringItem*>(pItem)->GetValue();
754 }
755 if(!sItemOpt.isEmpty())
756 aOpt.ReadUserData( sItemOpt );
757
758 xWriter->SetAsciiOptions( aOpt );
759 }
760
761 // Suppress SfxProgress when we are Embedded
762 SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule
::Writer)))
->SetEmbeddedLoadSave(
763 SfxObjectCreateMode::EMBEDDED == GetCreateMode());
764
765 // Span Context in order to suppress the Selection's View
766 ErrCode nErrno;
767 const OUString aFileName( rMedium.GetName() );
768
769 // No View, so the whole Document!
770 if (m_pWrtShell && !Application::IsHeadlessModeEnabled())
771 {
772 SwWait aWait( *this, true );
773 // #i106906#
774 const bool bFormerLockView = m_pWrtShell->IsViewLocked();
775 m_pWrtShell->LockView( true );
776 m_pWrtShell->StartAllAction();
777 m_pWrtShell->Push();
778 SwWriter aWrt( rMedium, *m_pWrtShell, true );
779 nErrno = aWrt.Write( xWriter, &aFileName );
780 //JP 16.05.97: In case the SFX revokes the View while saving
781 if (m_pWrtShell)
782 {
783 m_pWrtShell->Pop(SwCursorShell::PopMode::DeleteCurrent);
784 m_pWrtShell->EndAllAction();
785 // #i106906#
786 m_pWrtShell->LockView( bFormerLockView );
787 }
788 }
789 else
790 {
791 // are we in SourceView?
792 SwSrcView* pSrcView = ::lcl_GetSourceView( this );
793 if( pSrcView )
794 {
795 pSrcView->SaveContentTo(rMedium);
796 nErrno = ERRCODE_NONEErrCode(0);
797 }
798 else
799 {
800 SwWriter aWrt( rMedium, *m_xDoc );
801 nErrno = aWrt.Write( xWriter, &aFileName );
802 }
803 }
804
805 SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule
::Writer)))
->SetEmbeddedLoadSave( false );
806 SetError(nErrno ? nErrno : nVBWarning);
807 if( !rMedium.IsStorage() )
808 rMedium.CloseOutStream();
809
810 return ! nErrno.IsError();
811}
812
813// Hands off
814// do not yet activate, must deliver TRUE
815bool SwDocShell::SaveCompleted( const uno::Reference < embed::XStorage >& xStor )
816{
817 bool bRet = SfxObjectShell::SaveCompleted( xStor );
818 if( bRet )
819 {
820 // Do not decide until here, whether Saving was successful or not
821 if( IsModified() )
822 m_xDoc->getIDocumentState().SetModified();
823 else
824 m_xDoc->getIDocumentState().ResetModified();
825 }
826
827 if (m_pOLEChildList)
828 {
829 bool bResetModified = IsEnableSetModified();
830 if( bResetModified )
831 EnableSetModified( false );
832
833 uno::Sequence < OUString > aNames = m_pOLEChildList->GetObjectNames();
834 for( sal_Int32 n = aNames.getLength(); n; n-- )
835 {
836 if (!m_pOLEChildList->MoveEmbeddedObject(aNames[n-1], GetEmbeddedObjectContainer()))
837 {
838 OSL_FAIL("Copying of objects didn't work!" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/app/docsh.cxx"
":" "838" ": "), "%s", "Copying of objects didn't work!"); }
} while (false)
;
839 }
840 }
841
842 m_pOLEChildList.reset();
843 if( bResetModified )
844 EnableSetModified();
845 }
846 return bRet;
847}
848
849// Draw()-Override for OLE2 (Sfx)
850void SwDocShell::Draw( OutputDevice* pDev, const JobSetup& rSetup,
851 sal_uInt16 nAspect )
852{
853 //fix #25341# Draw should not affect the Modified
854 bool bResetModified = IsEnableSetModified();
855 if ( bResetModified )
856 EnableSetModified( false );
857
858 // When there is a JobSetup connected to the Document, we copy it to
859 // reconnect it after PrtOle2. We don't use an empty JobSetup because
860 // that would only lead to questionable results after expensive
861 // reformatting (Preview!)
862 std::unique_ptr<JobSetup> pOrig;
863 if ( !rSetup.GetPrinterName().isEmpty() && ASPECT_THUMBNAIL2 != nAspect )
864 {
865 const JobSetup* pCurrentJobSetup = m_xDoc->getIDocumentDeviceAccess().getJobsetup();
866 if( pCurrentJobSetup ) // then we copy that
867 pOrig.reset(new JobSetup( *pCurrentJobSetup ));
868 m_xDoc->getIDocumentDeviceAccess().setJobsetup( rSetup );
869 }
870
871 tools::Rectangle aRect( nAspect == ASPECT_THUMBNAIL2 ?
872 GetVisArea( nAspect ) : GetVisArea( ASPECT_CONTENT1 ) );
873
874 pDev->Push();
875 pDev->SetFillColor();
876 pDev->SetLineColor();
877 pDev->SetBackground();
878 const bool bWeb = dynamic_cast< const SwWebDocShell *>( this ) != nullptr;
879 SwPrintData aOpts;
880 SwViewShell::PrtOle2(m_xDoc.get(), SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule
::Writer)))
->GetUsrPref(bWeb), aOpts, *pDev, aRect);
881 pDev->Pop();
882
883 if( pOrig )
884 {
885 m_xDoc->getIDocumentDeviceAccess().setJobsetup( *pOrig );
886 }
887 if ( bResetModified )
888 EnableSetModified();
889}
890
891void SwDocShell::SetVisArea( const tools::Rectangle &rRect )
892{
893 tools::Rectangle aRect( rRect );
894 if (m_pView)
895 {
896 Size aSz( m_pView->GetDocSz() );
897 aSz.AdjustWidth(DOCUMENTBORDER284 ); aSz.AdjustHeight(DOCUMENTBORDER284 );
898 long nMoveX = 0, nMoveY = 0;
899 if ( aRect.Right() > aSz.Width() )
900 nMoveX = aSz.Width() - aRect.Right();
901 if ( aRect.Bottom() > aSz.Height() )
902 nMoveY = aSz.Height() - aRect.Bottom();
903 aRect.Move( nMoveX, nMoveY );
904 nMoveX = aRect.Left() < 0 ? -aRect.Left() : 0;
905 nMoveY = aRect.Top() < 0 ? -aRect.Top() : 0;
906 aRect.Move( nMoveX, nMoveY );
907
908 // Calls SfxInPlaceObject::SetVisArea()!
909 m_pView->SetVisArea( aRect );
910 }
911 else
912 SfxObjectShell::SetVisArea( aRect );
913}
914
915tools::Rectangle SwDocShell::GetVisArea( sal_uInt16 nAspect ) const
916{
917 if ( nAspect == ASPECT_THUMBNAIL2 )
918 {
919 // Preview: set VisArea to the first page.
920 SwNodeIndex aIdx( m_xDoc->GetNodes().GetEndOfExtras(), 1 );
921 SwContentNode* pNd = m_xDoc->GetNodes().GoNext( &aIdx );
922
923 const SwRect aPageRect = pNd->FindPageFrameRect();
924 if (aPageRect.IsEmpty())
925 return tools::Rectangle();
926 tools::Rectangle aRect(aPageRect.SVRect());
927
928 // tdf#81219 sanitize - nobody is interested in a thumbnail where's
929 // nothing visible
930 if (aRect.GetHeight() > 2*aRect.GetWidth())
931 aRect.SetSize(Size(aRect.GetWidth(), 2*aRect.GetWidth()));
932 else if (aRect.GetWidth() > 2*aRect.GetHeight())
933 aRect.SetSize(Size(2*aRect.GetHeight(), aRect.GetHeight()));
934
935 return aRect;
936 }
937 return SfxObjectShell::GetVisArea( nAspect );
938}
939
940Printer *SwDocShell::GetDocumentPrinter()
941{
942 return m_xDoc->getIDocumentDeviceAccess().getPrinter( false );
943}
944
945OutputDevice* SwDocShell::GetDocumentRefDev()
946{
947 return m_xDoc->getIDocumentDeviceAccess().getReferenceDevice( false );
948}
949
950void SwDocShell::OnDocumentPrinterChanged( Printer * pNewPrinter )
951{
952 if ( pNewPrinter )
953 GetDoc()->getIDocumentDeviceAccess().setJobsetup( pNewPrinter->GetJobSetup() );
954 else
955 GetDoc()->getIDocumentDeviceAccess().setPrinter( nullptr, true, true );
956}
957
958// #i20883# Digital Signatures and Encryption
959HiddenInformation SwDocShell::GetHiddenInformationState( HiddenInformation nStates )
960{
961 // get global state like HiddenInformation::DOCUMENTVERSIONS
962 HiddenInformation nState = SfxObjectShell::GetHiddenInformationState( nStates );
963
964 if ( nStates & HiddenInformation::RECORDEDCHANGES )
965 {
966 if ( !GetDoc()->getIDocumentRedlineAccess().GetRedlineTable().empty() )
967 nState |= HiddenInformation::RECORDEDCHANGES;
968 }
969 if ( nStates & HiddenInformation::NOTES )
970 {
971 OSL_ENSURE( GetWrtShell(), "No SwWrtShell, no information" )do { if (true && (!(GetWrtShell()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/app/docsh.cxx"
":" "971" ": "), "%s", "No SwWrtShell, no information"); } }
while (false)
;
972 if(GetWrtShell() && GetWrtShell()->GetFieldType(SwFieldIds::Postit, OUString())->HasHiddenInformationNotes())
973 nState |= HiddenInformation::NOTES;
974 }
975
976 return nState;
977}
978
979void SwDocShell::GetState(SfxItemSet& rSet)
980{
981 SfxWhichIter aIter(rSet);
982 sal_uInt16 nWhich = aIter.FirstWhich();
983
984 while (nWhich)
985 {
986 switch (nWhich)
987 {
988 case SID_PRINTPREVIEW(5000 + 325):
989 {
990 bool bDisable = IsInPlaceActive();
991 // Disable "multiple layout"
992 if ( !bDisable )
993 {
994 SfxViewFrame *pTmpFrame = SfxViewFrame::GetFirst(this);
995 while (pTmpFrame) // Look for Preview
996 {
997 if ( dynamic_cast<SwView*>( pTmpFrame->GetViewShell() ) &&
998 static_cast<SwView*>(pTmpFrame->GetViewShell())->GetWrtShell().GetViewOptions()->getBrowseMode() )
999 {
1000 bDisable = true;
1001 break;
1002 }
1003 pTmpFrame = SfxViewFrame::GetNext(*pTmpFrame, this);
1004 }
1005 }
1006 // End of disabled "multiple layout"
1007 if ( bDisable )
1008 rSet.DisableItem( SID_PRINTPREVIEW(5000 + 325) );
1009 else
1010 {
1011 SfxBoolItem aBool( SID_PRINTPREVIEW(5000 + 325), false );
1012 if( dynamic_cast<SwPagePreview*>( SfxViewShell::Current()) )
1013 aBool.SetValue( true );
1014 rSet.Put( aBool );
1015 }
1016 }
1017 break;
1018 case SID_AUTO_CORRECT_DLG(10000 + 424):
1019 if ( comphelper::LibreOfficeKit::isActive() )
1020 rSet.DisableItem( SID_AUTO_CORRECT_DLG(10000 + 424) );
1021 break;
1022 case SID_SOURCEVIEW(5000 + 675):
1023 {
1024 SfxViewShell* pCurrView = GetView() ? static_cast<SfxViewShell*>(GetView())
1025 : SfxViewShell::Current();
1026 bool bSourceView = dynamic_cast<SwSrcView*>( pCurrView ) != nullptr;
1027 rSet.Put(SfxBoolItem(SID_SOURCEVIEW(5000 + 675), bSourceView));
1028 }
1029 break;
1030 case SID_HTML_MODE(10000 + 414):
1031 rSet.Put(SfxUInt16Item(SID_HTML_MODE(10000 + 414), ::GetHtmlMode(this)));
1032 break;
1033
1034 case FN_ABSTRACT_STARIMPRESS((20000 + 1600) + 13):
1035 case FN_OUTLINE_TO_IMPRESS(20000 + 36):
1036 {
1037 SvtModuleOptions aMOpt;
1038 if (!aMOpt.IsImpress() || GetObjectShell()->isExportLocked())
1039 rSet.DisableItem( nWhich );
1040 }
1041 [[fallthrough]];
1042 case FN_ABSTRACT_NEWDOC((20000 + 1600) + 12):
1043 case FN_OUTLINE_TO_CLIPBOARD(20000 + 37):
1044 {
1045 if ( GetDoc()->GetNodes().GetOutLineNds().empty() )
1046 rSet.DisableItem( nWhich );
1047 }
1048 break;
1049 case SID_BROWSER_MODE(5000 + 1313):
1050 case FN_PRINT_LAYOUT((20000 + 200) + 37):
1051 {
1052 bool bState = GetDoc()->getIDocumentSettingAccess().get(DocumentSettingId::BROWSE_MODE);
1053 if(FN_PRINT_LAYOUT((20000 + 200) + 37) == nWhich)
1054 bState = !bState;
1055 rSet.Put( SfxBoolItem( nWhich, bState));
1056 }
1057 break;
1058
1059 case FN_NEW_GLOBAL_DOC(20000 + 4 ):
1060 if (dynamic_cast<const SwGlobalDocShell*>(this) != nullptr
1061 || GetObjectShell()->isExportLocked())
1062 rSet.DisableItem( nWhich );
1063 break;
1064
1065 case FN_NEW_HTML_DOC(20000 + 40 ):
1066 if (dynamic_cast<const SwWebDocShell*>(this) != nullptr
1067 || GetObjectShell()->isExportLocked())
1068 rSet.DisableItem( nWhich );
1069 break;
1070
1071 case FN_OPEN_FILE(20000 + 7 ):
1072 if( dynamic_cast< const SwWebDocShell *>( this ) != nullptr )
1073 rSet.DisableItem( nWhich );
1074 break;
1075
1076 case SID_ATTR_YEAR2000(((((10000 + 1499) + 1) + 499) + 1) + 87):
1077 {
1078 const SvNumberFormatter* pFormatr = m_xDoc->GetNumberFormatter(false);
1079 rSet.Put( SfxUInt16Item( nWhich,
1080 static_cast< sal_uInt16 >(
1081 pFormatr ? pFormatr->GetYear2000()
1082 : officecfg::Office::Common::DateFormat::TwoDigitYear::get())) );
1083 }
1084 break;
1085 case SID_ATTR_CHAR_FONTLIST( 10000 + 22 ):
1086 {
1087 rSet.Put( SvxFontListItem(m_pFontList.get(), SID_ATTR_CHAR_FONTLIST( 10000 + 22 )) );
1088 }
1089 break;
1090 case SID_MAIL_PREPAREEXPORT(5000 + 385):
1091 {
1092 //check if linked content or possibly hidden content is available
1093 //m_xDoc->UpdateFields( NULL, false );
1094 sfx2::LinkManager& rLnkMgr = m_xDoc->getIDocumentLinksAdministration().GetLinkManager();
1095 const ::sfx2::SvBaseLinks& rLnks = rLnkMgr.GetLinks();
1096 bool bRet = false;
1097 if( !rLnks.empty() )
1098 bRet = true;
1099 else
1100 {
1101 //sections with hidden flag, hidden character attribute, hidden paragraph/text or conditional text fields
1102 bRet = m_xDoc->HasInvisibleContent();
1103 }
1104 rSet.Put( SfxBoolItem( nWhich, bRet ) );
1105 }
1106 break;
1107 case SID_NOTEBOOKBAR(10000 + 338):
1108 {
1109 SfxViewShell* pViewShell = GetView()? GetView(): SfxViewShell::Current();
1110 bool bVisible = sfx2::SfxNotebookBar::StateMethod(pViewShell->GetViewFrame()->GetBindings(),
1111 "modules/swriter/ui/");
1112 rSet.Put( SfxBoolItem( SID_NOTEBOOKBAR(10000 + 338), bVisible ) );
1113 }
1114 break;
1115 case FN_REDLINE_ACCEPT_ALL((20000 + 1800) + 43):
1116 case FN_REDLINE_REJECT_ALL((20000 + 1800) + 44):
1117 {
1118 if (GetDoc()->getIDocumentRedlineAccess().GetRedlineTable().empty() ||
1119 HasChangeRecordProtection()) // tdf#128229 Disable Accept / Reject all if redlines are password protected
1120 rSet.DisableItem(nWhich);
1121 }
1122 break;
1123
1124 default: OSL_ENSURE(false,"You cannot get here!")do { if (true && (!(false))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/app/docsh.cxx"
":" "1124" ": "), "%s", "You cannot get here!"); } } while (
false)
;
1125
1126 }
1127 nWhich = aIter.NextWhich();
1128 }
1129}
1130
1131// OLE-Hdls
1132IMPL_LINK( SwDocShell, Ole2ModifiedHdl, bool, bNewStatus, void )void SwDocShell::LinkStubOle2ModifiedHdl(void * instance, bool
data) { return static_cast<SwDocShell *>(instance)->
Ole2ModifiedHdl(data); } void SwDocShell::Ole2ModifiedHdl(bool
bNewStatus)
1133{
1134 if( IsEnableSetModified() )
1135 SetModified( bNewStatus );
1136}
1137
1138// return Pool here, because virtual
1139SfxStyleSheetBasePool* SwDocShell::GetStyleSheetPool()
1140{
1141 return m_xBasePool.get();
1142}
1143
1144sfx2::StyleManager* SwDocShell::GetStyleManager()
1145{
1146 return m_pStyleManager.get();
1147}
1148
1149void SwDocShell::SetView(SwView* pVw)
1150{
1151 SetViewShell_Impl(pVw);
1152 m_pView = pVw;
1153 if (m_pView)
1154 {
1155 m_pWrtShell = &m_pView->GetWrtShell();
1156
1157 // Set view-specific redline author.
1158 const OUString& rRedlineAuthor = m_pView->GetRedlineAuthor();
1159 if (!rRedlineAuthor.isEmpty())
1160 SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule
::Writer)))
->SetRedlineAuthor(m_pView->GetRedlineAuthor());
1161 }
1162 else
1163 m_pWrtShell = nullptr;
1164}
1165
1166// #i59688#
1167// linked graphics are now loaded on demand.
1168// Thus, loading of linked graphics no longer needed and necessary for
1169// the load of document being finished.
1170void SwDocShell::LoadingFinished()
1171{
1172 // #i38810#
1173 // Original fix fails after integration of cws xmlsec11:
1174 // interface <SfxObjectShell::EnableSetModified(..)> no longer works, because
1175 // <SfxObjectShell::FinishedLoading(..)> doesn't care about its status and
1176 // enables the document modification again.
1177 // Thus, manual modify the document, if it's modified and its links are updated
1178 // before <FinishedLoading(..)> is called.
1179 const bool bHasDocToStayModified( m_xDoc->getIDocumentState().IsModified() && m_xDoc->getIDocumentLinksAdministration().LinksUpdated() );
1180
1181 FinishedLoading();
1182 SfxViewFrame* pVFrame = SfxViewFrame::GetFirst(this);
1183 if(pVFrame)
1184 {
1185 SfxViewShell* pShell = pVFrame->GetViewShell();
1186 if(auto pSrcView = dynamic_cast<SwSrcView*>( pShell) )
1187 pSrcView->Load(this);
1188 }
1189
1190 // #i38810#
1191 if ( bHasDocToStayModified && !m_xDoc->getIDocumentState().IsModified() )
1192 {
1193 m_xDoc->getIDocumentState().SetModified();
1194 }
1195}
1196
1197// a Transfer is cancelled (is called from SFX)
1198void SwDocShell::CancelTransfers()
1199{
1200 // Cancel all links from LinkManager
1201 m_xDoc->getIDocumentLinksAdministration().GetLinkManager().CancelTransfers();
1202 SfxObjectShell::CancelTransfers();
1203}
1204
1205SwEditShell * SwDocShell::GetEditShell()
1206{
1207 return m_pWrtShell;
1208}
1209
1210SwFEShell* SwDocShell::GetFEShell()
1211{
1212 return m_pWrtShell;
1213}
1214
1215void SwDocShell::RemoveOLEObjects()
1216{
1217 SwIterator<SwContentNode,SwFormatColl> aIter( *m_xDoc->GetDfltGrfFormatColl() );
1218 for( SwContentNode* pNd = aIter.First(); pNd; pNd = aIter.Next() )
1219 {
1220 SwOLENode* pOLENd = pNd->GetOLENode();
1221 if( pOLENd && ( pOLENd->IsOLEObjectDeleted() ||
1222 pOLENd->IsInGlobalDocSection() ) )
1223 {
1224 if (!m_pOLEChildList)
1225 m_pOLEChildList.reset( new comphelper::EmbeddedObjectContainer );
1226
1227 OUString aObjName = pOLENd->GetOLEObj().GetCurrentPersistName();
1228 GetEmbeddedObjectContainer().MoveEmbeddedObject( aObjName, *m_pOLEChildList );
1229 }
1230 }
1231}
1232
1233// When a document is loaded, SwDoc::PrtOLENotify is called to update
1234// the sizes of math objects. However, for objects that do not have a
1235// SwFrame at this time, only a flag is set (bIsOLESizeInvalid) and the
1236// size change takes place later, while calculating the layout in the
1237// idle handler. If this document is saved now, it is saved with invalid
1238// sizes. For this reason, the layout has to be calculated before a document is
1239// saved, but of course only id there are OLE objects with bOLESizeInvalid set.
1240void SwDocShell::CalcLayoutForOLEObjects()
1241{
1242 if (!m_pWrtShell)
1243 return;
1244
1245 if (m_pView && m_pView->GetIPClient())
1246 {
1247 // We have an active OLE edit: allow link updates, so an up to date replacement graphic can
1248 // be created.
1249 comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = getEmbeddedObjectContainer();
1250 rEmbeddedObjectContainer.setUserAllowsLinkUpdate(true);
1251 }
1252
1253 SwIterator<SwContentNode,SwFormatColl> aIter( *m_xDoc->GetDfltGrfFormatColl() );
1254 for( SwContentNode* pNd = aIter.First(); pNd; pNd = aIter.Next() )
1255 {
1256 SwOLENode* pOLENd = pNd->GetOLENode();
1257 if( pOLENd && pOLENd->IsOLESizeInvalid() )
1258 {
1259 m_pWrtShell->CalcLayout();
1260 break;
1261 }
1262 }
1263}
1264
1265// #i42634# Overwrites SfxObjectShell::UpdateLinks
1266// This new function is necessary to trigger update of links in docs
1267// read by the binary filter:
1268void SwDocShell::UpdateLinks()
1269{
1270 GetDoc()->getIDocumentLinksAdministration().UpdateLinks();
1271 // #i50703# Update footnote numbers
1272 SwTextFootnote::SetUniqueSeqRefNo( *GetDoc() );
1273 SwNodeIndex aTmp( GetDoc()->GetNodes() );
1274 GetDoc()->GetFootnoteIdxs().UpdateFootnote( aTmp );
1275}
1276
1277uno::Reference< frame::XController >
1278 SwDocShell::GetController()
1279{
1280 css::uno::Reference< css::frame::XController > aRet;
1281 // #i82346# No view in page preview
1282 if ( GetView() )
1283 aRet = GetView()->GetController();
1284 return aRet;
1285}
1286
1287static const char* s_EventNames[] =
1288{
1289 "OnPageCountChange",
1290 "OnMailMerge",
1291 "OnMailMergeFinished",
1292 "OnFieldMerge",
1293 "OnFieldMergeFinished",
1294 "OnLayoutFinished"
1295};
1296sal_Int32 const s_nEvents(SAL_N_ELEMENTS(s_EventNames)(sizeof(sal_n_array_size(s_EventNames))));
1297
1298Sequence< OUString > SwDocShell::GetEventNames()
1299{
1300 Sequence< OUString > aRet = SfxObjectShell::GetEventNames();
1301 sal_Int32 nLen = aRet.getLength();
1302 aRet.realloc(nLen + 6);
1303 OUString* pNames = aRet.getArray();
1304 pNames[nLen++] = GetEventName(0);
1305 pNames[nLen++] = GetEventName(1);
1306 pNames[nLen++] = GetEventName(2);
1307 pNames[nLen++] = GetEventName(3);
1308 pNames[nLen++] = GetEventName(4);
1309 pNames[nLen] = GetEventName(5);
1310
1311 return aRet;
1312}
1313
1314OUString SwDocShell::GetEventName( sal_Int32 nIndex )
1315{
1316 if (nIndex < s_nEvents)
1317 {
1318 return OUString::createFromAscii(s_EventNames[nIndex]);
1319 }
1320 return OUString();
1321}
1322
1323const ::sfx2::IXmlIdRegistry* SwDocShell::GetXmlIdRegistry() const
1324{
1325 return m_xDoc ? &m_xDoc->GetXmlIdRegistry() : nullptr;
1326}
1327
1328bool SwDocShell::IsChangeRecording() const
1329{
1330 if (!m_pWrtShell)
1331 return false;
1332 return bool(m_pWrtShell->GetRedlineFlags() & RedlineFlags::On);
1333}
1334
1335bool SwDocShell::HasChangeRecordProtection() const
1336{
1337 if (!m_pWrtShell)
1338 return false;
1339 return m_pWrtShell->getIDocumentRedlineAccess().GetRedlinePassword().hasElements();
1340}
1341
1342void SwDocShell::SetChangeRecording( bool bActivate )
1343{
1344 RedlineFlags nOn = bActivate ? RedlineFlags::On : RedlineFlags::NONE;
1345 RedlineFlags nMode = m_pWrtShell->GetRedlineFlags();
1346 m_pWrtShell->SetRedlineFlagsAndCheckInsMode( (nMode & ~RedlineFlags::On) | nOn );
1347}
1348
1349void SwDocShell::SetProtectionPassword( const OUString &rNewPassword )
1350{
1351 const SfxAllItemSet aSet( GetPool() );
1352 const SfxPoolItem* pItem = nullptr;
1353
1354 IDocumentRedlineAccess& rIDRA = m_pWrtShell->getIDocumentRedlineAccess();
1355 Sequence< sal_Int8 > aPasswd = rIDRA.GetRedlinePassword();
1356 if (SfxItemState::SET == aSet.GetItemState(FN_REDLINE_PROTECT((20000 + 1800) + 23), false, &pItem)
1357 && static_cast<const SfxBoolItem*>(pItem)->GetValue() == aPasswd.hasElements())
1358 return;
1359
1360 if (!rNewPassword.isEmpty())
1361 {
1362 // when password protection is applied change tracking must always be active
1363 SetChangeRecording( true );
1364
1365 Sequence< sal_Int8 > aNewPasswd;
1366 SvPasswordHelper::GetHashPassword( aNewPasswd, rNewPassword );
1367 rIDRA.SetRedlinePassword( aNewPasswd );
1368 }
1369 else
1370 {
1371 rIDRA.SetRedlinePassword( Sequence< sal_Int8 >() );
1372 }
1373}
1374
1375bool SwDocShell::GetProtectionHash( /*out*/ css::uno::Sequence< sal_Int8 > &rPasswordHash )
1376{
1377 bool bRes = false;
1378
1379 const SfxAllItemSet aSet( GetPool() );
1380 const SfxPoolItem* pItem = nullptr;
1381
1382 IDocumentRedlineAccess& rIDRA = m_pWrtShell->getIDocumentRedlineAccess();
1383 const Sequence< sal_Int8 >& aPasswdHash( rIDRA.GetRedlinePassword() );
1384 if (SfxItemState::SET == aSet.GetItemState(FN_REDLINE_PROTECT((20000 + 1800) + 23), false, &pItem)
1385 && static_cast<const SfxBoolItem*>(pItem)->GetValue() == aPasswdHash.hasElements())
1386 return false;
1387 rPasswordHash = aPasswdHash;
1388 bRes = true;
1389
1390 return bRes;
1391}
1392
1393void SwDocShell::RegisterAutomationDocumentEventsCaller(css::uno::Reference< ooo::vba::XSinkCaller > const& xCaller)
1394{
1395 mxAutomationDocumentEventsCaller = xCaller;
1396}
1397
1398void SwDocShell::CallAutomationDocumentEventSinks(const OUString& Method, css::uno::Sequence< css::uno::Any >& Arguments)
1399{
1400 if (mxAutomationDocumentEventsCaller.is())
1401 mxAutomationDocumentEventsCaller->CallSinks(Method, Arguments);
1402}
1403
1404void SwDocShell::RegisterAutomationDocumentObject(css::uno::Reference< ooo::vba::word::XDocument > const& xDocument)
1405{
1406 mxAutomationDocumentObject = xDocument;
1407}
1408
1409/* vim:set shiftwidth=4 softtabstop=4 expandtab: */