summaryrefslogtreecommitdiffstats
path: root/sw/source/uibase/app
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
commit267c6f2ac71f92999e969232431ba04678e7437e (patch)
tree358c9467650e1d0a1d7227a21dac2e3d08b622b2 /sw/source/uibase/app
parentInitial commit. (diff)
downloadlibreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz
libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sw/source/uibase/app')
-rw-r--r--sw/source/uibase/app/appenv.cxx497
-rw-r--r--sw/source/uibase/app/appenv.hxx19
-rw-r--r--sw/source/uibase/app/apphdl.cxx1128
-rw-r--r--sw/source/uibase/app/applab.cxx397
-rw-r--r--sw/source/uibase/app/appopt.cxx527
-rw-r--r--sw/source/uibase/app/docsh.cxx1433
-rw-r--r--sw/source/uibase/app/docsh2.cxx1805
-rw-r--r--sw/source/uibase/app/docshdrw.cxx100
-rw-r--r--sw/source/uibase/app/docshini.cxx711
-rw-r--r--sw/source/uibase/app/docst.cxx1693
-rw-r--r--sw/source/uibase/app/docstyle.cxx3380
-rw-r--r--sw/source/uibase/app/mainwn.cxx133
-rw-r--r--sw/source/uibase/app/swdll.cxx184
-rw-r--r--sw/source/uibase/app/swdllimpl.hxx45
-rw-r--r--sw/source/uibase/app/swmodul1.cxx693
-rw-r--r--sw/source/uibase/app/swmodule.cxx401
-rw-r--r--sw/source/uibase/app/swwait.cxx83
17 files changed, 13229 insertions, 0 deletions
diff --git a/sw/source/uibase/app/appenv.cxx b/sw/source/uibase/app/appenv.cxx
new file mode 100644
index 0000000000..6c744867ad
--- /dev/null
+++ b/sw/source/uibase/app/appenv.cxx
@@ -0,0 +1,497 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <hintids.hxx>
+
+#include <comphelper/string.hxx>
+#include <sfx2/request.hxx>
+
+#include <sfx2/bindings.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/pbinitem.hxx>
+#include <editeng/paperinf.hxx>
+#include <osl/diagnose.h>
+#include <fmthdft.hxx>
+#include <swwait.hxx>
+#include <swmodule.hxx>
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <docsh.hxx>
+#include <frmatr.hxx>
+#include <fldbas.hxx>
+#include <swundo.hxx>
+#include <IDocumentDeviceAccess.hxx>
+#include <dialoghelp.hxx>
+#include <fmtcol.hxx>
+#include <frmmgr.hxx>
+#include <fldmgr.hxx>
+#include <pagedesc.hxx>
+#include <poolfmt.hxx>
+#include <expfld.hxx>
+#include <SwStyleNameMapper.hxx>
+#include <fmtpdsc.hxx>
+
+#include <cmdid.h>
+#include <strings.hrc>
+#include <swabstdlg.hxx>
+#include <envimg.hxx>
+#include "appenv.hxx"
+
+#define ENV_NEWDOC RET_OK
+#define ENV_INSERT RET_USER
+
+// Function used for labels and envelopes in applab.cxx and appenv.cxx
+OUString InsertLabEnvText( SwWrtShell& rSh, SwFieldMgr& rFieldMgr, const OUString& rText )
+{
+ OUString sRet;
+ OUString aText = rText.replaceAll("\r", "");
+
+ sal_Int32 nTokenPos = 0;
+ while( -1 != nTokenPos )
+ {
+ OUString aLine = aText.getToken( 0, '\n', nTokenPos );
+ while ( !aLine.isEmpty() )
+ {
+ OUString sTmpText;
+ bool bField = false;
+
+ sal_Int32 nPos = aLine.indexOf( '<' );
+ if (0 != nPos)
+ {
+ sal_Int32 const nCopy((nPos != -1) ? nPos : aLine.getLength());
+ sTmpText = aLine.copy(0, nCopy);
+ aLine = aLine.copy(nCopy);
+ }
+ else
+ {
+ nPos = aLine.indexOf( '>' );
+ if ( nPos == -1 )
+ {
+ sTmpText = aLine;
+ aLine.clear();
+ }
+ else
+ {
+ sTmpText = aLine.copy( 0, nPos + 1);
+ aLine = aLine.copy( nPos + 1);
+
+ // Database fields must contain at least 3 points!
+ OUString sDBName( sTmpText.copy( 1, sTmpText.getLength() - 2));
+ if (comphelper::string::getTokenCount(sDBName, '.') >= 3)
+ {
+ sDBName = ::ReplacePoint(sDBName, true);
+ SwInsertField_Data aData(SwFieldTypesEnum::Database, 0, sDBName, OUString(), 0, &rSh);
+ rFieldMgr.InsertField( aData );
+ sRet = sDBName;
+ bField = true;
+ }
+ }
+ }
+ if ( !bField )
+ rSh.Insert( sTmpText );
+ }
+ rSh.SplitNode();
+ }
+ rSh.DelLeft(); // Again remove last linebreak
+
+ return sRet;
+}
+
+static void lcl_CopyCollAttr(SwWrtShell const * pOldSh, SwWrtShell* pNewSh, sal_uInt16 nCollId)
+{
+ sal_uInt16 nCollCnt = pOldSh->GetTextFormatCollCount();
+ for( sal_uInt16 nCnt = 0; nCnt < nCollCnt; ++nCnt )
+ {
+ SwTextFormatColl* pColl = &pOldSh->GetTextFormatColl(nCnt);
+ if(nCollId == pColl->GetPoolFormatId())
+ pNewSh->GetTextCollFromPool(nCollId)->SetFormatAttr(pColl->GetAttrSet());
+ }
+}
+
+void SwModule::InsertEnv( SfxRequest& rReq )
+{
+ static sal_uInt16 nTitleNo = 0;
+
+ SwDocShell *pMyDocSh;
+ SfxViewFrame *pFrame;
+ SwView *pNewView;
+ SwWrtShell *pOldSh,
+ *pSh;
+
+ // Get current shell
+ pMyDocSh = static_cast<SwDocShell*>( SfxObjectShell::Current());
+ pOldSh = pMyDocSh ? pMyDocSh->GetWrtShell() : nullptr;
+
+ // Create new document (don't show!)
+ SfxObjectShellLock xDocSh( new SwDocShell( SfxObjectCreateMode::STANDARD ) );
+ xDocSh->DoInitNew();
+ pFrame = SfxViewFrame::LoadHiddenDocument( *xDocSh, SFX_INTERFACE_NONE );
+ pNewView = static_cast<SwView*>( pFrame->GetViewShell());
+ pNewView->AttrChangedNotify(nullptr); // so that SelectShell is being called
+ pSh = pNewView->GetWrtShellPtr();
+
+ if (!pSh)
+ return;
+
+ OUString aTmp = SwResId(STR_ENV_TITLE) + OUString::number( ++nTitleNo );
+ xDocSh->SetTitle( aTmp );
+
+ // if applicable, copy the old Collections "Sender" and "Receiver" to
+ // a new document
+ if ( pOldSh )
+ {
+ ::lcl_CopyCollAttr(pOldSh, pSh, RES_POOLCOLL_ENVELOPE_ADDRESS);
+ ::lcl_CopyCollAttr(pOldSh, pSh, RES_POOLCOLL_SEND_ADDRESS);
+ }
+
+ // Read SwEnvItem from config
+ SwEnvCfgItem aEnvCfg;
+
+ // Check if there's already an envelope.
+ bool bEnvChange = false;
+
+ SfxItemSetFixed<FN_ENVELOP, FN_ENVELOP> aSet(GetPool());
+ aSet.Put(aEnvCfg.GetItem());
+
+ SfxPrinter* pTempPrinter = pSh->getIDocumentDeviceAccess().getPrinter( true );
+ if(pOldSh )
+ {
+ const SwPageDesc& rCurPageDesc = pOldSh->GetPageDesc(pOldSh->GetCurPageDesc());
+ OUString sEnvelope;
+ SwStyleNameMapper::FillUIName( RES_POOLPAGE_ENVELOPE, sEnvelope );
+ bEnvChange = rCurPageDesc.GetName() == sEnvelope;
+
+ IDocumentDeviceAccess& rIDDA_old = pOldSh->getIDocumentDeviceAccess();
+ if( rIDDA_old.getPrinter( false ) )
+ {
+ IDocumentDeviceAccess& rIDDA = pSh->getIDocumentDeviceAccess();
+ rIDDA.setJobsetup( *rIDDA_old.getJobsetup() );
+ //#69563# if it isn't the same printer then the pointer has been invalidated!
+ pTempPrinter = rIDDA.getPrinter( true );
+ }
+ pTempPrinter->SetPaperBin(rCurPageDesc.GetMaster().GetPaperBin().GetValue());
+
+ }
+
+ ScopedVclPtr<SfxAbstractTabDialog> pDlg;
+ short nMode = ENV_INSERT;
+
+ const SwEnvItem* pItem = rReq.GetArg<SwEnvItem>(FN_ENVELOP);
+ if ( !pItem )
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ pDlg.disposeAndReset(pFact->CreateSwEnvDlg(GetFrameWeld(pMyDocSh), aSet, pOldSh, pTempPrinter, !bEnvChange));
+ nMode = pDlg->Execute();
+ }
+ else
+ {
+ const SfxBoolItem* pBoolItem = rReq.GetArg<SfxBoolItem>(FN_PARAM_1);
+ if ( pBoolItem && pBoolItem->GetValue() )
+ nMode = ENV_NEWDOC;
+ }
+
+ if (nMode == ENV_NEWDOC || nMode == ENV_INSERT)
+ {
+ SwWait aWait( static_cast<SwDocShell&>(*xDocSh), true );
+
+ // Read dialog and save item to config
+ const SwEnvItem& rItem = pItem ? *pItem : static_cast<const SwEnvItem&>( pDlg->GetOutputItemSet()->Get(FN_ENVELOP) );
+ aEnvCfg.GetItem() = rItem;
+ aEnvCfg.Commit();
+
+ // When we print we take the Jobsetup that is set up in the dialog.
+ // Information has to be set here, before a possible destruction of
+ // the new shell because the shell's printer has been handed to the
+ // dialog.
+ if ( nMode != ENV_NEWDOC )
+ {
+ OSL_ENSURE(pOldSh, "No document - wasn't 'Insert' disabled???");
+ SvxPaperBinItem aItem( RES_PAPER_BIN );
+ aItem.SetValue(static_cast<sal_uInt8>(pSh->getIDocumentDeviceAccess().getPrinter(true)->GetPaperBin()));
+ pOldSh->GetPageDescFromPool(RES_POOLPAGE_ENVELOPE)->GetMaster().SetFormatAttr(aItem);
+ }
+
+ SwWrtShell *pTmp = nMode == ENV_INSERT ? pOldSh : pSh;
+ const SwPageDesc* pFollow = nullptr;
+ SwTextFormatColl *pSend = pTmp->GetTextCollFromPool(RES_POOLCOLL_SEND_ADDRESS),
+ *pAddr = pTmp->GetTextCollFromPool(RES_POOLCOLL_ENVELOPE_ADDRESS);
+ const OUString sSendMark = pSend->GetName();
+ const OUString sAddrMark = pAddr->GetName();
+
+ if (nMode == ENV_INSERT)
+ {
+
+ SetView(&pOldSh->GetView()); // Set pointer to top view
+
+ // Delete new document
+ xDocSh->DoClose();
+ pSh = pOldSh;
+ //#i4251# selected text or objects in the document should
+ //not be deleted on inserting envelopes
+ pSh->EnterStdMode();
+ // Here it goes (insert)
+ pSh->StartUndo(SwUndoId::UI_INSERT_ENVELOPE);
+ pSh->StartAllAction();
+ pSh->SttEndDoc(true);
+
+ if (bEnvChange)
+ {
+ // followup template: page 2
+ pFollow = pSh->GetPageDesc(pSh->GetCurPageDesc()).GetFollow();
+
+ // Delete text from the first page
+ if ( !pSh->SttNxtPg(true) )
+ pSh->EndPg(true);
+ pSh->DelRight();
+ // Delete frame of the first page
+ if ( pSh->GotoFly(sSendMark) )
+ {
+ pSh->EnterSelFrameMode();
+ pSh->DelRight();
+ }
+ if ( pSh->GotoFly(sAddrMark) )
+ {
+ pSh->EnterSelFrameMode();
+ pSh->DelRight();
+ }
+ pSh->SttEndDoc(true);
+ }
+ else
+ // Followup template: page 1
+ pFollow = &pSh->GetPageDesc(pSh->GetCurPageDesc());
+
+ // Insert page break
+ if ( pSh->IsCursorInTable() )
+ {
+ pSh->SplitNode();
+ pSh->Right( SwCursorSkipMode::Chars, false, 1, false );
+ SfxItemSetFixed<RES_PAGEDESC, RES_PAGEDESC> aBreakSet( pSh->GetAttrPool() );
+ aBreakSet.Put( SwFormatPageDesc( pFollow ) );
+ pSh->SetTableAttr( aBreakSet );
+ }
+ else
+ {
+ OUString sFollowName(pFollow->GetName());
+ pSh->InsertPageBreak(&sFollowName, std::nullopt);
+ }
+ pSh->SttEndDoc(true);
+ }
+ else
+ {
+ pFollow = &pSh->GetPageDesc(pSh->GetCurPageDesc());
+ // Let's go (print)
+ pSh->StartAllAction();
+ pSh->DoUndo(false);
+
+ // Again, copy the new collections "Sender" and "Receiver" to
+ // a new document
+ if ( pOldSh )
+ {
+ ::lcl_CopyCollAttr(pOldSh, pSh, RES_POOLCOLL_ENVELOPE_ADDRESS);
+ ::lcl_CopyCollAttr(pOldSh, pSh, RES_POOLCOLL_SEND_ADDRESS);
+ }
+ }
+
+ CurrShell aCurr(pSh);
+ pSh->SetNewDoc(); // Avoid performance problems
+
+ // Remember Flys of this site
+ std::vector<SwFrameFormat*> aFlyArr;
+ if( ENV_NEWDOC != nMode && !bEnvChange )
+ pSh->GetPageObjs( aFlyArr );
+
+ // Get page description
+ SwPageDesc* pDesc = pSh->GetPageDescFromPool(RES_POOLPAGE_ENVELOPE);
+ SwFrameFormat& rFormat = pDesc->GetMaster();
+
+ Printer *pPrt = pSh->getIDocumentDeviceAccess().getPrinter( true );
+
+ // Borders (are put together by Shift-Offset and alignment)
+ Size aPaperSize = pPrt->PixelToLogic( pPrt->GetPaperSizePixel(),
+ MapMode(MapUnit::MapTwip));
+ if ( !aPaperSize.Width() && !aPaperSize.Height() )
+ aPaperSize = SvxPaperInfo::GetPaperSize(PAPER_A4);
+ if ( aPaperSize.Width() > aPaperSize.Height() )
+ Swap( aPaperSize );
+
+ tools::Long lLeft = rItem.m_nShiftRight,
+ lUpper = rItem.m_nShiftDown;
+
+ sal_uInt16 nPageW = o3tl::narrowing<sal_uInt16>(std::max(rItem.m_nWidth, rItem.m_nHeight)),
+ nPageH = o3tl::narrowing<sal_uInt16>(std::min(rItem.m_nWidth, rItem.m_nHeight));
+
+ switch (rItem.m_eAlign)
+ {
+ case ENV_HOR_LEFT: break;
+ case ENV_HOR_CNTR: lLeft += std::max(tools::Long(0), aPaperSize.Width() - nPageW) / 2;
+ break;
+ case ENV_HOR_RGHT: lLeft += std::max(tools::Long(0), aPaperSize.Width() - nPageW);
+ break;
+ case ENV_VER_LEFT: lUpper += std::max(tools::Long(0), aPaperSize.Width() - nPageH);
+ break;
+ case ENV_VER_CNTR: lUpper += std::max(tools::Long(0), aPaperSize.Width() - nPageH) / 2;
+ break;
+ case ENV_VER_RGHT: break;
+ }
+ SvxLRSpaceItem aLRMargin( RES_LR_SPACE );
+ SvxULSpaceItem aULMargin( RES_UL_SPACE );
+ aLRMargin.SetLeft (o3tl::narrowing<sal_uInt16>(lLeft) );
+ aULMargin.SetUpper(o3tl::narrowing<sal_uInt16>(lUpper));
+ aLRMargin.SetRight(0);
+ aULMargin.SetLower(0);
+ rFormat.SetFormatAttr(aLRMargin);
+ rFormat.SetFormatAttr(aULMargin);
+
+ // Header and footer
+ rFormat.SetFormatAttr(SwFormatHeader(false));
+ pDesc->ChgHeaderShare(false);
+ rFormat.SetFormatAttr(SwFormatFooter(false));
+ pDesc->ChgFooterShare(false);
+
+ // Page numbering
+ pDesc->SetUseOn(UseOnPage::All);
+
+ // Page size
+ rFormat.SetFormatAttr(SwFormatFrameSize(SwFrameSize::Fixed,
+ nPageW + lLeft, nPageH + lUpper));
+
+ // Set type of page numbering
+ SvxNumberType aType;
+ aType.SetNumberingType(SVX_NUM_NUMBER_NONE);
+ pDesc->SetNumType(aType);
+
+ // Followup template
+ if (pFollow)
+ pDesc->SetFollow(pFollow);
+
+ // Landscape
+ pDesc->SetLandscape( rItem.m_eAlign >= ENV_VER_LEFT &&
+ rItem.m_eAlign <= ENV_VER_RGHT);
+
+ // Apply page description
+
+ size_t nPos;
+ pSh->FindPageDescByName( pDesc->GetName(),
+ false,
+ &nPos );
+
+ pSh->ChgPageDesc( nPos, *pDesc);
+ pSh->ChgCurPageDesc(*pDesc);
+
+ // Insert Frame
+ SwFlyFrameAttrMgr aMgr(false, pSh, Frmmgr_Type::ENVELP, nullptr);
+ SwFieldMgr aFieldMgr;
+ aMgr.SetHeightSizeType(SwFrameSize::Variable);
+
+ // Overwrite defaults!
+ aMgr.GetAttrSet().Put( SvxBoxItem(RES_BOX) );
+ aMgr.SetULSpace( 0, 0 );
+ aMgr.SetLRSpace( 0, 0 );
+
+ // Sender
+ if (rItem.m_bSend)
+ {
+ pSh->SttEndDoc(true);
+ aMgr.InsertFlyFrame(RndStdIds::FLY_AT_PAGE,
+ Point(rItem.m_nSendFromLeft + lLeft, rItem.m_nSendFromTop + lUpper),
+ Size (rItem.m_nAddrFromLeft - rItem.m_nSendFromLeft, 0));
+
+ pSh->EnterSelFrameMode();
+ pSh->SetFlyName(sSendMark);
+ pSh->UnSelectFrame();
+ pSh->LeaveSelFrameMode();
+ pSh->SetTextFormatColl( pSend );
+ InsertLabEnvText( *pSh, aFieldMgr, rItem.m_aSendText );
+ aMgr.UpdateAttrMgr();
+ }
+
+ // Addressee
+ pSh->SttEndDoc(true);
+
+ aMgr.InsertFlyFrame(RndStdIds::FLY_AT_PAGE,
+ Point(rItem.m_nAddrFromLeft + lLeft, rItem.m_nAddrFromTop + lUpper),
+ Size (nPageW - rItem.m_nAddrFromLeft - 566, 0));
+ pSh->EnterSelFrameMode();
+ pSh->SetFlyName(sAddrMark);
+ pSh->UnSelectFrame();
+ pSh->LeaveSelFrameMode();
+ pSh->SetTextFormatColl( pAddr );
+ InsertLabEnvText(*pSh, aFieldMgr, rItem.m_aAddrText);
+
+ // Move Flys to the "old" pages
+ if (!aFlyArr.empty())
+ pSh->SetPageObjsNewPage(aFlyArr);
+
+ // Finished
+ pSh->SttEndDoc(true);
+
+ pSh->EndAllAction();
+
+ if (nMode == ENV_NEWDOC)
+ pSh->DoUndo();
+ else
+ pSh->EndUndo(SwUndoId::UI_INSERT_ENVELOPE);
+
+ if (nMode == ENV_NEWDOC)
+ {
+ pFrame->GetFrame().Appear();
+
+ if ( rItem.m_aAddrText.indexOf('<') >= 0 )
+ {
+ static sal_uInt16 const aInva[] =
+ {
+ SID_SBA_BRW_UPDATE,
+ SID_SBA_BRW_INSERT,
+ SID_SBA_BRW_MERGE,
+ 0
+ };
+ pFrame->GetBindings().Invalidate( aInva );
+
+ // Open database beamer
+ ShowDBObj(*pNewView, pSh->GetDBData());
+ }
+ }
+
+ if ( !pItem )
+ {
+ rReq.AppendItem( rItem );
+ if ( nMode == ENV_NEWDOC )
+ rReq.AppendItem( SfxBoolItem( FN_PARAM_1, true ) );
+ }
+
+ rReq.Done();
+ }
+ else // Abort
+ {
+ rReq.Ignore();
+
+ xDocSh->DoClose();
+ --nTitleNo;
+
+ // Set pointer to top view
+ if (pOldSh)
+ SetView(&pOldSh->GetView());
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/app/appenv.hxx b/sw/source/uibase/app/appenv.hxx
new file mode 100644
index 0000000000..f077702bb9
--- /dev/null
+++ b/sw/source/uibase/app/appenv.hxx
@@ -0,0 +1,19 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <rtl/ustring.hxx>
+
+class SwWrtShell;
+class SwFieldMgr;
+
+OUString InsertLabEnvText(SwWrtShell&, SwFieldMgr&, const OUString&);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/app/apphdl.cxx b/sw/source/uibase/app/apphdl.cxx
new file mode 100644
index 0000000000..bca9d20dbd
--- /dev/null
+++ b/sw/source/uibase/app/apphdl.cxx
@@ -0,0 +1,1128 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_features.h>
+#include <config_fuzzers.h>
+#include <config_wasm_strip.h>
+
+#include <comphelper/propertysequence.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/event.hxx>
+#include <sfx2/objitem.hxx>
+#include <svx/dataaccessdescriptor.hxx>
+#include <svtools/restartdialog.hxx>
+#include <svl/eitem.hxx>
+#include <svl/whiter.hxx>
+#include <svl/stritem.hxx>
+#include <svl/voiditem.hxx>
+#include <sfx2/lokhelper.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <svl/ctloptions.hxx>
+#include <svtools/colorcfg.hxx>
+#include <svtools/accessibilityoptions.hxx>
+#include <comphelper/diagnose_ex.hxx>
+#include <unotools/useroptions.hxx>
+#include <com/sun/star/document/UpdateDocMode.hpp>
+#include <sfx2/docfile.hxx>
+#include <sfx2/objface.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <o3tl/string_view.hxx>
+
+#include <view.hxx>
+#include <pview.hxx>
+#include <srcview.hxx>
+#include <wrtsh.hxx>
+#include <docsh.hxx>
+#include <cmdid.h>
+#include <initui.hxx>
+#include <uitool.hxx>
+#include <swmodule.hxx>
+#include <wview.hxx>
+#include <usrpref.hxx>
+#include <gloslst.hxx>
+#include <glosdoc.hxx>
+#include <doc.hxx>
+#include <IDocumentLayoutAccess.hxx>
+#include <IDocumentFieldsAccess.hxx>
+#include <prtopt.hxx>
+#include <modcfg.hxx>
+#include <fontcfg.hxx>
+#include <barcfg.hxx>
+#include <navicfg.hxx>
+#include <uinums.hxx>
+#include <dbconfig.hxx>
+#include <mmconfigitem.hxx>
+#include <strings.hrc>
+#include <unotxdoc.hxx>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdb/TextConnectionSettings.hpp>
+#include <com/sun/star/sdbc/XDataSource.hpp>
+#include <com/sun/star/task/OfficeRestartManager.hpp>
+#include <org/freedesktop/PackageKit/SyncDbusSessionHelper.hpp>
+#include <swabstdlg.hxx>
+#include <comphelper/dispatchcommand.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/lok.hxx>
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
+
+#include <salhelper/simplereferenceobject.hxx>
+#include <rtl/ref.hxx>
+
+#include <officecfg/Office/Common.hxx>
+
+using namespace ::com::sun::star;
+
+// Slotmaps for the application's methods
+
+// here are the SlotID's being included
+// see Idl-file
+#define ShellClass_SwModule
+#include <sfx2/msg.hxx>
+#include <swslots.hxx>
+
+SFX_IMPL_INTERFACE(SwModule, SfxModule)
+
+void SwModule::InitInterface_Impl()
+{
+ GetStaticInterface()->RegisterStatusBar(StatusBarId::WriterStatusBar);
+
+ GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_APPLICATION,
+ SfxVisibilityFlags::Standard | SfxVisibilityFlags::Client | SfxVisibilityFlags::Viewer,
+ ToolbarId::Module_Toolbox);
+}
+
+// other states
+void SwModule::StateOther(SfxItemSet &rSet)
+{
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+
+ SwView* pActView = ::GetActiveView();
+ bool bWebView = dynamic_cast<SwWebView*>( pActView ) != nullptr;
+
+ while(nWhich)
+ {
+ switch(nWhich)
+ {
+ case FN_BUSINESS_CARD:
+ case FN_LABEL:
+ case FN_ENVELOP:
+ {
+ bool bDisable = false;
+ SfxViewShell* pCurrView = SfxViewShell::Current();
+ if( !pCurrView || dynamic_cast< const SwView *>( pCurrView ) == nullptr )
+ bDisable = true;
+ SwDocShell *pDocSh = static_cast<SwDocShell*>( SfxObjectShell::Current());
+ if ( bDisable ||
+ (pDocSh && (pDocSh->IsReadOnly() ||
+ pDocSh->GetCreateMode() == SfxObjectCreateMode::EMBEDDED)) )
+ rSet.DisableItem( nWhich );
+
+ }
+ break;
+ case FN_XFORMS_INIT:
+ // slot is always active!
+ break;
+ case FN_EDIT_FORMULA:
+ {
+ SwWrtShell* pSh = nullptr;
+ SelectionType nSelection = SelectionType::NONE;
+ if( pActView )
+ pSh = &pActView->GetWrtShell();
+ if( pSh )
+ nSelection = pSh->GetSelectionType();
+
+ if( (pSh && pSh->HasSelection()) ||
+ !(nSelection & (SelectionType::Text | SelectionType::Table)))
+ rSet.DisableItem(nWhich);
+ }
+ break;
+ case SID_ATTR_METRIC:
+ rSet.Put( SfxUInt16Item( SID_ATTR_METRIC, static_cast< sal_uInt16 >(::GetDfltMetric(bWebView))));
+ break;
+ case FN_SET_MODOPT_TBLNUMFMT:
+ rSet.Put( SfxBoolItem( nWhich, m_pModuleConfig->
+ IsInsTableFormatNum( bWebView )));
+ break;
+ case FN_MAILMERGE_WIZARD:
+ {
+ SfxObjectShell* pObjectShell = GetObjectShell();
+ if (pObjectShell && pObjectShell->isExportLocked())
+ rSet.DisableItem(nWhich);
+ break;
+ }
+ case FN_MAILMERGE_FIRST_ENTRY:
+ case FN_MAILMERGE_PREV_ENTRY:
+ case FN_MAILMERGE_NEXT_ENTRY:
+ case FN_MAILMERGE_LAST_ENTRY:
+ {
+ std::shared_ptr<SwMailMergeConfigItem> xConfigItem;
+ if (SwView* pView = GetActiveView())
+ xConfigItem = pView->GetMailMergeConfigItem();
+ if (!xConfigItem)
+ rSet.DisableItem(nWhich);
+ else if (xConfigItem->GetConnection().is()
+ && !xConfigItem->GetConnection()->isClosed())
+ {
+ bool bFirst, bLast;
+ bool bValid = xConfigItem->IsResultSetFirstLast(bFirst, bLast);
+
+ if (!bValid ||
+ (bFirst && (nWhich == FN_MAILMERGE_FIRST_ENTRY || nWhich == FN_MAILMERGE_PREV_ENTRY)) ||
+ (bLast && (nWhich == FN_MAILMERGE_LAST_ENTRY || nWhich == FN_MAILMERGE_NEXT_ENTRY)))
+ {
+ rSet.DisableItem(nWhich);
+ }
+ }
+ }
+ break;
+ case FN_MAILMERGE_CURRENT_ENTRY:
+ case FN_MAILMERGE_EXCLUDE_ENTRY:
+ {
+ // just trigger calling statusChanged() of MMExcludeEntryController
+ // resp. MMCurrentEntryController
+ rSet.InvalidateItem(nWhich);
+ }
+ break;
+ case FN_MAILMERGE_CREATE_DOCUMENTS:
+ case FN_MAILMERGE_SAVE_DOCUMENTS:
+ case FN_MAILMERGE_PRINT_DOCUMENTS:
+ case FN_MAILMERGE_EMAIL_DOCUMENTS:
+ {
+ std::shared_ptr<SwMailMergeConfigItem> xConfigItem;
+ if (SwView* pView = GetActiveView())
+ xConfigItem = pView->EnsureMailMergeConfigItem();
+
+ // #i51949# hide e-Mail option if e-Mail is not supported
+ // #i63267# printing might be disabled
+ // Without attempting to open the database, (in case it is remote or passworded),
+ // hide everything after determining there are no valid results. tdf#121606
+ if (!xConfigItem ||
+ xConfigItem->GetCurrentDBData().sDataSource.isEmpty() ||
+ xConfigItem->GetCurrentDBData().sCommand.isEmpty() ||
+ (xConfigItem->GetConnection().is() && !xConfigItem->GetConnection()->isClosed() && !xConfigItem->GetResultSet().is()) ||
+ (nWhich == FN_MAILMERGE_PRINT_DOCUMENTS && Application::GetSettings().GetMiscSettings().GetDisablePrinting()) ||
+ (nWhich == FN_MAILMERGE_EMAIL_DOCUMENTS && !xConfigItem->IsMailAvailable()))
+ {
+ rSet.DisableItem(nWhich);
+ }
+ }
+ break;
+ default:
+ OSL_FAIL("::StateOther: default");
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+// start field dialog
+static void NewXForms( SfxRequest& rReq ); // implementation: below
+
+std::shared_ptr<SwMailMergeConfigItem> SwView::EnsureMailMergeConfigItem(const SfxItemSet* pArgs)
+{
+ // create if it does not exist yet
+ std::shared_ptr<SwMailMergeConfigItem> xMMConfig = GetMailMergeConfigItem();
+ if (!xMMConfig)
+ {
+ xMMConfig = std::make_shared<SwMailMergeConfigItem>();
+ xMMConfig->SetSourceView(this);
+
+ //set the first used database as default source on the config item
+ const SfxUnoAnyItem* pItem = nullptr;
+ if (pArgs && (pItem = pArgs->GetItemIfSet(
+ FN_PARAM_DATABASE_PROPERTIES, false)))
+ {
+ //mailmerge has been called from the database beamer
+ uno::Sequence< beans::PropertyValue> aDBValues;
+ if (pItem->GetValue() >>= aDBValues)
+ {
+ SwDBData aDBData;
+ svx::ODataAccessDescriptor aDescriptor(aDBValues);
+ aDescriptor[svx::DataAccessDescriptorProperty::DataSource] >>= aDBData.sDataSource;
+ aDescriptor[svx::DataAccessDescriptorProperty::Command] >>= aDBData.sCommand;
+ aDescriptor[svx::DataAccessDescriptorProperty::CommandType] >>= aDBData.nCommandType;
+
+ uno::Reference< sdbc::XConnection> xConnection;
+ uno::Reference< sdbc::XDataSource> xSource;
+ uno::Reference< sdbcx::XColumnsSupplier> xColumnsSupplier;
+ if (aDescriptor.has(svx::DataAccessDescriptorProperty::Connection))
+ aDescriptor[svx::DataAccessDescriptorProperty::Connection] >>= xConnection;
+ uno::Reference<container::XChild> xChild(xConnection, uno::UNO_QUERY);
+ if (xChild.is())
+ xSource.set(xChild->getParent(), uno::UNO_QUERY);
+ xMMConfig->SetCurrentConnection(
+ xSource, SharedConnection(xConnection, SharedConnection::NoTakeOwnership),
+ xColumnsSupplier, aDBData);
+ }
+ }
+ else
+ {
+ std::vector<OUString> aDBNameList;
+ std::vector<OUString> aAllDBNames;
+ GetWrtShell().GetAllUsedDB(aDBNameList, &aAllDBNames);
+ if (!aDBNameList.empty())
+ {
+ OUString sDBName(aDBNameList[0]);
+ SwDBData aDBData;
+ sal_Int32 nIdx{ 0 };
+ aDBData.sDataSource = sDBName.getToken(0, DB_DELIM, nIdx);
+ aDBData.sCommand = sDBName.getToken(0, DB_DELIM, nIdx);
+ aDBData.nCommandType = o3tl::toInt32(o3tl::getToken(sDBName, 0, DB_DELIM, nIdx));
+ //set the currently used database for the wizard
+ xMMConfig->SetCurrentDBData(aDBData);
+ }
+ }
+
+ SetMailMergeConfigItem(xMMConfig);
+ }
+ return xMMConfig;
+}
+
+#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
+
+namespace
+{
+
+SwView* lcl_LoadDoc(SwView* pView, const OUString& rURL)
+{
+ SwView* pNewView = nullptr;
+ if(!rURL.isEmpty())
+ {
+ SfxStringItem aURL(SID_FILE_NAME, rURL);
+ SfxStringItem aTargetFrameName( SID_TARGETNAME, "_blank" );
+ SfxBoolItem aHidden( SID_HIDDEN, true );
+ SfxStringItem aReferer(SID_REFERER, pView->GetDocShell()->GetTitle());
+ const SfxPoolItemHolder aResult(
+ pView->GetViewFrame().GetDispatcher()->ExecuteList(SID_OPENDOC,
+ SfxCallMode::SYNCHRON,
+ { &aURL, &aHidden, &aReferer, &aTargetFrameName }));
+ const SfxObjectItem* pItem(static_cast<const SfxObjectItem*>(aResult.getItem()));
+ SfxShell* pShell = pItem ? pItem->GetShell() : nullptr;
+
+ if(pShell)
+ {
+ SfxViewShell* pViewShell = pShell->GetViewShell();
+ if(pViewShell)
+ {
+ pNewView = dynamic_cast<SwView*>(pViewShell);
+ if (pNewView)
+ {
+ pNewView->GetViewFrame().GetFrame().Appear();
+ }
+ else
+ {
+ pViewShell->GetViewFrame().DoClose();
+ }
+ }
+ }
+ }
+ else
+ {
+ SfxStringItem aFactory(SID_NEWDOCDIRECT, SwDocShell::Factory().GetFilterContainer()->GetName());
+ const SfxPoolItemHolder aResult(pView->GetViewFrame().GetDispatcher()->ExecuteList(
+ SID_NEWDOCDIRECT,
+ SfxCallMode::SYNCHRON, { &aFactory }));
+ const SfxFrameItem* pItem(static_cast<const SfxFrameItem*>(aResult.getItem()));
+ SfxFrame* pFrame = pItem ? pItem->GetFrame() : nullptr;
+ SfxViewFrame* pViewFrame = pFrame ? pFrame->GetCurrentViewFrame() : nullptr;
+ pNewView = pViewFrame ? dynamic_cast<SwView*>( pViewFrame->GetViewShell() ) : nullptr;
+ }
+
+ return pNewView;
+}
+
+class SwMailMergeWizardExecutor : public salhelper::SimpleReferenceObject
+{
+ SwView* m_pView; // never owner
+ SwView* m_pView2Close; // never owner
+ VclPtr<AbstractMailMergeWizard> m_pWizard; // always owner
+ VclPtr<AbstractMailMergeWizard> m_pWizardToDestroyInCallback;
+
+ void EndDialogHdl(sal_Int32 nResponse);
+ DECL_LINK( DestroyDialogHdl, void*, void );
+ DECL_LINK( DestroyWizardHdl, void*, void );
+ DECL_LINK( CancelHdl, void*, void );
+ DECL_LINK( CloseFrameHdl, void*, void );
+
+ void ExecutionFinished();
+ void ExecuteWizard();
+
+public:
+ SwMailMergeWizardExecutor();
+ virtual ~SwMailMergeWizardExecutor() override;
+
+ void ExecuteMailMergeWizard( const SfxItemSet * pArgs );
+};
+
+SwMailMergeWizardExecutor::SwMailMergeWizardExecutor()
+ : m_pView( nullptr ),
+ m_pView2Close( nullptr ),
+ m_pWizard( nullptr )
+{
+}
+
+SwMailMergeWizardExecutor::~SwMailMergeWizardExecutor()
+{
+ OSL_ENSURE( m_pWizard == nullptr, "SwMailMergeWizardExecutor: m_pWizard must be Null!" );
+}
+
+bool lcl_hasAllComponentsAvailable()
+{
+ try
+ {
+ return css::sdb::TextConnectionSettings::create(comphelper::getProcessComponentContext()).is();
+ }
+ catch (const css::uno::Exception &)
+ {
+ TOOLS_INFO_EXCEPTION(
+ "sw.core", "assuming Base to be missing; caught ");
+ return false;
+ }
+}
+
+void SwMailMergeWizardExecutor::ExecuteMailMergeWizard( const SfxItemSet * pArgs )
+{
+ if(!lcl_hasAllComponentsAvailable())
+ {
+ if (officecfg::Office::Common::PackageKit::EnableBaseInstallation::get())
+ {
+ try
+ {
+ using namespace org::freedesktop::PackageKit;
+ using namespace svtools;
+ css::uno::Reference< XSyncDbusSessionHelper > xSyncDbusSessionHelper(SyncDbusSessionHelper::create(comphelper::getProcessComponentContext()));
+ const css::uno::Sequence< OUString > vPackages{ "libreoffice-base" };
+ xSyncDbusSessionHelper->InstallPackageNames(vPackages, OUString());
+ SolarMutexGuard aGuard;
+ executeRestartDialog(comphelper::getProcessComponentContext(), nullptr, RESTART_REASON_MAILMERGE_INSTALL);
+ }
+ catch (const css::uno::Exception &)
+ {
+ TOOLS_INFO_EXCEPTION(
+ "sw.core",
+ "trying to install LibreOffice Base, caught");
+ auto xRestartManager
+ = css::task::OfficeRestartManager::get(comphelper::getProcessComponentContext());
+ if (!xRestartManager->isRestartRequested(false))
+ {
+ // Base is absent, and could not initiate its install - ask user to do that manually
+ // Only show the dialog if restart is not initiated yet
+ std::unique_ptr<weld::MessageDialog> xWarnBox(Application::CreateMessageDialog(
+ nullptr, VclMessageType::Info, VclButtonsType::Ok,
+ SwResId(STR_NO_BASE_FOR_MERGE)));
+ xWarnBox->run();
+ }
+ }
+ } else {
+ auto xRestartManager
+ = css::task::OfficeRestartManager::get(comphelper::getProcessComponentContext());
+ if (!xRestartManager->isRestartRequested(false))
+ {
+ // Base is absent, and could not initiate its install - ask user to do that manually
+ // Only show the dialog if restart is not initiated yet
+ std::unique_ptr<weld::MessageDialog> xWarnBox(Application::CreateMessageDialog(
+ nullptr, VclMessageType::Info, VclButtonsType::Ok,
+ SwResId(STR_NO_BASE_FOR_MERGE)));
+ xWarnBox->run();
+ }
+ }
+ return;
+ }
+ if ( m_pView )
+ {
+ OSL_FAIL("SwMailMergeWizardExecutor::ExecuteMailMergeWizard: Already executing the wizard!" );
+ return;
+ }
+
+ m_pView = ::GetActiveView();
+ if (!m_pView)
+ return;
+
+ // keep self alive until done.
+ acquire();
+
+ // create if it does not exist yet
+ std::shared_ptr<SwMailMergeConfigItem> xMMConfig = m_pView->EnsureMailMergeConfigItem(pArgs);
+
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ m_pWizard = pFact->CreateMailMergeWizard(*m_pView, xMMConfig);
+
+ ExecuteWizard();
+}
+
+void SwMailMergeWizardExecutor::ExecutionFinished()
+{
+ std::shared_ptr<SwMailMergeConfigItem> xMMConfig = m_pView->GetMailMergeConfigItem();
+ if (xMMConfig)
+ xMMConfig->Commit();
+
+ SwDoc* pDoc = m_pView->GetDocShell()->GetDoc();
+ if (pDoc)
+ {
+ SwDBManager* pDbManager = pDoc->GetDBManager();
+ if (pDbManager)
+ pDbManager->CommitLastRegistrations();
+
+ // Show the toolbar
+ m_pView->ShowUIElement("private:resource/toolbar/mailmerge");
+
+ // Update Mail Merge controls
+ const sal_uInt16 slotIds[] = { FN_MAILMERGE_FIRST_ENTRY,
+ FN_MAILMERGE_PREV_ENTRY,
+ FN_MAILMERGE_NEXT_ENTRY,
+ FN_MAILMERGE_LAST_ENTRY,
+ FN_MAILMERGE_CURRENT_ENTRY,
+ FN_MAILMERGE_EXCLUDE_ENTRY,
+ FN_MAILMERGE_CREATE_DOCUMENTS,
+ FN_MAILMERGE_SAVE_DOCUMENTS,
+ FN_MAILMERGE_PRINT_DOCUMENTS,
+ FN_MAILMERGE_EMAIL_DOCUMENTS,
+ 0 };
+ m_pView->GetViewFrame().GetBindings().Invalidate(slotIds);
+ }
+
+ // release/destroy asynchronously
+ Application::PostUserEvent( LINK( this, SwMailMergeWizardExecutor, DestroyDialogHdl ) );
+}
+
+void SwMailMergeWizardExecutor::ExecuteWizard()
+{
+ m_pWizard->StartExecuteAsync([this](sal_Int32 nResult){
+ EndDialogHdl(nResult);
+ });
+}
+
+void SwMailMergeWizardExecutor::EndDialogHdl(sal_Int32 nRet)
+{
+ sal_uInt16 nRestartPage = m_pWizard->GetRestartPage();
+
+ switch ( nRet )
+ {
+ case RET_LOAD_DOC:
+ {
+ SwView* pNewView = lcl_LoadDoc(m_pView, m_pWizard->GetReloadDocument());
+
+ // Destroy wizard asynchronously, since we are deep inside the wizard and dialog
+ // machinery code here
+ m_pWizardToDestroyInCallback = m_pWizard;
+ Application::PostUserEvent(
+ LINK( this, SwMailMergeWizardExecutor, DestroyWizardHdl ), nullptr );
+
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ std::shared_ptr<SwMailMergeConfigItem> xMMConfig = m_pView->GetMailMergeConfigItem();
+ if (pNewView)
+ {
+ pNewView->SetMailMergeConfigItem(xMMConfig);
+ m_pView = pNewView;
+ xMMConfig->DocumentReloaded();
+ //new source view!
+ xMMConfig->SetSourceView( m_pView );
+ m_pWizard = pFact->CreateMailMergeWizard(*m_pView, xMMConfig);
+ m_pWizard->ShowPage( nRestartPage );
+ }
+ else
+ {
+ m_pWizard = pFact->CreateMailMergeWizard(*m_pView, xMMConfig);
+ }
+
+ // execute the wizard again
+ ExecuteWizard();
+ break;
+ }
+ case RET_TARGET_CREATED:
+ {
+ std::shared_ptr<SwMailMergeConfigItem> xMMConfig = m_pView->GetMailMergeConfigItem();
+ SwView* pTargetView = xMMConfig->GetTargetView();
+ OSL_ENSURE(pTargetView, "No target view has been created");
+ if(pTargetView)
+ {
+ // destroy wizard asynchronously
+ m_pWizardToDestroyInCallback = m_pWizard;
+ Application::PostUserEvent(
+ LINK( this, SwMailMergeWizardExecutor, DestroyWizardHdl ), nullptr );
+
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ m_pWizard = pFact->CreateMailMergeWizard(*pTargetView, xMMConfig);
+ m_pWizard->ShowPage( nRestartPage );
+
+ // execute the wizard again
+ ExecuteWizard();
+ }
+ else
+ {
+ // should not happen - just in case no target view has been created
+ ExecutionFinished();
+ }
+ break;
+ }
+ case RET_REMOVE_TARGET:
+ {
+ std::shared_ptr<SwMailMergeConfigItem> xMMConfig = m_pView->GetMailMergeConfigItem();
+ SwView* pTargetView = xMMConfig->GetTargetView();
+ SwView* pSourceView = xMMConfig->GetSourceView();
+ OSL_ENSURE(pTargetView && pSourceView, "source or target view not available" );
+ if(pTargetView && pSourceView)
+ {
+ m_pView2Close = pTargetView;
+ pTargetView->GetViewFrame().GetTopViewFrame()->GetWindow().Hide();
+ pSourceView->GetViewFrame().GetFrame().AppearWithUpdate();
+ // the current view has be set when the target is destroyed
+ m_pView = pSourceView;
+ xMMConfig->SetTargetView(nullptr);
+
+ // destroy wizard asynchronously
+ m_pWizardToDestroyInCallback = m_pWizard;
+ Application::PostUserEvent(
+ LINK( this, SwMailMergeWizardExecutor, CloseFrameHdl ), m_pWizard );
+
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ m_pWizard = pFact->CreateMailMergeWizard(*pSourceView, xMMConfig);
+ m_pWizard->ShowPage( nRestartPage );
+
+ // execute the wizard again
+ ExecuteWizard();
+ }
+ else
+ {
+ // should not happen - just in case no target view has been created
+ ExecutionFinished();
+ }
+ break;
+ }
+ case RET_CANCEL:
+ {
+ // close frame and destroy wizard asynchronously
+ Application::PostUserEvent(
+ LINK( this, SwMailMergeWizardExecutor, CancelHdl ), m_pWizard );
+ break;
+ }
+ default: // finish
+ {
+ std::shared_ptr<SwMailMergeConfigItem> xMMConfig = m_pView->GetMailMergeConfigItem();
+ SwView* pSourceView = xMMConfig ? xMMConfig->GetSourceView() : nullptr;
+ if(pSourceView)
+ {
+ xMMConfig->GetSourceView()->GetViewFrame().GetFrame().Appear();
+ }
+ ExecutionFinished();
+ break;
+ }
+
+ } // switch
+}
+
+IMPL_LINK_NOARG(SwMailMergeWizardExecutor, DestroyDialogHdl, void*, void)
+{
+ m_pWizard.disposeAndClear();
+
+ release();
+}
+
+IMPL_LINK_NOARG(SwMailMergeWizardExecutor, DestroyWizardHdl, void*, void)
+{
+ m_pWizardToDestroyInCallback.disposeAndClear();
+}
+
+IMPL_LINK_NOARG(SwMailMergeWizardExecutor, CancelHdl, void*, void)
+{
+ std::shared_ptr<SwMailMergeConfigItem> xMMConfig = m_pView->GetMailMergeConfigItem();
+ if (xMMConfig)
+ {
+ if (xMMConfig->GetTargetView())
+ {
+ xMMConfig->GetTargetView()->GetViewFrame().DoClose();
+ xMMConfig->SetTargetView(nullptr);
+ }
+ if (xMMConfig->GetSourceView())
+ {
+ auto& rViewFrame(xMMConfig->GetSourceView()->GetViewFrame());
+ rViewFrame.GetFrame().AppearWithUpdate();
+ }
+ xMMConfig->Commit();
+ }
+
+ // Revoke created connections
+ SwDoc* pDoc = m_pView->GetDocShell()->GetDoc();
+ SwDBManager* pDbManager = pDoc->GetDBManager();
+ if (pDbManager)
+ pDbManager->RevokeLastRegistrations();
+
+ m_pWizard.disposeAndClear();
+ release();
+}
+
+IMPL_LINK_NOARG(SwMailMergeWizardExecutor, CloseFrameHdl, void*, void)
+{
+ if ( m_pView2Close )
+ {
+ m_pView2Close->GetViewFrame().DoClose();
+ m_pView2Close = nullptr;
+ }
+ m_pWizardToDestroyInCallback.disposeAndClear();
+}
+} // namespace
+
+#endif // HAVE_FEATURE_DBCONNECTIVITY
+
+void SwModule::ExecOther(SfxRequest& rReq)
+{
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ const SfxPoolItem* pItem = nullptr;
+
+ sal_uInt16 nWhich = rReq.GetSlot();
+ switch (nWhich)
+ {
+ case FN_ENVELOP:
+ InsertEnv( rReq );
+ break;
+
+ case FN_BUSINESS_CARD:
+ case FN_LABEL:
+ InsertLab(rReq, nWhich == FN_LABEL);
+ break;
+
+ case FN_XFORMS_INIT:
+ NewXForms( rReq );
+ break;
+
+ case SID_ATTR_METRIC:
+ if(pArgs && SfxItemState::SET == pArgs->GetItemState(nWhich, false, &pItem))
+ {
+ FieldUnit eUnit = static_cast<FieldUnit>(static_cast<const SfxUInt16Item*>(pItem)->GetValue());
+ switch( eUnit )
+ {
+ case FieldUnit::MM:
+ case FieldUnit::CM:
+ case FieldUnit::INCH:
+ case FieldUnit::PICA:
+ case FieldUnit::POINT:
+ {
+ SwView* pActView = ::GetActiveView();
+ bool bWebView = dynamic_cast<SwWebView*>( pActView ) != nullptr;
+ ::SetDfltMetric(eUnit, bWebView);
+ }
+ break;
+ default:;//prevent warning
+ }
+ }
+ break;
+
+ case FN_SET_MODOPT_TBLNUMFMT:
+ {
+ bool bWebView = dynamic_cast<SwWebView*>( ::GetActiveView() )!= nullptr ,
+ bSet;
+
+ if( pArgs && SfxItemState::SET == pArgs->GetItemState(
+ nWhich, false, &pItem ))
+ bSet = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ else
+ bSet = !m_pModuleConfig->IsInsTableFormatNum( bWebView );
+
+ m_pModuleConfig->SetInsTableFormatNum( bWebView, bSet );
+ }
+ break;
+#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
+ case FN_MAILMERGE_WIZARD:
+ {
+ // show the mailmerge wizard
+ rtl::Reference< SwMailMergeWizardExecutor > xEx( new SwMailMergeWizardExecutor );
+ xEx->ExecuteMailMergeWizard( pArgs );
+ }
+ break;
+ case FN_MAILMERGE_FIRST_ENTRY:
+ case FN_MAILMERGE_PREV_ENTRY:
+ case FN_MAILMERGE_NEXT_ENTRY:
+ case FN_MAILMERGE_LAST_ENTRY:
+ case FN_MAILMERGE_CURRENT_ENTRY:
+ {
+ SwView* pView = ::GetActiveView();
+ if (!pView)
+ return;
+
+ const std::shared_ptr<SwMailMergeConfigItem>& xConfigItem = pView->GetMailMergeConfigItem();
+ if (!xConfigItem)
+ return;
+
+ const bool bHadConnection
+ = xConfigItem->GetConnection().is() && !xConfigItem->GetConnection()->isClosed();
+
+ sal_Int32 nPos = xConfigItem->GetResultSetPosition();
+ switch (nWhich)
+ {
+ case FN_MAILMERGE_FIRST_ENTRY: xConfigItem->MoveResultSet(1); break;
+ case FN_MAILMERGE_PREV_ENTRY: xConfigItem->MoveResultSet(nPos - 1); break;
+ case FN_MAILMERGE_NEXT_ENTRY: xConfigItem->MoveResultSet(nPos + 1); break;
+ case FN_MAILMERGE_LAST_ENTRY: xConfigItem->MoveResultSet(-1); break;
+ case FN_MAILMERGE_CURRENT_ENTRY: /* don't move the result set, just update the document */ break;
+ default: break;
+ }
+
+ // now the record has to be merged into the source document
+ // TODO can we re-use PerformMailMerge() here somehow?
+ const SwDBData& rDBData = xConfigItem->GetCurrentDBData();
+ uno::Sequence<uno::Any> vSelection({ uno::Any(xConfigItem->GetResultSetPosition()) });
+ svx::ODataAccessDescriptor aDescriptor(::comphelper::InitPropertySequence({
+ {"Selection", uno::Any(vSelection)},
+ {"DataSourceName", uno::Any(rDBData.sDataSource)},
+ {"Command", uno::Any(rDBData.sCommand)},
+ {"CommandType", uno::Any(rDBData.nCommandType)},
+ {"ActiveConnection", uno::Any(xConfigItem->GetConnection().getTyped())},
+ {"Filter", uno::Any(xConfigItem->GetFilter())},
+ {"Cursor", uno::Any(xConfigItem->GetResultSet())}
+ }));
+
+ SwWrtShell& rSh = pView->GetWrtShell();
+ SwMergeDescriptor aMergeDesc(DBMGR_MERGE, rSh, aDescriptor);
+ rSh.GetDBManager()->Merge(aMergeDesc);
+
+ // update enabled / disabled status of the buttons in the toolbar
+ SfxBindings& rBindings = rSh.GetView().GetViewFrame().GetBindings();
+ rBindings.Invalidate(FN_MAILMERGE_FIRST_ENTRY);
+ rBindings.Invalidate(FN_MAILMERGE_PREV_ENTRY);
+ rBindings.Invalidate(FN_MAILMERGE_NEXT_ENTRY);
+ rBindings.Invalidate(FN_MAILMERGE_LAST_ENTRY);
+ rBindings.Invalidate(FN_MAILMERGE_CURRENT_ENTRY);
+ rBindings.Invalidate(FN_MAILMERGE_EXCLUDE_ENTRY);
+ if (!bHadConnection && xConfigItem->GetConnection().is()
+ && !xConfigItem->GetConnection()->isClosed())
+ {
+ // The connection has been activated. Update controls that were disabled
+ rBindings.Invalidate(FN_MAILMERGE_CREATE_DOCUMENTS);
+ rBindings.Invalidate(FN_MAILMERGE_SAVE_DOCUMENTS);
+ rBindings.Invalidate(FN_MAILMERGE_PRINT_DOCUMENTS);
+ rBindings.Invalidate(FN_MAILMERGE_EMAIL_DOCUMENTS);
+ }
+ rBindings.Update();
+ }
+ break;
+ case FN_MAILMERGE_CREATE_DOCUMENTS:
+ case FN_MAILMERGE_SAVE_DOCUMENTS:
+ case FN_MAILMERGE_PRINT_DOCUMENTS:
+ case FN_MAILMERGE_EMAIL_DOCUMENTS:
+ {
+ SwView* pView = ::GetActiveView();
+ if (!pView)
+ return;
+
+ std::shared_ptr<SwMailMergeConfigItem> xConfigItem = pView->GetMailMergeConfigItem();
+ assert(xConfigItem);
+ if (!xConfigItem->GetResultSet().is())
+ {
+ // The connection has been attempted, but failed or no results found,
+ // so invalidate the toolbar buttons in case they need to be disabled.
+ SfxBindings& rBindings
+ = pView->GetWrtShell().GetView().GetViewFrame().GetBindings();
+ rBindings.Invalidate(FN_MAILMERGE_CREATE_DOCUMENTS);
+ rBindings.Invalidate(FN_MAILMERGE_SAVE_DOCUMENTS);
+ rBindings.Invalidate(FN_MAILMERGE_PRINT_DOCUMENTS);
+ rBindings.Invalidate(FN_MAILMERGE_EMAIL_DOCUMENTS);
+ rBindings.Invalidate(FN_MAILMERGE_FIRST_ENTRY);
+ rBindings.Invalidate(FN_MAILMERGE_PREV_ENTRY);
+ rBindings.Invalidate(FN_MAILMERGE_NEXT_ENTRY);
+ rBindings.Invalidate(FN_MAILMERGE_LAST_ENTRY);
+ rBindings.Update();
+ return;
+ }
+
+ if (nWhich == FN_MAILMERGE_CREATE_DOCUMENTS)
+ {
+ xConfigItem = SwDBManager::PerformMailMerge(pView);
+
+ if (xConfigItem && xConfigItem->GetTargetView())
+ xConfigItem->GetTargetView()->GetViewFrame().GetFrame().Appear();
+ }
+ else
+ {
+ xConfigItem->SetTargetView(nullptr);
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ if (nWhich == FN_MAILMERGE_SAVE_DOCUMENTS)
+ pFact->ExecuteMMResultSaveDialog(rReq.GetFrameWeld());
+ else if (nWhich == FN_MAILMERGE_PRINT_DOCUMENTS)
+ pFact->ExecuteMMResultPrintDialog(rReq.GetFrameWeld());
+ else if (nWhich == FN_MAILMERGE_EMAIL_DOCUMENTS)
+ pFact->ExecuteMMResultEmailDialog(rReq.GetFrameWeld());
+ }
+ }
+ break;
+#endif
+ }
+}
+
+// Catch notifications
+
+// Catch hint for DocInfo
+void SwModule::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
+{
+ if (rHint.GetId() == SfxHintId::ThisIsAnSfxEventHint)
+ {
+ const SfxEventHint& rEvHint = static_cast<const SfxEventHint&>(rHint);
+ SwDocShell* pDocSh = dynamic_cast<SwDocShell*>(rEvHint.GetObjShell());
+ if( pDocSh )
+ {
+ SwWrtShell* pWrtSh = pDocSh->GetWrtShell();
+ switch (rEvHint.GetEventId())
+ {
+ case SfxEventHintId::LoadFinished:
+ // if it is a new document created from a template,
+ // update fixed fields
+ if (pDocSh->GetMedium())
+ {
+ const SfxBoolItem* pTemplateItem = pDocSh->GetMedium()->GetItemSet().GetItem(SID_TEMPLATE, false);
+ if (pTemplateItem && pTemplateItem->GetValue())
+ {
+ // assume that not calling via SwEditShell::SetFixFields
+ // is allowed, because the shell hasn't been created yet
+ assert(!pWrtSh || pWrtSh->GetView().GetViewFrame().GetFrame().IsClosing_Impl());
+ pDocSh->GetDoc()->getIDocumentFieldsAccess().SetFixFields(nullptr);
+ }
+ }
+ break;
+ case SfxEventHintId::CreateDoc:
+ // Update all FIX-Date/Time fields
+ if( pWrtSh )
+ {
+ const SfxUInt16Item* pUpdateDocItem = pDocSh->GetMedium()->GetItemSet().GetItem(SID_UPDATEDOCMODE, false);
+ bool bUpdateFields = true;
+ if( pUpdateDocItem && pUpdateDocItem->GetValue() == document::UpdateDocMode::NO_UPDATE)
+ bUpdateFields = false;
+ if(bUpdateFields)
+ {
+ comphelper::dispatchCommand(".uno:UpdateInputFields", {});
+
+ // Are database fields contained?
+ // Get all used databases for the first time
+ SwDoc *pDoc = pDocSh->GetDoc();
+ std::vector<OUString> aDBNameList;
+ pDoc->GetAllUsedDB( aDBNameList );
+ if(!aDBNameList.empty())
+ { // Open database beamer
+ ShowDBObj(pWrtSh->GetView(), pDoc->GetDBData());
+ }
+ }
+ }
+ break;
+ default: break;
+ }
+ }
+ }
+ else
+ {
+ if (rHint.GetId() == SfxHintId::Deinitializing)
+ {
+ m_pWebUsrPref.reset();
+ m_pUsrPref.reset();
+ m_pModuleConfig.reset();
+ m_pPrintOptions.reset();
+ m_pWebPrintOptions.reset();
+ m_pChapterNumRules.reset();
+ m_pStdFontConfig.reset();
+ m_pNavigationConfig.reset();
+ m_pToolbarConfig.reset();
+ m_pWebToolbarConfig.reset();
+ m_pDBConfig.reset();
+ if( m_pColorConfig )
+ {
+ m_pColorConfig->RemoveListener(this);
+ m_pColorConfig.reset();
+ }
+ if( m_pAccessibilityOptions )
+ {
+ m_pAccessibilityOptions->RemoveListener(this);
+ m_pAccessibilityOptions.reset();
+ }
+ if( m_pCTLOptions )
+ {
+ m_pCTLOptions->RemoveListener(this);
+ m_pCTLOptions.reset();
+ }
+ if( m_pUserOptions )
+ {
+ m_pUserOptions->RemoveListener(this);
+ m_pUserOptions.reset();
+ }
+ }
+ }
+}
+
+void SwModule::ConfigurationChanged(utl::ConfigurationBroadcaster* pBrdCst, ConfigurationHints eHints)
+{
+ if( pBrdCst == m_pUserOptions.get() )
+ {
+ m_bAuthorInitialised = false;
+ }
+ else if ( pBrdCst == m_pColorConfig.get() )
+ {
+ //invalidate only the current view in tiled rendering mode, or all views otherwise
+ const bool bKit = comphelper::LibreOfficeKit::isActive();
+ SfxViewShell* pViewShell = bKit ? SfxViewShell::Current() : SfxViewShell::GetFirst();
+ while(pViewShell)
+ {
+ if(pViewShell->GetWindow())
+ {
+ auto pSwView = dynamic_cast<SwView *>(pViewShell);
+ if (pSwView)
+ {
+ SwViewOption aNewOptions = *pSwView->GetWrtShell().GetViewOptions();
+ aNewOptions.SetThemeName(svtools::ColorConfig::GetCurrentSchemeName());
+ SwViewColors aViewColors(*m_pColorConfig);
+ aNewOptions.SetColorConfig(aViewColors);
+ const bool bChanged(aNewOptions != *pSwView->GetWrtShell().GetViewOptions());
+ if (bChanged)
+ pSwView->GetWrtShell().ApplyViewOptions(aNewOptions);
+ else if (bKit)
+ {
+ SwXTextDocument* pModel = comphelper::getFromUnoTunnel<SwXTextDocument>(pViewShell->GetCurrentDocument());
+ SfxLokHelper::notifyViewRenderState(pViewShell, pModel);
+ }
+
+ if (bKit)
+ {
+ pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_APPLICATION_BACKGROUND_COLOR,
+ aViewColors.m_aAppBackgroundColor.AsRGBHexString().toUtf8());
+ pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_DOCUMENT_BACKGROUND_COLOR,
+ aViewColors.m_aAppBackgroundColor.AsRGBHexString().toUtf8());
+ }
+
+ // if nothing changed, and the hint was OnlyCurrentDocumentColorScheme we can skip invalidate
+ const bool bSkipInvalidate = !bChanged && bKit && eHints == ConfigurationHints::OnlyCurrentDocumentColorScheme;
+ if (!bSkipInvalidate)
+ pViewShell->GetWindow()->Invalidate();
+ }
+ else if (dynamic_cast< const SwPagePreview *>( pViewShell ) != nullptr ||
+ dynamic_cast< const SwSrcView *>( pViewShell ) != nullptr)
+ {
+ pViewShell->GetWindow()->Invalidate();
+ }
+ }
+ if (bKit)
+ break;
+ pViewShell = SfxViewShell::GetNext( *pViewShell );
+ }
+ }
+#if !ENABLE_WASM_STRIP_ACCESSIBILITY
+ else if ( pBrdCst == m_pAccessibilityOptions.get() )
+ {
+ //set Accessibility options
+ SfxViewShell* pViewShell = SfxViewShell::GetFirst();
+ while(pViewShell)
+ {
+ if(pViewShell->GetWindow())
+ {
+ auto pSwView = dynamic_cast<SwView *>( pViewShell );
+ auto pPagePreview = dynamic_cast<SwPagePreview *>( pViewShell );
+
+ if(pSwView)
+ pSwView->ApplyAccessibilityOptions();
+ else if(pPagePreview)
+ pPagePreview->ApplyAccessibilityOptions();
+
+ if(pSwView || pPagePreview || dynamic_cast< const SwSrcView *>( pViewShell ) != nullptr)
+ {
+ pViewShell->GetWindow()->Invalidate();
+ }
+ }
+ pViewShell = SfxViewShell::GetNext( *pViewShell );
+ }
+ }
+#endif
+ else if( pBrdCst == m_pCTLOptions.get() )
+ {
+ const SfxObjectShell* pObjSh = SfxObjectShell::GetFirst();
+ while( pObjSh )
+ {
+ if( auto pDocShell = dynamic_cast<const SwDocShell*>(pObjSh) )
+ {
+ SwDoc* pDoc = const_cast<SwDocShell*>(pDocShell)->GetDoc();
+ SwViewShell* pVSh = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
+ if ( pVSh )
+ pVSh->ChgNumberDigits();
+ }
+ pObjSh = SfxObjectShell::GetNext(*pObjSh);
+ }
+ }
+
+}
+
+SwDBConfig* SwModule::GetDBConfig()
+{
+ if(!m_pDBConfig)
+ m_pDBConfig.reset(new SwDBConfig);
+ return m_pDBConfig.get();
+}
+
+svtools::ColorConfig& SwModule::GetColorConfig()
+{
+ if(!m_pColorConfig)
+ {
+ m_pColorConfig.reset(new svtools::ColorConfig);
+ SwViewOption::SetInitialColorConfig(*m_pColorConfig);
+ m_pColorConfig->AddListener(this);
+ }
+ return *m_pColorConfig;
+}
+
+SvtUserOptions& SwModule::GetUserOptions()
+{
+ if(!m_pUserOptions)
+ {
+ m_pUserOptions.reset(new SvtUserOptions);
+ m_pUserOptions->AddListener(this);
+ }
+ return *m_pUserOptions;
+}
+
+const SwMasterUsrPref *SwModule::GetUsrPref(bool bWeb) const
+{
+ SwModule* pNonConstModule = const_cast<SwModule*>(this);
+ if(bWeb && !m_pWebUsrPref)
+ {
+ // The SpellChecker is needed in SwMasterUsrPref's Load, but it must not
+ // be created there #58256#
+ pNonConstModule->m_pWebUsrPref.reset(new SwMasterUsrPref(true));
+ }
+ else if(!bWeb && !m_pUsrPref)
+ {
+ pNonConstModule->m_pUsrPref.reset(new SwMasterUsrPref(false));
+ }
+ return bWeb ? m_pWebUsrPref.get() : m_pUsrPref.get();
+}
+
+void NewXForms( SfxRequest& rReq )
+{
+ // copied & excerpted from SwModule::InsertLab(..)
+
+ // create new document
+ SwDocShellRef xDocSh( new SwDocShell( SfxObjectCreateMode::STANDARD) );
+ xDocSh->DoInitNew();
+
+ // initialize XForms
+ xDocSh->GetDoc()->initXForms(true);
+
+ // load document into frame
+ SfxViewFrame::DisplayNewDocument( *xDocSh, rReq );
+
+ // set return value
+ rReq.SetReturnValue( SfxVoidItem( rReq.GetSlot() ) );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/app/applab.cxx b/sw/source/uibase/app/applab.cxx
new file mode 100644
index 0000000000..f440fefe86
--- /dev/null
+++ b/sw/source/uibase/app/applab.cxx
@@ -0,0 +1,397 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_features.h>
+#include <config_fuzzers.h>
+
+#include <hintids.hxx>
+
+#include <comphelper/string.hxx>
+#include <svl/voiditem.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <editeng/pbinitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <com/sun/star/frame/XModel.hpp>
+#include <osl/diagnose.h>
+#include <fmthdft.hxx>
+#include <fmtanchr.hxx>
+#include <fmtfsize.hxx>
+#include <fmtornt.hxx>
+#include <swwait.hxx>
+#include <gloshdl.hxx>
+#include <swmodule.hxx>
+#include <view.hxx>
+#include <docsh.hxx>
+#include <fldbas.hxx>
+#include <wrtsh.hxx>
+#include <cmdid.h>
+#include <dbmgr.hxx>
+#include <fldmgr.hxx>
+#include <labimg.hxx>
+#include <section.hxx>
+#include <pagedesc.hxx>
+#include <poolfmt.hxx>
+
+#include <strings.hrc>
+#include <swabstdlg.hxx>
+
+#include <IDocumentDeviceAccess.hxx>
+
+#include "appenv.hxx"
+#include <memory>
+
+using namespace ::com::sun::star;
+
+constexpr OUString MASTER_LABEL = u"MasterLabel"_ustr;
+
+static const SwFrameFormat *lcl_InsertBCText( SwWrtShell& rSh, const SwLabItem& rItem,
+ SwFrameFormat &rFormat,
+ sal_uInt16 nCol, sal_uInt16 nRow )
+{
+ SfxItemSetFixed<RES_VERT_ORIENT, RES_ANCHOR> aSet( rSh.GetAttrPool() );
+ sal_uInt16 nPhyPageNum, nVirtPageNum;
+ rSh.GetPageNum( nPhyPageNum, nVirtPageNum );
+
+ //anchor frame to page
+ aSet.Put( SwFormatAnchor( RndStdIds::FLY_AT_PAGE, nPhyPageNum ) );
+ aSet.Put( SwFormatHoriOrient( rItem.m_lLeft + static_cast<SwTwips>(nCol) * rItem.m_lHDist,
+ text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME ) );
+ aSet.Put( SwFormatVertOrient( rItem.m_lUpper + static_cast<SwTwips>(nRow) * rItem.m_lVDist,
+ text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME ) );
+ const SwFrameFormat *pFormat = rSh.NewFlyFrame(aSet, true, &rFormat ); // Insert Fly
+ OSL_ENSURE( pFormat, "Fly not inserted" );
+
+ rSh.UnSelectFrame(); //Frame was selected automatically
+
+ rSh.SetTextFormatColl( rSh.GetTextCollFromPool( RES_POOLCOLL_STANDARD ) );
+
+ if(!rItem.m_bSynchron || !(nCol|nRow))
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ::GlossarySetActGroup fnSetActGroup = pFact->SetGlossaryActGroupFunc();
+ if ( fnSetActGroup )
+ (*fnSetActGroup)( rItem.m_sGlossaryGroup );
+ SwGlossaryHdl* pGlosHdl = rSh.GetView().GetGlosHdl();
+ pGlosHdl->SetCurGroup(rItem.m_sGlossaryGroup, true);
+ pGlosHdl->InsertGlossary( rItem.m_sGlossaryBlockName );
+ }
+
+ return pFormat;
+}
+
+static const SwFrameFormat *lcl_InsertLabText( SwWrtShell& rSh, const SwLabItem& rItem,
+ SwFrameFormat &rFormat, SwFieldMgr& rFieldMgr,
+ sal_uInt16 nCol, sal_uInt16 nRow, bool bLast )
+{
+ SfxItemSetFixed<RES_VERT_ORIENT, RES_ANCHOR> aSet( rSh.GetAttrPool() );
+ sal_uInt16 nPhyPageNum, nVirtPageNum;
+ rSh.GetPageNum( nPhyPageNum, nVirtPageNum );
+
+ //anchor frame to page
+ aSet.Put( SwFormatAnchor( RndStdIds::FLY_AT_PAGE, nPhyPageNum ) );
+ aSet.Put( SwFormatHoriOrient( rItem.m_lLeft + static_cast<SwTwips>(nCol) * rItem.m_lHDist,
+ text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME ) );
+ aSet.Put( SwFormatVertOrient( rItem.m_lUpper + static_cast<SwTwips>(nRow) * rItem.m_lVDist,
+ text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME ) );
+ const SwFrameFormat *pFormat = rSh.NewFlyFrame(aSet, true, &rFormat ); // Insert Fly
+ OSL_ENSURE( pFormat, "Fly not inserted" );
+
+ rSh.UnSelectFrame(); //Frame was selected automatically
+
+ rSh.SetTextFormatColl( rSh.GetTextCollFromPool( RES_POOLCOLL_STANDARD ) );
+
+ // If applicable "next dataset"
+ OUString sDBName;
+ if( (!rItem.m_bSynchron || !(nCol|nRow)) && !(sDBName = InsertLabEnvText( rSh, rFieldMgr, rItem.m_aWriting )).isEmpty() && !bLast )
+ {
+ sDBName = comphelper::string::setToken(sDBName, 3, DB_DELIM, u"True");
+ SwInsertField_Data aData(SwFieldTypesEnum::DatabaseNextSet, 0, sDBName, OUString(), 0, &rSh);
+ rFieldMgr.InsertField( aData );
+ }
+
+ return pFormat;
+}
+
+void SwModule::InsertLab(SfxRequest& rReq, bool bLabel)
+{
+ static sal_uInt16 nLabelTitleNo = 0;
+ static sal_uInt16 nBCTitleNo = 0;
+
+#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
+ // Create DB-Manager
+ std::unique_ptr<SwDBManager> pDBManager(new SwDBManager(nullptr));
+#endif
+
+ // Read SwLabItem from Config
+ SwLabCfgItem aLabCfg(bLabel);
+
+ // Move up Dialog
+ SfxItemSetFixed<FN_LABEL, FN_LABEL> aSet( GetPool() );
+ aSet.Put( aLabCfg.GetItem() );
+
+ SwAbstractDialogFactory* pDialogFactory = SwAbstractDialogFactory::Create();
+
+ ScopedVclPtr<AbstractSwLabDlg> pDlg(pDialogFactory->CreateSwLabDlg(rReq.GetFrameWeld(), aSet,
+#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
+ pDBManager.get(),
+#else
+ NULL,
+#endif
+ bLabel));
+
+ if ( RET_OK != pDlg->Execute() )
+ return;
+
+ // Read dialog, store item in config
+ const SwLabItem& rItem = static_cast<const SwLabItem&>( pDlg->
+ GetOutputItemSet()->Get(FN_LABEL));
+ aLabCfg.GetItem() = rItem;
+ aLabCfg.Commit();
+
+ // Create new document
+ SfxObjectShellLock xDocSh( new SwDocShell( SfxObjectCreateMode::STANDARD));
+ xDocSh->DoInitNew();
+
+ // Printer
+ Printer *pPrt = pDlg->GetPrt();
+ if (pPrt)
+ {
+ SwDocShell *pDocSh = static_cast<SwDocShell*>(&*xDocSh);
+ pDocSh->getIDocumentDeviceAccess().setJobsetup(pPrt->GetJobSetup());
+ }
+
+ SfxViewFrame* pViewFrame = SfxViewFrame::DisplayNewDocument( *xDocSh, rReq );
+ if (!pViewFrame)
+ return;
+
+ SwView *pNewView = static_cast<SwView*>( pViewFrame->GetViewShell());
+ pNewView->AttrChangedNotify(nullptr);// So that SelectShell is being called.
+
+ // Set document title
+ OUString aTmp;
+ if(bLabel)
+ {
+ aTmp = SwResId( STR_LAB_TITLE) +
+ OUString::number(++nLabelTitleNo );
+ }
+ else
+ {
+ aTmp = pDlg->GetBusinessCardStr() +
+ OUString::number( ++nBCTitleNo );
+ }
+ xDocSh->SetTitle( aTmp );
+
+ pViewFrame->GetFrame().Appear();
+
+ // Determine Shell
+ SwWrtShell *pSh = pNewView->GetWrtShellPtr();
+ OSL_ENSURE( pSh, "missing WrtShell" );
+
+ if (pSh)
+ { // block for locks the dispatcher!!
+
+ SwWait aWait( static_cast<SwDocShell&>(*xDocSh), true );
+
+ CurrShell aCurr(pSh);
+ pSh->SetLabelDoc(rItem.m_bSynchron);
+ pSh->DoUndo( false );
+ pSh->StartAllAction();
+
+ pSh->SetNewDoc(); // Avoid performance problems
+
+ SwPageDesc aDesc = pSh->GetPageDesc( 0 );
+ SwFrameFormat& rFormat = aDesc.GetMaster();
+
+ // Borders
+ SvxLRSpaceItem aLRMargin( RES_LR_SPACE );
+ SvxULSpaceItem aULMargin( RES_UL_SPACE );
+ aLRMargin.SetLeft (o3tl::narrowing<sal_uInt16>(rItem.m_lLeft) );
+ aULMargin.SetUpper(o3tl::narrowing<sal_uInt16>(rItem.m_lUpper));
+ aLRMargin.SetRight( 0 );
+ aULMargin.SetLower( 0 );
+ rFormat.SetFormatAttr(aLRMargin);
+ rFormat.SetFormatAttr(aULMargin);
+
+ // Header and footer
+ rFormat.SetFormatAttr(SwFormatHeader(false));
+ aDesc.ChgHeaderShare(false);
+ rFormat.SetFormatAttr(SwFormatFooter(false));
+ aDesc.ChgFooterShare(false);
+
+ aDesc.SetUseOn(UseOnPage::All); // Site numbering
+
+ // Set page size
+ tools::Long lPgWidth, lPgHeight;
+ lPgWidth = std::max<sal_Int32>(rItem.m_lPWidth, MINLAY);
+ lPgHeight = std::max<sal_Int32>(rItem.m_lPHeight, MINLAY);
+ rFormat.SetFormatAttr( SwFormatFrameSize( SwFrameSize::Fixed, lPgWidth, lPgHeight ));
+ // Numbering type
+ SvxNumberType aType;
+ aType.SetNumberingType(SVX_NUM_NUMBER_NONE);
+ aDesc.SetNumType( aType );
+
+ // Followup template
+ const SwPageDesc &rFollow = pSh->GetPageDesc( pSh->GetCurPageDesc() );
+ aDesc.SetFollow( &rFollow );
+
+ pPrt = pSh->getIDocumentDeviceAccess().getPrinter( true );
+ SvxPaperBinItem aItem( RES_PAPER_BIN );
+ aItem.SetValue(static_cast<sal_Int8>(pPrt->GetPaperBin()));
+ rFormat.SetFormatAttr(aItem);
+
+ // Determine orientation of the resulting page
+ aDesc.SetLandscape(rItem.m_lPWidth > rItem.m_lPHeight);
+
+ pSh->ChgPageDesc( 0, aDesc );
+
+ // Insert frame
+ std::optional<SwFieldMgr> pFieldMgr;
+ pFieldMgr.emplace();
+ pFieldMgr->SetEvalExpFields(false);
+
+ // Prepare border template
+ SwFrameFormat* pFormat = pSh->GetFrameFormatFromPool( RES_POOLFRM_LABEL );
+ sal_Int32 iResultWidth = rItem.m_lLeft + (rItem.m_nCols - 1) * rItem.m_lHDist + rItem.m_lWidth - rItem.m_lPWidth;
+ sal_Int32 iResultHeight = rItem.m_lUpper + (rItem.m_nRows - 1) * rItem.m_lVDist + rItem.m_lHeight - rItem.m_lPHeight;
+ sal_Int32 iWidth = (iResultWidth > 0 ? rItem.m_lWidth - (iResultWidth / rItem.m_nCols) - 1 : rItem.m_lWidth);
+ sal_Int32 iHeight = (iResultHeight > 0 ? rItem.m_lHeight - (iResultHeight / rItem.m_nRows) - 1 : rItem.m_lHeight);
+ SwFormatFrameSize aFrameSize( SwFrameSize::Fixed, iWidth, iHeight );
+ pFormat->SetFormatAttr( aFrameSize );
+
+ //frame represents label itself, no border space
+ SvxULSpaceItem aFrameNoULSpace( 0, 0, RES_UL_SPACE );
+ SvxLRSpaceItem aFrameNoLRSpace( 0, 0, 0, RES_LR_SPACE );
+ pFormat->SetFormatAttr( aFrameNoULSpace );
+ pFormat->SetFormatAttr( aFrameNoLRSpace );
+
+ const SwFrameFormat *pFirstFlyFormat = nullptr;
+ if ( rItem.m_bPage )
+ {
+ SwFormatVertOrient aFrameVertOrient( pFormat->GetVertOrient() );
+ aFrameVertOrient.SetVertOrient( text::VertOrientation::TOP );
+ pFormat->SetFormatAttr(aFrameVertOrient);
+
+ for ( sal_Int32 i = 0; i < rItem.m_nRows; ++i )
+ {
+ for ( sal_Int32 j = 0; j < rItem.m_nCols; ++j )
+ {
+ pSh->Push();
+ const SwFrameFormat *pTmp = ( bLabel ?
+ lcl_InsertLabText( *pSh, rItem, *pFormat, *pFieldMgr, j, i,
+ i == rItem.m_nRows - 1 && j == rItem.m_nCols - 1 ) :
+ lcl_InsertBCText( *pSh, rItem, *pFormat, j, i ) );
+ if (!(i|j))
+ {
+ pFirstFlyFormat = pTmp;
+
+ if (rItem.m_bSynchron)
+ {
+ // if there is no content in the fly then
+ // don't leave the fly!!!
+ pSh->Push();
+ pSh->StartOfSection();
+ bool bInFly = nullptr != pSh->WizardGetFly();
+ pSh->Pop(bInFly ? SwCursorShell::PopMode::DeleteStack : SwCursorShell::PopMode::DeleteCurrent);
+
+ if( bInFly )
+ pSh->EndOfSection(true); // select all content
+ // in the fly
+ else
+ pSh->SetMark(); // set only the mark
+
+ SwSectionData aSect(SectionType::Content, MASTER_LABEL);
+ pSh->InsertSection(aSect);
+ }
+ }
+ else if (rItem.m_bSynchron)
+ {
+ SwSectionData aSect(SectionType::FileLink,
+ pSh->GetUniqueSectionName());
+ OUString sLinkName =
+ OUStringChar(sfx2::cTokenSeparator) +
+ OUStringChar(sfx2::cTokenSeparator) +
+ MASTER_LABEL;
+ aSect.SetLinkFileName(sLinkName);
+ aSect.SetProtectFlag(true);
+ pSh->Insert("."); // Dummytext to allocate the Section
+ pSh->StartOfSection();
+ pSh->EndOfSection(true); // Select everything in the frame
+ pSh->InsertSection(aSect);
+ }
+ pSh->Pop(SwCursorShell::PopMode::DeleteCurrent);
+ }
+ }
+ }
+ else
+ {
+ pFirstFlyFormat = bLabel ?
+ lcl_InsertLabText( *pSh, rItem, *pFormat, *pFieldMgr,
+ static_cast< sal_uInt16 >(rItem.m_nCol - 1),
+ static_cast< sal_uInt16 >(rItem.m_nRow - 1), true ) :
+ lcl_InsertBCText(*pSh, rItem, *pFormat,
+ static_cast< sal_uInt16 >(rItem.m_nCol - 1),
+ static_cast< sal_uInt16 >(rItem.m_nRow - 1));
+ }
+
+ //fill the user fields
+ if(!bLabel)
+ {
+ uno::Reference< frame::XModel > xModel = pSh->GetView().GetDocShell()->GetBaseModel();
+ OSL_ENSURE(pDialogFactory, "SwAbstractDialogFactory fail!");
+ SwLabDlgMethod SwLabDlgUpdateFieldInformation = pDialogFactory->GetSwLabDlgStaticMethod ();
+ SwLabDlgUpdateFieldInformation(xModel, rItem);
+ }
+
+ pFieldMgr->SetEvalExpFields(true);
+ pFieldMgr->EvalExpFields(pSh);
+
+ pFieldMgr.reset();
+
+ if (pFirstFlyFormat)
+ pSh->GotoFly(pFirstFlyFormat->GetName(), FLYCNTTYPE_ALL, false);
+
+ if (pSh->IsAnyDatabaseFieldInDoc())
+ pSh->GetView().ShowUIElement("private:resource/toolbar/mailmerge");
+
+ pSh->EndAllAction();
+ pSh->DoUndo();
+ }
+
+ if (pSh && rItem.m_aWriting.indexOf('<') >= 0)
+ {
+ // Open database browser on recently used database
+ ShowDBObj( *pNewView, pSh->GetDBData() );
+ }
+
+ if( rItem.m_bSynchron )
+ {
+ SfxDispatcher* pDisp = pViewFrame->GetDispatcher();
+ assert(pDisp && "No dispatcher in frame?");
+ pDisp->Execute(FN_SYNC_LABELS, SfxCallMode::ASYNCHRON);
+ }
+ rReq.SetReturnValue(SfxVoidItem(bLabel ? FN_LABEL : FN_BUSINESS_CARD));
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/app/appopt.cxx b/sw/source/uibase/app/appopt.cxx
new file mode 100644
index 0000000000..7be59a1dab
--- /dev/null
+++ b/sw/source/uibase/app/appopt.cxx
@@ -0,0 +1,527 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <cmdid.h>
+
+#include <com/sun/star/i18n/ScriptType.hpp>
+
+#include <sal/log.hxx>
+#include <hintids.hxx>
+#include <svl/eitem.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <sfx2/bindings.hxx>
+#include <editeng/brushitem.hxx>
+#include <editeng/tstpitem.hxx>
+#include <svx/optgrid.hxx>
+#include <svx/dialogs.hrc>
+#include <tools/UnitConversion.hxx>
+#include <i18nlangtag/mslangid.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <fontcfg.hxx>
+#include <swmodule.hxx>
+#include <view.hxx>
+#include <doc.hxx>
+#include <wrtsh.hxx>
+#include <IDocumentDeviceAccess.hxx>
+#include <IDocumentSettingAccess.hxx>
+#include <uitool.hxx>
+#include <wview.hxx>
+#include <cfgitems.hxx>
+#include <prtopt.hxx>
+#include <pview.hxx>
+#include <usrpref.hxx>
+#include <uiitems.hxx>
+#include <editeng/langitem.hxx>
+#include <unotools/lingucfg.hxx>
+#include <globals.hrc>
+#include <swabstdlg.hxx>
+#include <swwrtshitem.hxx>
+
+#include <sfx2/dispatch.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+
+std::optional<SfxItemSet> SwModule::CreateItemSet( sal_uInt16 nId )
+{
+ bool bTextDialog = (nId == SID_SW_EDITOPTIONS);
+
+ // the options for the Web- and Textdialog are put together here
+ SwViewOption aViewOpt = *GetUsrPref(!bTextDialog);
+ SwMasterUsrPref* pPref = bTextDialog ? m_pUsrPref.get() : m_pWebUsrPref.get();
+ // no MakeUsrPref, because only options from textdoks can be used here
+ SwView* pAppView = GetView();
+ if(pAppView && &pAppView->GetViewFrame() != SfxViewFrame::Current())
+ pAppView = nullptr;
+ if(pAppView)
+ {
+ bool bWebView = dynamic_cast<SwWebView*>( pAppView ) != nullptr;
+ // if Text then no WebView and vice versa
+ if (bWebView != bTextDialog)
+ {
+ aViewOpt = *pAppView->GetWrtShell().GetViewOptions();
+ }
+ else
+ pAppView = nullptr; // with View, there's nothing to win here
+ }
+
+ // Options/Edit
+ SfxItemSetFixed<
+ RES_BACKGROUND, RES_BACKGROUND,
+ XATTR_FILL_FIRST, XATTR_FILL_LAST,
+ SID_PRINTPREVIEW, SID_PRINTPREVIEW,
+ SID_ATTR_GRID_OPTIONS, SID_ATTR_GRID_OPTIONS,
+ SID_HTML_MODE, SID_HTML_MODE,
+ SID_ATTR_CHAR_CJK_LANGUAGE, SID_ATTR_CHAR_CJK_LANGUAGE,
+ SID_ATTR_CHAR_CTL_LANGUAGE, SID_ATTR_CHAR_CTL_LANGUAGE,
+ SID_ATTR_LANGUAGE, SID_ATTR_METRIC,
+ SID_ATTR_DEFTABSTOP, SID_ATTR_DEFTABSTOP,
+ SID_ATTR_APPLYCHARUNIT, SID_ATTR_APPLYCHARUNIT,
+ FN_HSCROLL_METRIC, FN_VSCROLL_METRIC,
+ FN_PARAM_ADDPRINTER, FN_PARAM_ADDPRINTER,
+ FN_PARAM_DOCDISP, FN_PARAM_ELEM,
+ FN_PARAM_PRINTER, FN_PARAM_STDFONTS,
+ FN_PARAM_WRTSHELL, FN_PARAM_WRTSHELL,
+ FN_PARAM_SHADOWCURSOR, FN_PARAM_SHADOWCURSOR,
+ FN_PARAM_CRSR_IN_PROTECTED, FN_PARAM_CRSR_IN_PROTECTED>
+ aRet(GetPool());
+
+ aRet.Put( SwDocDisplayItem( aViewOpt ) );
+ aRet.Put( SwElemItem( aViewOpt ) );
+ if( bTextDialog )
+ {
+ aRet.Put( SwShadowCursorItem( aViewOpt ));
+ aRet.Put( SfxBoolItem(FN_PARAM_CRSR_IN_PROTECTED, aViewOpt.IsCursorInProtectedArea()));
+ }
+
+ if( pAppView )
+ {
+ SwWrtShell& rWrtShell = pAppView->GetWrtShell();
+
+ SfxPrinter* pPrt = rWrtShell.getIDocumentDeviceAccess().getPrinter( false );
+ if( pPrt )
+ aRet.Put(SwPtrItem(FN_PARAM_PRINTER, pPrt));
+ aRet.Put(SwPtrItem(FN_PARAM_WRTSHELL, &rWrtShell));
+
+ aRet.Put(rWrtShell.GetDefault(RES_CHRATR_LANGUAGE).CloneSetWhich(SID_ATTR_LANGUAGE));
+ aRet.Put(rWrtShell.GetDefault(RES_CHRATR_CJK_LANGUAGE).CloneSetWhich(SID_ATTR_CHAR_CJK_LANGUAGE));
+ aRet.Put(rWrtShell.GetDefault(RES_CHRATR_CTL_LANGUAGE).CloneSetWhich(SID_ATTR_CHAR_CTL_LANGUAGE));
+ }
+ else
+ {
+ SvtLinguConfig aLinguCfg;
+ css::lang::Locale aLocale;
+ LanguageType nLang;
+
+ using namespace ::com::sun::star::i18n::ScriptType;
+
+ Any aLang = aLinguCfg.GetProperty(u"DefaultLocale");
+ aLang >>= aLocale;
+ nLang = MsLangId::resolveSystemLanguageByScriptType(LanguageTag::convertToLanguageType( aLocale, false), LATIN);
+ aRet.Put(SvxLanguageItem(nLang, SID_ATTR_LANGUAGE));
+
+ aLang = aLinguCfg.GetProperty(u"DefaultLocale_CJK");
+ aLang >>= aLocale;
+ nLang = MsLangId::resolveSystemLanguageByScriptType(LanguageTag::convertToLanguageType( aLocale, false), ASIAN);
+ aRet.Put(SvxLanguageItem(nLang, SID_ATTR_CHAR_CJK_LANGUAGE));
+
+ aLang = aLinguCfg.GetProperty(u"DefaultLocale_CTL");
+ aLang >>= aLocale;
+ nLang = MsLangId::resolveSystemLanguageByScriptType(LanguageTag::convertToLanguageType( aLocale, false), COMPLEX);
+ aRet.Put(SvxLanguageItem(nLang, SID_ATTR_CHAR_CTL_LANGUAGE));
+ }
+ if(bTextDialog)
+ aRet.Put(SwPtrItem(FN_PARAM_STDFONTS, GetStdFontConfig()));
+ if( dynamic_cast<SwPagePreview*>( SfxViewShell::Current())!=nullptr )
+ {
+ SfxBoolItem aBool(SfxBoolItem(SID_PRINTPREVIEW, true));
+ aRet.Put(aBool);
+ }
+
+ FieldUnit eUnit = pPref->GetHScrollMetric();
+ if(pAppView)
+ pAppView->GetHRulerMetric(eUnit);
+ aRet.Put(SfxUInt16Item( FN_HSCROLL_METRIC, static_cast< sal_uInt16 >(eUnit)));
+
+ eUnit = pPref->GetVScrollMetric();
+ if(pAppView)
+ pAppView->GetVRulerMetric(eUnit);
+ aRet.Put(SfxUInt16Item( FN_VSCROLL_METRIC, static_cast< sal_uInt16 >(eUnit) ));
+ aRet.Put(SfxUInt16Item( SID_ATTR_METRIC, static_cast< sal_uInt16 >(pPref->GetMetric()) ));
+ aRet.Put(SfxBoolItem(SID_ATTR_APPLYCHARUNIT, pPref->IsApplyCharUnit()));
+ if(bTextDialog)
+ {
+ if(pAppView)
+ {
+ const SvxTabStopItem& rDefTabs =
+ pAppView->GetWrtShell().GetDefault(RES_PARATR_TABSTOP);
+ aRet.Put( SfxUInt16Item( SID_ATTR_DEFTABSTOP, o3tl::narrowing<sal_uInt16>(::GetTabDist(rDefTabs))));
+ }
+ else
+ aRet.Put(SfxUInt16Item( SID_ATTR_DEFTABSTOP, o3tl::toTwips(pPref->GetDefTabInMm100(), o3tl::Length::mm100)));
+ }
+
+ // Options for GridTabPage
+ SvxGridItem aGridItem( SID_ATTR_GRID_OPTIONS);
+
+ aGridItem.SetUseGridSnap( aViewOpt.IsSnap());
+ aGridItem.SetSynchronize( aViewOpt.IsSynchronize());
+ aGridItem.SetGridVisible( aViewOpt.IsGridVisible());
+
+ const Size& rSnapSize = aViewOpt.GetSnapSize();
+ aGridItem.SetFieldDrawX( o3tl::narrowing<sal_uInt16>(rSnapSize.Width() ));
+ aGridItem.SetFieldDrawY( o3tl::narrowing<sal_uInt16>(rSnapSize.Height()));
+
+ aGridItem.SetFieldDivisionX( aViewOpt.GetDivisionX());
+ aGridItem.SetFieldDivisionY( aViewOpt.GetDivisionY());
+
+ aRet.Put(aGridItem);
+
+ // Options for PrintTabPage
+ const SwPrintData* pOpt = GetPrtOptions(!bTextDialog);
+ SwAddPrinterItem aAddPrinterItem(*pOpt );
+ aRet.Put(aAddPrinterItem);
+
+ // Options for Web
+ if(!bTextDialog)
+ {
+ aRet.Put(SvxBrushItem(aViewOpt.GetRetoucheColor(), RES_BACKGROUND));
+ aRet.Put(SfxUInt16Item(SID_HTML_MODE, HTMLMODE_ON));
+ }
+
+ return aRet;
+}
+
+void SwModule::ApplyItemSet( sal_uInt16 nId, const SfxItemSet& rSet )
+{
+ bool bTextDialog = nId == SID_SW_EDITOPTIONS;
+ SwView* pAppView = GetView();
+ if(pAppView && &pAppView->GetViewFrame() != SfxViewFrame::Current())
+ pAppView = nullptr;
+ if(pAppView)
+ {
+ // the text dialog mustn't apply data to the web view and vice versa
+ bool bWebView = dynamic_cast<SwWebView*>( pAppView ) != nullptr;
+ if(bWebView == bTextDialog)
+ pAppView = nullptr;
+ }
+
+ SwViewOption aViewOpt = *GetUsrPref(!bTextDialog);
+ SwMasterUsrPref* pPref = bTextDialog ? m_pUsrPref.get() : m_pWebUsrPref.get();
+
+ SfxBindings *pBindings = pAppView ? &pAppView->GetViewFrame().GetBindings()
+ : nullptr;
+
+ // Interpret the page Documentview
+ if( const SwDocDisplayItem* pDocDispItem = rSet.GetItemIfSet( FN_PARAM_DOCDISP, false ))
+ {
+ if(!aViewOpt.IsViewMetaChars())
+ {
+ if( (!aViewOpt.IsTab( true ) && pDocDispItem->m_bTab) ||
+ (!aViewOpt.IsBlank( true ) && pDocDispItem->m_bSpace) ||
+ (!aViewOpt.IsShowBookmarks(true) && pDocDispItem->m_bBookmarks) ||
+ (!aViewOpt.IsParagraph( true ) && pDocDispItem->m_bParagraphEnd) ||
+ (!aViewOpt.IsLineBreak( true ) && pDocDispItem->m_bManualBreak) )
+ {
+ aViewOpt.SetViewMetaChars(true);
+ if(pBindings)
+ pBindings->Invalidate(FN_VIEW_META_CHARS);
+ }
+
+ }
+ pDocDispItem->FillViewOptions( aViewOpt );
+ if(pBindings)
+ {
+ pBindings->Invalidate(FN_VIEW_GRAPHIC);
+ pBindings->Invalidate(FN_VIEW_HIDDEN_PARA);
+ }
+ }
+
+ // Elements - interpret Item
+ bool bReFoldOutlineFolding = false;
+ if( const SwElemItem* pElemItem = rSet.GetItemIfSet( FN_PARAM_ELEM, false ) )
+ {
+ pElemItem->FillViewOptions( aViewOpt );
+
+ // Outline-folding options
+ if (SwWrtShell* pWrtShell = GetActiveWrtShell())
+ {
+ bool bIsOutlineFoldingOn = pWrtShell->GetViewOptions()->IsShowOutlineContentVisibilityButton();
+ bool bTreatSubsChanged = aViewOpt.IsTreatSubOutlineLevelsAsContent()
+ != pWrtShell->GetViewOptions()->IsTreatSubOutlineLevelsAsContent();
+ if (bIsOutlineFoldingOn &&
+ (!aViewOpt.IsShowOutlineContentVisibilityButton() || bTreatSubsChanged))
+ {
+ // Outline-folding options have change which require to show all content.
+ // Either outline-folding is being switched off or outline-folding is currently on
+ // and the treat subs option has changed.
+ pWrtShell->GetView().GetViewFrame().GetDispatcher()->Execute(FN_SHOW_OUTLINECONTENTVISIBILITYBUTTON);
+ if (bTreatSubsChanged)
+ bReFoldOutlineFolding = true; // folding method changed, set flag to refold below
+ }
+ else
+ {
+ // Refold needs to be done when outline-folding is being turned on or off
+ bReFoldOutlineFolding =
+ pWrtShell->GetViewOptions()->IsShowOutlineContentVisibilityButton() !=
+ aViewOpt.IsShowOutlineContentVisibilityButton();
+ }
+ }
+ }
+
+ if( const SfxUInt16Item* pMetricItem = rSet.GetItemIfSet(SID_ATTR_METRIC, false ) )
+ {
+ SfxApplication::SetOptions(rSet);
+ PutItem(*pMetricItem);
+ ::SetDfltMetric(static_cast<FieldUnit>(pMetricItem->GetValue()), !bTextDialog);
+ }
+ if( const SfxBoolItem* pCharItem = rSet.GetItemIfSet(SID_ATTR_APPLYCHARUNIT,
+ false ) )
+ {
+ SfxApplication::SetOptions(rSet);
+ ::SetApplyCharUnit(pCharItem->GetValue(), !bTextDialog);
+ }
+
+ if( const SfxUInt16Item* pMetricItem = rSet.GetItemIfSet(FN_HSCROLL_METRIC, false ) )
+ {
+ FieldUnit eUnit = static_cast<FieldUnit>(pMetricItem->GetValue());
+ pPref->SetHScrollMetric(eUnit);
+ if(pAppView)
+ pAppView->ChangeTabMetric(eUnit);
+ }
+
+ if( const SfxUInt16Item* pMetricItem = rSet.GetItemIfSet(FN_VSCROLL_METRIC, false ) )
+ {
+ FieldUnit eUnit = static_cast<FieldUnit>(pMetricItem->GetValue());
+ pPref->SetVScrollMetric(eUnit);
+ if(pAppView)
+ pAppView->ChangeVRulerMetric(eUnit);
+ }
+
+ if( const SfxUInt16Item* pItem = rSet.GetItemIfSet(SID_ATTR_DEFTABSTOP, false ) )
+ {
+ sal_uInt16 nTabDist = pItem->GetValue();
+ pPref->SetDefTabInMm100(convertTwipToMm100(nTabDist));
+ if(pAppView)
+ {
+ SvxTabStopItem aDefTabs( 0, 0, SvxTabAdjust::Default, RES_PARATR_TABSTOP );
+ MakeDefTabs( nTabDist, aDefTabs );
+ pAppView->GetWrtShell().SetDefault( aDefTabs );
+ }
+ }
+
+ // Background only in WebDialog
+ if(SfxItemState::SET == rSet.GetItemState(RES_BACKGROUND))
+ {
+ const SvxBrushItem& rBrushItem = rSet.Get(RES_BACKGROUND);
+ aViewOpt.SetRetoucheColor( rBrushItem.GetColor() );
+ }
+
+ // Interpret page Grid Settings
+ if( const SvxGridItem* pGridItem = rSet.GetItemIfSet( SID_ATTR_GRID_OPTIONS, false ))
+ {
+ aViewOpt.SetSnap( pGridItem->GetUseGridSnap() );
+ aViewOpt.SetSynchronize(pGridItem->GetSynchronize());
+ if( aViewOpt.IsGridVisible() != pGridItem->GetGridVisible() )
+ aViewOpt.SetGridVisible( pGridItem->GetGridVisible());
+ Size aSize( pGridItem->GetFieldDrawX(), pGridItem->GetFieldDrawY() );
+ if( aViewOpt.GetSnapSize() != aSize )
+ aViewOpt.SetSnapSize( aSize );
+ short nDiv = static_cast<short>(pGridItem->GetFieldDivisionX()) ;
+ if( aViewOpt.GetDivisionX() != nDiv )
+ aViewOpt.SetDivisionX( nDiv );
+ nDiv = static_cast<short>(pGridItem->GetFieldDivisionY());
+ if( aViewOpt.GetDivisionY() != nDiv )
+ aViewOpt.SetDivisionY( nDiv );
+
+ if(pBindings)
+ {
+ pBindings->Invalidate(SID_GRID_VISIBLE);
+ pBindings->Invalidate(SID_GRID_USE);
+ }
+ }
+
+ // Interpret Writer Printer Options
+ if( const SwAddPrinterItem* pAddPrinterAttr = rSet.GetItemIfSet( FN_PARAM_ADDPRINTER, false ) )
+ {
+ SwPrintOptions* pOpt = GetPrtOptions(!bTextDialog);
+ if (pOpt)
+ {
+ *pOpt = *pAddPrinterAttr;
+ }
+ }
+
+ if( const SwShadowCursorItem* pItem = rSet.GetItemIfSet( FN_PARAM_SHADOWCURSOR, false ))
+ {
+ pItem->FillViewOptions( aViewOpt );
+ if(pBindings)
+ pBindings->Invalidate(FN_SHADOWCURSOR);
+ }
+
+ if( pAppView )
+ {
+ SwWrtShell &rWrtSh = pAppView->GetWrtShell();
+ const bool bAlignFormulas = rWrtSh.GetDoc()->getIDocumentSettingAccess().get( DocumentSettingId::MATH_BASELINE_ALIGNMENT );
+ pPref->SetAlignMathObjectsToBaseline( bAlignFormulas );
+
+ // don't align formulas in documents that are currently loading
+ if (bAlignFormulas && !rWrtSh.GetDoc()->IsInReading())
+ rWrtSh.AlignAllFormulasToBaseline();
+ }
+
+ if( const SfxBoolItem* pItem = rSet.GetItemIfSet( FN_PARAM_CRSR_IN_PROTECTED, false ))
+ {
+ aViewOpt.SetCursorInProtectedArea(pItem->GetValue());
+ }
+
+ // set elements for the current view and shell
+ ApplyUsrPref( aViewOpt, pAppView, bTextDialog? SvViewOpt::DestText : SvViewOpt::DestWeb);
+
+ // must be done after ApplyUsrPref
+ if (SfxItemState::SET != rSet.GetItemState(FN_PARAM_ELEM, false))
+ return;
+
+ if (bReFoldOutlineFolding)
+ {
+ if (SwWrtShell* pWrtShell = GetActiveWrtShell())
+ {
+ pWrtShell->GetView().GetViewFrame().GetDispatcher()->Execute(FN_SHOW_OUTLINECONTENTVISIBILITYBUTTON);
+ pWrtShell->GetView().GetViewFrame().GetDispatcher()->Execute(FN_SHOW_OUTLINECONTENTVISIBILITYBUTTON);
+ }
+ }
+}
+
+std::unique_ptr<SfxTabPage> SwModule::CreateTabPage( sal_uInt16 nId, weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet )
+{
+ std::unique_ptr<SfxTabPage> xRet;
+ SfxAllItemSet aSet(*(rSet.GetPool()));
+ switch( nId )
+ {
+ case RID_SW_TP_CONTENT_OPT:
+ case RID_SW_TP_HTML_CONTENT_OPT:
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ::CreateTabPage fnCreatePage = pFact->GetTabPageCreatorFunc( nId );
+ xRet = (*fnCreatePage)( pPage, pController, &rSet );
+ break;
+ }
+ case RID_SW_TP_HTML_OPTGRID_PAGE:
+ case RID_SVXPAGE_GRID:
+ xRet = SvxGridTabPage::Create(pPage, pController, rSet);
+ break;
+
+ case RID_SW_TP_STD_FONT:
+ case RID_SW_TP_STD_FONT_CJK:
+ case RID_SW_TP_STD_FONT_CTL:
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ::CreateTabPage fnCreatePage = pFact->GetTabPageCreatorFunc( nId );
+ xRet = (*fnCreatePage)( pPage, pController, &rSet );
+ if(RID_SW_TP_STD_FONT != nId)
+ {
+ aSet.Put (SfxUInt16Item(SID_FONTMODE_TYPE, RID_SW_TP_STD_FONT_CJK == nId ? FONT_GROUP_CJK : FONT_GROUP_CTL));
+ xRet->PageCreated(aSet);
+ }
+ }
+ break;
+ case RID_SW_TP_HTML_OPTPRINT_PAGE:
+ case RID_SW_TP_OPTPRINT_PAGE:
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ::CreateTabPage fnCreatePage = pFact->GetTabPageCreatorFunc( nId );
+ xRet = (*fnCreatePage)( pPage, pController, &rSet );
+ aSet.Put (SfxBoolItem(SID_FAX_LIST, true));
+ xRet->PageCreated(aSet);
+ }
+ break;
+ case RID_SW_TP_HTML_OPTTABLE_PAGE:
+ case RID_SW_TP_OPTTABLE_PAGE:
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ::CreateTabPage fnCreatePage = pFact->GetTabPageCreatorFunc( nId );
+ xRet = (*fnCreatePage)( pPage, pController, &rSet );
+ SwView* pCurrView = GetView();
+ if(pCurrView)
+ {
+ // if text then not WebView and vice versa
+ bool bWebView = dynamic_cast<SwWebView*>( pCurrView ) != nullptr;
+ if( (bWebView && RID_SW_TP_HTML_OPTTABLE_PAGE == nId) ||
+ (!bWebView && RID_SW_TP_HTML_OPTTABLE_PAGE != nId) )
+ {
+ aSet.Put (SwWrtShellItem(pCurrView->GetWrtShellPtr()));
+ xRet->PageCreated(aSet);
+ }
+ }
+ }
+ break;
+ case RID_SW_TP_OPTSHDWCRSR:
+ case RID_SW_TP_HTML_OPTSHDWCRSR:
+ case RID_SW_TP_REDLINE_OPT:
+ case RID_SW_TP_COMPARISON_OPT:
+ case RID_SW_TP_OPTLOAD_PAGE:
+ case RID_SW_TP_OPTCOMPATIBILITY_PAGE:
+ case RID_SW_TP_MAILCONFIG:
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ::CreateTabPage fnCreatePage = pFact->GetTabPageCreatorFunc( nId );
+ xRet = (*fnCreatePage)( pPage, pController, &rSet );
+ if (nId == RID_SW_TP_OPTSHDWCRSR || nId == RID_SW_TP_HTML_OPTSHDWCRSR)
+ {
+ SwView* pCurrView = GetView();
+ if(pCurrView)
+ {
+ aSet.Put( SwWrtShellItem( pCurrView->GetWrtShellPtr() ) );
+ xRet->PageCreated(aSet);
+ }
+ }
+ }
+ break;
+ case RID_SW_TP_OPTTEST_PAGE:
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ::CreateTabPage fnCreatePage = pFact->GetTabPageCreatorFunc( nId );
+ xRet = (*fnCreatePage)( pPage, pController, &rSet );
+ break;
+ }
+ case RID_SW_TP_BACKGROUND:
+ {
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ ::CreateTabPage fnCreatePage = pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BKG );
+ xRet = (*fnCreatePage)( pPage, pController, &rSet );
+ xRet->PageCreated( rSet );
+ break;
+ }
+ case RID_SW_TP_OPTCAPTION_PAGE:
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ::CreateTabPage fnCreatePage = pFact->GetTabPageCreatorFunc( RID_SW_TP_OPTCAPTION_PAGE );
+ xRet = (*fnCreatePage)( pPage, pController, &rSet );
+ }
+ break;
+ }
+
+ if(!xRet)
+ SAL_WARN( "sw", "SwModule::CreateTabPage(): Unknown tabpage id " << nId );
+ return xRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/app/docsh.cxx b/sw/source/uibase/app/docsh.cxx
new file mode 100644
index 0000000000..1cddf3070b
--- /dev/null
+++ b/sw/source/uibase/app/docsh.cxx
@@ -0,0 +1,1433 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_features.h>
+
+#include <officecfg/Office/Common.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/syswin.hxx>
+#include <vcl/jobset.hxx>
+#include <svl/numformat.hxx>
+#include <svl/whiter.hxx>
+#include <svl/eitem.hxx>
+#include <svl/stritem.hxx>
+#include <svl/PasswordHelper.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/notebookbar/SfxNotebookBar.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <editeng/flstitem.hxx>
+#include <comphelper/lok.hxx>
+#include <comphelper/classids.hxx>
+#include <basic/sbmod.hxx>
+#include <osl/diagnose.h>
+#include <node.hxx>
+#include <swwait.hxx>
+#include <printdata.hxx>
+#include <view.hxx>
+#include <edtwin.hxx>
+#include <PostItMgr.hxx>
+#include <wrtsh.hxx>
+#include <docsh.hxx>
+#include <viewopt.hxx>
+#include <wdocsh.hxx>
+#include <swmodule.hxx>
+#include <globdoc.hxx>
+#include <usrpref.hxx>
+#include <shellio.hxx>
+#include <docstyle.hxx>
+#include <doc.hxx>
+#include <docfunc.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <IDocumentSettingAccess.hxx>
+#include <IDocumentLinksAdministration.hxx>
+#include <IDocumentDeviceAccess.hxx>
+#include <IDocumentDrawModelAccess.hxx>
+#include <IDocumentRedlineAccess.hxx>
+#include <IDocumentStatistics.hxx>
+#include <IDocumentState.hxx>
+#include <pview.hxx>
+#include <srcview.hxx>
+#include <ndindex.hxx>
+#include <ndole.hxx>
+#include <txtftn.hxx>
+#include <ftnidx.hxx>
+#include <fldbas.hxx>
+#include <docary.hxx>
+#include <swerror.h>
+#include <cmdid.h>
+#include <strings.hrc>
+
+#include <unotools/fltrcfg.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/objface.hxx>
+
+#define ShellClass_SwDocShell
+#include <sfx2/msg.hxx>
+#include <swslots.hxx>
+#include <com/sun/star/document/UpdateDocMode.hpp>
+
+#include <com/sun/star/script/XLibraryContainer.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/sdb/DatabaseContext.hpp>
+#include <com/sun/star/sdb/XDocumentDataSource.hpp>
+#include <com/sun/star/uri/UriReferenceFactory.hpp>
+#include <com/sun/star/uri/VndSunStarPkgUrlReferenceFactory.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <ooo/vba/XSinkCaller.hpp>
+
+#include <unotextrange.hxx>
+
+#include <dbmgr.hxx>
+#include <iodetect.hxx>
+
+#include <comphelper/processfactory.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::script;
+using namespace ::com::sun::star::container;
+
+SFX_IMPL_SUPERCLASS_INTERFACE(SwDocShell, SfxObjectShell)
+
+void SwDocShell::InitInterface_Impl()
+{
+}
+
+
+SFX_IMPL_OBJECTFACTORY(SwDocShell, SvGlobalName(SO3_SW_CLASSID), "swriter" )
+
+bool SwDocShell::InsertGeneratedStream(SfxMedium & rMedium,
+ uno::Reference<text::XTextRange> const& xInsertPosition)
+{
+ SwUnoInternalPaM aPam(*GetDoc()); // must have doc since called from SwView
+ if (!::sw::XTextRangeToSwPaM(aPam, xInsertPosition))
+ return false;
+ // similar to SwView::InsertMedium
+ SwReaderPtr pReader;
+ Reader *const pRead = StartConvertFrom(rMedium, pReader, nullptr, &aPam);
+ if (!pRead)
+ return false;
+ ErrCodeMsg const nError = pReader->Read(*pRead);
+ return ERRCODE_NONE == nError;
+}
+
+// Prepare loading
+Reader* SwDocShell::StartConvertFrom(SfxMedium& rMedium, SwReaderPtr& rpRdr,
+ SwCursorShell const *pCursorShell,
+ SwPaM* pPaM )
+{
+ bool bAPICall = false;
+ if( const SfxBoolItem* pApiItem = rMedium.GetItemSet().GetItemIfSet( FN_API_CALL ) )
+ bAPICall = pApiItem->GetValue();
+
+ std::shared_ptr<const SfxFilter> pFlt = rMedium.GetFilter();
+ if( !pFlt )
+ {
+ if(!bAPICall)
+ {
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(nullptr,
+ VclMessageType::Info, VclButtonsType::Ok,
+ SwResId(STR_CANTOPEN)));
+ xInfoBox->run();
+ }
+ return nullptr;
+ }
+ OUString aFileName( rMedium.GetName() );
+ Reader* pRead = SwReaderWriter::GetReader( pFlt->GetUserData() );
+ if( !pRead )
+ return nullptr;
+
+ if( rMedium.IsStorage()
+ ? SwReaderType::Storage & pRead->GetReaderType()
+ : SwReaderType::Stream & pRead->GetReaderType() )
+ {
+ if (pPaM)
+ rpRdr.reset(new SwReader( rMedium, aFileName, *pPaM ));
+ else if (pCursorShell)
+ rpRdr.reset(new SwReader( rMedium, aFileName, *pCursorShell->GetCursor() ));
+ else
+ rpRdr.reset(new SwReader( rMedium, aFileName, m_xDoc.get() ));
+ }
+ else
+ return nullptr;
+
+ // #i30171# set the UpdateDocMode at the SwDocShell
+ const SfxUInt16Item* pUpdateDocItem = rMedium.GetItemSet().GetItem(SID_UPDATEDOCMODE, false);
+ m_nUpdateDocMode = pUpdateDocItem ? pUpdateDocItem->GetValue() : document::UpdateDocMode::NO_UPDATE;
+
+ if (!pFlt->GetDefaultTemplate().isEmpty())
+ pRead->SetTemplateName( pFlt->GetDefaultTemplate() );
+
+ if( pRead == ReadAscii && nullptr != rMedium.GetInStream() &&
+ pFlt->GetUserData() == FILTER_TEXT_DLG )
+ {
+ SwAsciiOptions aOpt;
+ if( const SfxStringItem* pItem = rMedium.GetItemSet().GetItemIfSet( SID_FILE_FILTEROPTIONS ) )
+ aOpt.ReadUserData( pItem->GetValue() );
+
+ pRead->GetReaderOpt().SetASCIIOpts( aOpt );
+ }
+
+ return pRead;
+}
+
+// Loading
+bool SwDocShell::ConvertFrom( SfxMedium& rMedium )
+{
+ SwReaderPtr pRdr;
+ Reader* pRead = StartConvertFrom(rMedium, pRdr);
+ if (!pRead)
+ return false; // #129881# return if no reader is found
+ tools::SvRef<SotStorage> pStg=pRead->getSotStorageRef(); // #i45333# save sot storage ref in case of recursive calls
+
+ m_xDoc->setDocAccTitle(OUString());
+ if (const auto pFrame1 = SfxViewFrame::GetFirst(this))
+ {
+ if (auto pSysWin = pFrame1->GetWindow().GetSystemWindow())
+ {
+ pSysWin->SetAccessibleName(OUString());
+ }
+ }
+ SwWait aWait( *this, true );
+
+ // Suppress SfxProgress, when we are Embedded
+ SW_MOD()->SetEmbeddedLoadSave(
+ SfxObjectCreateMode::EMBEDDED == GetCreateMode() );
+
+ pRdr->GetDoc().getIDocumentSettingAccess().set(DocumentSettingId::HTML_MODE, dynamic_cast< const SwWebDocShell *>( this ) != nullptr);
+
+ // Restore the pool default if reading a saved document.
+ m_xDoc->RemoveAllFormatLanguageDependencies();
+
+ ErrCodeMsg nErr = pRdr->Read( *pRead );
+
+ // Maybe put away one old Doc
+ if (m_xDoc.get() != &pRdr->GetDoc())
+ {
+ RemoveLink();
+ m_xDoc = &pRdr->GetDoc();
+
+ AddLink();
+
+ if (!m_xBasePool.is())
+ m_xBasePool = new SwDocStyleSheetPool( *m_xDoc, SfxObjectCreateMode::ORGANIZER == GetCreateMode() );
+ }
+
+ UpdateFontList();
+ InitDrawModelAndDocShell(this, m_xDoc ? m_xDoc->getIDocumentDrawModelAccess().GetDrawModel() : nullptr);
+
+ pRdr.reset();
+
+ SW_MOD()->SetEmbeddedLoadSave( false );
+
+ SetError(nErr);
+ bool bOk = !nErr.IsError();
+
+ if (bOk && !m_xDoc->IsInLoadAsynchron())
+ {
+ LoadingFinished();
+ }
+
+ pRead->setSotStorageRef(pStg); // #i45333# save sot storage ref in case of recursive calls
+
+ return bOk;
+}
+
+// Saving the Default-Format, Stg present
+bool SwDocShell::Save()
+{
+ //#i3370# remove quick help to prevent saving of autocorrection suggestions
+ if (m_pView)
+ m_pView->GetEditWin().StopQuickHelp();
+ SwWait aWait( *this, true );
+
+ CalcLayoutForOLEObjects(); // format for OLE objects
+ // #i62875#
+ // reset compatibility flag <DoNotCaptureDrawObjsOnPage>, if possible
+ if (m_pWrtShell && m_xDoc &&
+ m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE) &&
+ docfunc::AllDrawObjsOnPage(*m_xDoc))
+ {
+ m_xDoc->getIDocumentSettingAccess().set(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE, false);
+ }
+
+ ErrCodeMsg nErr = ERR_SWG_WRITE_ERROR;
+ ErrCode nVBWarning = ERRCODE_NONE;
+ if( SfxObjectShell::Save() )
+ {
+ switch( GetCreateMode() )
+ {
+ case SfxObjectCreateMode::INTERNAL:
+ nErr = ERRCODE_NONE;
+ break;
+
+ case SfxObjectCreateMode::ORGANIZER:
+ {
+ WriterRef xWrt;
+ ::GetXMLWriter(std::u16string_view(), GetMedium()->GetBaseURL(true), xWrt);
+ xWrt->SetOrganizerMode( true );
+ SwWriter aWrt( *GetMedium(), *m_xDoc );
+ nErr = aWrt.Write( xWrt );
+ xWrt->SetOrganizerMode( false );
+ }
+ break;
+
+ case SfxObjectCreateMode::EMBEDDED:
+ // Suppress SfxProgress, if we are Embedded
+ SW_MOD()->SetEmbeddedLoadSave( true );
+ [[fallthrough]];
+
+ case SfxObjectCreateMode::STANDARD:
+ default:
+ {
+ if (m_xDoc->ContainsMSVBasic())
+ {
+ if( SvtFilterOptions::Get().IsLoadWordBasicStorage() )
+ nVBWarning = GetSaveWarningOfMSVBAStorage( static_cast<SfxObjectShell&>(*this) );
+ m_xDoc->SetContainsMSVBasic( false );
+ }
+
+ // End TableBox Edit!
+ if (m_pWrtShell)
+ m_pWrtShell->EndAllTableBoxEdit();
+
+ WriterRef xWrt;
+ ::GetXMLWriter(std::u16string_view(), GetMedium()->GetBaseURL(true), xWrt);
+
+ bool bLockedView(false);
+ if (m_pWrtShell)
+ {
+ bLockedView = m_pWrtShell->IsViewLocked();
+ m_pWrtShell->LockView( true ); //lock visible section
+ }
+
+ SwWriter aWrt( *GetMedium(), *m_xDoc );
+ nErr = aWrt.Write( xWrt );
+
+ if (m_pWrtShell)
+ m_pWrtShell->LockView( bLockedView );
+ }
+ break;
+ }
+ SW_MOD()->SetEmbeddedLoadSave( false );
+ }
+ SetError(nErr ? nErr : nVBWarning);
+
+ SfxViewFrame *const pFrame =
+ m_pWrtShell ? &m_pWrtShell->GetView().GetViewFrame() : nullptr;
+ if( pFrame )
+ {
+ pFrame->GetBindings().SetState(SfxBoolItem(SID_DOC_MODIFIED, false));
+ }
+ return !nErr.IsError();
+}
+
+SwDocShell::LockAllViewsGuard_Impl::LockAllViewsGuard_Impl(SwViewShell* pViewShell)
+{
+ if (!pViewShell)
+ return;
+ for (SwViewShell& rShell : pViewShell->GetRingContainer())
+ {
+ if (!rShell.IsViewLocked())
+ {
+ m_aViewWasUnLocked.push_back(&rShell);
+ rShell.LockView(true);
+ }
+ }
+}
+
+SwDocShell::LockAllViewsGuard_Impl::~LockAllViewsGuard_Impl()
+{
+ for (SwViewShell* pShell : m_aViewWasUnLocked)
+ pShell->LockView(false);
+}
+
+std::unique_ptr<SfxObjectShell::LockAllViewsGuard> SwDocShell::LockAllViews()
+{
+ return std::make_unique<LockAllViewsGuard_Impl>(GetEditShell());
+}
+
+// Save using the Defaultformat
+bool SwDocShell::SaveAs( SfxMedium& rMedium )
+{
+ SwWait aWait( *this, true );
+ //#i3370# remove quick help to prevent saving of autocorrection suggestions
+ if (m_pView)
+ m_pView->GetEditWin().StopQuickHelp();
+
+ //#i91811# mod if we have an active margin window, write back the text
+ if (m_pView &&
+ m_pView->GetPostItMgr() &&
+ m_pView->GetPostItMgr()->HasActiveSidebarWin())
+ {
+ m_pView->GetPostItMgr()->UpdateDataOnActiveSidebarWin();
+ }
+
+ if (m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT) &&
+ !m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT_SAVE_LINKS))
+ RemoveOLEObjects();
+
+ if (GetMedium())
+ {
+ // Task 75666 - is the Document imported by our Microsoft-Filters?
+ std::shared_ptr<const SfxFilter> pOldFilter = GetMedium()->GetFilter();
+ if( pOldFilter &&
+ ( pOldFilter->GetUserData() == FILTER_WW8 ||
+ pOldFilter->GetUserData() == "CWW6" ||
+ pOldFilter->GetUserData() == "WW6" ) )
+ {
+ // when saving it in our own fileformat, then remove the template
+ // name from the docinfo.
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps
+ = xDPS->getDocumentProperties();
+ xDocProps->setTemplateName(OUString());
+ xDocProps->setTemplateURL(OUString());
+ xDocProps->setTemplateDate(::util::DateTime());
+ }
+ }
+
+ CalcLayoutForOLEObjects(); // format for OLE objects
+
+ const bool bURLChanged = GetMedium() && GetMedium()->GetURLObject() != rMedium.GetURLObject();
+ const SwDBManager* const pMgr = m_xDoc->GetDBManager();
+ const bool bHasEmbedded = pMgr && !pMgr->getEmbeddedName().isEmpty();
+ bool bSaveDS = bHasEmbedded && bURLChanged;
+ if (bSaveDS)
+ {
+ // Don't save data source in case a temporary is being saved for preview in MM wizard
+ if (const SfxBoolItem* pNoEmbDS
+ = rMedium.GetItemSet().GetItem(SID_NO_EMBEDDED_DS, false))
+ bSaveDS = !pNoEmbDS->GetValue();
+ }
+ if (bSaveDS)
+ {
+ // We have an embedded data source definition, need to re-store it,
+ // otherwise relative references will break when the new file is in a
+ // different directory.
+
+ OUString aURL(GetMedium()->GetURLObject().GetMainURL(INetURLObject::DecodeMechanism::NONE));
+ if (aURL.isEmpty())
+ {
+ // No old URL - is this a new document created from a template with embedded DS?
+ // Try to get the template URL to reconstruct the embedded data source URL
+ const css::beans::PropertyValues& rArgs = GetMedium()->GetArgs();
+ const auto aURLIter = std::find_if(rArgs.begin(), rArgs.end(),
+ [](const auto& v) { return v.Name == "URL"; });
+ if (aURLIter != rArgs.end())
+ aURLIter->Value >>= aURL;
+ }
+
+ if (!aURL.isEmpty())
+ {
+ auto xContext(comphelper::getProcessComponentContext());
+ auto xUri = css::uri::UriReferenceFactory::create(xContext)->parse(aURL);
+ assert(xUri.is());
+ xUri = css::uri::VndSunStarPkgUrlReferenceFactory::create(xContext)
+ ->createVndSunStarPkgUrlReference(xUri);
+ assert(xUri.is());
+ aURL = xUri->getUriReference() + "/"
+ + INetURLObject::encode(pMgr->getEmbeddedName(), INetURLObject::PART_FPATH,
+ INetURLObject::EncodeMechanism::All);
+
+ bool bCopyTo = GetCreateMode() == SfxObjectCreateMode::EMBEDDED;
+ if (!bCopyTo)
+ {
+ if (const SfxBoolItem* pSaveToItem
+ = rMedium.GetItemSet().GetItem(SID_SAVETO, false))
+ bCopyTo = pSaveToItem->GetValue();
+ }
+
+ auto xDatabaseContext = sdb::DatabaseContext::create(xContext);
+ uno::Reference<sdb::XDocumentDataSource> xDataSource(xDatabaseContext->getByName(aURL),
+ uno::UNO_QUERY);
+ if (xDataSource)
+ {
+ uno::Reference<frame::XStorable> xStorable(xDataSource->getDatabaseDocument(),
+ uno::UNO_QUERY);
+ SwDBManager::StoreEmbeddedDataSource(xStorable, rMedium.GetOutputStorage(),
+ pMgr->getEmbeddedName(), rMedium.GetName(),
+ bCopyTo);
+ }
+ }
+ }
+
+ // #i62875#
+ // reset compatibility flag <DoNotCaptureDrawObjsOnPage>, if possible
+ if (m_pWrtShell &&
+ m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE) &&
+ docfunc::AllDrawObjsOnPage(*m_xDoc))
+ {
+ m_xDoc->getIDocumentSettingAccess().set(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE, false);
+ }
+
+ ErrCodeMsg nErr = ERR_SWG_WRITE_ERROR;
+ ErrCode nVBWarning = ERRCODE_NONE;
+ uno::Reference < embed::XStorage > xStor = rMedium.GetOutputStorage();
+ if( SfxObjectShell::SaveAs( rMedium ) )
+ {
+ if( GetDoc()->getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT) && dynamic_cast< const SwGlobalDocShell *>( this ) == nullptr )
+ {
+ // The document is closed explicitly, but using SfxObjectShellLock is still more correct here
+ SfxObjectShellLock xDocSh =
+ new SwGlobalDocShell( SfxObjectCreateMode::INTERNAL );
+ // the global document can not be a template
+ xDocSh->SetupStorage( xStor, SotStorage::GetVersion( xStor ), false );
+ xDocSh->DoClose();
+ }
+
+ if (m_xDoc->ContainsMSVBasic())
+ {
+ if( SvtFilterOptions::Get().IsLoadWordBasicStorage() )
+ nVBWarning = GetSaveWarningOfMSVBAStorage( static_cast<SfxObjectShell&>(*this) );
+ m_xDoc->SetContainsMSVBasic( false );
+ }
+
+ if (m_pWrtShell)
+ {
+ // End TableBox Edit!
+ m_pWrtShell->EndAllTableBoxEdit();
+
+ // Remove invalid signatures.
+ m_pWrtShell->ValidateAllParagraphSignatures(false);
+
+ m_pWrtShell->ClassifyDocPerHighestParagraphClass();
+ }
+
+ // Remember and preserve Modified-Flag without calling the Link
+ // (for OLE; after Statement from MM)
+ const bool bIsModified = m_xDoc->getIDocumentState().IsModified();
+ m_xDoc->GetIDocumentUndoRedo().LockUndoNoModifiedPosition();
+ Link<bool,void> aOldOLELnk( m_xDoc->GetOle2Link() );
+ m_xDoc->SetOle2Link( Link<bool,void>() );
+
+ // Suppress SfxProgress when we are Embedded
+ SW_MOD()->SetEmbeddedLoadSave(
+ SfxObjectCreateMode::EMBEDDED == GetCreateMode() );
+
+ WriterRef xWrt;
+ ::GetXMLWriter(std::u16string_view(), rMedium.GetBaseURL(true), xWrt);
+
+ bool bLockedView(false);
+ if (m_pWrtShell)
+ {
+ bLockedView = m_pWrtShell->IsViewLocked();
+ m_pWrtShell->LockView( true ); //lock visible section
+ }
+
+ SwWriter aWrt( rMedium, *m_xDoc );
+ nErr = aWrt.Write( xWrt );
+
+ if (m_pWrtShell)
+ m_pWrtShell->LockView( bLockedView );
+
+ if( bIsModified )
+ {
+ m_xDoc->getIDocumentState().SetModified();
+ m_xDoc->GetIDocumentUndoRedo().UnLockUndoNoModifiedPosition();
+ }
+ m_xDoc->SetOle2Link( aOldOLELnk );
+
+ SW_MOD()->SetEmbeddedLoadSave( false );
+
+ // Increase RSID
+ m_xDoc->setRsid( m_xDoc->getRsid() );
+
+ m_xDoc->cleanupUnoCursorTable();
+ }
+ SetError(nErr ? nErr : nVBWarning);
+
+ return !nErr.IsError();
+}
+
+// Save all Formats
+static SwSrcView* lcl_GetSourceView( SwDocShell const * pSh )
+{
+ // are we in SourceView?
+ SfxViewFrame* pVFrame = SfxViewFrame::GetFirst( pSh );
+ SfxViewShell* pViewShell = pVFrame ? pVFrame->GetViewShell() : nullptr;
+ return dynamic_cast<SwSrcView*>( pViewShell );
+}
+
+bool SwDocShell::ConvertTo( SfxMedium& rMedium )
+{
+ std::shared_ptr<const SfxFilter> pFlt = rMedium.GetFilter();
+ if( !pFlt )
+ return false;
+
+ WriterRef xWriter;
+ SwReaderWriter::GetWriter( pFlt->GetUserData(), rMedium.GetBaseURL( true ), xWriter );
+ if( !xWriter.is() )
+ { // Filter not available
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(nullptr,
+ VclMessageType::Info, VclButtonsType::Ok,
+ SwResId(STR_DLLNOTFOUND)));
+ xInfoBox->run();
+ return false;
+ }
+
+ //#i3370# remove quick help to prevent saving of autocorrection suggestions
+ if (m_pView)
+ m_pView->GetEditWin().StopQuickHelp();
+
+ //#i91811# mod if we have an active margin window, write back the text
+ if (m_pView &&
+ m_pView->GetPostItMgr() &&
+ m_pView->GetPostItMgr()->HasActiveSidebarWin())
+ {
+ m_pView->GetPostItMgr()->UpdateDataOnActiveSidebarWin();
+ }
+
+ ErrCode nVBWarning = ERRCODE_NONE;
+
+ if (m_xDoc->ContainsMSVBasic())
+ {
+ bool bSave = pFlt->GetUserData() == "CWW8"
+ && SvtFilterOptions::Get().IsLoadWordBasicStorage();
+
+ if ( bSave )
+ {
+ tools::SvRef<SotStorage> xStg = new SotStorage( rMedium.GetOutStream(), false );
+ OSL_ENSURE( !xStg->GetError(), "No storage available for storing VBA macros!" );
+ if ( !xStg->GetError() )
+ {
+ nVBWarning = SaveOrDelMSVBAStorage( static_cast<SfxObjectShell&>(*this), *xStg, bSave, "Macros" );
+ xStg->Commit();
+ m_xDoc->SetContainsMSVBasic( true );
+ }
+ }
+ }
+
+ // End TableBox Edit!
+ if (m_pWrtShell)
+ m_pWrtShell->EndAllTableBoxEdit();
+
+ if( pFlt->GetUserData() == "HTML" )
+ {
+#if HAVE_FEATURE_SCRIPTING
+ if( !officecfg::Office::Common::Filter::HTML::Export::Basic::get()
+ && officecfg::Office::Common::Filter::HTML::Export::Warning::get()
+ && HasBasic() )
+ {
+ uno::Reference< XLibraryContainer > xLibCont = GetBasicContainer();
+ uno::Reference< XNameAccess > xLib;
+ const Sequence<OUString> aNames = xLibCont->getElementNames();
+ for(const OUString& rName : aNames)
+ {
+ Any aLib = xLibCont->getByName(rName);
+ aLib >>= xLib;
+ if(xLib.is())
+ {
+ Sequence<OUString> aModNames = xLib->getElementNames();
+ if(aModNames.hasElements())
+ {
+ SetError(WARN_SWG_HTML_NO_MACROS);
+ break;
+ }
+ }
+ }
+ }
+#endif
+ }
+
+ // #i76360# Update document statistics
+ if ( !rMedium.IsSkipImages() )
+ m_xDoc->getIDocumentStatistics().UpdateDocStat( false, true );
+
+ CalcLayoutForOLEObjects(); // format for OLE objects
+ // #i62875#
+ // reset compatibility flag <DoNotCaptureDrawObjsOnPage>, if possible
+ if (m_pWrtShell &&
+ m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE) &&
+ docfunc::AllDrawObjsOnPage(*m_xDoc))
+ {
+ m_xDoc->getIDocumentSettingAccess().set(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE, false);
+ }
+
+ if( xWriter->IsStgWriter() &&
+ ( pFlt->GetUserData() == FILTER_XML ||
+ pFlt->GetUserData() == FILTER_XMLV ||
+ pFlt->GetUserData() == FILTER_XMLVW ) )
+ {
+ // determine the own Type
+ sal_uInt8 nMyType = 0;
+ if( dynamic_cast< const SwWebDocShell *>( this ) != nullptr )
+ nMyType = 1;
+ else if( dynamic_cast< const SwGlobalDocShell *>( this ) != nullptr )
+ nMyType = 2;
+
+ // determine the desired Type
+ sal_uInt8 nSaveType = 0;
+ SotClipboardFormatId nSaveClipId = pFlt->GetFormat();
+ if( SotClipboardFormatId::STARWRITERWEB_8 == nSaveClipId ||
+ SotClipboardFormatId::STARWRITERWEB_60 == nSaveClipId ||
+ SotClipboardFormatId::STARWRITERWEB_50 == nSaveClipId ||
+ SotClipboardFormatId::STARWRITERWEB_40 == nSaveClipId )
+ nSaveType = 1;
+ else if( SotClipboardFormatId::STARWRITERGLOB_8 == nSaveClipId ||
+ SotClipboardFormatId::STARWRITERGLOB_8_TEMPLATE == nSaveClipId ||
+ SotClipboardFormatId::STARWRITERGLOB_60 == nSaveClipId ||
+ SotClipboardFormatId::STARWRITERGLOB_50 == nSaveClipId ||
+ SotClipboardFormatId::STARWRITERGLOB_40 == nSaveClipId )
+ nSaveType = 2;
+
+ // Change Flags of the Document accordingly
+ bool bIsHTMLModeSave = GetDoc()->getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE);
+ bool bIsGlobalDocSave = GetDoc()->getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT);
+ bool bIsGlblDocSaveLinksSave = GetDoc()->getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT_SAVE_LINKS);
+ if( nMyType != nSaveType )
+ {
+ GetDoc()->getIDocumentSettingAccess().set(DocumentSettingId::HTML_MODE, 1 == nSaveType);
+ GetDoc()->getIDocumentSettingAccess().set(DocumentSettingId::GLOBAL_DOCUMENT, 2 == nSaveType);
+ if( 2 != nSaveType )
+ GetDoc()->getIDocumentSettingAccess().set(DocumentSettingId::GLOBAL_DOCUMENT_SAVE_LINKS, false);
+ }
+
+ // if the target format is storage based, then the output storage must be already created
+ if ( rMedium.IsStorage() )
+ {
+ // set MediaType on target storage
+ // (MediaType will be queried during SaveAs)
+ try
+ {
+ // TODO/MBA: testing
+ uno::Reference < beans::XPropertySet > xSet( rMedium.GetStorage(), uno::UNO_QUERY );
+ if ( xSet.is() )
+ xSet->setPropertyValue("MediaType", uno::Any( SotExchange::GetFormatMimeType( nSaveClipId ) ) );
+ }
+ catch (const uno::Exception&)
+ {
+ }
+ }
+
+ // Now normally save the Document
+ bool bRet = SaveAs( rMedium );
+
+ if( nMyType != nSaveType )
+ {
+ GetDoc()->getIDocumentSettingAccess().set(DocumentSettingId::HTML_MODE, bIsHTMLModeSave );
+ GetDoc()->getIDocumentSettingAccess().set(DocumentSettingId::GLOBAL_DOCUMENT, bIsGlobalDocSave);
+ GetDoc()->getIDocumentSettingAccess().set(DocumentSettingId::GLOBAL_DOCUMENT_SAVE_LINKS, bIsGlblDocSaveLinksSave);
+ }
+
+ return bRet;
+ }
+
+ if( pFlt->GetUserData() == FILTER_TEXT_DLG &&
+ (m_pWrtShell || !::lcl_GetSourceView(this)))
+ {
+ SwAsciiOptions aOpt;
+ OUString sItemOpt;
+ if( const SfxStringItem* pItem = rMedium.GetItemSet().GetItemIfSet( SID_FILE_FILTEROPTIONS ) )
+ sItemOpt = pItem->GetValue();
+ if(!sItemOpt.isEmpty())
+ aOpt.ReadUserData( sItemOpt );
+
+ xWriter->SetAsciiOptions( aOpt );
+ }
+
+ // Suppress SfxProgress when we are Embedded
+ SW_MOD()->SetEmbeddedLoadSave(
+ SfxObjectCreateMode::EMBEDDED == GetCreateMode());
+
+ // Span Context in order to suppress the Selection's View
+ ErrCodeMsg nErrno;
+ const OUString aFileName( rMedium.GetName() );
+
+ bool bSelection = false;
+ if (m_pWrtShell)
+ {
+ const SfxBoolItem* pSelectionItem = rMedium.GetItemSet().GetItemIfSet(SID_SELECTION);
+ bSelection = pSelectionItem && pSelectionItem->GetValue();
+ }
+
+ // No View, so the whole Document! (unless SID_SELECTION explicitly set)
+ if (m_pWrtShell && (!Application::IsHeadlessModeEnabled() || bSelection))
+ {
+
+ SwWait aWait( *this, true );
+ // #i106906#
+ const bool bFormerLockView = m_pWrtShell->IsViewLocked();
+ m_pWrtShell->LockView( true );
+ m_pWrtShell->StartAllAction();
+ m_pWrtShell->Push();
+ SwWriter aWrt( rMedium, *m_pWrtShell, !bSelection );
+ nErrno = aWrt.Write( xWriter, &aFileName );
+ //JP 16.05.97: In case the SFX revokes the View while saving
+ if (m_pWrtShell)
+ {
+ m_pWrtShell->Pop(SwCursorShell::PopMode::DeleteCurrent);
+ m_pWrtShell->EndAllAction();
+ // #i106906#
+ m_pWrtShell->LockView( bFormerLockView );
+ }
+ }
+ else
+ {
+ // are we in SourceView?
+ SwSrcView* pSrcView = ::lcl_GetSourceView( this );
+ if( pSrcView )
+ {
+ pSrcView->SaveContentTo(rMedium);
+ nErrno = ERRCODE_NONE;
+ }
+ else
+ {
+ SwWriter aWrt( rMedium, *m_xDoc );
+ nErrno = aWrt.Write( xWriter, &aFileName );
+ }
+ }
+
+ SW_MOD()->SetEmbeddedLoadSave( false );
+ SetError(nErrno ? nErrno : nVBWarning);
+ if( !rMedium.IsStorage() )
+ rMedium.CloseOutStream();
+
+ return ! nErrno.IsError();
+}
+
+// Hands off
+// do not yet activate, must deliver TRUE
+bool SwDocShell::SaveCompleted( const uno::Reference < embed::XStorage >& xStor )
+{
+ bool bRet = SfxObjectShell::SaveCompleted( xStor );
+ if( bRet )
+ {
+ // Do not decide until here, whether Saving was successful or not
+ if( IsModified() )
+ m_xDoc->getIDocumentState().SetModified();
+ else
+ m_xDoc->getIDocumentState().ResetModified();
+ }
+
+ if (m_pOLEChildList)
+ {
+ bool bResetModified = IsEnableSetModified();
+ if( bResetModified )
+ EnableSetModified( false );
+
+ uno::Sequence < OUString > aNames = m_pOLEChildList->GetObjectNames();
+ for( sal_Int32 n = aNames.getLength(); n; n-- )
+ {
+ if (!m_pOLEChildList->MoveEmbeddedObject(aNames[n-1], GetEmbeddedObjectContainer()))
+ {
+ OSL_FAIL("Copying of objects didn't work!" );
+ }
+ }
+
+ m_pOLEChildList.reset();
+ if( bResetModified )
+ EnableSetModified();
+ }
+ return bRet;
+}
+
+// Draw()-Override for OLE2 (Sfx)
+void SwDocShell::Draw( OutputDevice* pDev, const JobSetup& rSetup,
+ sal_uInt16 nAspect, bool bOutputForScreen )
+{
+ //fix #25341# Draw should not affect the Modified
+ bool bResetModified = IsEnableSetModified();
+ if ( bResetModified )
+ EnableSetModified( false );
+
+ // When there is a JobSetup connected to the Document, we copy it to
+ // reconnect it after PrtOle2. We don't use an empty JobSetup because
+ // that would only lead to questionable results after expensive
+ // reformatting (Preview!)
+ std::unique_ptr<JobSetup> pOrig;
+ if ( !rSetup.GetPrinterName().isEmpty() && ASPECT_THUMBNAIL != nAspect )
+ {
+ const JobSetup* pCurrentJobSetup = m_xDoc->getIDocumentDeviceAccess().getJobsetup();
+ if( pCurrentJobSetup ) // then we copy that
+ pOrig.reset(new JobSetup( *pCurrentJobSetup ));
+ m_xDoc->getIDocumentDeviceAccess().setJobsetup( rSetup );
+ }
+
+ tools::Rectangle aRect( nAspect == ASPECT_THUMBNAIL ?
+ GetVisArea( nAspect ) : GetVisArea( ASPECT_CONTENT ) );
+
+ pDev->Push();
+ pDev->SetFillColor();
+ pDev->SetLineColor();
+ pDev->SetBackground();
+ const bool bWeb = dynamic_cast< const SwWebDocShell *>( this ) != nullptr;
+ SwPrintData aOpts;
+ SwViewShell::PrtOle2(m_xDoc.get(), SW_MOD()->GetUsrPref(bWeb), aOpts, *pDev, aRect, bOutputForScreen);
+ pDev->Pop();
+
+ if( pOrig )
+ {
+ m_xDoc->getIDocumentDeviceAccess().setJobsetup( *pOrig );
+ }
+ if ( bResetModified )
+ EnableSetModified();
+}
+
+void SwDocShell::SetVisArea( const tools::Rectangle &rRect )
+{
+ tools::Rectangle aRect( rRect );
+ if (m_pView)
+ {
+ Size aSz( m_pView->GetDocSz() );
+ aSz.AdjustWidth(DOCUMENTBORDER ); aSz.AdjustHeight(DOCUMENTBORDER );
+ tools::Long nMoveX = 0, nMoveY = 0;
+ if ( aRect.Right() > aSz.Width() )
+ nMoveX = aSz.Width() - aRect.Right();
+ if ( aRect.Bottom() > aSz.Height() )
+ nMoveY = aSz.Height() - aRect.Bottom();
+ aRect.Move( nMoveX, nMoveY );
+ nMoveX = aRect.Left() < 0 ? -aRect.Left() : 0;
+ nMoveY = aRect.Top() < 0 ? -aRect.Top() : 0;
+ aRect.Move( nMoveX, nMoveY );
+
+ // Calls SfxInPlaceObject::SetVisArea()!
+ m_pView->SetVisArea( aRect );
+ }
+ else
+ SfxObjectShell::SetVisArea( aRect );
+}
+
+tools::Rectangle SwDocShell::GetVisArea( sal_uInt16 nAspect ) const
+{
+ if ( nAspect == ASPECT_THUMBNAIL )
+ {
+ // Preview: set VisArea to the first page.
+ SwNodeIndex aIdx( m_xDoc->GetNodes().GetEndOfExtras(), 1 );
+ SwContentNode* pNd = m_xDoc->GetNodes().GoNext( &aIdx );
+
+ const SwRect aPageRect = pNd->FindPageFrameRect();
+ if (aPageRect.IsEmpty())
+ return tools::Rectangle();
+ tools::Rectangle aRect(aPageRect.SVRect());
+
+ // tdf#81219 sanitize - nobody is interested in a thumbnail where's
+ // nothing visible
+ if (aRect.GetHeight() > 2*aRect.GetWidth())
+ aRect.SetSize(Size(aRect.GetWidth(), 2*aRect.GetWidth()));
+ else if (aRect.GetWidth() > 2*aRect.GetHeight())
+ aRect.SetSize(Size(2*aRect.GetHeight(), aRect.GetHeight()));
+
+ return aRect;
+ }
+ return SfxObjectShell::GetVisArea( nAspect );
+}
+
+Printer *SwDocShell::GetDocumentPrinter()
+{
+ return m_xDoc->getIDocumentDeviceAccess().getPrinter( false );
+}
+
+OutputDevice* SwDocShell::GetDocumentRefDev()
+{
+ return m_xDoc->getIDocumentDeviceAccess().getReferenceDevice( false );
+}
+
+void SwDocShell::OnDocumentPrinterChanged( Printer * pNewPrinter )
+{
+ if ( pNewPrinter )
+ GetDoc()->getIDocumentDeviceAccess().setJobsetup( pNewPrinter->GetJobSetup() );
+ else
+ GetDoc()->getIDocumentDeviceAccess().setPrinter( nullptr, true, true );
+}
+
+// #i20883# Digital Signatures and Encryption
+HiddenInformation SwDocShell::GetHiddenInformationState( HiddenInformation nStates )
+{
+ // get global state like HiddenInformation::DOCUMENTVERSIONS
+ HiddenInformation nState = SfxObjectShell::GetHiddenInformationState( nStates );
+
+ if ( nStates & HiddenInformation::RECORDEDCHANGES )
+ {
+ if ( !GetDoc()->getIDocumentRedlineAccess().GetRedlineTable().empty() )
+ nState |= HiddenInformation::RECORDEDCHANGES;
+ }
+ if ( nStates & HiddenInformation::NOTES )
+ {
+ OSL_ENSURE( GetWrtShell(), "No SwWrtShell, no information" );
+ if(GetWrtShell() && GetWrtShell()->GetFieldType(SwFieldIds::Postit, OUString())->HasHiddenInformationNotes())
+ nState |= HiddenInformation::NOTES;
+ }
+
+ return nState;
+}
+
+void SwDocShell::GetState(SfxItemSet& rSet)
+{
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+
+ while (nWhich)
+ {
+ switch (nWhich)
+ {
+ case SID_PRINTPREVIEW:
+ {
+ bool bDisable = IsInPlaceActive();
+ // Disable "multiple layout"
+ if ( !bDisable )
+ {
+ SfxViewFrame *pTmpFrame = SfxViewFrame::GetFirst(this);
+ while (pTmpFrame) // Look for Preview
+ {
+ if ( auto pSwView = dynamic_cast<SwView*>( pTmpFrame->GetViewShell() ) )
+ if (pSwView->GetWrtShell().GetViewOptions()->getBrowseMode())
+ {
+ bDisable = true;
+ break;
+ }
+ pTmpFrame = SfxViewFrame::GetNext(*pTmpFrame, this);
+ }
+ }
+ // End of disabled "multiple layout"
+ if ( bDisable )
+ rSet.DisableItem( SID_PRINTPREVIEW );
+ else
+ {
+ SfxBoolItem aBool( SID_PRINTPREVIEW, false );
+ if( dynamic_cast<SwPagePreview*>( SfxViewShell::Current()) )
+ aBool.SetValue( true );
+ rSet.Put( aBool );
+ }
+ }
+ break;
+ case SID_AUTO_CORRECT_DLG:
+ if ( comphelper::LibreOfficeKit::isActive() )
+ rSet.DisableItem( SID_AUTO_CORRECT_DLG );
+ break;
+ case SID_SOURCEVIEW:
+ {
+ SfxViewShell* pCurrView = GetView() ? static_cast<SfxViewShell*>(GetView())
+ : SfxViewShell::Current();
+ bool bSourceView = dynamic_cast<SwSrcView*>( pCurrView ) != nullptr;
+ rSet.Put(SfxBoolItem(SID_SOURCEVIEW, bSourceView));
+ }
+ break;
+ case SID_HTML_MODE:
+ rSet.Put(SfxUInt16Item(SID_HTML_MODE, ::GetHtmlMode(this)));
+ break;
+
+ case FN_ABSTRACT_STARIMPRESS:
+ case FN_OUTLINE_TO_IMPRESS:
+ {
+ SvtModuleOptions aMOpt;
+ if (!aMOpt.IsImpress() || GetObjectShell()->isExportLocked())
+ rSet.DisableItem( nWhich );
+ }
+ [[fallthrough]];
+ case FN_ABSTRACT_NEWDOC:
+ case FN_OUTLINE_TO_CLIPBOARD:
+ {
+ if ( GetDoc()->GetNodes().GetOutLineNds().empty() )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+ case SID_BROWSER_MODE:
+ case FN_PRINT_LAYOUT:
+ {
+ bool bState = GetDoc()->getIDocumentSettingAccess().get(DocumentSettingId::BROWSE_MODE);
+ if(FN_PRINT_LAYOUT == nWhich)
+ bState = !bState;
+ rSet.Put( SfxBoolItem( nWhich, bState));
+ }
+ break;
+
+ case FN_NEW_GLOBAL_DOC:
+ if (dynamic_cast<const SwGlobalDocShell*>(this) != nullptr
+ || GetObjectShell()->isExportLocked())
+ rSet.DisableItem( nWhich );
+ break;
+
+ case FN_NEW_HTML_DOC:
+ if (dynamic_cast<const SwWebDocShell*>(this) != nullptr
+ || GetObjectShell()->isExportLocked())
+ rSet.DisableItem( nWhich );
+ break;
+
+ case FN_OPEN_FILE:
+ if( dynamic_cast< const SwWebDocShell *>( this ) != nullptr )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_ATTR_YEAR2000:
+ {
+ const SvNumberFormatter* pFormatr = m_xDoc->GetNumberFormatter(false);
+ rSet.Put( SfxUInt16Item( nWhich,
+ static_cast< sal_uInt16 >(
+ pFormatr ? pFormatr->GetYear2000()
+ : officecfg::Office::Common::DateFormat::TwoDigitYear::get())) );
+ }
+ break;
+ case SID_ATTR_CHAR_FONTLIST:
+ {
+ rSet.Put( SvxFontListItem(m_pFontList.get(), SID_ATTR_CHAR_FONTLIST) );
+ }
+ break;
+ case SID_MAIL_PREPAREEXPORT:
+ {
+ //check if linked content or possibly hidden content is available
+ //m_xDoc->UpdateFields( NULL, false );
+ sfx2::LinkManager& rLnkMgr = m_xDoc->getIDocumentLinksAdministration().GetLinkManager();
+ const ::sfx2::SvBaseLinks& rLnks = rLnkMgr.GetLinks();
+ bool bRet = false;
+ if( !rLnks.empty() )
+ bRet = true;
+ else
+ {
+ //sections with hidden flag, hidden character attribute, hidden paragraph/text or conditional text fields
+ bRet = m_xDoc->HasInvisibleContent();
+ }
+ rSet.Put( SfxBoolItem( nWhich, bRet ) );
+ }
+ break;
+ case SID_NOTEBOOKBAR:
+ {
+ SfxViewShell* pViewShell = GetView()? GetView(): SfxViewShell::Current();
+ bool bVisible = sfx2::SfxNotebookBar::StateMethod(pViewShell->GetViewFrame().GetBindings(),
+ u"modules/swriter/ui/");
+ rSet.Put( SfxBoolItem( SID_NOTEBOOKBAR, bVisible ) );
+ }
+ break;
+ case FN_REDLINE_ACCEPT_ALL:
+ case FN_REDLINE_REJECT_ALL:
+ {
+ if (GetDoc()->getIDocumentRedlineAccess().GetRedlineTable().empty() ||
+ HasChangeRecordProtection()) // tdf#128229 Disable Accept / Reject all if redlines are password protected
+ rSet.DisableItem(nWhich);
+ }
+ break;
+
+ default: OSL_ENSURE(false,"You cannot get here!");
+
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+// OLE-Hdls
+IMPL_LINK( SwDocShell, Ole2ModifiedHdl, bool, bNewStatus, void )
+{
+ if (m_pWrtShell)
+ {
+ SwOLENode* pOLENode = nullptr;
+ if (!m_pWrtShell->IsTableMode())
+ {
+ pOLENode = m_pWrtShell->GetCursor()->GetPointNode().GetOLENode();
+ }
+ if (pOLENode)
+ {
+ if (pOLENode->GetOLEObj().IsProtected())
+ {
+ return;
+ }
+ }
+ }
+
+ if( IsEnableSetModified() )
+ SetModified( bNewStatus );
+}
+
+// return Pool here, because virtual
+SfxStyleSheetBasePool* SwDocShell::GetStyleSheetPool()
+{
+ return m_xBasePool.get();
+}
+
+sfx2::StyleManager* SwDocShell::GetStyleManager()
+{
+ return m_pStyleManager.get();
+}
+
+void SwDocShell::SetView(SwView* pVw)
+{
+ SetViewShell_Impl(pVw);
+ m_pView = pVw;
+ if (m_pView)
+ {
+ m_pWrtShell = &m_pView->GetWrtShell();
+
+ // Set view-specific redline author.
+ const OUString& rRedlineAuthor = m_pView->GetRedlineAuthor();
+ if (!rRedlineAuthor.isEmpty())
+ SW_MOD()->SetRedlineAuthor(m_pView->GetRedlineAuthor());
+ }
+ else
+ m_pWrtShell = nullptr;
+}
+
+// #i59688#
+// linked graphics are now loaded on demand.
+// Thus, loading of linked graphics no longer needed and necessary for
+// the load of document being finished.
+void SwDocShell::LoadingFinished()
+{
+ // #i38810#
+ // Original fix fails after integration of cws xmlsec11:
+ // interface <SfxObjectShell::EnableSetModified(..)> no longer works, because
+ // <SfxObjectShell::FinishedLoading(..)> doesn't care about its status and
+ // enables the document modification again.
+ // Thus, manual modify the document, if it's modified and its links are updated
+ // before <FinishedLoading(..)> is called.
+ const bool bHasDocToStayModified( m_xDoc->getIDocumentState().IsModified() && m_xDoc->getIDocumentLinksAdministration().LinksUpdated() );
+
+ FinishedLoading();
+ SfxViewFrame* pVFrame = SfxViewFrame::GetFirst(this);
+ if(pVFrame)
+ {
+ SfxViewShell* pShell = pVFrame->GetViewShell();
+ if(auto pSrcView = dynamic_cast<SwSrcView*>( pShell) )
+ pSrcView->Load(this);
+ }
+
+ // #i38810#
+ if ( bHasDocToStayModified && !m_xDoc->getIDocumentState().IsModified() )
+ {
+ m_xDoc->getIDocumentState().SetModified();
+ }
+}
+
+// a Transfer is cancelled (is called from SFX)
+void SwDocShell::CancelTransfers()
+{
+ // Cancel all links from LinkManager
+ m_xDoc->getIDocumentLinksAdministration().GetLinkManager().CancelTransfers();
+ SfxObjectShell::CancelTransfers();
+}
+
+SwEditShell * SwDocShell::GetEditShell()
+{
+ return m_pWrtShell;
+}
+
+SwFEShell* SwDocShell::GetFEShell()
+{
+ return m_pWrtShell;
+}
+
+void SwDocShell::RemoveOLEObjects()
+{
+ SwIterator<SwContentNode,SwFormatColl> aIter( *m_xDoc->GetDfltGrfFormatColl() );
+ for( SwContentNode* pNd = aIter.First(); pNd; pNd = aIter.Next() )
+ {
+ SwOLENode* pOLENd = pNd->GetOLENode();
+ if( pOLENd && ( pOLENd->IsOLEObjectDeleted() ||
+ pOLENd->IsInGlobalDocSection() ) )
+ {
+ if (!m_pOLEChildList)
+ m_pOLEChildList.reset( new comphelper::EmbeddedObjectContainer );
+
+ OUString aObjName = pOLENd->GetOLEObj().GetCurrentPersistName();
+ GetEmbeddedObjectContainer().MoveEmbeddedObject( aObjName, *m_pOLEChildList );
+ }
+ }
+}
+
+// When a document is loaded, SwDoc::PrtOLENotify is called to update
+// the sizes of math objects. However, for objects that do not have a
+// SwFrame at this time, only a flag is set (bIsOLESizeInvalid) and the
+// size change takes place later, while calculating the layout in the
+// idle handler. If this document is saved now, it is saved with invalid
+// sizes. For this reason, the layout has to be calculated before a document is
+// saved, but of course only id there are OLE objects with bOLESizeInvalid set.
+void SwDocShell::CalcLayoutForOLEObjects()
+{
+ if (!m_pWrtShell)
+ return;
+
+ if (m_pView && m_pView->GetIPClient())
+ {
+ // We have an active OLE edit: allow link updates, so an up to date replacement graphic can
+ // be created.
+ comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = getEmbeddedObjectContainer();
+ rEmbeddedObjectContainer.setUserAllowsLinkUpdate(true);
+ }
+
+ SwIterator<SwContentNode,SwFormatColl> aIter( *m_xDoc->GetDfltGrfFormatColl() );
+ for( SwContentNode* pNd = aIter.First(); pNd; pNd = aIter.Next() )
+ {
+ SwOLENode* pOLENd = pNd->GetOLENode();
+ if( pOLENd && pOLENd->IsOLESizeInvalid() )
+ {
+ m_pWrtShell->CalcLayout();
+ break;
+ }
+ }
+}
+
+// #i42634# Overwrites SfxObjectShell::UpdateLinks
+// This new function is necessary to trigger update of links in docs
+// read by the binary filter:
+void SwDocShell::UpdateLinks()
+{
+ GetDoc()->getIDocumentLinksAdministration().UpdateLinks();
+ // #i50703# Update footnote numbers
+ SwTextFootnote::SetUniqueSeqRefNo( *GetDoc() );
+ SwNodeIndex aTmp( GetDoc()->GetNodes() );
+ GetDoc()->GetFootnoteIdxs().UpdateFootnote( aTmp.GetNode() );
+}
+
+uno::Reference< frame::XController >
+ SwDocShell::GetController()
+{
+ css::uno::Reference< css::frame::XController > aRet;
+ // #i82346# No view in page preview
+ if ( GetView() )
+ aRet = GetView()->GetController();
+ return aRet;
+}
+
+static const char* s_EventNames[] =
+{
+ "OnPageCountChange",
+ "OnMailMerge",
+ "OnMailMergeFinished",
+ "OnFieldMerge",
+ "OnFieldMergeFinished",
+ "OnLayoutFinished"
+};
+sal_Int32 const s_nEvents(SAL_N_ELEMENTS(s_EventNames));
+
+Sequence< OUString > SwDocShell::GetEventNames()
+{
+ Sequence< OUString > aRet = SfxObjectShell::GetEventNames();
+ sal_Int32 nLen = aRet.getLength();
+ aRet.realloc(nLen + 6);
+ OUString* pNames = aRet.getArray();
+ pNames[nLen++] = GetEventName(0);
+ pNames[nLen++] = GetEventName(1);
+ pNames[nLen++] = GetEventName(2);
+ pNames[nLen++] = GetEventName(3);
+ pNames[nLen++] = GetEventName(4);
+ pNames[nLen] = GetEventName(5);
+
+ return aRet;
+}
+
+OUString SwDocShell::GetEventName( sal_Int32 nIndex )
+{
+ if (nIndex < s_nEvents)
+ {
+ return OUString::createFromAscii(s_EventNames[nIndex]);
+ }
+ return OUString();
+}
+
+const ::sfx2::IXmlIdRegistry* SwDocShell::GetXmlIdRegistry() const
+{
+ return m_xDoc ? &m_xDoc->GetXmlIdRegistry() : nullptr;
+}
+
+bool SwDocShell::IsChangeRecording() const
+{
+ if (!m_pWrtShell)
+ return false;
+ return bool(m_pWrtShell->GetRedlineFlags() & RedlineFlags::On);
+}
+
+bool SwDocShell::HasChangeRecordProtection() const
+{
+ if (!m_pWrtShell)
+ return false;
+ return m_pWrtShell->getIDocumentRedlineAccess().GetRedlinePassword().hasElements();
+}
+
+void SwDocShell::SetChangeRecording( bool bActivate, bool bLockAllViews )
+{
+ RedlineFlags nOn = bActivate ? RedlineFlags::On : RedlineFlags::NONE;
+ RedlineFlags nMode = m_pWrtShell->GetRedlineFlags();
+ if (bLockAllViews)
+ {
+ // tdf#107870: prevent jumping to cursor
+ auto aViewGuard(LockAllViews());
+ m_pWrtShell->SetRedlineFlagsAndCheckInsMode( (nMode & ~RedlineFlags::On) | nOn );
+ }
+ else
+ {
+ m_pWrtShell->SetRedlineFlagsAndCheckInsMode( (nMode & ~RedlineFlags::On) | nOn );
+ }
+}
+
+void SwDocShell::SetProtectionPassword( const OUString &rNewPassword )
+{
+ const SfxAllItemSet aSet( GetPool() );
+
+ IDocumentRedlineAccess& rIDRA = m_pWrtShell->getIDocumentRedlineAccess();
+ Sequence< sal_Int8 > aPasswd = rIDRA.GetRedlinePassword();
+ const SfxBoolItem* pRedlineProtectItem = aSet.GetItemIfSet(FN_REDLINE_PROTECT, false);
+ if (pRedlineProtectItem
+ && pRedlineProtectItem->GetValue() == aPasswd.hasElements())
+ return;
+
+ if (!rNewPassword.isEmpty())
+ {
+ // when password protection is applied change tracking must always be active
+ SetChangeRecording( true );
+
+ Sequence< sal_Int8 > aNewPasswd;
+ SvPasswordHelper::GetHashPassword( aNewPasswd, rNewPassword );
+ rIDRA.SetRedlinePassword( aNewPasswd );
+ }
+ else
+ {
+ rIDRA.SetRedlinePassword( Sequence< sal_Int8 >() );
+ }
+}
+
+bool SwDocShell::GetProtectionHash( /*out*/ css::uno::Sequence< sal_Int8 > &rPasswordHash )
+{
+ bool bRes = false;
+
+ const SfxAllItemSet aSet( GetPool() );
+
+ IDocumentRedlineAccess& rIDRA = m_pWrtShell->getIDocumentRedlineAccess();
+ const Sequence< sal_Int8 >& aPasswdHash( rIDRA.GetRedlinePassword() );
+ const SfxBoolItem* pRedlineProtectItem = aSet.GetItemIfSet(FN_REDLINE_PROTECT, false);
+ if (pRedlineProtectItem
+ && pRedlineProtectItem->GetValue() == aPasswdHash.hasElements())
+ return false;
+ rPasswordHash = aPasswdHash;
+ bRes = true;
+
+ return bRes;
+}
+
+void SwDocShell::RegisterAutomationDocumentEventsCaller(css::uno::Reference< ooo::vba::XSinkCaller > const& xCaller)
+{
+ mxAutomationDocumentEventsCaller = xCaller;
+}
+
+void SwDocShell::CallAutomationDocumentEventSinks(const OUString& Method, css::uno::Sequence< css::uno::Any >& Arguments)
+{
+ if (mxAutomationDocumentEventsCaller.is())
+ mxAutomationDocumentEventsCaller->CallSinks(Method, Arguments);
+}
+
+void SwDocShell::RegisterAutomationDocumentObject(css::uno::Reference< ooo::vba::word::XDocument > const& xDocument)
+{
+ mxAutomationDocumentObject = xDocument;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/app/docsh2.cxx b/sw/source/uibase/app/docsh2.cxx
new file mode 100644
index 0000000000..47c8a3ec65
--- /dev/null
+++ b/sw/source/uibase/app/docsh2.cxx
@@ -0,0 +1,1805 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_features.h>
+
+#include <osl/diagnose.h>
+#include <com/sun/star/drawing/ModuleDispatcher.hpp>
+#include <com/sun/star/frame/DispatchHelper.hpp>
+#include <ooo/vba/word/XDocument.hpp>
+#include <comphelper/fileformat.h>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/string.hxx>
+
+#include <sal/log.hxx>
+#include <edtwin.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/tempfile.hxx>
+#include <unotools/configmgr.hxx>
+#include <vcl/errinf.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <svl/eitem.hxx>
+#include <svl/macitem.hxx>
+#include <unotools/pathoptions.hxx>
+#include <vcl/transfer.hxx>
+#include <sfx2/dinfdlg.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/new.hxx>
+#include <sfx2/notebookbar/SfxNotebookBar.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/evntconf.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/docfilt.hxx>
+#include <svx/dialogs.hrc>
+#include <svx/drawitem.hxx>
+#include <editeng/svxacorr.hxx>
+#include <svx/fmshell.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <sfx2/classificationhelper.hxx>
+#include <sfx2/watermarkitem.hxx>
+
+#include <svx/ofaitem.hxx>
+#include <SwSmartTagMgr.hxx>
+#include <sfx2/app.hxx>
+#include <basic/sbstar.hxx>
+#include <basic/basmgr.hxx>
+#include <comphelper/classids.hxx>
+#include <fmtcol.hxx>
+#include <istype.hxx>
+#include <view.hxx>
+#include <docsh.hxx>
+#include <docary.hxx>
+#include <wrtsh.hxx>
+#include <rootfrm.hxx>
+#include <fldbas.hxx>
+#include <viewopt.hxx>
+#include <globdoc.hxx>
+#include <fldwrap.hxx>
+#include <redlndlg.hxx>
+#include <doc.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <IDocumentSettingAccess.hxx>
+#include <IDocumentDeviceAccess.hxx>
+#include <IDocumentLinksAdministration.hxx>
+#include <IDocumentFieldsAccess.hxx>
+#include <IDocumentStatistics.hxx>
+#include <IDocumentLayoutAccess.hxx>
+#include <IDocumentRedlineAccess.hxx>
+#include <IDocumentState.hxx>
+#include <shellio.hxx>
+#include <pview.hxx>
+#include <srcview.hxx>
+#include <wdocsh.hxx>
+#include <unotxdoc.hxx>
+#include <acmplwrd.hxx>
+#include <swmodule.hxx>
+#include <unobaseclass.hxx>
+#include <swwait.hxx>
+#include <swcli.hxx>
+
+#include <cmdid.h>
+#include <helpids.h>
+#include <strings.hrc>
+#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
+#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
+#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/ListboxControlActions.hpp>
+#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
+#include <com/sun/star/script/vba/VBAEventId.hpp>
+#include <editeng/acorrcfg.hxx>
+#include <officecfg/Office/Security.hxx>
+#include <officecfg/Office/Common.hxx>
+
+#include <sfx2/fcontnr.hxx>
+#include <svx/ClassificationDialog.hxx>
+#include <svtools/embedhlp.hxx>
+
+#include <swabstdlg.hxx>
+#include <watermarkdialog.hxx>
+
+#include <ndtxt.hxx>
+#include <iodetect.hxx>
+
+#include <memory>
+
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star;
+using namespace ::sfx2;
+
+// create DocInfo (virtual)
+std::shared_ptr<SfxDocumentInfoDialog> SwDocShell::CreateDocumentInfoDialog(weld::Window* pParent, const SfxItemSet &rSet)
+{
+ std::shared_ptr<SfxDocumentInfoDialog> xDlg = std::make_shared<SfxDocumentInfoDialog>(pParent, rSet);
+ //only with statistics, when this document is being shown, not
+ //from within the Doc-Manager
+ SwDocShell* pDocSh = static_cast<SwDocShell*>( SfxObjectShell::Current());
+ if( pDocSh == this )
+ {
+ //Not for SourceView.
+ SfxViewShell *pVSh = SfxViewShell::Current();
+ if ( pVSh && dynamic_cast< const SwSrcView *>( pVSh ) == nullptr )
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ xDlg->AddFontTabPage();
+ xDlg->AddTabPage("writerstats", SwResId(STR_DOC_STAT), pFact->GetTabPageCreatorFunc(RID_SW_TP_DOC_STAT));
+ }
+ }
+ return xDlg;
+}
+
+void SwDocShell::ToggleLayoutMode(SwView* pView)
+{
+ OSL_ENSURE( pView, "SwDocShell::ToggleLayoutMode, pView is null." );
+
+ const SwViewOption& rViewOptions = *pView->GetWrtShell().GetViewOptions();
+
+ //TODO: Should HideWhitespace flag be saved in the document settings?
+ GetDoc()->getIDocumentSettingAccess().set(DocumentSettingId::BROWSE_MODE, rViewOptions.getBrowseMode());
+ UpdateFontList(); // Why is this necessary here?
+
+ pView->GetViewFrame().GetBindings().Invalidate(FN_SHADOWCURSOR);
+ if( !GetDoc()->getIDocumentDeviceAccess().getPrinter( false ) )
+ pView->SetPrinter( GetDoc()->getIDocumentDeviceAccess().getPrinter( false ), SfxPrinterChangeFlags::PRINTER | SfxPrinterChangeFlags::JOBSETUP );
+ GetDoc()->CheckDefaultPageFormat();
+ SfxViewFrame *pTmpFrame = SfxViewFrame::GetFirst(this, false);
+ while (pTmpFrame)
+ {
+ if( pTmpFrame != &pView->GetViewFrame() )
+ {
+ pTmpFrame->DoClose();
+ pTmpFrame = SfxViewFrame::GetFirst(this, false);
+ }
+ else
+ pTmpFrame = SfxViewFrame::GetNext(*pTmpFrame, this, false);
+ }
+
+ pView->GetWrtShell().InvalidateLayout(true);
+
+ pView->RecheckBrowseMode();
+
+ pView->SetNewWindowAllowed(!rViewOptions.getBrowseMode());
+}
+
+// update text fields on document properties changes
+void SwDocShell::DoFlushDocInfo()
+{
+ if (!m_xDoc)
+ return;
+
+ bool bUnlockView(true);
+ if (m_pWrtShell)
+ {
+ bUnlockView = !m_pWrtShell->IsViewLocked();
+ m_pWrtShell->LockView( true ); // lock visible section
+ m_pWrtShell->StartAllAction();
+ }
+
+ m_xDoc->getIDocumentStatistics().DocInfoChgd(IsEnableSetModified());
+
+ if (m_pWrtShell)
+ {
+ m_pWrtShell->EndAllAction();
+ if (bUnlockView)
+ {
+ m_pWrtShell->LockView( false );
+ }
+ }
+}
+
+static void lcl_processCompatibleSfxHint( const uno::Reference< script::vba::XVBAEventProcessor >& xVbaEvents, const SfxHint& rHint )
+{
+ using namespace com::sun::star::script::vba::VBAEventId;
+ if (rHint.GetId() != SfxHintId::ThisIsAnSfxEventHint)
+ return;
+
+ uno::Sequence< uno::Any > aArgs;
+ switch (static_cast<const SfxEventHint&>(rHint).GetEventId())
+ {
+ case SfxEventHintId::CreateDoc:
+ xVbaEvents->processVbaEvent(AUTO_NEW, aArgs);
+ xVbaEvents->processVbaEvent(DOCUMENT_NEW, aArgs);
+ break;
+ case SfxEventHintId::OpenDoc:
+ xVbaEvents->processVbaEvent(AUTO_OPEN, aArgs);
+ xVbaEvents->processVbaEvent(DOCUMENT_OPEN, aArgs);
+ break;
+ default: break;
+ }
+}
+
+// Notification on DocInfo changes
+void SwDocShell::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if (!m_xDoc)
+ {
+ return ;
+ }
+
+ uno::Reference< script::vba::XVBAEventProcessor > const xVbaEvents =
+ m_xDoc->GetVbaEventProcessor();
+ if( xVbaEvents.is() )
+ lcl_processCompatibleSfxHint( xVbaEvents, rHint );
+
+ if (rHint.GetId() == SfxHintId::ThisIsAnSfxEventHint)
+ {
+ switch (static_cast<const SfxEventHint&>(rHint).GetEventId())
+ {
+ case SfxEventHintId::ActivateDoc:
+ case SfxEventHintId::CreateDoc:
+ case SfxEventHintId::OpenDoc:
+ {
+ uno::Sequence< css::uno::Any > aArgs;
+ SW_MOD()->CallAutomationApplicationEventSinks( "DocumentChange", aArgs );
+ break;
+ }
+ default:
+ break;
+ }
+
+ switch (static_cast<const SfxEventHint&>(rHint).GetEventId())
+ {
+ case SfxEventHintId::CreateDoc:
+ {
+ uno::Any aDocument;
+ aDocument <<= mxAutomationDocumentObject;
+ uno::Sequence< uno::Any > aArgs{ aDocument };
+ SW_MOD()->CallAutomationApplicationEventSinks( "NewDocument", aArgs );
+ }
+ break;
+ case SfxEventHintId::OpenDoc:
+ {
+ uno::Any aDocument;
+ aDocument <<= mxAutomationDocumentObject;
+ uno::Sequence< uno::Any > aArgs{ aDocument };
+ SW_MOD()->CallAutomationApplicationEventSinks( "DocumentOpen", aArgs );
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ sal_uInt16 nAction = 0;
+ if (rHint.GetId() == SfxHintId::ThisIsAnSfxEventHint &&
+ static_cast<const SfxEventHint&>(rHint).GetEventId() == SfxEventHintId::LoadFinished)
+ {
+ // #i38126# - own action id
+ nAction = 3;
+ }
+ else
+ {
+ // switch for more actions
+ if( rHint.GetId() == SfxHintId::TitleChanged)
+ {
+ if( GetMedium() )
+ nAction = 2;
+ }
+ }
+
+ if( !nAction )
+ return;
+
+ bool bUnlockView = true; //initializing prevents warning
+ if (m_pWrtShell)
+ {
+ bUnlockView = !m_pWrtShell->IsViewLocked();
+ m_pWrtShell->LockView( true ); //lock visible section
+ m_pWrtShell->StartAllAction();
+ }
+ switch( nAction )
+ {
+ case 2:
+ m_xDoc->getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::Filename )->UpdateFields();
+ break;
+ // #i38126# - own action for event LOADFINISHED
+ // in order to avoid a modified document.
+ // #i41679# - Also for the instance of <SwDoc>
+ // it has to be assured, that it's not modified.
+ // Perform the same as for action id 1, but disable <SetModified>.
+ case 3:
+ {
+ const bool bResetModified = IsEnableSetModified();
+ if ( bResetModified )
+ EnableSetModified( false );
+ // #i41679#
+ const bool bIsDocModified = m_xDoc->getIDocumentState().IsModified();
+ // TODO: is the ResetModified() below because of only the direct call from DocInfoChgd, or does UpdateFields() set it too?
+
+ m_xDoc->getIDocumentStatistics().DocInfoChgd(false);
+
+ // #i41679#
+ if ( !bIsDocModified )
+ m_xDoc->getIDocumentState().ResetModified();
+ if ( bResetModified )
+ EnableSetModified();
+ }
+ break;
+ }
+
+ if (m_pWrtShell)
+ {
+ m_pWrtShell->EndAllAction();
+ if( bUnlockView )
+ m_pWrtShell->LockView( false );
+ }
+}
+
+// Notification Close Doc
+bool SwDocShell::PrepareClose( bool bUI )
+{
+ bool bRet = SfxObjectShell::PrepareClose( bUI );
+
+ // If we are going to close it at this point, let potential DocumentBeforeClose event handlers
+ // in Automation clients veto it.
+ if (bRet && m_xDoc && IsInPrepareClose())
+ {
+ uno::Any aDocument;
+ aDocument <<= mxAutomationDocumentObject;
+
+ uno::Sequence<uno::Any> aArgs{ // Arg 0: Document
+ aDocument,
+ // Arg 1: Cancel
+ uno::Any(false)
+ };
+
+ SW_MOD()->CallAutomationApplicationEventSinks( "DocumentBeforeClose", aArgs );
+
+ // If the Cancel argument was set to True by an event handler, return false.
+ bool bCancel(false);
+ aArgs[1] >>= bCancel;
+ if (bCancel)
+ bRet = false;
+ }
+
+ if( bRet )
+ EndListening( *this );
+
+ if (m_xDoc && IsInPrepareClose())
+ {
+ uno::Reference< script::vba::XVBAEventProcessor > const xVbaEvents =
+ m_xDoc->GetVbaEventProcessor();
+ if( xVbaEvents.is() )
+ {
+ using namespace com::sun::star::script::vba::VBAEventId;
+ uno::Sequence< uno::Any > aNoArgs;
+ xVbaEvents->processVbaEvent(AUTO_CLOSE, aNoArgs);
+ xVbaEvents->processVbaEvent(DOCUMENT_CLOSE, aNoArgs);
+ }
+ }
+ return bRet;
+}
+
+void SwDocShell::Execute(SfxRequest& rReq)
+{
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ const SfxPoolItem* pItem;
+ sal_uInt16 nWhich = rReq.GetSlot();
+ bool bDone = false;
+ switch ( nWhich )
+ {
+ case SID_AUTO_CORRECT_DLG:
+ {
+ SvxSwAutoFormatFlags* pAFlags = &SvxAutoCorrCfg::Get().GetAutoCorrect()->GetSwFlags();
+ SwAutoCompleteWord& rACW = SwDoc::GetAutoCompleteWords();
+
+ bool bOldLocked = rACW.IsLockWordLstLocked(),
+ bOldAutoCmpltCollectWords = pAFlags->bAutoCmpltCollectWords;
+
+ rACW.SetLockWordLstLocked( true );
+
+ editeng::SortedAutoCompleteStrings aTmpLst( rACW.GetWordList().createNonOwningCopy() );
+ pAFlags->m_pAutoCompleteList = &aTmpLst;
+
+ SfxApplication* pApp = SfxGetpApp();
+ SfxRequest aAppReq(SID_AUTO_CORRECT_DLG, SfxCallMode::SYNCHRON, pApp->GetPool());
+ SfxBoolItem aSwOptions( SID_AUTO_CORRECT_DLG, true );
+ aAppReq.AppendItem(aSwOptions);
+
+ pAFlags->pSmartTagMgr = &SwSmartTagMgr::Get();
+
+ SfxItemSetFixed<SID_AUTO_CORRECT_DLG, SID_AUTO_CORRECT_DLG, SID_OPEN_SMARTTAGOPTIONS, SID_OPEN_SMARTTAGOPTIONS> aSet( pApp->GetPool() );
+ aSet.Put( aSwOptions );
+
+ const SfxBoolItem* pOpenSmartTagOptionsItem = nullptr;
+ if( pArgs && (pOpenSmartTagOptionsItem = pArgs->GetItemIfSet( SID_OPEN_SMARTTAGOPTIONS, false )) )
+ aSet.Put( *pOpenSmartTagOptionsItem );
+
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ VclPtr<SfxAbstractTabDialog> pDlg = pFact->CreateAutoCorrTabDialog(GetView()->GetFrameWeld(), &aSet);
+ pDlg->Execute();
+ pDlg.disposeAndClear();
+
+
+ rACW.SetLockWordLstLocked( bOldLocked );
+
+ SwEditShell::SetAutoFormatFlags( pAFlags );
+ rACW.SetMinWordLen( pAFlags->nAutoCmpltWordLen );
+ rACW.SetMaxCount( pAFlags->nAutoCmpltListLen );
+ if (pAFlags->m_pAutoCompleteList) // any changes?
+ {
+ rACW.CheckChangedList( aTmpLst );
+ // clear the temp WordList pointer
+ pAFlags->m_pAutoCompleteList = nullptr;
+ }
+
+ if( !bOldAutoCmpltCollectWords && bOldAutoCmpltCollectWords !=
+ pAFlags->bAutoCmpltCollectWords )
+ {
+ // call on all Docs the idle formatter to start
+ // the collection of Words
+ for( SwDocShell *pDocSh = static_cast<SwDocShell*>(SfxObjectShell::GetFirst(checkSfxObjectShell<SwDocShell>));
+ pDocSh;
+ pDocSh = static_cast<SwDocShell*>(SfxObjectShell::GetNext( *pDocSh, checkSfxObjectShell<SwDocShell> )) )
+ {
+ SwDoc* pTmp = pDocSh->GetDoc();
+ if ( pTmp->getIDocumentLayoutAccess().GetCurrentViewShell() )
+ pTmp->InvalidateAutoCompleteFlag();
+ }
+ }
+ }
+ break;
+
+ case SID_PRINTPREVIEW:
+ {
+ bool bSet = false;
+ bool bFound = false, bOnly = true;
+ SfxViewFrame *pTmpFrame = SfxViewFrame::GetFirst(this);
+ SfxViewShell* pViewShell = SfxViewShell::Current();
+ SwView* pCurrView = dynamic_cast< SwView *> ( pViewShell );
+ bool bCurrent = isType<SwPagePreview>( pViewShell );
+
+ while( pTmpFrame ) // search Preview
+ {
+ if( isType<SwView>( pTmpFrame->GetViewShell()) )
+ bOnly = false;
+ else if( isType<SwPagePreview>( pTmpFrame->GetViewShell()))
+ {
+ pTmpFrame->GetFrame().Appear();
+ bFound = true;
+ }
+ if( bFound && !bOnly )
+ break;
+ pTmpFrame = SfxViewFrame::GetNext(*pTmpFrame, this);
+ }
+
+ if( pArgs && SfxItemState::SET ==
+ pArgs->GetItemState( SID_PRINTPREVIEW, false, &pItem ))
+ bSet = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ else
+ bSet = !bCurrent;
+
+ sal_uInt16 nSlotId = 0;
+ if( bSet && !bFound ) // Nothing found, so create new Preview
+ nSlotId = SID_VIEWSHELL1;
+ else if( bFound && !bSet )
+ nSlotId = bOnly ? SID_VIEWSHELL0 : SID_VIEWSHELL1;
+
+ if( nSlotId )
+ {
+ // PagePreview in the WebDocShell
+ // is found under Id VIEWSHELL2.
+ if( dynamic_cast< const SwWebDocShell *>( this ) != nullptr && SID_VIEWSHELL1 == nSlotId )
+ nSlotId = SID_VIEWSHELL2;
+
+ if( pCurrView && pCurrView->GetDocShell() == this )
+ pTmpFrame = &pCurrView->GetViewFrame();
+ else
+ pTmpFrame = SfxViewFrame::GetFirst( this );
+
+ if (pTmpFrame)
+ pTmpFrame->GetDispatcher()->Execute( nSlotId, SfxCallMode::ASYNCHRON );
+ }
+
+ rReq.SetReturnValue(SfxBoolItem(SID_PRINTPREVIEW, bSet ));
+ }
+ break;
+ case SID_TEMPLATE_LOAD:
+ {
+ OUString aFileName;
+ static bool bText = true;
+ static bool bFrame = false;
+ static bool bPage = false;
+ static bool bNum = false;
+ static bool bMerge = false;
+
+ SfxTemplateFlags nFlags = bFrame ? SfxTemplateFlags::LOAD_FRAME_STYLES : SfxTemplateFlags::NONE;
+ if(bPage)
+ nFlags |= SfxTemplateFlags::LOAD_PAGE_STYLES;
+ if(bNum)
+ nFlags |= SfxTemplateFlags::LOAD_NUM_STYLES;
+ if(nFlags == SfxTemplateFlags::NONE || bText)
+ nFlags |= SfxTemplateFlags::LOAD_TEXT_STYLES;
+ if(bMerge)
+ nFlags |= SfxTemplateFlags::MERGE_STYLES;
+
+ if ( pArgs )
+ {
+ const SfxStringItem* pTemplateItem = rReq.GetArg<SfxStringItem>(SID_TEMPLATE_NAME);
+ if ( pTemplateItem )
+ {
+ aFileName = pTemplateItem->GetValue();
+ const SfxInt32Item* pFlagsItem = rReq.GetArg<SfxInt32Item>(SID_TEMPLATE_LOAD);
+ if ( pFlagsItem )
+ nFlags = static_cast<SfxTemplateFlags>(o3tl::narrowing<sal_uInt16>(pFlagsItem->GetValue()));
+ }
+ }
+
+ if ( aFileName.isEmpty() )
+ {
+ SfxNewFileDialog aNewFileDlg(GetView()->GetFrameWeld(), SfxNewFileDialogMode::LoadTemplate);
+ aNewFileDlg.SetTemplateFlags(nFlags);
+
+ sal_uInt16 nRet = aNewFileDlg.run();
+ if(RET_TEMPLATE_LOAD == nRet)
+ {
+ FileDialogHelper aDlgHelper(TemplateDescription::FILEOPEN_SIMPLE,
+ FileDialogFlags::NONE, GetView()->GetFrameWeld());
+ aDlgHelper.SetContext(FileDialogHelper::WriterLoadTemplate);
+ uno::Reference < XFilePicker3 > xFP = aDlgHelper.GetFilePicker();
+
+ SfxObjectFactory &rFact = GetFactory();
+ SfxFilterMatcher aMatcher( rFact.GetFactoryName() );
+ SfxFilterMatcherIter aIter( aMatcher );
+ std::shared_ptr<const SfxFilter> pFlt = aIter.First();
+ while( pFlt )
+ {
+ // --> OD #i117339#
+ if( pFlt && pFlt->IsAllowedAsTemplate() &&
+ ( pFlt->GetUserData() == "CXML" ||
+ pFlt->GetUserData() == "CXMLV" ) )
+ {
+ const OUString sWild = pFlt->GetWildcard().getGlob();
+ xFP->appendFilter( pFlt->GetUIName(), sWild );
+ }
+ pFlt = aIter.Next();
+ }
+ bool bWeb = dynamic_cast< SwWebDocShell *>( this ) != nullptr;
+ std::shared_ptr<const SfxFilter> pOwnFlt =
+ SwDocShell::Factory().GetFilterContainer()->
+ GetFilter4FilterName("writer8");
+
+ // make sure the default file format is also available
+ if(bWeb)
+ {
+ const OUString sWild = pOwnFlt->GetWildcard().getGlob();
+ xFP->appendFilter( pOwnFlt->GetUIName(), sWild );
+ }
+
+ bool bError = false;
+ // catch exception if wrong filter is selected - should not happen anymore
+ try
+ {
+ xFP->setCurrentFilter( pOwnFlt->GetUIName() );
+ }
+ catch (const uno::Exception&)
+ {
+ bError = true;
+ }
+
+ if( !bError && ERRCODE_NONE == aDlgHelper.Execute() )
+ {
+ aFileName = xFP->getSelectedFiles().getConstArray()[0];
+ }
+ }
+ else if( RET_OK == nRet)
+ {
+ aFileName = aNewFileDlg.GetTemplateFileName();
+ }
+
+ nFlags = aNewFileDlg.GetTemplateFlags();
+ rReq.AppendItem( SfxStringItem( SID_TEMPLATE_NAME, aFileName ) );
+ rReq.AppendItem( SfxInt32Item( SID_TEMPLATE_LOAD, static_cast<tools::Long>(nFlags) ) );
+ }
+
+ if( !aFileName.isEmpty() )
+ {
+ SwgReaderOption aOpt;
+ bText = bool(nFlags & SfxTemplateFlags::LOAD_TEXT_STYLES );
+ aOpt.SetTextFormats(bText);
+ bFrame = bool(nFlags & SfxTemplateFlags::LOAD_FRAME_STYLES);
+ aOpt.SetFrameFormats(bFrame);
+ bPage = bool(nFlags & SfxTemplateFlags::LOAD_PAGE_STYLES );
+ aOpt.SetPageDescs(bPage);
+ bNum = bool(nFlags & SfxTemplateFlags::LOAD_NUM_STYLES );
+ aOpt.SetNumRules(bNum);
+ //different meaning between SFX_MERGE_STYLES and aOpt.SetMerge!
+ bMerge = bool(nFlags & SfxTemplateFlags::MERGE_STYLES);
+ aOpt.SetMerge( !bMerge );
+
+ SetError(LoadStylesFromFile(aFileName, aOpt, false));
+ if ( !GetErrorIgnoreWarning() )
+ rReq.Done();
+ }
+ }
+ break;
+ case SID_SOURCEVIEW:
+ {
+ SfxViewShell* pViewShell = GetView()
+ ? static_cast<SfxViewShell*>(GetView())
+ : SfxViewShell::Current();
+ SfxViewFrame& rViewFrame = pViewShell->GetViewFrame();
+ SwSrcView* pSrcView = dynamic_cast< SwSrcView *>( pViewShell );
+ if(!pSrcView)
+ {
+ // 3 possible state:
+ // 1 - file unsaved -> save as HTML
+ // 2 - file modified and HTML filter active -> save
+ // 3 - file saved in non-HTML -> QueryBox to save as HTML
+ std::shared_ptr<const SfxFilter> pHtmlFlt =
+ SwIoSystem::GetFilterOfFormat(
+ u"HTML",
+ SwWebDocShell::Factory().GetFilterContainer() );
+ bool bLocalHasName = HasName();
+ if(bLocalHasName)
+ {
+ //check for filter type
+ std::shared_ptr<const SfxFilter> pFlt = GetMedium()->GetFilter();
+ if(!pFlt || pFlt->GetUserData() != pHtmlFlt->GetUserData())
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(rViewFrame.GetFrameWeld(), "modules/swriter/ui/saveashtmldialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("SaveAsHTMLDialog"));
+ if (RET_YES == xQuery->run())
+ bLocalHasName = false;
+ else
+ break;
+ }
+ }
+ if(!bLocalHasName)
+ {
+ FileDialogHelper aDlgHelper(TemplateDescription::FILESAVE_AUTOEXTENSION,
+ FileDialogFlags::NONE,
+ GetView()->GetFrameWeld());
+ aDlgHelper.SetContext(FileDialogHelper::WriterSaveHTML);
+ aDlgHelper.AddFilter( pHtmlFlt->GetFilterName(), pHtmlFlt->GetDefaultExtension() );
+ aDlgHelper.SetCurrentFilter( pHtmlFlt->GetFilterName() );
+ if( ERRCODE_NONE != aDlgHelper.Execute())
+ {
+ break;
+ }
+ OUString sPath = aDlgHelper.GetPath();
+ SfxStringItem aName(SID_FILE_NAME, sPath);
+ SfxStringItem aFilter(SID_FILTER_NAME, pHtmlFlt->GetName());
+ const SfxPoolItemHolder aResult(
+ rViewFrame.GetDispatcher()->ExecuteList(
+ SID_SAVEASDOC, SfxCallMode::SYNCHRON,
+ { &aName, &aFilter }));
+ const SfxBoolItem* pBool(static_cast<const SfxBoolItem*>(aResult.getItem()));
+ if(!pBool || !pBool->GetValue())
+ break;
+ }
+ }
+
+ assert(dynamic_cast<SwWebDocShell*>(this) && "SourceView only in WebDocShell");
+
+ // the SourceView is not the 1 for SwWebDocShell
+ sal_uInt16 nSlot = SID_VIEWSHELL1;
+ bool bSetModified = false;
+ VclPtr<SfxPrinter> pSavePrinter;
+ if( nullptr != pSrcView)
+ {
+ SfxPrinter* pTemp = GetDoc()->getIDocumentDeviceAccess().getPrinter( false );
+ if(pTemp)
+ pSavePrinter = VclPtr<SfxPrinter>::Create(*pTemp);
+ bSetModified = IsModified() || pSrcView->IsModified();
+ if(pSrcView->IsModified()||pSrcView->HasSourceSaved())
+ {
+ utl::TempFileNamed aTempFile;
+ aTempFile.EnableKillingFile();
+ pSrcView->SaveContent(aTempFile.GetURL());
+ bDone = true;
+ SvxMacro aMac(OUString(), OUString(), STARBASIC);
+ SfxEventConfiguration::ConfigureEvent(GlobalEventConfig::GetEventName( GlobalEventId::OPENDOC ), aMac, this);
+ SfxEventConfiguration::ConfigureEvent(GlobalEventConfig::GetEventName( GlobalEventId::PREPARECLOSEDOC ), aMac, this);
+ SfxEventConfiguration::ConfigureEvent(GlobalEventConfig::GetEventName( GlobalEventId::ACTIVATEDOC ), aMac, this);
+ SfxEventConfiguration::ConfigureEvent(GlobalEventConfig::GetEventName( GlobalEventId::DEACTIVATEDOC ), aMac, this);
+ ReloadFromHtml(aTempFile.GetURL(), pSrcView);
+ nSlot = 0;
+ }
+ else
+ {
+ nSlot = SID_VIEWSHELL0;
+ }
+ }
+ if (nSlot)
+ rViewFrame.GetDispatcher()->Execute(nSlot, SfxCallMode::SYNCHRON);
+ if(bSetModified)
+ GetDoc()->getIDocumentState().SetModified();
+ if(pSavePrinter)
+ {
+ GetDoc()->getIDocumentDeviceAccess().setPrinter( pSavePrinter, true, true);
+ //pSavePrinter must not be deleted again
+ }
+ rViewFrame.GetBindings().SetState(SfxBoolItem(SID_SOURCEVIEW, false)); // not SID_VIEWSHELL2
+ rViewFrame.GetBindings().Invalidate( SID_NEWWINDOW );
+ rViewFrame.GetBindings().Invalidate( SID_BROWSER_MODE );
+ rViewFrame.GetBindings().Invalidate( FN_PRINT_LAYOUT );
+ }
+ break;
+ case SID_GET_COLORLIST:
+ {
+ const SvxColorListItem* pColItem = GetItem(SID_COLOR_TABLE);
+ const XColorListRef& pList = pColItem->GetColorList();
+ rReq.SetReturnValue(OfaXColorListItem(SID_GET_COLORLIST, pList));
+ }
+ break;
+ case FN_ABSTRACT_STARIMPRESS:
+ case FN_ABSTRACT_NEWDOC:
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSwInsertAbstractDlg> pDlg(pFact->CreateSwInsertAbstractDlg(GetView()->GetFrameWeld()));
+ if(RET_OK == pDlg->Execute())
+ {
+ sal_uInt8 nLevel = pDlg->GetLevel();
+ sal_uInt8 nPara = pDlg->GetPara();
+ SwDoc* pSmryDoc = new SwDoc();
+ SfxObjectShellLock xDocSh(new SwDocShell(*pSmryDoc, SfxObjectCreateMode::STANDARD));
+ xDocSh->DoInitNew();
+
+ bool bImpress = FN_ABSTRACT_STARIMPRESS == nWhich;
+ m_xDoc->Summary(*pSmryDoc, nLevel, nPara, bImpress);
+ if( bImpress )
+ {
+ WriterRef xWrt;
+ // mba: looks as if relative URLs don't make sense here
+ ::GetRTFWriter(std::u16string_view(), OUString(), xWrt);
+ SvMemoryStream *pStrm = new SvMemoryStream();
+ pStrm->SetBufferSize( 16348 );
+ SwWriter aWrt( *pStrm, *pSmryDoc );
+ ErrCodeMsg eErr = aWrt.Write( xWrt );
+ if( !eErr.IgnoreWarning() )
+ {
+ uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ uno::Reference< frame::XDispatchProvider > xProv = drawing::ModuleDispatcher::create( xContext );
+
+ uno::Reference< frame::XDispatchHelper > xHelper( frame::DispatchHelper::create(xContext) );
+ pStrm->Seek( STREAM_SEEK_TO_END );
+ pStrm->WriteChar( '\0' );
+ pStrm->Seek( STREAM_SEEK_TO_BEGIN );
+
+ // Transfer ownership of stream to a lockbytes object
+ SvLockBytes aLockBytes( pStrm, true );
+ SvLockBytesStat aStat;
+ if ( aLockBytes.Stat( &aStat ) == ERRCODE_NONE )
+ {
+ sal_uInt32 nLen = aStat.nSize;
+ std::size_t nRead = 0;
+ uno::Sequence< sal_Int8 > aSeq( nLen );
+ aLockBytes.ReadAt( 0, aSeq.getArray(), nLen, &nRead );
+
+ uno::Sequence< beans::PropertyValue > aArgs{
+ comphelper::makePropertyValue("RtfOutline", aSeq)
+ };
+ xHelper->executeDispatch( xProv, "SendOutlineToImpress", OUString(), 0, aArgs );
+ }
+ }
+ else
+ ErrorHandler::HandleError( eErr );
+ }
+ else
+ {
+ // Create new document
+ SfxViewFrame *pFrame = SfxViewFrame::LoadDocument( *xDocSh, SFX_INTERFACE_NONE );
+ SwView *pCurrView = static_cast<SwView*>( pFrame->GetViewShell());
+
+ // Set document's title
+ OUString aTmp = SwResId(STR_ABSTRACT_TITLE) + GetTitle();
+ xDocSh->SetTitle( aTmp );
+ pCurrView->GetWrtShell().SetNewDoc();
+ pFrame->Show();
+ pSmryDoc->getIDocumentState().SetModified();
+ }
+
+ }
+ }
+ break;
+ case FN_OUTLINE_TO_CLIPBOARD:
+ case FN_OUTLINE_TO_IMPRESS:
+ {
+ bool bEnable = IsEnableSetModified();
+ EnableSetModified( false );
+ WriterRef xWrt;
+ // mba: looks as if relative URLs don't make sense here
+ ::GetRTFWriter( u"O", OUString(), xWrt );
+ std::unique_ptr<SvMemoryStream> pStrm (new SvMemoryStream());
+ pStrm->SetBufferSize( 16348 );
+ SwWriter aWrt( *pStrm, *GetDoc() );
+ ErrCodeMsg eErr = aWrt.Write( xWrt );
+ EnableSetModified( bEnable );
+ if( !eErr.IgnoreWarning() )
+ {
+ pStrm->Seek( STREAM_SEEK_TO_END );
+ pStrm->WriteChar( '\0' );
+ pStrm->Seek( STREAM_SEEK_TO_BEGIN );
+ if ( nWhich == FN_OUTLINE_TO_IMPRESS )
+ {
+ uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ uno::Reference< frame::XDispatchProvider > xProv = drawing::ModuleDispatcher::create( xContext );
+
+ uno::Reference< frame::XDispatchHelper > xHelper( frame::DispatchHelper::create(xContext) );
+ pStrm->Seek( STREAM_SEEK_TO_END );
+ pStrm->WriteChar( '\0' );
+ pStrm->Seek( STREAM_SEEK_TO_BEGIN );
+
+ // Transfer ownership of stream to a lockbytes object
+ SvLockBytes aLockBytes( pStrm.release(), true );
+ SvLockBytesStat aStat;
+ if ( aLockBytes.Stat( &aStat ) == ERRCODE_NONE )
+ {
+ sal_uInt32 nLen = aStat.nSize;
+ std::size_t nRead = 0;
+ uno::Sequence< sal_Int8 > aSeq( nLen );
+ aLockBytes.ReadAt( 0, aSeq.getArray(), nLen, &nRead );
+
+ uno::Sequence< beans::PropertyValue > aArgs{
+ comphelper::makePropertyValue("RtfOutline", aSeq)
+ };
+ xHelper->executeDispatch( xProv, "SendOutlineToImpress", OUString(), 0, aArgs );
+ }
+ }
+ else
+ {
+ rtl::Reference<TransferDataContainer> pClipCntnr = new TransferDataContainer;
+
+ pClipCntnr->CopyAnyData( SotClipboardFormatId::RTF, static_cast<char const *>(
+ pStrm->GetData()), pStrm->GetEndOfData() );
+ pClipCntnr->CopyToClipboard(
+ GetView()? &GetView()->GetEditWin() : nullptr );
+ }
+ }
+ else
+ ErrorHandler::HandleError( eErr );
+ }
+ break;
+ case SID_SPELLCHECKER_CHANGED:
+ {
+ //! false, true, true is on the save side but a probably overdone
+ SwModule::CheckSpellChanges(false, true, true, false );
+ Broadcast(SfxHint(SfxHintId::LanguageChanged));
+ }
+ break;
+
+ case SID_MAIL_PREPAREEXPORT:
+ {
+ const SfxBoolItem* pNoUpdate = pArgs ?
+ pArgs->GetItem<SfxBoolItem>(FN_NOUPDATE, false) :
+ nullptr;
+
+ //pWrtShell is not set in page preview
+ if (m_pWrtShell)
+ m_pWrtShell->StartAllAction();
+
+ if (!pNoUpdate || !pNoUpdate->GetValue())
+ {
+ m_xDoc->getIDocumentFieldsAccess().UpdateFields( false );
+ m_xDoc->getIDocumentLinksAdministration().EmbedAllLinks();
+ }
+
+ m_IsRemovedInvisibleContent
+ = officecfg::Office::Security::HiddenContent::RemoveHiddenContent::get();
+ if (m_IsRemovedInvisibleContent)
+ m_xDoc->RemoveInvisibleContent();
+ if (m_pWrtShell)
+ m_pWrtShell->EndAllAction();
+ }
+ break;
+
+ case SID_MAIL_EXPORT_FINISHED:
+ {
+ if (m_pWrtShell)
+ m_pWrtShell->StartAllAction();
+ //try to undo the removal of invisible content
+ if (m_IsRemovedInvisibleContent)
+ m_xDoc->RestoreInvisibleContent();
+ if (m_pWrtShell)
+ m_pWrtShell->EndAllAction();
+ }
+ break;
+ case FN_NEW_HTML_DOC:
+ case FN_NEW_GLOBAL_DOC:
+ {
+ bDone = false;
+ bool bCreateHtml = FN_NEW_HTML_DOC == nWhich;
+
+ bool bCreateByOutlineLevel = false;
+ sal_Int32 nTemplateOutlineLevel = 0;
+
+ OUString aFileName, aTemplateName;
+ if( pArgs && SfxItemState::SET == pArgs->GetItemState( nWhich, false, &pItem ) )
+ {
+ aFileName = static_cast<const SfxStringItem*>(pItem)->GetValue();
+ const SfxStringItem* pTemplItem = SfxItemSet::GetItem<SfxStringItem>(pArgs, SID_TEMPLATE_NAME, false);
+ if ( pTemplItem )
+ aTemplateName = pTemplItem->GetValue();
+ }
+ if ( aFileName.isEmpty() )
+ {
+ bool bError = false;
+
+ FileDialogHelper aDlgHelper(TemplateDescription::FILESAVE_AUTOEXTENSION_TEMPLATE, FileDialogFlags::NONE,
+ GetView()->GetFrameWeld());
+ aDlgHelper.SetContext(FileDialogHelper::WriterNewHTMLGlobalDoc);
+
+ const sal_Int16 nControlIds[] = {
+ CommonFilePickerElementIds::PUSHBUTTON_OK,
+ CommonFilePickerElementIds::PUSHBUTTON_CANCEL,
+ CommonFilePickerElementIds::LISTBOX_FILTER,
+ CommonFilePickerElementIds::CONTROL_FILEVIEW,
+ CommonFilePickerElementIds::EDIT_FILEURL,
+ ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION,
+ ExtendedFilePickerElementIds::LISTBOX_TEMPLATE,
+ 0
+ };
+
+ if (bCreateHtml)
+ {
+ const char* aHTMLHelpIds[] =
+ {
+ HID_SEND_HTML_CTRL_PUSHBUTTON_OK,
+ HID_SEND_HTML_CTRL_PUSHBUTTON_CANCEL,
+ HID_SEND_HTML_CTRL_LISTBOX_FILTER,
+ HID_SEND_HTML_CTRL_CONTROL_FILEVIEW,
+ HID_SEND_HTML_CTRL_EDIT_FILEURL,
+ HID_SEND_HTML_CTRL_CHECKBOX_AUTOEXTENSION,
+ HID_SEND_HTML_CTRL_LISTBOX_TEMPLATE,
+ ""
+ };
+ aDlgHelper.SetControlHelpIds( nControlIds, aHTMLHelpIds );
+ }
+ else
+ {
+ const char* aMasterHelpIds[] =
+ {
+ HID_SEND_MASTER_CTRL_PUSHBUTTON_OK,
+ HID_SEND_MASTER_CTRL_PUSHBUTTON_CANCEL,
+ HID_SEND_MASTER_CTRL_LISTBOX_FILTER,
+ HID_SEND_MASTER_CTRL_CONTROL_FILEVIEW,
+ HID_SEND_MASTER_CTRL_EDIT_FILEURL,
+ HID_SEND_MASTER_CTRL_CHECKBOX_AUTOEXTENSION,
+ HID_SEND_MASTER_CTRL_LISTBOX_TEMPLATE,
+ ""
+ };
+ aDlgHelper.SetControlHelpIds( nControlIds, aMasterHelpIds );
+ }
+ uno::Reference < XFilePicker3 > xFP = aDlgHelper.GetFilePicker();
+
+ std::shared_ptr<const SfxFilter> pFlt;
+ TranslateId pStrId;
+
+ if( bCreateHtml )
+ {
+ // for HTML there is only one filter!!
+ pFlt = SwIoSystem::GetFilterOfFormat(
+ u"HTML",
+ SwWebDocShell::Factory().GetFilterContainer() );
+ pStrId = STR_LOAD_HTML_DOC;
+ }
+ else
+ {
+ // for Global-documents we now only offer the current one.
+ pFlt = SwGlobalDocShell::Factory().GetFilterContainer()->
+ GetFilter4Extension( "odm" );
+ pStrId = STR_LOAD_GLOBAL_DOC;
+ }
+
+ if( pFlt )
+ {
+ const OUString sWild = pFlt->GetWildcard().getGlob();
+ xFP->appendFilter( pFlt->GetUIName(), sWild );
+ try
+ {
+ xFP->setCurrentFilter( pFlt->GetUIName() ) ;
+ }
+ catch (const uno::Exception&)
+ {
+ bError = true;
+ }
+ }
+ if(!bError)
+ {
+ uno::Reference<XFilePickerControlAccess> xCtrlAcc(xFP, UNO_QUERY);
+
+ bool bOutline[MAXLEVEL] = {false};
+ const SwOutlineNodes& rOutlNds = m_xDoc->GetNodes().GetOutLineNds();
+ for( size_t n = 0; n < rOutlNds.size(); ++n )
+ {
+ const int nLevel = rOutlNds[n]->GetTextNode()->GetAttrOutlineLevel();
+ if( nLevel > 0 && ! bOutline[nLevel-1] )
+ {
+ bOutline[nLevel-1] = true;
+ }
+ }
+
+ const sal_uInt16 nStyleCount = m_xDoc->GetTextFormatColls()->size();
+ Sequence<OUString> aListBoxEntries( MAXLEVEL + nStyleCount);
+ OUString* pEntries = aListBoxEntries.getArray();
+ sal_Int32 nIdx = 0 ;
+
+ OUString sOutline( SwResId(STR_FDLG_OUTLINE_LEVEL) );
+ for( sal_uInt16 i = 0; i < MAXLEVEL; ++i )
+ {
+ if( bOutline[i] )
+ pEntries[nIdx++] = sOutline + OUString::number( i+1 );
+ }
+
+ OUString sStyle( SwResId(STR_FDLG_STYLE) );
+ for(sal_uInt16 i = 0; i < nStyleCount; ++i)
+ {
+ SwTextFormatColl &rTextColl = *(*m_xDoc->GetTextFormatColls())[ i ];
+ if( !rTextColl.IsDefault() && rTextColl.IsAtDocNodeSet() )
+ {
+ pEntries[nIdx++] = sStyle + rTextColl.GetName();
+ }
+ }
+
+ aListBoxEntries.realloc(nIdx);
+ sal_Int16 nSelect = 0;
+
+ try
+ {
+ Any aTemplates(&aListBoxEntries, cppu::UnoType<decltype(aListBoxEntries)>::get());
+
+ xCtrlAcc->setValue( ExtendedFilePickerElementIds::LISTBOX_TEMPLATE,
+ ListboxControlActions::ADD_ITEMS , aTemplates );
+ Any aSelectPos(&nSelect, cppu::UnoType<decltype(nSelect)>::get());
+ xCtrlAcc->setValue( ExtendedFilePickerElementIds::LISTBOX_TEMPLATE,
+ ListboxControlActions::SET_SELECT_ITEM, aSelectPos );
+ xCtrlAcc->setLabel( ExtendedFilePickerElementIds::LISTBOX_TEMPLATE,
+ SwResId( STR_FDLG_TEMPLATE_NAME ));
+ }
+ catch (const Exception&)
+ {
+ OSL_FAIL("control access failed");
+ }
+
+ xFP->setTitle(SwResId(pStrId));
+ SvtPathOptions aPathOpt;
+ xFP->setDisplayDirectory( aPathOpt.GetWorkPath() );
+ if( ERRCODE_NONE == aDlgHelper.Execute())
+ {
+ aFileName = xFP->getSelectedFiles().getConstArray()[0];
+ Any aTemplateValue = xCtrlAcc->getValue(
+ ExtendedFilePickerElementIds::LISTBOX_TEMPLATE,
+ ListboxControlActions::GET_SELECTED_ITEM );
+ OUString sTmpl;
+ aTemplateValue >>= sTmpl;
+
+ OUString aStyle(SwResId(STR_FDLG_STYLE));
+ OUString aOutline(SwResId(STR_FDLG_OUTLINE_LEVEL));
+
+ if ( sTmpl.startsWith(aStyle) )
+ {
+ aTemplateName = sTmpl.copy( aStyle.getLength() ); //get string behind "Style: "
+ }
+ else if ( sTmpl.startsWith(aOutline) )
+ {
+ nTemplateOutlineLevel = o3tl::toInt32(sTmpl.subView(aOutline.getLength())); //get string behind "Outline: Level ";
+ bCreateByOutlineLevel = true;
+ }
+
+ if ( !aFileName.isEmpty() )
+ {
+ rReq.AppendItem( SfxStringItem( nWhich, aFileName ) );
+ if( !aTemplateName.isEmpty() )
+ rReq.AppendItem( SfxStringItem( SID_TEMPLATE_NAME, aTemplateName ) );
+ }
+ }
+ }
+ }
+
+ if( !aFileName.isEmpty() )
+ {
+ if( PrepareClose( false ) )
+ {
+ SwWait aWait( *this, true );
+
+ if ( bCreateByOutlineLevel )
+ {
+ bDone = bCreateHtml
+ ? m_xDoc->GenerateHTMLDoc( aFileName, nTemplateOutlineLevel )
+ : m_xDoc->GenerateGlobalDoc( aFileName, nTemplateOutlineLevel );
+ }
+ else
+ {
+ const SwTextFormatColl* pSplitColl = nullptr;
+ if ( !aTemplateName.isEmpty() )
+ pSplitColl = m_xDoc->FindTextFormatCollByName(aTemplateName);
+ bDone = bCreateHtml
+ ? m_xDoc->GenerateHTMLDoc( aFileName, pSplitColl )
+ : m_xDoc->GenerateGlobalDoc( aFileName, pSplitColl );
+ }
+ if( bDone )
+ {
+ SfxStringItem aName( SID_FILE_NAME, aFileName );
+ SfxStringItem aReferer(SID_REFERER, OUString());
+ SfxViewShell* pViewShell = SfxViewShell::GetFirst();
+ while(pViewShell)
+ {
+ //search for the view that created the call
+ if(pViewShell->GetObjectShell() == this && pViewShell->GetDispatcher())
+ {
+ SfxFrameItem aFrameItem(SID_DOCFRAME, &pViewShell->GetViewFrame());
+ SfxDispatcher* pDispatch = pViewShell->GetDispatcher();
+ pDispatch->ExecuteList(SID_OPENDOC,
+ SfxCallMode::ASYNCHRON,
+ { &aName, &aReferer, &aFrameItem });
+ break;
+ }
+ pViewShell = SfxViewShell::GetNext(*pViewShell);
+ }
+ }
+ }
+ if( !bDone && !rReq.IsAPI() )
+ {
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(nullptr,
+ VclMessageType::Info, VclButtonsType::Ok,
+ SwResId(STR_CANTCREATE)));
+ xInfoBox->run();
+ }
+ }
+ }
+ rReq.SetReturnValue(SfxBoolItem( nWhich, bDone ));
+ if (bDone)
+ rReq.Done();
+ else
+ rReq.Ignore();
+ break;
+
+ case SID_ATTR_YEAR2000:
+ if ( pArgs && SfxItemState::SET == pArgs->GetItemState( nWhich , false, &pItem ))
+ {
+ assert(dynamic_cast< const SfxUInt16Item *>( pItem ) && "wrong Item");
+ sal_uInt16 nYear2K = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
+ // iterate over Views and put the State to FormShells
+
+ SfxViewFrame* pVFrame = SfxViewFrame::GetFirst( this );
+ SfxViewShell* pViewShell = pVFrame ? pVFrame->GetViewShell() : nullptr;
+ SwView* pCurrView = dynamic_cast< SwView* >( pViewShell );
+ while(pCurrView)
+ {
+ FmFormShell* pFormShell = pCurrView->GetFormShell();
+ if(pFormShell)
+ pFormShell->SetY2KState(nYear2K);
+ pVFrame = SfxViewFrame::GetNext( *pVFrame, this );
+ pViewShell = pVFrame ? pVFrame->GetViewShell() : nullptr;
+ pCurrView = dynamic_cast<SwView*>( pViewShell );
+ }
+ m_xDoc->GetNumberFormatter()->SetYear2000(nYear2K);
+ }
+ break;
+ case FN_OPEN_FILE:
+ {
+ SfxViewShell* pViewShell = GetView();
+ if (!pViewShell)
+ pViewShell = SfxViewShell::Current();
+
+ if (!pViewShell)
+ // Ok. I did my best.
+ break;
+
+ if (SfxDispatcher* pDispatch = pViewShell->GetDispatcher())
+ {
+ SfxStringItem aApp(SID_DOC_SERVICE, "com.sun.star.text.TextDocument");
+ SfxStringItem aTarget(SID_TARGETNAME, "_blank");
+ pDispatch->ExecuteList(SID_OPENDOC, SfxCallMode::API|SfxCallMode::SYNCHRON, { &aApp, &aTarget });
+ }
+ }
+ break;
+ case SID_CLASSIFICATION_APPLY:
+ {
+ if (pArgs && pArgs->GetItemState(nWhich, false, &pItem) == SfxItemState::SET)
+ {
+ SwWrtShell* pSh = GetWrtShell();
+ const OUString& rValue = static_cast<const SfxStringItem*>(pItem)->GetValue();
+ auto eType = SfxClassificationPolicyType::IntellectualProperty;
+ if (const SfxStringItem* pTypeNameItem = pArgs->GetItemIfSet(SID_TYPE_NAME, false))
+ {
+ const OUString& rType = pTypeNameItem->GetValue();
+ eType = SfxClassificationHelper::stringToPolicyType(rType);
+ }
+ pSh->SetClassification(rValue, eType);
+ }
+ else
+ SAL_WARN("sw.ui", "missing parameter for SID_CLASSIFICATION_APPLY");
+ }
+ break;
+ case SID_CLASSIFICATION_DIALOG:
+ if (SfxObjectShell* pObjSh = SfxObjectShell::Current())
+ {
+ auto xDialog = std::make_shared<svx::ClassificationDialog>(GetView()->GetFrameWeld(), pObjSh->getDocProperties(), false);
+
+ SwWrtShell* pShell = GetWrtShell();
+ std::vector<svx::ClassificationResult> aInput = pShell->CollectAdvancedClassification();
+ xDialog->setupValues(std::move(aInput));
+
+ weld::DialogController::runAsync(xDialog, [xDialog, pShell](sal_Int32 nResult){
+ if (RET_OK == nResult)
+ pShell->ApplyAdvancedClassification(xDialog->getResult());
+ });
+ }
+ break;
+ case SID_PARAGRAPH_SIGN_CLASSIFY_DLG:
+ if (SfxObjectShell* pObjSh = SfxObjectShell::Current())
+ {
+ SwWrtShell* pShell = GetWrtShell();
+ auto xDialog = std::make_shared<svx::ClassificationDialog>(GetView()->GetFrameWeld(), pObjSh->getDocProperties(), true, [pShell]()
+ {
+ pShell->SignParagraph();
+ });
+
+ std::vector<svx::ClassificationResult> aInput = pShell->CollectParagraphClassification();
+ xDialog->setupValues(std::move(aInput));
+
+ weld::DialogController::runAsync(xDialog, [xDialog, pShell](sal_Int32 nResult){
+ if (RET_OK == nResult)
+ pShell->ApplyParagraphClassification(xDialog->getResult());
+ });
+ }
+ break;
+ case SID_WATERMARK:
+ {
+ SwWrtShell* pSh = GetWrtShell();
+ if ( pSh )
+ {
+ if (pArgs && pArgs->GetItemState( SID_WATERMARK, false, &pItem ) == SfxItemState::SET)
+ {
+ SfxWatermarkItem aItem;
+ aItem.SetText( static_cast<const SfxStringItem*>( pItem )->GetValue() );
+
+ if ( const SfxStringItem* pFontItem = pArgs->GetItemIfSet( SID_WATERMARK_FONT, false ) )
+ aItem.SetFont( pFontItem->GetValue() );
+ if ( const SfxInt16Item* pAngleItem = pArgs->GetItemIfSet( SID_WATERMARK_ANGLE, false ) )
+ aItem.SetAngle( pAngleItem->GetValue() );
+ if ( const SfxInt16Item* pTransItem = pArgs->GetItemIfSet( SID_WATERMARK_TRANSPARENCY, false ) )
+ aItem.SetTransparency( pTransItem->GetValue() );
+ if ( const SfxUInt32Item* pColorItem = pArgs->GetItemIfSet( SID_WATERMARK_COLOR, false ) )
+ aItem.SetColor( Color(ColorTransparency, pColorItem->GetValue()) );
+
+ pSh->SetWatermark( aItem );
+ }
+ else
+ {
+ SfxViewShell* pViewShell = GetView() ? GetView() : SfxViewShell::Current();
+ SfxBindings& rBindings( pViewShell->GetViewFrame().GetBindings() );
+ auto xDlg = std::make_shared<SwWatermarkDialog>(pViewShell->GetViewFrame().GetFrameWeld(),
+ rBindings);
+ weld::DialogController::runAsync(xDlg, [](sal_Int32 /*nResult*/){});
+ }
+ }
+ }
+ break;
+ case SID_NOTEBOOKBAR:
+ {
+ const SfxStringItem* pFile = rReq.GetArg<SfxStringItem>( SID_NOTEBOOKBAR );
+ SfxViewShell* pViewShell = GetView()? GetView(): SfxViewShell::Current();
+ SfxBindings& rBindings( pViewShell->GetViewFrame().GetBindings() );
+
+ if ( SfxNotebookBar::IsActive() )
+ sfx2::SfxNotebookBar::ExecMethod( rBindings, pFile ? pFile->GetValue() : "" );
+ else
+ {
+ sfx2::SfxNotebookBar::CloseMethod( rBindings );
+ }
+ }
+ break;
+ case FN_REDLINE_ACCEPT_ALL:
+ case FN_REDLINE_REJECT_ALL:
+ {
+ IDocumentRedlineAccess& rRedlineAccess = GetDoc()->getIDocumentRedlineAccess();
+ SwWrtShell *pWrtShell = dynamic_cast<SwWrtShell*>(GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell());
+
+ if (rRedlineAccess.GetRedlineTable().empty())
+ {
+ break;
+ }
+
+ // tables with tracked deletion need Show Changes
+ bool bHideChanges = pWrtShell && pWrtShell->GetLayout() &&
+ pWrtShell->GetLayout()->IsHideRedlines();
+ bool bChangedHideChanges = false;
+ if ( bHideChanges )
+ {
+ SwTableNode* pOldTableNd = nullptr;
+ const SwRedlineTable& aRedlineTable = rRedlineAccess.GetRedlineTable();
+ for (SwRedlineTable::size_type n = 0; n < aRedlineTable.size(); ++n)
+ {
+ const SwRangeRedline* pRedline = aRedlineTable[n];
+ if ( pRedline->GetType() == RedlineType::Delete )
+ {
+ SwTableNode* pTableNd =
+ pRedline->GetPoint()->GetNode().FindTableNode();
+ if ( pTableNd && pTableNd !=
+ pOldTableNd && pTableNd->GetTable().HasDeletedRowOrCell() )
+ {
+ SfxBoolItem aShow(FN_REDLINE_SHOW, true);
+ SfxViewShell* pViewShell = GetView()
+ ? GetView()
+ : SfxViewShell::Current();
+ pViewShell->GetViewFrame().GetDispatcher()->ExecuteList(
+ FN_REDLINE_SHOW, SfxCallMode::SYNCHRON|SfxCallMode::RECORD,
+ { &aShow });
+ bChangedHideChanges = true;
+ break;
+ }
+ pOldTableNd = pTableNd;
+ }
+ }
+ }
+
+ if (pWrtShell)
+ {
+ pWrtShell->StartAllAction();
+ }
+
+ rRedlineAccess.AcceptAllRedline(nWhich == FN_REDLINE_ACCEPT_ALL);
+
+ if (pWrtShell)
+ {
+ pWrtShell->EndAllAction();
+ }
+
+ if ( bChangedHideChanges )
+ {
+ SfxBoolItem aShow(FN_REDLINE_SHOW, false);
+ SfxViewShell* pViewShell = GetView()? GetView(): SfxViewShell::Current();
+ pViewShell->GetViewFrame().GetDispatcher()->ExecuteList(
+ FN_REDLINE_SHOW, SfxCallMode::SYNCHRON|SfxCallMode::RECORD, { &aShow });
+ }
+
+ Broadcast(SfxHint(SfxHintId::RedlineChanged));
+ rReq.Done();
+ }
+ break;
+
+ default: OSL_FAIL("wrong Dispatcher");
+ }
+}
+
+#if defined(_WIN32)
+bool SwDocShell::DdeGetData( const OUString& rItem, const OUString& rMimeType,
+ uno::Any & rValue )
+{
+ return m_xDoc->getIDocumentLinksAdministration().GetData( rItem, rMimeType, rValue );
+}
+
+bool SwDocShell::DdeSetData( const OUString& rItem, const OUString& /*rMimeType*/,
+ const uno::Any & /*rValue*/ )
+{
+ m_xDoc->getIDocumentLinksAdministration().SetData( rItem );
+ return false;
+}
+
+#endif
+
+::sfx2::SvLinkSource* SwDocShell::DdeCreateLinkSource( const OUString& rItem )
+{
+ if(officecfg::Office::Common::Security::Scripting::DisableActiveContent::get())
+ return nullptr;
+ return m_xDoc->getIDocumentLinksAdministration().CreateLinkSource( rItem );
+}
+
+void SwDocShell::ReconnectDdeLink(SfxObjectShell& rServer)
+{
+ if (m_xDoc)
+ {
+ ::sfx2::LinkManager& rLinkManager = m_xDoc->getIDocumentLinksAdministration().GetLinkManager();
+ rLinkManager.ReconnectDdeLink(rServer);
+ }
+}
+
+void SwDocShell::FillClass( SvGlobalName * pClassName,
+ SotClipboardFormatId * pClipFormat,
+ OUString * pLongUserName,
+ sal_Int32 nVersion,
+ bool bTemplate /* = false */) const
+{
+ if (nVersion == SOFFICE_FILEFORMAT_60)
+ {
+ *pClassName = SvGlobalName( SO3_SW_CLASSID_60 );
+ *pClipFormat = SotClipboardFormatId::STARWRITER_60;
+ *pLongUserName = SwResId(STR_WRITER_DOCUMENT_FULLTYPE);
+ }
+ else if (nVersion == SOFFICE_FILEFORMAT_8)
+ {
+ *pClassName = SvGlobalName( SO3_SW_CLASSID_60 );
+ *pClipFormat = bTemplate ? SotClipboardFormatId::STARWRITER_8_TEMPLATE : SotClipboardFormatId::STARWRITER_8;
+ *pLongUserName = SwResId(STR_WRITER_DOCUMENT_FULLTYPE);
+ }
+// #FIXME check with new Event handling
+#if 0
+ uno::Reference< document::XVbaEventsHelper > xVbaEventsHelper = m_xDoc->GetVbaEventsHelper();
+ if( xVbaEventsHelper.is() )
+ lcl_processCompatibleSfxHint( xVbaEventsHelper, rHint );
+#endif
+}
+
+void SwDocShell::SetModified( bool bSet )
+{
+ if (utl::ConfigManager::IsFuzzing())
+ return;
+ SfxObjectShell::SetModified( bSet );
+ if( !IsEnableSetModified())
+ return;
+
+ if (!m_xDoc->getIDocumentState().IsInCallModified())
+ {
+ EnableSetModified( false );
+ if( bSet )
+ {
+ bool const bOld = m_xDoc->getIDocumentState().IsModified();
+ m_xDoc->getIDocumentState().SetModified();
+ if( !bOld )
+ {
+ m_xDoc->GetIDocumentUndoRedo().SetUndoNoResetModified();
+ }
+ }
+ else
+ m_xDoc->getIDocumentState().ResetModified();
+
+ EnableSetModified();
+ }
+
+ UpdateChildWindows();
+ Broadcast(SfxHint(SfxHintId::DocChanged));
+}
+
+void SwDocShell::UpdateChildWindows()
+{
+ // if necessary newly initialize Fielddlg (i.e. for TYP_SETVAR)
+ if(!GetView())
+ return;
+ SfxViewFrame& rVFrame = GetView()->GetViewFrame();
+ SwFieldDlgWrapper *pWrp = static_cast<SwFieldDlgWrapper*>(rVFrame.
+ GetChildWindow( SwFieldDlgWrapper::GetChildWindowId() ));
+ if( pWrp )
+ pWrp->ReInitDlg( this );
+
+ // if necessary newly initialize RedlineDlg
+ SwRedlineAcceptChild *pRed = static_cast<SwRedlineAcceptChild*>(rVFrame.
+ GetChildWindow( SwRedlineAcceptChild::GetChildWindowId() ));
+ if( pRed )
+ pRed->ReInitDlg( this );
+}
+
+namespace {
+
+// #i48748#
+class SwReloadFromHtmlReader : public SwReader
+{
+ public:
+ SwReloadFromHtmlReader( SfxMedium& _rTmpMedium,
+ const OUString& _rFilename,
+ SwDoc* _pDoc )
+ : SwReader( _rTmpMedium, _rFilename, _pDoc )
+ {
+ SetBaseURL( _rFilename );
+ }
+};
+
+}
+
+void SwDocShell::ReloadFromHtml( const OUString& rStreamName, SwSrcView* pSrcView )
+{
+ bool bModified = IsModified();
+
+ // The HTTP-Header fields have to be removed, otherwise
+ // there are some from Meta-Tags duplicated or triplicated afterwards.
+ ClearHeaderAttributesForSourceViewHack();
+
+#if HAVE_FEATURE_SCRIPTING
+ // The Document-Basic also bites the dust ...
+ // A EnterBasicCall is not needed here, because nothing is called and
+ // there can't be any Dok-Basic, that has not yet been loaded inside
+ // of an HTML document.
+ //#59620# HasBasic() shows, that there already is a BasicManager at the DocShell.
+ // That was always generated in HTML-Import, when there are
+ // Macros in the source code.
+ if( officecfg::Office::Common::Filter::HTML::Export::Basic::get() && HasBasic())
+ {
+ BasicManager *pBasicMan = GetBasicManager();
+ if( pBasicMan && (pBasicMan != SfxApplication::GetBasicManager()) )
+ {
+ sal_uInt16 nLibCount = pBasicMan->GetLibCount();
+ while( nLibCount )
+ {
+ StarBASIC *pBasic = pBasicMan->GetLib( --nLibCount );
+ if( pBasic )
+ {
+ // Notify the IDE
+ SfxUnoAnyItem aShellItem( SID_BASICIDE_ARG_DOCUMENT_MODEL, Any( GetModel() ) );
+ OUString aLibName( pBasic->GetName() );
+ SfxStringItem aLibNameItem( SID_BASICIDE_ARG_LIBNAME, aLibName );
+ pSrcView->GetViewFrame().GetDispatcher()->ExecuteList(
+ SID_BASICIDE_LIBREMOVED,
+ SfxCallMode::SYNCHRON,
+ { &aShellItem, &aLibNameItem });
+
+ // Only the modules are deleted from the standard-lib
+ if( nLibCount )
+ pBasicMan->RemoveLib( nLibCount, true );
+ else
+ pBasic->Clear();
+ }
+ }
+
+ OSL_ENSURE( pBasicMan->GetLibCount() <= 1,
+ "Deleting Basics didn't work" );
+ }
+ }
+#endif
+ bool bWasBrowseMode = m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::BROWSE_MODE);
+ RemoveLink();
+
+ // now also the UNO-Model has to be informed about the new Doc #51535#
+ uno::Reference<text::XTextDocument> xDoc(GetBaseModel(), uno::UNO_QUERY);
+ text::XTextDocument* pxDoc = xDoc.get();
+ static_cast<SwXTextDocument*>(pxDoc)->InitNewDoc();
+
+ AddLink();
+ //#116402# update font list when new document is created
+ UpdateFontList();
+ m_xDoc->getIDocumentSettingAccess().set(DocumentSettingId::BROWSE_MODE, bWasBrowseMode);
+ pSrcView->SetPool(&GetPool());
+
+ const OUString& rMedname = GetMedium()->GetName();
+
+ // The HTML template still has to be set
+ SetHTMLTemplate( *GetDoc() ); //Styles from HTML.vor
+
+ SfxViewShell* pViewShell = GetView() ? static_cast<SfxViewShell*>(GetView())
+ : SfxViewShell::Current();
+ SfxViewFrame& rViewFrame = pViewShell->GetViewFrame();
+ rViewFrame.GetDispatcher()->Execute( SID_VIEWSHELL0, SfxCallMode::SYNCHRON );
+
+ SubInitNew();
+
+ SfxMedium aMed( rStreamName, StreamMode::READ );
+ // #i48748# - use class <SwReloadFromHtmlReader>, because
+ // the base URL has to be set to the filename of the document <rMedname>
+ // and not to the base URL of the temporary file <aMed> in order to get
+ // the URLs of the linked graphics correctly resolved.
+ SwReloadFromHtmlReader aReader( aMed, rMedname, m_xDoc.get() );
+
+ aReader.Read( *ReadHTML );
+
+ const SwView* pCurrView = GetView();
+ //in print layout the first page(s) may have been formatted as a mix of browse
+ //and print layout
+ if(!bWasBrowseMode && pCurrView)
+ {
+ SwWrtShell& rWrtSh = pCurrView->GetWrtShell();
+ if( rWrtSh.GetLayout())
+ rWrtSh.InvalidateLayout( true );
+ }
+
+ // Take HTTP-Header-Attributes over into the DocInfo again.
+ // The Base-URL doesn't matter here because TLX uses the one from the document
+ // for absolutization.
+ SetHeaderAttributesForSourceViewHack();
+
+ if(bModified && !IsReadOnly())
+ SetModified();
+ else
+ m_xDoc->getIDocumentState().ResetModified();
+}
+
+ErrCodeMsg SwDocShell::LoadStylesFromFile(const OUString& rURL, SwgReaderOption& rOpt, bool bUnoCall)
+{
+ ErrCodeMsg nErr = ERRCODE_NONE;
+
+ // Set filter:
+ SfxFilterMatcher aMatcher( SwDocShell::Factory().GetFactoryName() );
+
+ // search for filter in WebDocShell, too
+ SfxMedium aMed( rURL, StreamMode::STD_READ );
+ if (rURL == "private:stream")
+ aMed.setStreamToLoadFrom(rOpt.GetInputStream(), true);
+ std::shared_ptr<const SfxFilter> pFlt;
+ aMatcher.DetectFilter( aMed, pFlt );
+ if(!pFlt)
+ {
+ SfxFilterMatcher aWebMatcher( SwWebDocShell::Factory().GetFactoryName() );
+ aWebMatcher.DetectFilter( aMed, pFlt );
+ }
+ // --> OD #i117339# - trigger import only for own formats
+ bool bImport( false );
+ if ( aMed.IsStorage() )
+ {
+ // As <SfxMedium.GetFilter().IsOwnFormat() resp. IsOwnTemplateFormat()
+ // does not work correct (e.g., MS Word 2007 XML Template),
+ // use workaround provided by MAV.
+ uno::Reference< embed::XStorage > xStorage = aMed.GetStorage();
+ if ( xStorage.is() )
+ {
+ // use <try-catch> on retrieving <MediaType> in order to check,
+ // if the storage is one of our own ones.
+ try
+ {
+ uno::Reference< beans::XPropertySet > xProps( xStorage, uno::UNO_QUERY_THROW );
+ xProps->getPropertyValue( "MediaType" );
+ bImport = true;
+ }
+ catch (const uno::Exception&)
+ {
+ bImport = false;
+ }
+ }
+ }
+ if ( bImport )
+ {
+ Reader* pRead = ReadXML;
+ SwReaderPtr pReader;
+ std::optional<SwPaM> pPam;
+ // the SW3IO - Reader need the pam/wrtshell, because only then he
+ // insert the styles!
+ if( bUnoCall )
+ {
+ SwNodeIndex aIdx( m_xDoc->GetNodes().GetEndOfContent(), -1 );
+ pPam.emplace( aIdx );
+ pReader.reset(new SwReader( aMed, rURL, *pPam ));
+ }
+ else
+ {
+ pReader.reset(new SwReader( aMed, rURL, *m_pWrtShell->GetCursor() ));
+ }
+
+ pRead->GetReaderOpt().SetTextFormats( rOpt.IsTextFormats() );
+ pRead->GetReaderOpt().SetFrameFormats( rOpt.IsFrameFormats() );
+ pRead->GetReaderOpt().SetPageDescs( rOpt.IsPageDescs() );
+ pRead->GetReaderOpt().SetNumRules( rOpt.IsNumRules() );
+ pRead->GetReaderOpt().SetMerge( rOpt.IsMerge() );
+
+ if( bUnoCall )
+ {
+ UnoActionContext aAction( m_xDoc.get() );
+ nErr = pReader->Read( *pRead );
+ }
+ else
+ {
+ m_pWrtShell->StartAllAction();
+ nErr = pReader->Read( *pRead );
+ m_pWrtShell->EndAllAction();
+ }
+ }
+
+ return nErr;
+}
+
+// Get a client for an embedded object if possible.
+SfxInPlaceClient* SwDocShell::GetIPClient( const ::svt::EmbeddedObjectRef& xObjRef )
+{
+ SfxInPlaceClient* pResult = nullptr;
+
+ SwWrtShell* pShell = GetWrtShell();
+ if ( pShell )
+ {
+ pResult = pShell->GetView().FindIPClient( xObjRef.GetObject(), &pShell->GetView().GetEditWin() );
+ if ( !pResult )
+ pResult = new SwOleClient( &pShell->GetView(), &pShell->GetView().GetEditWin(), xObjRef );
+ }
+
+ return pResult;
+}
+
+int SwFindDocShell( SfxObjectShellRef& xDocSh,
+ SfxObjectShellLock& xLockRef,
+ std::u16string_view rFileName,
+ const OUString& rPasswd,
+ const OUString& rFilter,
+ sal_Int16 nVersion,
+ SwDocShell* pDestSh )
+{
+ if ( rFileName.empty() )
+ return 0;
+
+ // 1. Does the file already exist in the list of all Documents?
+ INetURLObject aTmpObj( rFileName );
+ aTmpObj.SetMark( u"" );
+
+ // Iterate over the DocShell and get the ones with the name
+
+ SfxObjectShell* pShell = pDestSh;
+ bool bFirst = nullptr != pShell;
+
+ if( !bFirst )
+ // No DocShell passed, starting with the first from the DocShell list
+ pShell = SfxObjectShell::GetFirst( checkSfxObjectShell<SwDocShell> );
+
+ while( pShell )
+ {
+ // We want this one
+ SfxMedium* pMed = pShell->GetMedium();
+ if( pMed && pMed->GetURLObject() == aTmpObj )
+ {
+ const SfxPoolItem* pItem;
+ if( ( SfxItemState::SET == pMed->GetItemSet().GetItemState(
+ SID_VERSION, false, &pItem ) )
+ ? (nVersion == static_cast<const SfxInt16Item*>(pItem)->GetValue())
+ : !nVersion )
+ {
+ // Found, thus return
+ xDocSh = pShell;
+ return 1;
+ }
+ }
+
+ if( bFirst )
+ {
+ bFirst = false;
+ pShell = SfxObjectShell::GetFirst( checkSfxObjectShell<SwDocShell> );
+ }
+ else
+ pShell = SfxObjectShell::GetNext( *pShell, checkSfxObjectShell<SwDocShell> );
+ }
+
+ // 2. Open the file ourselves
+ std::unique_ptr<SfxMedium> xMed(new SfxMedium( aTmpObj.GetMainURL(
+ INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ));
+ if( INetProtocol::File == aTmpObj.GetProtocol() )
+ xMed->Download(); // Touch the medium (download it)
+
+ std::shared_ptr<const SfxFilter> pSfxFlt;
+ if (!xMed->GetErrorIgnoreWarning())
+ {
+ SfxFilterMatcher aMatcher( rFilter == "writerglobal8"
+ ? SwGlobalDocShell::Factory().GetFactoryName()
+ : SwDocShell::Factory().GetFactoryName() );
+
+ // No Filter, so search for it. Else test if the one passed is a valid one
+ if( !rFilter.isEmpty() )
+ {
+ pSfxFlt = aMatcher.GetFilter4FilterName( rFilter );
+ }
+
+ if( nVersion )
+ xMed->GetItemSet().Put( SfxInt16Item( SID_VERSION, nVersion ));
+
+ if( !rPasswd.isEmpty() )
+ xMed->GetItemSet().Put( SfxStringItem( SID_PASSWORD, rPasswd ));
+
+ if( !pSfxFlt )
+ aMatcher.DetectFilter( *xMed, pSfxFlt );
+
+ if( pSfxFlt )
+ {
+ // We cannot do anything without a Filter
+ xMed->SetFilter( pSfxFlt );
+
+ // If the new shell is created, SfxObjectShellLock should be used to let it be closed later for sure
+ SwDocShell *const pNew(new SwDocShell(SfxObjectCreateMode::INTERNAL));
+ xLockRef = pNew;
+ xDocSh = static_cast<SfxObjectShell*>(xLockRef);
+ if (xDocSh->DoLoad(xMed.release()))
+ {
+ return 2;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/app/docshdrw.cxx b/sw/source/uibase/app/docshdrw.cxx
new file mode 100644
index 0000000000..f767191fbd
--- /dev/null
+++ b/sw/source/uibase/app/docshdrw.cxx
@@ -0,0 +1,100 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svx/svxids.hrc>
+#include <svx/drawitem.hxx>
+#include <svx/svdoutl.hxx>
+#include <svx/xtable.hxx>
+#include <unotools/configmgr.hxx>
+#include <docsh.hxx>
+#include <drawdoc.hxx>
+#include <swtypes.hxx>
+
+using namespace ::com::sun::star;
+
+// Load Document
+void InitDrawModelAndDocShell(SwDocShell* pSwDocShell, SwDrawModel* pSwDrawDocument)
+{
+ if(pSwDrawDocument)
+ {
+ if(pSwDocShell == pSwDrawDocument->GetObjectShell())
+ {
+ // association already done, nothing to do
+ }
+ else
+ {
+ // set object shell (mainly for FormControl stuff), maybe zero
+ pSwDrawDocument->SetObjectShell(pSwDocShell);
+
+ // set persist, maybe zero
+ pSwDrawDocument->SetPersist(pSwDocShell);
+
+ // get and decide on the color table to use
+ if(pSwDocShell)
+ {
+ const SvxColorListItem* pColItemFromDocShell = pSwDocShell->GetItem(SID_COLOR_TABLE);
+
+ if(pColItemFromDocShell)
+ {
+ // the DocShell has a ColorTable, use it also in DrawingLayer
+ const XColorListRef& xCol(pColItemFromDocShell->GetColorList());
+ pSwDrawDocument->SetPropertyList(static_cast<XPropertyList*>(xCol.get()));
+ }
+ else
+ {
+ // Use the ColorTable which is used at the DrawingLayer's SdrModel
+ XColorListRef xColorList = pSwDrawDocument->GetColorList();
+ if (xColorList.is())
+ {
+ pSwDocShell->PutItem(SvxColorListItem(xColorList, SID_COLOR_TABLE));
+ }
+ else if (!utl::ConfigManager::IsFuzzing())
+ {
+ // there wasn't one, get the standard and set to the
+ // docshell and then to the drawdocument
+ xColorList = XColorList::GetStdColorList();
+ pSwDocShell->PutItem(SvxColorListItem(xColorList, SID_COLOR_TABLE));
+ pSwDrawDocument->SetPropertyList(xColorList);
+ }
+ }
+
+ // add other tables in SfxItemSet of the DocShell
+ pSwDocShell->PutItem(SvxGradientListItem(pSwDrawDocument->GetGradientList(), SID_GRADIENT_LIST));
+ pSwDocShell->PutItem(SvxHatchListItem(pSwDrawDocument->GetHatchList(), SID_HATCH_LIST));
+ pSwDocShell->PutItem(SvxBitmapListItem(pSwDrawDocument->GetBitmapList(), SID_BITMAP_LIST));
+ pSwDocShell->PutItem(SvxPatternListItem(pSwDrawDocument->GetPatternList(), SID_PATTERN_LIST));
+ pSwDocShell->PutItem(SvxDashListItem(pSwDrawDocument->GetDashList(), SID_DASH_LIST));
+ pSwDocShell->PutItem(SvxLineEndListItem(pSwDrawDocument->GetLineEndList(), SID_LINEEND_LIST));
+ }
+
+ // init hyphenator for DrawingLayer outliner
+ uno::Reference<linguistic2::XHyphenator> xHyphenator(::GetHyphenator());
+ Outliner& rOutliner = pSwDrawDocument->GetDrawOutliner();
+
+ rOutliner.SetHyphenator(xHyphenator);
+ }
+ }
+ else if(pSwDocShell)
+ {
+ // fallback: add the default color list to have one when someone requests it from the DocShell
+ pSwDocShell->PutItem(SvxColorListItem(XColorList::GetStdColorList(), SID_COLOR_TABLE));
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/app/docshini.cxx b/sw/source/uibase/app/docshini.cxx
new file mode 100644
index 0000000000..5acee759db
--- /dev/null
+++ b/sw/source/uibase/app/docshini.cxx
@@ -0,0 +1,711 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <hintids.hxx>
+
+#include <osl/diagnose.h>
+#include <sal/log.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <i18nlangtag/mslangid.hxx>
+#include <svtools/ctrltool.hxx>
+#include <unotools/configmgr.hxx>
+#include <unotools/lingucfg.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/sfxmodelfactory.hxx>
+#include <sfx2/printer.hxx>
+#include <svl/asiancfg.hxx>
+#include <svl/intitem.hxx>
+#include <editeng/adjustitem.hxx>
+#include <editeng/autokernitem.hxx>
+#include <com/sun/star/document/UpdateDocMode.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <svx/compatflags.hxx>
+#include <svx/svxids.hrc>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/flstitem.hxx>
+#include <editeng/tstpitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/orphitem.hxx>
+#include <editeng/widwitem.hxx>
+#include <editeng/hyphenzoneitem.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <prtopt.hxx>
+#include <fmtcol.hxx>
+#include <docsh.hxx>
+#include <wdocsh.hxx>
+#include <swmodule.hxx>
+#include <doc.hxx>
+#include <IDocumentSettingAccess.hxx>
+#include <IDocumentDeviceAccess.hxx>
+#include <IDocumentDrawModelAccess.hxx>
+#include <IDocumentStylePoolAccess.hxx>
+#include <IDocumentChartDataProviderAccess.hxx>
+#include <IDocumentState.hxx>
+#include <docfac.hxx>
+#include <docstyle.hxx>
+#include <shellio.hxx>
+#include <swdtflvr.hxx>
+#include <usrpref.hxx>
+#include <fontcfg.hxx>
+#include <poolfmt.hxx>
+#include <globdoc.hxx>
+#include <unotxdoc.hxx>
+#include <linkenum.hxx>
+#include <swwait.hxx>
+#include <swerror.h>
+#include <unochart.hxx>
+#include <drawdoc.hxx>
+
+#include <svx/CommonStyleManager.hxx>
+
+#include <memory>
+
+#include <officecfg/Office/Common.hxx>
+
+using namespace ::com::sun::star::i18n;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star;
+
+// Load Document
+bool SwDocShell::InitNew( const uno::Reference < embed::XStorage >& xStor )
+{
+ bool bRet = SfxObjectShell::InitNew( xStor );
+ OSL_ENSURE( GetMapUnit() == MapUnit::MapTwip, "map unit is not twip!" );
+ bool bHTMLTemplSet = false;
+ if( bRet )
+ {
+ AddLink(); // create m_xDoc / pIo if applicable
+
+ bool bWeb = dynamic_cast< const SwWebDocShell *>( this ) != nullptr;
+ if ( bWeb )
+ bHTMLTemplSet = SetHTMLTemplate( *GetDoc() );// Styles from HTML.vor
+ else if( dynamic_cast< const SwGlobalDocShell *>( this ) != nullptr )
+ GetDoc()->getIDocumentSettingAccess().set(DocumentSettingId::GLOBAL_DOCUMENT, true); // Globaldokument
+
+ if ( GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
+ SwTransferable::InitOle( this );
+
+ // set forbidden characters if necessary
+ const bool bFuzzing = utl::ConfigManager::IsFuzzing();
+ if (!bFuzzing)
+ {
+ SvxAsianConfig aAsian;
+ const Sequence<lang::Locale> aLocales = aAsian.GetStartEndCharLocales();
+ for(const lang::Locale& rLocale : aLocales)
+ {
+ ForbiddenCharacters aForbidden;
+ aAsian.GetStartEndChars( rLocale, aForbidden.beginLine, aForbidden.endLine);
+ LanguageType eLang = LanguageTag::convertToLanguageType(rLocale);
+ m_xDoc->getIDocumentSettingAccess().setForbiddenCharacters( eLang, aForbidden);
+ }
+ m_xDoc->getIDocumentSettingAccess().set(DocumentSettingId::KERN_ASIAN_PUNCTUATION,
+ !aAsian.IsKerningWesternTextOnly());
+ m_xDoc->getIDocumentSettingAccess().setCharacterCompressionType(aAsian.GetCharDistanceCompression());
+ m_xDoc->getIDocumentDeviceAccess().setPrintData(*SW_MOD()->GetPrtOptions(bWeb));
+ }
+
+ SubInitNew();
+
+ // for all
+
+ SwStdFontConfig* pStdFont = SW_MOD()->GetStdFontConfig();
+ SfxPrinter* pPrt = m_xDoc->getIDocumentDeviceAccess().getPrinter( false );
+
+ OUString sEntry;
+ static const sal_uInt16 aFontWhich[] =
+ { RES_CHRATR_FONT,
+ RES_CHRATR_CJK_FONT,
+ RES_CHRATR_CTL_FONT
+ };
+ static const sal_uInt16 aFontHeightWhich[] =
+ {
+ RES_CHRATR_FONTSIZE,
+ RES_CHRATR_CJK_FONTSIZE,
+ RES_CHRATR_CTL_FONTSIZE
+ };
+ static const sal_uInt16 aFontIds[] =
+ {
+ FONT_STANDARD,
+ FONT_STANDARD_CJK,
+ FONT_STANDARD_CTL
+ };
+ static const DefaultFontType nFontTypes[] =
+ {
+ DefaultFontType::LATIN_TEXT,
+ DefaultFontType::CJK_TEXT,
+ DefaultFontType::CTL_TEXT
+ };
+ static const sal_uInt16 aLangTypes[] =
+ {
+ RES_CHRATR_LANGUAGE,
+ RES_CHRATR_CJK_LANGUAGE,
+ RES_CHRATR_CTL_LANGUAGE
+ };
+
+ for(sal_uInt8 i = 0; i < 3; i++)
+ {
+ sal_uInt16 nFontWhich = aFontWhich[i];
+ sal_uInt16 nFontId = aFontIds[i];
+ std::unique_ptr<SvxFontItem> pFontItem;
+ const SvxLanguageItem& rLang = static_cast<const SvxLanguageItem&>(m_xDoc->GetDefault( aLangTypes[i] ));
+ LanguageType eLanguage = rLang.GetLanguage();
+ if(!pStdFont->IsFontDefault(nFontId))
+ {
+ sEntry = pStdFont->GetFontFor(nFontId);
+
+ vcl::Font aFont( sEntry, Size( 0, 10 ) );
+ if( pPrt )
+ {
+ aFont = pPrt->GetFontMetric( aFont );
+ }
+
+ pFontItem.reset(new SvxFontItem(aFont.GetFamilyType(), aFont.GetFamilyName(),
+ OUString(), aFont.GetPitch(), aFont.GetCharSet(), nFontWhich));
+ }
+ else
+ {
+ // #107782# OJ use korean language if latin was used
+ if ( i == 0 )
+ {
+ LanguageType eUiLanguage = Application::GetSettings().GetUILanguageTag().getLanguageType();
+ if (MsLangId::isKorean(eUiLanguage))
+ eLanguage = eUiLanguage;
+ }
+
+ vcl::Font aLangDefFont = OutputDevice::GetDefaultFont(
+ nFontTypes[i],
+ eLanguage,
+ GetDefaultFontFlags::OnlyOne );
+ pFontItem.reset(new SvxFontItem(aLangDefFont.GetFamilyType(), aLangDefFont.GetFamilyName(),
+ OUString(), aLangDefFont.GetPitch(), aLangDefFont.GetCharSet(), nFontWhich));
+ }
+ m_xDoc->SetDefault(*pFontItem);
+ if( !bHTMLTemplSet )
+ {
+ SwTextFormatColl *pColl = m_xDoc->getIDocumentStylePoolAccess().GetTextCollFromPool(RES_POOLCOLL_STANDARD);
+ pColl->ResetFormatAttr(nFontWhich);
+ }
+ pFontItem.reset();
+ sal_Int32 nFontHeight = pStdFont->GetFontHeight( FONT_STANDARD, i, eLanguage );
+ if(nFontHeight <= 0)
+ nFontHeight = SwStdFontConfig::GetDefaultHeightFor( nFontId, eLanguage );
+ m_xDoc->SetDefault(SvxFontHeightItem( nFontHeight, 100, aFontHeightWhich[i] ));
+ if( !bHTMLTemplSet )
+ {
+ SwTextFormatColl *pColl = m_xDoc->getIDocumentStylePoolAccess().GetTextCollFromPool(RES_POOLCOLL_STANDARD);
+ pColl->ResetFormatAttr(aFontHeightWhich[i]);
+ }
+
+ }
+ sal_uInt16 aFontIdPoolId[] =
+ {
+ FONT_OUTLINE, RES_POOLCOLL_HEADLINE_BASE,
+ FONT_LIST, RES_POOLCOLL_NUMBER_BULLET_BASE,
+ FONT_CAPTION, RES_POOLCOLL_LABEL,
+ FONT_INDEX, RES_POOLCOLL_REGISTER_BASE,
+ FONT_OUTLINE_CJK, RES_POOLCOLL_HEADLINE_BASE,
+ FONT_LIST_CJK, RES_POOLCOLL_NUMBER_BULLET_BASE,
+ FONT_CAPTION_CJK, RES_POOLCOLL_LABEL,
+ FONT_INDEX_CJK, RES_POOLCOLL_REGISTER_BASE,
+ FONT_OUTLINE_CTL, RES_POOLCOLL_HEADLINE_BASE,
+ FONT_LIST_CTL, RES_POOLCOLL_NUMBER_BULLET_BASE,
+ FONT_CAPTION_CTL, RES_POOLCOLL_LABEL,
+ FONT_INDEX_CTL, RES_POOLCOLL_REGISTER_BASE
+ };
+
+ TypedWhichId<SvxFontItem> nFontWhich = RES_CHRATR_FONT;
+ TypedWhichId<SvxFontHeightItem> nFontHeightWhich = RES_CHRATR_FONTSIZE;
+ LanguageType eLanguage = m_xDoc->GetDefault( RES_CHRATR_LANGUAGE ).GetLanguage();
+ bool bDisableBuiltinStyles = !bFuzzing && officecfg::Office::Common::Load::DisableBuiltinStyles::get();
+ sal_uInt8 nLimit = bDisableBuiltinStyles ? 0 : 24;
+ for(sal_uInt8 nIdx = 0; nIdx < nLimit; nIdx += 2)
+ {
+ if(nIdx == 8)
+ {
+ nFontWhich = RES_CHRATR_CJK_FONT;
+ nFontHeightWhich = RES_CHRATR_CJK_FONTSIZE;
+ eLanguage = m_xDoc->GetDefault( RES_CHRATR_CJK_LANGUAGE ).GetLanguage();
+ }
+ else if(nIdx == 16)
+ {
+ nFontWhich = RES_CHRATR_CTL_FONT;
+ nFontHeightWhich = RES_CHRATR_CTL_FONTSIZE;
+ eLanguage = m_xDoc->GetDefault( RES_CHRATR_CTL_LANGUAGE ).GetLanguage();
+ }
+ SwTextFormatColl *pColl = nullptr;
+ if(!pStdFont->IsFontDefault(aFontIdPoolId[nIdx]))
+ {
+ sEntry = pStdFont->GetFontFor(aFontIdPoolId[nIdx]);
+
+ vcl::Font aFont( sEntry, Size( 0, 10 ) );
+ if( pPrt )
+ aFont = pPrt->GetFontMetric( aFont );
+
+ pColl = m_xDoc->getIDocumentStylePoolAccess().GetTextCollFromPool(aFontIdPoolId[nIdx + 1]);
+ if( !bHTMLTemplSet ||
+ SfxItemState::SET != pColl->GetAttrSet().GetItemState(
+ nFontWhich, false ) )
+ {
+ pColl->SetFormatAttr(SvxFontItem(aFont.GetFamilyType(), aFont.GetFamilyName(),
+ OUString(), aFont.GetPitch(), aFont.GetCharSet(), nFontWhich));
+ }
+ }
+ sal_Int32 nFontHeight = pStdFont->GetFontHeight( static_cast< sal_Int8 >(aFontIdPoolId[nIdx]), 0, eLanguage );
+ if(nFontHeight <= 0)
+ nFontHeight = SwStdFontConfig::GetDefaultHeightFor( aFontIdPoolId[nIdx], eLanguage );
+ if(!pColl)
+ pColl = m_xDoc->getIDocumentStylePoolAccess().GetTextCollFromPool(aFontIdPoolId[nIdx + 1]);
+ SvxFontHeightItem aFontHeight( pColl->GetFormatAttr( nFontHeightWhich ) );
+ if(aFontHeight.GetHeight() != sal::static_int_cast<sal_uInt32, sal_Int32>(nFontHeight))
+ {
+ aFontHeight.SetHeight(nFontHeight);
+ pColl->SetFormatAttr( aFontHeight );
+ }
+ }
+
+ // the default for documents created via 'File/New' should be 'on'
+ // (old documents, where this property was not yet implemented, will get the
+ // value 'false' in the SwDoc c-tor)
+ m_xDoc->getIDocumentSettingAccess().set( DocumentSettingId::MATH_BASELINE_ALIGNMENT,
+ SW_MOD()->GetUsrPref( bWeb )->IsAlignMathObjectsToBaseline() );
+ m_xDoc->getIDocumentSettingAccess().set( DocumentSettingId::FOOTNOTE_IN_COLUMN_TO_PAGEEND, true);
+ }
+
+ /* #106748# If the default frame direction of a document is RTL
+ the default adjustment is to the right. */
+ if( !bHTMLTemplSet &&
+ SvxFrameDirection::Horizontal_RL_TB == GetDefaultFrameDirection(GetAppLanguage()) )
+ {
+ m_xDoc->SetDefault( SvxAdjustItem(SvxAdjust::Right, RES_PARATR_ADJUST ) );
+ }
+
+// #i29550#
+ m_xDoc->SetDefault( SfxBoolItem( RES_COLLAPSING_BORDERS, true ) );
+// <-- collapsing
+
+ //#i16874# AutoKerning as default for new documents
+ m_xDoc->SetDefault( SvxAutoKernItem( true, RES_CHRATR_AUTOKERN ) );
+
+ // #i42080# - Due to the several calls of method <SetDefault(..)>
+ // at the document instance, the document is modified. Thus, reset this
+ // status here. Note: In method <SubInitNew()> this is also done.
+ m_xDoc->getIDocumentState().ResetModified();
+
+ return bRet;
+}
+
+// Ctor with SfxCreateMode ?????
+SwDocShell::SwDocShell( SfxObjectCreateMode const eMode )
+ : SfxObjectShell(eMode)
+ , m_IsInUpdateFontList(false)
+ , m_pStyleManager(new svx::CommonStyleManager(*this))
+ , m_pView(nullptr)
+ , m_pWrtShell(nullptr)
+ , m_nUpdateDocMode(document::UpdateDocMode::ACCORDING_TO_CONFIG)
+ , m_IsATemplate(false)
+ , m_IsRemovedInvisibleContent(false)
+{
+ Init_Impl();
+}
+
+// Ctor / Dtor
+SwDocShell::SwDocShell( const SfxModelFlags i_nSfxCreationFlags )
+ : SfxObjectShell ( i_nSfxCreationFlags )
+ , m_IsInUpdateFontList(false)
+ , m_pStyleManager(new svx::CommonStyleManager(*this))
+ , m_pView(nullptr)
+ , m_pWrtShell(nullptr)
+ , m_nUpdateDocMode(document::UpdateDocMode::ACCORDING_TO_CONFIG)
+ , m_IsATemplate(false)
+ , m_IsRemovedInvisibleContent(false)
+{
+ Init_Impl();
+}
+
+// Ctor / Dtor
+SwDocShell::SwDocShell( SwDoc& rD, SfxObjectCreateMode const eMode )
+ : SfxObjectShell(eMode)
+ , m_xDoc(&rD)
+ , m_IsInUpdateFontList(false)
+ , m_pStyleManager(new svx::CommonStyleManager(*this))
+ , m_pView(nullptr)
+ , m_pWrtShell(nullptr)
+ , m_nUpdateDocMode(document::UpdateDocMode::ACCORDING_TO_CONFIG)
+ , m_IsATemplate(false)
+ , m_IsRemovedInvisibleContent(false)
+{
+ Init_Impl();
+}
+
+// Dtor
+SwDocShell::~SwDocShell()
+{
+ // disable chart related objects now because in ~SwDoc it may be too late for this
+ if (m_xDoc)
+ {
+ m_xDoc->getIDocumentChartDataProviderAccess().GetChartControllerHelper().Disconnect();
+ SwChartDataProvider *pPCD = m_xDoc->getIDocumentChartDataProviderAccess().GetChartDataProvider();
+ if (pPCD)
+ pPCD->dispose();
+ }
+
+ RemoveLink();
+ m_pFontList.reset();
+
+ // we, as BroadCaster also become our own Listener
+ // (for DocInfo/FileNames/...)
+ EndListening( *this );
+
+ m_pOLEChildList.reset();
+}
+
+void SwDocShell::Init_Impl()
+{
+ SetPool(&SW_MOD()->GetPool());
+ SetBaseModel(new SwXTextDocument(this));
+ // we, as BroadCaster also become our own Listener
+ // (for DocInfo/FileNames/...)
+ StartListening( *this );
+ //position of the "Automatic" style filter for the stylist (app.src)
+ SetAutoStyleFilterIndex(3);
+
+ // set map unit to twip
+ SetMapUnit( MapUnit::MapTwip );
+}
+
+void SwDocShell::AddLink()
+{
+ if (!m_xDoc)
+ {
+ SwDocFac aFactory;
+ m_xDoc = &aFactory.GetDoc();
+ m_xDoc->getIDocumentSettingAccess().set(DocumentSettingId::HTML_MODE, dynamic_cast< const SwWebDocShell *>( this ) != nullptr );
+ }
+ m_xDoc->SetDocShell( this ); // set the DocShell-Pointer for Doc
+ uno::Reference< text::XTextDocument > xDoc(GetBaseModel(), uno::UNO_QUERY);
+ static_cast<SwXTextDocument*>(xDoc.get())->Reactivate(this);
+
+ SetPool(&m_xDoc->GetAttrPool());
+
+ // most suitably not until a sdbcx::View is created!!!
+ m_xDoc->SetOle2Link(LINK(this, SwDocShell, Ole2ModifiedHdl));
+}
+
+// create new FontList Change Printer
+void SwDocShell::UpdateFontList()
+{
+ if (!m_IsInUpdateFontList)
+ {
+ m_IsInUpdateFontList = true;
+ OSL_ENSURE(m_xDoc, "No Doc no FontList");
+ if (m_xDoc)
+ {
+ m_pFontList.reset( new FontList( m_xDoc->getIDocumentDeviceAccess().getReferenceDevice(true) ) );
+ PutItem( SvxFontListItem( m_pFontList.get(), SID_ATTR_CHAR_FONTLIST ) );
+ }
+ m_IsInUpdateFontList = false;
+ }
+}
+
+void SwDocShell::RemoveLink()
+{
+ // disconnect Uno-Object
+ uno::Reference< text::XTextDocument > xDoc(GetBaseModel(), uno::UNO_QUERY);
+ static_cast<SwXTextDocument*>(xDoc.get())->Invalidate();
+ if (m_xDoc)
+ {
+ if (m_xBasePool.is())
+ {
+ m_xBasePool->dispose();
+ m_xBasePool.clear();
+ }
+ m_xDoc->SetOle2Link(Link<bool,void>());
+ m_xDoc->SetDocShell( nullptr );
+ m_xDoc.clear(); // we don't have the Doc anymore!!
+ }
+}
+void SwDocShell::InvalidateModel()
+{
+ // disconnect Uno-Object
+ uno::Reference< text::XTextDocument > xDoc(GetBaseModel(), uno::UNO_QUERY);
+ static_cast<SwXTextDocument*>(xDoc.get())->Invalidate();
+}
+void SwDocShell::ReactivateModel()
+{
+ // disconnect Uno-Object
+ uno::Reference< text::XTextDocument > xDoc(GetBaseModel(), uno::UNO_QUERY);
+ static_cast<SwXTextDocument*>(xDoc.get())->Reactivate(this);
+}
+
+// Load, Default-Format
+bool SwDocShell::Load( SfxMedium& rMedium )
+{
+ bool bRet = false;
+
+ if (SfxObjectShell::Load(rMedium))
+ {
+ comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = getEmbeddedObjectContainer();
+ rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false);
+
+ SAL_INFO( "sw.ui", "after SfxInPlaceObject::Load" );
+ if (m_xDoc) // for last version!!
+ RemoveLink(); // release the existing
+
+ AddLink(); // set Link and update Data!!
+
+ // Define some settings for legacy ODF files that have different default values now
+ // (if required, they will be overridden later when settings will be read)
+ if (IsOwnStorageFormat(rMedium))
+ {
+ SwDrawModel* pDrawModel = m_xDoc->getIDocumentDrawModelAccess().GetDrawModel();
+ if (pDrawModel)
+ {
+ pDrawModel->SetCompatibilityFlag(SdrCompatibilityFlag::AnchoredTextOverflowLegacy,
+ true); // legacy processing for tdf#99729
+ pDrawModel->SetCompatibilityFlag(SdrCompatibilityFlag::LegacyFontwork,
+ true); // legacy processing for tdf#148000
+ }
+ }
+
+ // Loading
+ // for MD
+ OSL_ENSURE( !m_xBasePool.is(), "who hasn't destroyed their Pool?" );
+ m_xBasePool = new SwDocStyleSheetPool( *m_xDoc, SfxObjectCreateMode::ORGANIZER == GetCreateMode() );
+ if(GetCreateMode() != SfxObjectCreateMode::ORGANIZER)
+ {
+ const SfxUInt16Item* pUpdateDocItem = rMedium.GetItemSet().GetItem(SID_UPDATEDOCMODE, false);
+ m_nUpdateDocMode = pUpdateDocItem ? pUpdateDocItem->GetValue() : document::UpdateDocMode::NO_UPDATE;
+ }
+
+ SwWait aWait( *this, true );
+ ErrCodeMsg nErr = ERR_SWG_READ_ERROR;
+ switch( GetCreateMode() )
+ {
+ case SfxObjectCreateMode::ORGANIZER:
+ {
+ if( ReadXML )
+ {
+ ReadXML->SetOrganizerMode( true );
+ SwReader aRdr(rMedium, OUString(), m_xDoc.get());
+ nErr = aRdr.Read( *ReadXML );
+ ReadXML->SetOrganizerMode( false );
+ }
+ }
+ break;
+
+ case SfxObjectCreateMode::INTERNAL:
+ case SfxObjectCreateMode::EMBEDDED:
+ {
+ SwTransferable::InitOle( this );
+ }
+ // suppress SfxProgress, when we are Embedded
+ SW_MOD()->SetEmbeddedLoadSave( true );
+ [[fallthrough]];
+
+ case SfxObjectCreateMode::STANDARD:
+ {
+ Reader *pReader = ReadXML;
+ if( pReader )
+ {
+ // set Doc's DocInfo at DocShell-Medium
+ SAL_INFO( "sw.ui", "before ReadDocInfo" );
+ SwReader aRdr(rMedium, OUString(), m_xDoc.get());
+ SAL_INFO( "sw.ui", "before Read" );
+ nErr = aRdr.Read( *pReader );
+ SAL_INFO( "sw.ui", "after Read" );
+ // If a XML document is loaded, the global doc/web doc
+ // flags have to be set, because they aren't loaded
+ // by this formats.
+ if( dynamic_cast< const SwWebDocShell *>( this ) != nullptr )
+ {
+ if (!m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE))
+ m_xDoc->getIDocumentSettingAccess().set(DocumentSettingId::HTML_MODE, true);
+ }
+ if( dynamic_cast< const SwGlobalDocShell *>( this ) != nullptr )
+ {
+ if (!m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT))
+ m_xDoc->getIDocumentSettingAccess().set(DocumentSettingId::GLOBAL_DOCUMENT, true);
+ }
+ }
+ }
+ break;
+
+ default:
+ OSL_ENSURE( false, "Load: new CreateMode?" );
+ }
+
+ UpdateFontList();
+ InitDrawModelAndDocShell(this, m_xDoc ? m_xDoc->getIDocumentDrawModelAccess().GetDrawModel()
+ : nullptr);
+
+ SetError(nErr);
+ bRet = !nErr.IsError();
+
+ if (bRet && !m_xDoc->IsInLoadAsynchron() &&
+ GetCreateMode() == SfxObjectCreateMode::STANDARD)
+ {
+ LoadingFinished();
+ }
+
+ // suppress SfxProgress, when we are Embedded
+ SW_MOD()->SetEmbeddedLoadSave( false );
+ }
+
+ return bRet;
+}
+
+bool SwDocShell::LoadFrom( SfxMedium& rMedium )
+{
+ bool bRet = false;
+ if (m_xDoc)
+ RemoveLink();
+
+ AddLink(); // set Link and update Data!!
+
+ do { // middle check loop
+ ErrCodeMsg nErr = ERR_SWG_READ_ERROR;
+ OUString aStreamName = "styles.xml";
+ uno::Reference < container::XNameAccess > xAccess = rMedium.GetStorage();
+ if ( xAccess->hasByName( aStreamName ) && rMedium.GetStorage()->isStreamElement( aStreamName ) )
+ {
+ // Loading
+ SwWait aWait( *this, true );
+ {
+ OSL_ENSURE( !m_xBasePool.is(), "who hasn't destroyed their Pool?" );
+ m_xBasePool = new SwDocStyleSheetPool( *m_xDoc, SfxObjectCreateMode::ORGANIZER == GetCreateMode() );
+ if( ReadXML )
+ {
+ ReadXML->SetOrganizerMode( true );
+ SwReader aRdr(rMedium, OUString(), m_xDoc.get());
+ nErr = aRdr.Read( *ReadXML );
+ ReadXML->SetOrganizerMode( false );
+ }
+ }
+ }
+ else
+ {
+ OSL_FAIL("Code removed!");
+ }
+
+ SetError(nErr);
+ bRet = !nErr.IsError();
+
+ } while( false );
+
+ SfxObjectShell::LoadFrom( rMedium );
+ m_xDoc->getIDocumentState().ResetModified();
+ return bRet;
+}
+
+void SwDocShell::SubInitNew()
+{
+ OSL_ENSURE( !m_xBasePool.is(), "who hasn't destroyed their Pool?" );
+ m_xBasePool = new SwDocStyleSheetPool( *m_xDoc, SfxObjectCreateMode::ORGANIZER == GetCreateMode() );
+ UpdateFontList();
+ InitDrawModelAndDocShell(this, m_xDoc ? m_xDoc->getIDocumentDrawModelAccess().GetDrawModel() : nullptr);
+
+ m_xDoc->getIDocumentSettingAccess().setLinkUpdateMode( GLOBALSETTING );
+ m_xDoc->getIDocumentSettingAccess().setFieldUpdateFlags( AUTOUPD_GLOBALSETTING );
+
+ bool bWeb = dynamic_cast< const SwWebDocShell *>( this ) != nullptr;
+
+ static const WhichRangesContainer nRange1(svl::Items<
+ RES_CHRATR_COLOR, RES_CHRATR_COLOR,
+ RES_CHRATR_LANGUAGE, RES_CHRATR_LANGUAGE,
+ RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CJK_LANGUAGE,
+ RES_CHRATR_CTL_LANGUAGE, RES_CHRATR_CTL_LANGUAGE,
+ RES_PARATR_ADJUST, RES_PARATR_ADJUST
+ >);
+ static const WhichRangesContainer nRange2(svl::Items<
+ RES_CHRATR_COLOR, RES_CHRATR_COLOR,
+ RES_CHRATR_LANGUAGE, RES_CHRATR_LANGUAGE,
+ RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CJK_LANGUAGE,
+ RES_CHRATR_CTL_LANGUAGE, RES_CHRATR_CTL_LANGUAGE,
+ RES_PARATR_ADJUST, RES_PARATR_ADJUST,
+ RES_PARATR_TABSTOP, RES_PARATR_HYPHENZONE
+ >);
+ SfxItemSet aDfltSet( m_xDoc->GetAttrPool(), bWeb ? nRange1 : nRange2 );
+
+ //! get lingu options without loading lingu DLL
+ SvtLinguOptions aLinguOpt;
+
+ const bool bFuzzing = utl::ConfigManager::IsFuzzing();
+ if (!bFuzzing)
+ SvtLinguConfig().GetOptions(aLinguOpt);
+
+ LanguageType nVal = MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage, css::i18n::ScriptType::LATIN),
+ eCJK = MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage_CJK, css::i18n::ScriptType::ASIAN),
+ eCTL = MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage_CTL, css::i18n::ScriptType::COMPLEX);
+ aDfltSet.Put( SvxLanguageItem( nVal, RES_CHRATR_LANGUAGE ) );
+ aDfltSet.Put( SvxLanguageItem( eCJK, RES_CHRATR_CJK_LANGUAGE ) );
+ aDfltSet.Put( SvxLanguageItem( eCTL, RES_CHRATR_CTL_LANGUAGE ) );
+
+ if(!bWeb)
+ {
+ SvxHyphenZoneItem aHyp( m_xDoc->GetDefault(RES_PARATR_HYPHENZONE) );
+ aHyp.GetMinLead() = static_cast< sal_uInt8 >(aLinguOpt.nHyphMinLeading);
+ aHyp.GetMinTrail() = static_cast< sal_uInt8 >(aLinguOpt.nHyphMinTrailing);
+ aHyp.GetMinWordLength() = static_cast< sal_uInt8 >(aLinguOpt.nHyphMinWordLength);
+
+ aDfltSet.Put( aHyp );
+
+ sal_uInt16 nNewPos = o3tl::toTwips(SW_MOD()->GetUsrPref(false)->GetDefTabInMm100(), o3tl::Length::mm100);
+ if( nNewPos )
+ aDfltSet.Put( SvxTabStopItem( 1, nNewPos,
+ SvxTabAdjust::Default, RES_PARATR_TABSTOP ) );
+ }
+ aDfltSet.Put( SvxColorItem( COL_AUTO, RES_CHRATR_COLOR ) );
+
+ m_xDoc->SetDefault( aDfltSet );
+
+ //default page mode for text grid
+ if(!bWeb)
+ {
+ bool bSquaredPageMode = SW_MOD()->GetUsrPref(false)->IsSquaredPageMode();
+ m_xDoc->SetDefaultPageMode( bSquaredPageMode );
+
+ // only set Widow/Orphan defaults on a new, non-web document - not an opened one
+ if (GetMedium() && GetMedium()->GetOrigURL().isEmpty() && !bFuzzing)
+ {
+ m_xDoc->SetDefault( SvxWidowsItem( sal_uInt8(2), RES_PARATR_WIDOWS) );
+ m_xDoc->SetDefault( SvxOrphansItem( sal_uInt8(2), RES_PARATR_ORPHANS) );
+ }
+ }
+
+ m_xDoc->getIDocumentState().ResetModified();
+}
+
+/*
+ * Document Interface Access
+ */
+IDocumentDeviceAccess& SwDocShell::getIDocumentDeviceAccess()
+{
+ return m_xDoc->getIDocumentDeviceAccess();
+}
+
+IDocumentChartDataProviderAccess& SwDocShell::getIDocumentChartDataProviderAccess()
+{
+ return m_xDoc->getIDocumentChartDataProviderAccess();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/app/docst.cxx b/sw/source/uibase/app/docst.cxx
new file mode 100644
index 0000000000..ba6c850a86
--- /dev/null
+++ b/sw/source/uibase/app/docst.cxx
@@ -0,0 +1,1693 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_wasm_strip.h>
+
+#include <memory>
+
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <comphelper/flagguard.hxx>
+#include <o3tl/any.hxx>
+#include <sal/log.hxx>
+#include <osl/diagnose.h>
+#include <hintids.hxx>
+#include <sfx2/styledlg.hxx>
+#include <svl/whiter.hxx>
+#include <sfx2/tplpitem.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/newstyle.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svl/stritem.hxx>
+#include <svl/ctloptions.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <swmodule.hxx>
+#include <fchrfmt.hxx>
+#include <svx/xdef.hxx>
+#include <SwStyleNameMapper.hxx>
+#include <SwRewriter.hxx>
+#include <numrule.hxx>
+#include <swundo.hxx>
+#include <svx/drawitem.hxx>
+#include <utility>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <docsh.hxx>
+#include <uitool.hxx>
+#include <cmdid.h>
+#include <viewopt.hxx>
+#include <doc.hxx>
+#include <drawdoc.hxx>
+#include <IDocumentDrawModelAccess.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <IDocumentSettingAccess.hxx>
+#include <IDocumentDeviceAccess.hxx>
+#include <IDocumentFieldsAccess.hxx>
+#include <IDocumentState.hxx>
+#include <frmfmt.hxx>
+#include <charfmt.hxx>
+#include <poolfmt.hxx>
+#include <pagedesc.hxx>
+#include <docstyle.hxx>
+#include <uiitems.hxx>
+#include <fmtcol.hxx>
+#include <edtwin.hxx>
+#include <unochart.hxx>
+#include <swabstdlg.hxx>
+#include <tblafmt.hxx>
+#include <sfx2/watermarkitem.hxx>
+#include <svl/grabbagitem.hxx>
+#include <PostItMgr.hxx>
+#include <AnnotationWin.hxx>
+#include <SwUndoFmt.hxx>
+#include <strings.hrc>
+#include <AccessibilityCheck.hxx>
+#include <docmodel/theme/Theme.hxx>
+#include <svx/svdpage.hxx>
+#include <officecfg/Office/Common.hxx>
+
+using namespace ::com::sun::star;
+
+void SwDocShell::StateStyleSheet(SfxItemSet& rSet, SwWrtShell* pSh)
+{
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ SfxStyleFamily nActualFamily = SfxStyleFamily(USHRT_MAX);
+
+ SwWrtShell* pShell = pSh ? pSh : GetWrtShell();
+ if(!pShell)
+ {
+ while (nWhich)
+ {
+ rSet.DisableItem(nWhich);
+ nWhich = aIter.NextWhich();
+ }
+ return;
+ }
+ else
+ {
+ SfxViewFrame& rFrame = pShell->GetView().GetViewFrame();
+ std::unique_ptr<SfxUInt16Item> pFamilyItem;
+ rFrame.GetBindings().QueryState(SID_STYLE_FAMILY, pFamilyItem);
+ if (pFamilyItem)
+ {
+ nActualFamily = static_cast<SfxStyleFamily>(pFamilyItem->GetValue());
+ }
+ }
+
+ while (nWhich)
+ {
+ // determine current template to every family
+ OUString aName;
+ SwTableAutoFormat aTableAutoFormat("dummy"); // needed to check if can take a table auto format at current cursor position
+ switch (nWhich)
+ {
+ case SID_STYLE_APPLY:
+ {// here the template and its family are passed to the StyleBox
+ // so that this family is being showed
+ if(pShell->IsFrameSelected())
+ {
+ SwFrameFormat* pFormat = pShell->GetSelectedFrameFormat();
+ if( pFormat )
+ aName = pFormat->GetName();
+ }
+ else if (pShell->GetSelectionType() == SelectionType::PostIt)
+ {
+ auto pStyle = pShell->GetPostItMgr()->GetActiveSidebarWin()->GetOutlinerView()->GetStyleSheet();
+ if (pStyle)
+ aName = pStyle->GetName();
+ }
+ else
+ {
+ SwTextFormatColl* pColl = pShell->GetCurTextFormatColl();
+ if(pColl)
+ aName = pColl->GetName();
+ }
+ rSet.Put(SfxTemplateItem(nWhich, aName));
+ }
+ break;
+ case SID_STYLE_FAMILY1:
+ if( !pShell->IsFrameSelected() )
+ {
+ SwCharFormat* pFormat = pShell->GetCurCharFormat();
+ if(pFormat)
+ aName = pFormat->GetName();
+ else
+ aName = SwResId(STR_POOLCHR_STANDARD);
+ rSet.Put(SfxTemplateItem(nWhich, aName));
+ }
+ break;
+
+ case SID_STYLE_FAMILY2:
+ if(!pShell->IsFrameSelected())
+ {
+ OUString aProgName;
+ if (pShell->GetSelectionType() == SelectionType::PostIt)
+ {
+ if (auto pStyle = pShell->GetPostItMgr()->GetActiveSidebarWin()->GetOutlinerView()->GetStyleSheet())
+ {
+ aName = pStyle->GetName();
+ aProgName = SwStyleNameMapper::GetProgName(aName, SwGetPoolIdFromName::TxtColl);
+ }
+ }
+ else if (auto pColl = pShell->GetCurTextFormatColl())
+ {
+ aName = pColl->GetName();
+ sal_uInt16 nId = pColl->GetPoolFormatId();
+ SwStyleNameMapper::FillProgName(nId, aProgName);
+ }
+
+ SfxTemplateItem aItem(nWhich, aName, aProgName);
+
+ SfxStyleSearchBits nMask = SfxStyleSearchBits::Auto;
+ if (m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE))
+ nMask = SfxStyleSearchBits::SwHtml;
+ else
+ {
+ const FrameTypeFlags nSelection = pShell->GetFrameType(nullptr,true);
+ if(pShell->GetCurTOX())
+ nMask = SfxStyleSearchBits::SwIndex ;
+ else if(nSelection & FrameTypeFlags::HEADER ||
+ nSelection & FrameTypeFlags::FOOTER ||
+ nSelection & FrameTypeFlags::TABLE ||
+ nSelection & FrameTypeFlags::FLY_ANY ||
+ nSelection & FrameTypeFlags::FOOTNOTE ||
+ nSelection & FrameTypeFlags::FTNPAGE)
+ nMask = SfxStyleSearchBits::SwExtra;
+ else
+ nMask = SfxStyleSearchBits::SwText;
+ }
+
+ aItem.SetValue(nMask);
+ rSet.Put(aItem);
+ }
+
+ break;
+
+ case SID_STYLE_FAMILY3:
+
+ if (m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE))
+ rSet.DisableItem( nWhich );
+ else
+ {
+ SwFrameFormat* pFormat = pShell->GetSelectedFrameFormat();
+ if(pFormat && pShell->IsFrameSelected())
+ {
+ aName = pFormat->GetName();
+ rSet.Put(SfxTemplateItem(nWhich, aName));
+ }
+ }
+ break;
+
+ case SID_STYLE_FAMILY4:
+ {
+ if (m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE) && !officecfg::Office::Common::Filter::HTML::Export::PrintLayout::get())
+ rSet.DisableItem( nWhich );
+ else
+ {
+ size_t n = pShell->GetCurPageDesc( false );
+ if( n < pShell->GetPageDescCnt() )
+ aName = pShell->GetPageDesc( n ).GetName();
+
+ rSet.Put(SfxTemplateItem(nWhich, aName));
+ }
+ }
+ break;
+ case SID_STYLE_FAMILY5:
+ {
+ const SwNumRule* pRule = pShell->GetNumRuleAtCurrCursorPos();
+ if( pRule )
+ aName = pRule->GetName();
+
+ rSet.Put(SfxTemplateItem(nWhich, aName));
+ }
+ break;
+ case SID_STYLE_FAMILY6:
+ {
+ const SwTableNode *pTableNd = pShell->IsCursorInTable();
+ if( pTableNd )
+ aName = pTableNd->GetTable().GetTableStyleName();
+
+ rSet.Put(SfxTemplateItem(nWhich, aName));
+ }
+ break;
+
+ case SID_STYLE_WATERCAN:
+ {
+ SwEditWin& rEdtWin = pShell->GetView().GetEditWin();
+ SwApplyTemplate* pApply = rEdtWin.GetApplyTemplate();
+ rSet.Put(SfxBoolItem(nWhich, pApply && pApply->eType != SfxStyleFamily(0)));
+ }
+ break;
+ case SID_STYLE_UPDATE_BY_EXAMPLE:
+ if( pShell->IsFrameSelected()
+ ? SfxStyleFamily::Frame != nActualFamily
+ : ( SfxStyleFamily::Frame == nActualFamily ||
+ SfxStyleFamily::Page == nActualFamily ||
+ (SfxStyleFamily::Pseudo == nActualFamily && !pShell->GetNumRuleAtCurrCursorPos()) ||
+ (SfxStyleFamily::Table == nActualFamily && !pShell->GetTableAutoFormat(aTableAutoFormat))) )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_STYLE_NEW_BY_EXAMPLE:
+ if( (pShell->IsFrameSelected()
+ ? SfxStyleFamily::Frame != nActualFamily
+ : SfxStyleFamily::Frame == nActualFamily) ||
+ (SfxStyleFamily::Pseudo == nActualFamily && !pShell->GetNumRuleAtCurrCursorPos()) ||
+ (SfxStyleFamily::Table == nActualFamily && !pShell->GetTableAutoFormat(aTableAutoFormat)) )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_CLASSIFICATION_APPLY:
+ // Just trigger ClassificationCategoriesController::statusChanged().
+ rSet.InvalidateItem(nWhich);
+ break;
+ case SID_CLASSIFICATION_DIALOG:
+ rSet.InvalidateItem(nWhich);
+ break;
+ case SID_STYLE_EDIT:
+ break;
+ case SID_WATERMARK:
+ if (pSh)
+ {
+ SfxWatermarkItem aItem = pSh->GetWatermark();
+ rSet.Put(aItem);
+ }
+ break;
+ default:
+ OSL_FAIL("Invalid SlotId");
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+// evaluate StyleSheet-Requests
+void SwDocShell::ExecStyleSheet( SfxRequest& rReq )
+{
+ sal_uInt16 nSlot = rReq.GetSlot();
+
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ const SfxPoolItem* pItem;
+ switch (nSlot)
+ {
+ case SID_STYLE_NEW:
+ if( pArgs && SfxItemState::SET == pArgs->GetItemState( SID_STYLE_FAMILY,
+ false, &pItem ))
+ {
+ const SfxStyleFamily nFamily = static_cast<SfxStyleFamily>(static_cast<const SfxUInt16Item*>(pItem)->GetValue());
+
+ OUString sName;
+ SfxStyleSearchBits nMask = SfxStyleSearchBits::Auto;
+ if( SfxItemState::SET == pArgs->GetItemState( SID_STYLE_NEW,
+ false, &pItem ))
+ sName = static_cast<const SfxStringItem*>(pItem)->GetValue();
+ if( SfxItemState::SET == pArgs->GetItemState( SID_STYLE_MASK,
+ false, &pItem ))
+ nMask = static_cast<SfxStyleSearchBits>(static_cast<const SfxUInt16Item*>(pItem)->GetValue());
+ OUString sParent;
+ if( SfxItemState::SET == pArgs->GetItemState( SID_STYLE_REFERENCE,
+ false, &pItem ))
+ sParent = static_cast<const SfxStringItem*>(pItem)->GetValue();
+
+ if (sName.isEmpty() && m_xBasePool)
+ sName = SfxStyleDialogController::GenerateUnusedName(*m_xBasePool, nFamily);
+
+ Edit(rReq.GetFrameWeld(), sName, sParent, nFamily, nMask, true, {}, nullptr, &rReq, nSlot);
+ }
+ break;
+
+ case SID_STYLE_APPLY:
+ if( !pArgs )
+ {
+ GetView()->GetViewFrame().GetDispatcher()->Execute(SID_STYLE_DESIGNER);
+ break;
+ }
+ else
+ {
+ // convert internal StyleName to DisplayName (slot implementation uses the latter)
+ const SfxStringItem* pNameItem = rReq.GetArg<SfxStringItem>(SID_APPLY_STYLE);
+ const SfxStringItem* pFamilyItem = rReq.GetArg<SfxStringItem>(SID_STYLE_FAMILYNAME);
+ if ( pFamilyItem && pNameItem )
+ {
+ uno::Reference< style::XStyleFamiliesSupplier > xModel(GetModel(), uno::UNO_QUERY);
+ try
+ {
+ uno::Reference< container::XNameAccess > xStyles;
+ uno::Reference< container::XNameAccess > xCont = xModel->getStyleFamilies();
+ xCont->getByName(pFamilyItem->GetValue()) >>= xStyles;
+ uno::Reference< beans::XPropertySet > xInfo;
+ xStyles->getByName( pNameItem->GetValue() ) >>= xInfo;
+ OUString aUIName;
+ xInfo->getPropertyValue("DisplayName") >>= aUIName;
+ if ( !aUIName.isEmpty() )
+ rReq.AppendItem( SfxStringItem( SID_STYLE_APPLY, aUIName ) );
+ }
+ catch (const uno::Exception&)
+ {
+ }
+ }
+ }
+
+ [[fallthrough]];
+
+ case SID_STYLE_EDIT:
+ case SID_STYLE_FONT:
+ case SID_STYLE_DELETE:
+ case SID_STYLE_HIDE:
+ case SID_STYLE_SHOW:
+ case SID_STYLE_WATERCAN:
+ case SID_STYLE_FAMILY:
+ case SID_STYLE_UPDATE_BY_EXAMPLE:
+ case SID_STYLE_NEW_BY_EXAMPLE:
+ {
+ OUString aParam;
+ SfxStyleFamily nFamily = SfxStyleFamily::Para;
+ SfxStyleSearchBits nMask = SfxStyleSearchBits::Auto;
+ SwWrtShell* pActShell = nullptr;
+
+ if( !pArgs )
+ {
+ switch (nSlot)
+ {
+ case SID_STYLE_NEW_BY_EXAMPLE:
+ {
+ SfxStyleSheetBasePool& rPool = *GetStyleSheetPool();
+ SfxNewStyleDlg aDlg(GetView()->GetFrameWeld(), rPool, nFamily);
+ if (aDlg.run() == RET_OK)
+ {
+ aParam = aDlg.GetName();
+ rReq.AppendItem(SfxStringItem(nSlot, aParam));
+ }
+ }
+ break;
+
+ case SID_STYLE_UPDATE_BY_EXAMPLE:
+ case SID_STYLE_EDIT:
+ {
+ if (GetWrtShell()->GetSelectionType() == SelectionType::PostIt)
+ {
+ auto pOLV = GetWrtShell()->GetPostItMgr()->GetActiveSidebarWin()->GetOutlinerView();
+ if (auto pStyle = pOLV->GetStyleSheet())
+ aParam = pStyle->GetName();
+ }
+ else if (auto pColl = GetWrtShell()->GetCurTextFormatColl())
+ aParam = pColl->GetName();
+
+ if (!aParam.isEmpty())
+ rReq.AppendItem(SfxStringItem(nSlot, aParam));
+ }
+ break;
+ }
+ }
+ else
+ {
+ SAL_WARN_IF( !pArgs->Count(), "sw.ui", "SfxBug ItemSet is empty" );
+
+ SwWrtShell* pShell = GetWrtShell();
+ if( SfxItemState::SET == pArgs->GetItemState(nSlot, false, &pItem ))
+ aParam = static_cast<const SfxStringItem*>(pItem)->GetValue();
+
+ if( SfxItemState::SET == pArgs->GetItemState(SID_STYLE_FAMILY,
+ false, &pItem ))
+ nFamily = static_cast<SfxStyleFamily>(static_cast<const SfxUInt16Item*>(pItem)->GetValue());
+
+ if( SfxItemState::SET == pArgs->GetItemState(SID_STYLE_FAMILYNAME, false, &pItem ))
+ {
+ OUString aFamily = static_cast<const SfxStringItem*>(pItem)->GetValue();
+ if(aFamily == "CharacterStyles")
+ nFamily = SfxStyleFamily::Char;
+ else
+ if(aFamily == "ParagraphStyles")
+ nFamily = SfxStyleFamily::Para;
+ else
+ if(aFamily == "PageStyles")
+ nFamily = SfxStyleFamily::Page;
+ else
+ if(aFamily == "FrameStyles")
+ nFamily = SfxStyleFamily::Frame;
+ else
+ if(aFamily == "NumberingStyles")
+ nFamily = SfxStyleFamily::Pseudo;
+ else
+ if(aFamily == "TableStyles")
+ nFamily = SfxStyleFamily::Table;
+ }
+
+ if( SfxItemState::SET == pArgs->GetItemState(SID_STYLE_MASK,
+ false, &pItem ))
+ nMask = static_cast<SfxStyleSearchBits>(static_cast<const SfxUInt16Item*>(pItem)->GetValue());
+ if( const SwPtrItem* pShellItem = pArgs->GetItemIfSet(FN_PARAM_WRTSHELL, false ))
+ pActShell = pShell = static_cast<SwWrtShell*>(pShellItem->GetValue());
+
+ if( nSlot == SID_STYLE_UPDATE_BY_EXAMPLE && aParam.isEmpty() )
+ {
+ switch( nFamily )
+ {
+ case SfxStyleFamily::Para:
+ {
+ SwTextFormatColl* pColl = pShell->GetCurTextFormatColl();
+ if(pColl)
+ aParam = pColl->GetName();
+ }
+ break;
+ case SfxStyleFamily::Frame:
+ {
+ SwFrameFormat* pFrame = m_pWrtShell->GetSelectedFrameFormat();
+ if( pFrame )
+ aParam = pFrame->GetName();
+ }
+ break;
+ case SfxStyleFamily::Char:
+ {
+ SwCharFormat* pChar = m_pWrtShell->GetCurCharFormat();
+ if( pChar )
+ aParam = pChar->GetName();
+ }
+ break;
+ case SfxStyleFamily::Pseudo:
+ if(const SfxStringItem* pExName = pArgs->GetItemIfSet(SID_STYLE_UPD_BY_EX_NAME, false))
+ {
+ aParam = pExName->GetValue();
+ }
+ break;
+ case SfxStyleFamily::Table:
+ if(const SfxStringItem* pExName = pArgs->GetItemIfSet(SID_STYLE_UPD_BY_EX_NAME, false))
+ {
+ aParam = pExName->GetValue();
+ }
+ break;
+ default: break;
+ }
+ rReq.AppendItem(SfxStringItem(nSlot, aParam));
+ }
+ }
+ if (!aParam.isEmpty() || nSlot == SID_STYLE_WATERCAN )
+ {
+ sal_uInt16 nRet = 0xffff;
+ bool bReturns = false;
+
+ switch(nSlot)
+ {
+ case SID_STYLE_EDIT:
+ case SID_STYLE_FONT:
+ Edit(rReq.GetFrameWeld(), aParam, {}, nFamily, nMask, false, (nSlot == SID_STYLE_FONT) ? "font" : OUString(), pActShell);
+ break;
+ case SID_STYLE_DELETE:
+ Delete(aParam, nFamily);
+ break;
+ case SID_STYLE_HIDE:
+ case SID_STYLE_SHOW:
+ Hide(aParam, nFamily, nSlot == SID_STYLE_HIDE);
+ break;
+ case SID_STYLE_APPLY:
+ // Shell-switch in ApplyStyles
+ nRet = static_cast<sal_uInt16>(ApplyStyles(aParam, nFamily, pActShell, rReq.GetModifier() ));
+ bReturns = true;
+ break;
+ case SID_STYLE_WATERCAN:
+ nRet = static_cast<sal_uInt16>(DoWaterCan(aParam, nFamily));
+ bReturns = true;
+ break;
+ case SID_STYLE_UPDATE_BY_EXAMPLE:
+ UpdateStyle(aParam, nFamily, pActShell);
+ break;
+ case SID_STYLE_NEW_BY_EXAMPLE:
+ MakeByExample(aParam, nFamily, nMask, pActShell);
+ break;
+
+ default:
+ OSL_FAIL("Invalid SlotId");
+ }
+
+ // Update formatting toolbar buttons status
+ if (GetWrtShell()->GetSelectionType() == SelectionType::PostIt)
+ GetView()->GetViewFrame().GetBindings().InvalidateAll(false);
+
+ if (bReturns)
+ {
+ if(rReq.IsAPI()) // Basic only gets TRUE or FALSE
+ rReq.SetReturnValue(SfxUInt16Item(nSlot, sal_uInt16(nRet !=0)));
+ else
+ rReq.SetReturnValue(SfxUInt16Item(nSlot, nRet));
+ }
+
+ rReq.Done();
+ }
+
+ break;
+ }
+ }
+}
+
+namespace {
+
+class ApplyStyle
+{
+public:
+ ApplyStyle(SwDocShell &rDocSh, bool bNew,
+ rtl::Reference< SwDocStyleSheet > xTmp,
+ SfxStyleFamily nFamily, SfxAbstractApplyTabDialog *pDlg,
+ rtl::Reference< SfxStyleSheetBasePool > xBasePool,
+ bool bModified)
+ : m_pDlg(pDlg)
+ , m_rDocSh(rDocSh)
+ , m_bNew(bNew)
+ , m_xTmp(std::move(xTmp))
+ , m_nFamily(nFamily)
+ , m_xBasePool(std::move(xBasePool))
+ , m_bModified(bModified)
+ {
+ }
+ DECL_LINK( ApplyHdl, LinkParamNone*, void );
+ void apply()
+ {
+ ApplyHdl(nullptr);
+ }
+ VclPtr<SfxAbstractApplyTabDialog> m_pDlg;
+ // true if the document was initially modified before ApplyStyle was created
+ // or if ApplyStyle:::apply was called
+ bool DocIsModified() const
+ {
+ return m_bModified;
+ }
+private:
+ SwDocShell &m_rDocSh;
+ bool m_bNew;
+ rtl::Reference< SwDocStyleSheet > m_xTmp;
+ SfxStyleFamily m_nFamily;
+ rtl::Reference< SfxStyleSheetBasePool > m_xBasePool;
+ bool m_bModified;
+};
+
+}
+
+IMPL_LINK_NOARG(ApplyStyle, ApplyHdl, LinkParamNone*, void)
+{
+ SwWrtShell* pWrtShell = m_rDocSh.GetWrtShell();
+ SwDoc* pDoc = m_rDocSh.GetDoc();
+ SwView* pView = m_rDocSh.GetView();
+
+ pWrtShell->StartAllAction();
+
+ if( SfxStyleFamily::Para == m_nFamily )
+ {
+ SfxItemSet aSet( *m_pDlg->GetOutputItemSet() );
+ ::ConvertAttrGenToChar(aSet, m_xTmp->GetItemSet(), /*bIsPara=*/true);
+ ::SfxToSwPageDescAttr( *pWrtShell, aSet );
+ // reset indent attributes at paragraph style, if a list style
+ // will be applied and no indent attributes will be applied.
+ m_xTmp->SetItemSet( aSet, false, true );
+ }
+ else
+ {
+ if(SfxStyleFamily::Page == m_nFamily || SfxStyleFamily::Frame == m_nFamily)
+ {
+ static const sal_uInt16 aInval[] = {
+ SID_IMAGE_ORIENTATION,
+ SID_ATTR_CHAR_FONT,
+ FN_INSERT_CTRL, FN_INSERT_OBJ_CTRL,
+ FN_TABLE_INSERT_COL_BEFORE,
+ FN_TABLE_INSERT_COL_AFTER, 0};
+ pView->GetViewFrame().GetBindings().Invalidate(aInval);
+ }
+ SfxItemSet aTmpSet( *m_pDlg->GetOutputItemSet() );
+ if( SfxStyleFamily::Char == m_nFamily )
+ {
+ ::ConvertAttrGenToChar(aTmpSet, m_xTmp->GetItemSet());
+ }
+
+ m_xTmp->SetItemSet( aTmpSet, false );
+
+ if( SfxStyleFamily::Page == m_nFamily && SvtCTLOptions::IsCTLFontEnabled() )
+ {
+ const SfxPoolItem *pItem = nullptr;
+ if( aTmpSet.GetItemState( m_rDocSh.GetPool().GetTrueWhich( SID_ATTR_FRAMEDIRECTION, false ) , true, &pItem ) == SfxItemState::SET )
+ SwChartHelper::DoUpdateAllCharts( pDoc );
+ }
+
+ if (m_nFamily == SfxStyleFamily::Page)
+ {
+ if (const SfxGrabBagItem* pGrabBagItem = aTmpSet.GetItemIfSet(SID_ATTR_CHAR_GRABBAG))
+ {
+ bool bGutterAtTop{};
+ auto it = pGrabBagItem->GetGrabBag().find("GutterAtTop");
+ if (it != pGrabBagItem->GetGrabBag().end())
+ {
+ it->second >>= bGutterAtTop;
+ }
+ bool bOldGutterAtTop
+ = pDoc->getIDocumentSettingAccess().get(DocumentSettingId::GUTTER_AT_TOP);
+ if (bOldGutterAtTop != bGutterAtTop)
+ {
+ pDoc->getIDocumentSettingAccess().set(DocumentSettingId::GUTTER_AT_TOP,
+ bGutterAtTop);
+ pWrtShell->InvalidateLayout(/*bSizeChanged=*/true);
+ }
+ }
+ }
+
+ if (m_nFamily == SfxStyleFamily::Frame)
+ {
+ if (const SfxBoolItem* pBoolItem = aTmpSet.GetItemIfSet(FN_KEEP_ASPECT_RATIO))
+ {
+ const SwViewOption* pVOpt = pWrtShell->GetViewOptions();
+ SwViewOption aUsrPref(*pVOpt);
+ aUsrPref.SetKeepRatio(pBoolItem->GetValue());
+ if (pBoolItem->GetValue() != pVOpt->IsKeepRatio())
+ {
+ SW_MOD()->ApplyUsrPref(aUsrPref, &pWrtShell->GetView());
+ }
+ }
+ }
+ }
+
+ if(m_bNew)
+ {
+ if(SfxStyleFamily::Frame == m_nFamily || SfxStyleFamily::Para == m_nFamily)
+ {
+ // clear FillStyle so that it works as a derived attribute
+ SfxItemSet aTmpSet(*m_pDlg->GetOutputItemSet());
+
+ aTmpSet.ClearItem(XATTR_FILLSTYLE);
+ m_xTmp->SetItemSet(aTmpSet, false);
+ }
+ }
+
+ if(SfxStyleFamily::Page == m_nFamily)
+ pView->InvalidateRulerPos();
+
+ if( m_bNew )
+ m_xBasePool->Broadcast(SfxStyleSheetHint(SfxHintId::StyleSheetCreated, *m_xTmp));
+ else
+ m_xBasePool->Broadcast(SfxStyleSheetHint(SfxHintId::StyleSheetModified, *m_xTmp));
+
+ pDoc->getIDocumentState().SetModified();
+ if( !m_bModified )
+ {
+ pDoc->GetIDocumentUndoRedo().SetUndoNoResetModified();
+ m_bModified = true;
+ }
+
+ pWrtShell->EndAllAction();
+}
+
+namespace
+{
+/// Checks if there is an Endnote page style in use, and makes sure it has the same orientation
+/// with the Default (Standard) page style.
+void syncEndnoteOrientation(const uno::Reference< style::XStyleFamiliesSupplier >& xStyleFamSupp)
+{
+ if (!xStyleFamSupp.is())
+ {
+ SAL_WARN("sw.ui", "Ref to XStyleFamiliesSupplier is null.");
+ return;
+ }
+ uno::Reference<container::XNameAccess> xStyleFamilies = xStyleFamSupp->getStyleFamilies();
+
+ if (!xStyleFamilies.is())
+ return;
+
+ uno::Reference<container::XNameAccess> xPageStyles(xStyleFamilies->getByName("PageStyles"),
+ uno::UNO_QUERY);
+
+ if (!xPageStyles.is())
+ return;
+
+ uno::Reference<css::style::XStyle> xEndnotePageStyle(xPageStyles->getByName("Endnote"),
+ uno::UNO_QUERY);
+
+ if (!xEndnotePageStyle.is())
+ return;
+
+ // Language-independent name of the "Default Style" is "Standard"
+ uno::Reference<css::style::XStyle> xDefaultPageStyle(xPageStyles->getByName("Standard"),
+ uno::UNO_QUERY);
+ if (!xDefaultPageStyle.is())
+ return;
+
+ if (xEndnotePageStyle->isUserDefined() || !xEndnotePageStyle->isInUse())
+ return;
+
+ uno::Reference<beans::XPropertySet> xEndnotePagePropSet(xPageStyles->getByName("Endnote"), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xDefaultPagePropSet(xPageStyles->getByName("Standard"), uno::UNO_QUERY);
+
+ if (!xEndnotePagePropSet.is() || !xDefaultPagePropSet.is())
+ {
+ SAL_WARN("sw.ui", "xEndnotePagePropSet or xDefaultPagePropSet is null.");
+ return;
+ }
+
+ auto const bIsDefLandScape = *o3tl::doAccess<bool>(
+ xDefaultPagePropSet->getPropertyValue("IsLandscape"));
+ auto const bIsEndLandScape = *o3tl::doAccess<bool>(
+ xEndnotePagePropSet->getPropertyValue("IsLandscape"));
+
+ if (bIsDefLandScape == bIsEndLandScape)
+ return;
+
+ auto const nWidth = xEndnotePagePropSet->getPropertyValue("Width");
+ auto const nHeight = xEndnotePagePropSet->getPropertyValue("Height");
+
+ xEndnotePagePropSet->setPropertyValue("IsLandscape", css::uno::toAny(bIsDefLandScape));
+ xEndnotePagePropSet->setPropertyValue("Width", nHeight);
+ xEndnotePagePropSet->setPropertyValue("Height", nWidth);
+}
+}
+
+void SwDocShell::Edit(
+ weld::Window* pDialogParent,
+ const OUString &rName,
+ const OUString &rParent,
+ const SfxStyleFamily nFamily,
+ SfxStyleSearchBits nMask,
+ const bool bNew,
+ const OUString& sPage,
+ SwWrtShell* pActShell,
+ SfxRequest* pReq,
+ sal_uInt16 nSlot)
+{
+ assert( GetWrtShell() );
+ const bool bBasic = pReq && pReq->IsAPI();
+ SfxStyleSheetBase *pStyle = nullptr;
+
+ bool bModified = m_xDoc->getIDocumentState().IsModified();
+
+ SwUndoId nNewStyleUndoId(SwUndoId::EMPTY);
+
+ if( bNew )
+ {
+ if (!bBasic)
+ {
+ // start undo action in order to get only one undo action for the
+ // UI new style + change style operations
+ m_pWrtShell->StartUndo();
+ }
+
+ if( SfxStyleSearchBits::All != nMask && SfxStyleSearchBits::AllVisible != nMask && SfxStyleSearchBits::Used != nMask )
+ nMask |= SfxStyleSearchBits::UserDefined;
+ else
+ nMask = SfxStyleSearchBits::UserDefined;
+
+ if ( nFamily == SfxStyleFamily::Para || nFamily == SfxStyleFamily::Char || nFamily == SfxStyleFamily::Frame )
+ {
+ // Prevent undo append from being done during paragraph, character, and frame style Make
+ // Do it after ok return from style dialog when derived from style is known
+ ::sw::UndoGuard const undoGuard(GetDoc()->GetIDocumentUndoRedo());
+ pStyle = &m_xBasePool->Make( rName, nFamily, nMask );
+ }
+ else
+ {
+ pStyle = &m_xBasePool->Make( rName, nFamily, nMask );
+ }
+
+ // set the current one as Parent
+ SwDocStyleSheet* pDStyle = static_cast<SwDocStyleSheet*>(pStyle);
+ switch( nFamily )
+ {
+ case SfxStyleFamily::Para:
+ {
+ if(!rParent.isEmpty())
+ {
+ SwTextFormatColl* pColl = m_pWrtShell->FindTextFormatCollByName( rParent );
+ if(!pColl)
+ {
+ sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(rParent, SwGetPoolIdFromName::TxtColl);
+ if(USHRT_MAX != nId)
+ pColl = m_pWrtShell->GetTextCollFromPool( nId );
+ }
+ pDStyle->GetCollection()->SetDerivedFrom( pColl );
+ pDStyle->PresetParent( rParent );
+ }
+ else
+ {
+ SwTextFormatColl* pColl = m_pWrtShell->GetCurTextFormatColl();
+ pDStyle->GetCollection()->SetDerivedFrom( pColl );
+ if( pColl )
+ pDStyle->PresetParent( pColl->GetName() );
+ }
+ }
+ break;
+ case SfxStyleFamily::Char:
+ {
+ if(!rParent.isEmpty())
+ {
+ SwCharFormat* pCFormat = m_pWrtShell->FindCharFormatByName(rParent);
+ if(!pCFormat)
+ {
+ sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(rParent, SwGetPoolIdFromName::ChrFmt);
+ if(USHRT_MAX != nId)
+ pCFormat = m_pWrtShell->GetCharFormatFromPool( nId );
+ }
+
+ pDStyle->GetCharFormat()->SetDerivedFrom( pCFormat );
+ pDStyle->PresetParent( rParent );
+ }
+ else
+ {
+ SwCharFormat* pCFormat = m_pWrtShell->GetCurCharFormat();
+ pDStyle->GetCharFormat()->SetDerivedFrom( pCFormat );
+ if( pCFormat )
+ pDStyle->PresetParent( pCFormat->GetName() );
+ }
+ }
+ break;
+ case SfxStyleFamily::Frame :
+ {
+ if(!rParent.isEmpty())
+ {
+ SwFrameFormat* pFFormat = m_pWrtShell->GetDoc()->FindFrameFormatByName( rParent );
+ if(!pFFormat)
+ {
+ sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(rParent, SwGetPoolIdFromName::FrmFmt);
+ if(USHRT_MAX != nId)
+ pFFormat = m_pWrtShell->GetFrameFormatFromPool( nId );
+ }
+ pDStyle->GetFrameFormat()->SetDerivedFrom( pFFormat );
+ pDStyle->PresetParent( rParent );
+ }
+ }
+ break;
+ default: break;
+ }
+
+ if (!bBasic)
+ {
+ //Get the undo id for the type of style that was created in order to re-use that comment for the grouped
+ //create style + change style operations
+ m_pWrtShell->GetLastUndoInfo(nullptr, &nNewStyleUndoId);
+ }
+ }
+ else
+ {
+ pStyle = m_xBasePool->Find( rName, nFamily );
+ SAL_WARN_IF( !pStyle, "sw.ui", "Style not found" );
+ }
+
+ if(!pStyle)
+ return;
+
+ // put dialogues together
+ rtl::Reference< SwDocStyleSheet > xTmp( new SwDocStyleSheet( *static_cast<SwDocStyleSheet*>(pStyle) ) );
+ if( SfxStyleFamily::Para == nFamily )
+ {
+ SfxItemSet& rSet = xTmp->GetItemSet();
+ ::SwToSfxPageDescAttr( rSet );
+ // merge list level indent attributes into the item set if needed
+ xTmp->MergeIndentAttrsOfListStyle( rSet );
+
+ ::ConvertAttrCharToGen(xTmp->GetItemSet(), /*bIsPara=*/true);
+ }
+ else if( SfxStyleFamily::Char == nFamily )
+ {
+ ::ConvertAttrCharToGen(xTmp->GetItemSet());
+ }
+
+ if(SfxStyleFamily::Page == nFamily || SfxStyleFamily::Para == nFamily)
+ {
+ // create needed items for XPropertyList entries from the DrawModel so that
+ // the Area TabPage can access them
+ SfxItemSet& rSet = xTmp->GetItemSet();
+ const SwDrawModel* pDrawModel = GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
+
+ rSet.Put(SvxColorListItem(pDrawModel->GetColorList(), SID_COLOR_TABLE));
+ rSet.Put(SvxGradientListItem(pDrawModel->GetGradientList(), SID_GRADIENT_LIST));
+ rSet.Put(SvxHatchListItem(pDrawModel->GetHatchList(), SID_HATCH_LIST));
+ rSet.Put(SvxBitmapListItem(pDrawModel->GetBitmapList(), SID_BITMAP_LIST));
+ rSet.Put(SvxPatternListItem(pDrawModel->GetPatternList(), SID_PATTERN_LIST));
+
+ std::optional<SfxGrabBagItem> oGrabBag;
+ if (SfxGrabBagItem const* pItem = rSet.GetItemIfSet(SID_ATTR_CHAR_GRABBAG))
+ {
+ oGrabBag.emplace(*pItem);
+ }
+ else
+ {
+ oGrabBag.emplace(SID_ATTR_CHAR_GRABBAG);
+ }
+ bool bGutterAtTop
+ = GetDoc()->getIDocumentSettingAccess().get(DocumentSettingId::GUTTER_AT_TOP);
+ oGrabBag->GetGrabBag()["GutterAtTop"] <<= bGutterAtTop;
+ rSet.Put(*oGrabBag);
+ }
+
+ SwWrtShell* pCurrShell = pActShell ? pActShell : m_pWrtShell;
+ if (nFamily == SfxStyleFamily::Frame)
+ {
+ SfxItemSet& rSet = xTmp->GetItemSet();
+ const SwViewOption* pVOpt = pCurrShell->GetViewOptions();
+ rSet.Put(SfxBoolItem(FN_KEEP_ASPECT_RATIO, pVOpt->IsKeepRatio()));
+ }
+
+ if (!bBasic)
+ {
+ // prior to the dialog the HtmlMode at the DocShell is being sunk
+ sal_uInt16 nHtmlMode = ::GetHtmlMode(this);
+
+ // In HTML mode, we do not always have a printer. In order to show
+ // the correct page size in the Format - Page dialog, we have to
+ // get one here.
+ if( ( HTMLMODE_ON & nHtmlMode ) &&
+ !pCurrShell->getIDocumentDeviceAccess().getPrinter( false ) )
+ pCurrShell->InitPrt( pCurrShell->getIDocumentDeviceAccess().getPrinter( true ) );
+
+ PutItem(SfxUInt16Item(SID_HTML_MODE, nHtmlMode));
+ FieldUnit eMetric = ::GetDfltMetric(0 != (HTMLMODE_ON&nHtmlMode));
+ SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)));
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ if (!pDialogParent)
+ {
+ SAL_WARN("sw.ui", "no parent for dialog supplied, assuming document frame is good enough");
+ pDialogParent = GetView()->GetFrameWeld();
+ }
+ VclPtr<SfxAbstractApplyTabDialog> pDlg(pFact->CreateTemplateDialog(pDialogParent,
+ *xTmp, nFamily, sPage, pCurrShell, bNew));
+ auto pApplyStyleHelper = std::make_shared<ApplyStyle>(*this, bNew, xTmp, nFamily, pDlg.get(), m_xBasePool, bModified);
+ pDlg->SetApplyHdl(LINK(pApplyStyleHelper.get(), ApplyStyle, ApplyHdl));
+
+ std::shared_ptr<SfxRequest> pRequest;
+ if (pReq)
+ {
+ pRequest = std::make_shared<SfxRequest>(*pReq);
+ pReq->Ignore(); // the 'old' request is not relevant any more
+ }
+
+ bool bIsDefaultPage = nFamily == SfxStyleFamily::Page
+ && rName == SwResId(STR_POOLPAGE_STANDARD)
+ && pStyle->IsUsed()
+ && !pStyle->IsUserDefined();
+
+ pDlg->StartExecuteAsync([bIsDefaultPage, bNew, nFamily, nSlot, nNewStyleUndoId, pApplyStyleHelper, pRequest, xTmp, this](sal_Int32 nResult){
+ if (RET_OK == nResult)
+ pApplyStyleHelper->apply();
+
+ if (bNew)
+ {
+ switch( nFamily )
+ {
+ case SfxStyleFamily::Para:
+ {
+ if(!xTmp->GetParent().isEmpty())
+ {
+ SwTextFormatColl* pColl = m_pWrtShell->FindTextFormatCollByName(xTmp->GetParent());
+ if (GetDoc()->GetIDocumentUndoRedo().DoesUndo())
+ {
+ GetDoc()->GetIDocumentUndoRedo().AppendUndo(
+ std::make_unique<SwUndoTextFormatCollCreate>(xTmp->GetCollection(), pColl, *GetDoc()));
+ }
+ }
+ }
+ break;
+ case SfxStyleFamily::Char:
+ {
+ if(!xTmp->GetParent().isEmpty())
+ {
+ SwCharFormat* pCFormat = m_pWrtShell->FindCharFormatByName(xTmp->GetParent());
+ if (GetDoc()->GetIDocumentUndoRedo().DoesUndo())
+ {
+ GetDoc()->GetIDocumentUndoRedo().AppendUndo(
+ std::make_unique<SwUndoCharFormatCreate>(xTmp->GetCharFormat(), pCFormat, *GetDoc()));
+ }
+ }
+ }
+ break;
+ case SfxStyleFamily::Frame:
+ {
+ if(!xTmp->GetParent().isEmpty())
+ {
+ SwFrameFormat* pFFormat = m_pWrtShell->GetDoc()->FindFrameFormatByName(xTmp->GetParent());
+ if (GetDoc()->GetIDocumentUndoRedo().DoesUndo())
+ {
+ GetDoc()->GetIDocumentUndoRedo().AppendUndo(
+ std::make_unique<SwUndoFrameFormatCreate>(xTmp->GetFrameFormat(), pFFormat, *GetDoc()));
+ }
+ }
+ }
+ break;
+ default: break;
+ }
+
+ SwRewriter aRewriter;
+ aRewriter.AddRule(UndoArg1, xTmp->GetName());
+ //Group the create style and change style operations together under the
+ //one "create style" comment
+ m_pWrtShell->EndUndo(nNewStyleUndoId, &aRewriter);
+ }
+
+ bool bDocModified = pApplyStyleHelper->DocIsModified();
+
+ if (RET_OK != nResult)
+ {
+ if (bNew)
+ {
+ GetWrtShell()->Undo();
+ m_xDoc->GetIDocumentUndoRedo().ClearRedo();
+ }
+
+ if (!bDocModified)
+ m_xDoc->getIDocumentState().ResetModified();
+ }
+
+ // Update Watermark if new page style was created
+ if (nSlot == SID_STYLE_NEW && nFamily == SfxStyleFamily::Page)
+ {
+ SwWrtShell* pShell = GetWrtShell();
+ const SfxWatermarkItem aWatermark = pShell->GetWatermark();
+ pShell->SetWatermark(aWatermark);
+ }
+
+ pApplyStyleHelper->m_pDlg.disposeAndClear();
+ if (pRequest)
+ pRequest->Done();
+
+ if (bIsDefaultPage && bDocModified)
+ {
+ uno::Reference< style::XStyleFamiliesSupplier > xStyleFamSupp(GetModel(), uno::UNO_QUERY);
+
+ if (!xStyleFamSupp.is())
+ {
+ SAL_WARN("sw.ui", "Ref to XStyleFamiliesSupplier is null.");
+ return;
+ }
+
+ syncEndnoteOrientation(xStyleFamSupp);
+ }
+ });
+ }
+ else
+ {
+ // prior to the dialog the HtmlMode at the DocShell is being sunk
+ PutItem(SfxUInt16Item(SID_HTML_MODE, ::GetHtmlMode(this)));
+
+ GetWrtShell()->StartAllAction();
+
+ if( SfxStyleFamily::Para == nFamily )
+ {
+ ::SfxToSwPageDescAttr( *GetWrtShell(), xTmp->GetItemSet() );
+ ::ConvertAttrGenToChar(xTmp->GetItemSet(), xTmp->GetItemSet(), /*bIsPara=*/true);
+ }
+ else
+ {
+ ::ConvertAttrGenToChar(xTmp->GetItemSet(), xTmp->GetItemSet());
+ }
+ if(SfxStyleFamily::Page == nFamily)
+ m_pView->InvalidateRulerPos();
+
+ if( bNew )
+ m_xBasePool->Broadcast(SfxStyleSheetHint(SfxHintId::StyleSheetCreated, *xTmp));
+
+ m_xDoc->getIDocumentState().SetModified();
+ if( !bModified ) // Bug 57028
+ {
+ m_xDoc->GetIDocumentUndoRedo().SetUndoNoResetModified();
+ }
+ GetWrtShell()->EndAllAction();
+ }
+}
+
+void SwDocShell::Delete(const OUString &rName, SfxStyleFamily nFamily)
+{
+ SfxStyleSheetBase *pStyle = m_xBasePool->Find(rName, nFamily);
+
+ if(pStyle)
+ {
+ assert( GetWrtShell() );
+
+ GetWrtShell()->StartAllAction();
+ m_xBasePool->Remove(pStyle);
+ GetWrtShell()->EndAllAction();
+ }
+}
+
+void SwDocShell::Hide(const OUString &rName, SfxStyleFamily nFamily, bool bHidden)
+{
+ SfxStyleSheetBase *pStyle = m_xBasePool->Find(rName, nFamily);
+
+ if(pStyle)
+ {
+ assert( GetWrtShell() );
+
+ GetWrtShell()->StartAllAction();
+ rtl::Reference< SwDocStyleSheet > xTmp( new SwDocStyleSheet( *static_cast<SwDocStyleSheet*>(pStyle) ) );
+ xTmp->SetHidden( bHidden );
+ GetWrtShell()->EndAllAction();
+ }
+}
+
+// apply template
+SfxStyleFamily SwDocShell::ApplyStyles(const OUString &rName, SfxStyleFamily nFamily,
+ SwWrtShell* pShell, const sal_uInt16 nMode )
+{
+ SwDocStyleSheet* pStyle = static_cast<SwDocStyleSheet*>( m_xBasePool->Find( rName, nFamily ) );
+
+ SAL_WARN_IF( !pStyle, "sw.ui", "Style not found" );
+
+ if(!pStyle)
+ return SfxStyleFamily::None;
+
+ SwWrtShell *pSh = pShell ? pShell : GetWrtShell();
+
+ assert( pSh );
+
+ pSh->StartAllAction();
+
+ switch (nFamily)
+ {
+ case SfxStyleFamily::Char:
+ {
+ SwFormatCharFormat aFormat(pStyle->GetCharFormat());
+ pSh->SetAttrItem( aFormat, (nMode & KEY_SHIFT) ?
+ SetAttrMode::DONTREPLACE : SetAttrMode::DEFAULT );
+ break;
+ }
+ case SfxStyleFamily::Para:
+ {
+ if (pSh->GetPostItMgr() && pSh->GetPostItMgr()->HasActiveSidebarWin())
+ {
+ pSh->GetPostItMgr()->GetActiveSidebarWin()->GetOutlinerView()->SetStyleSheet(rName);
+ }
+ else
+ {
+ // When outline-folding is enabled, MakeAllOutlineContentTemporarilyVisible makes
+ // application of a paragraph style that has an outline-level greater than the previous
+ // outline node become folded content of the previous outline node if the previous
+ // outline node's content is folded.
+ MakeAllOutlineContentTemporarilyVisible a(GetDoc());
+ // #i62675#
+ // clear also list attributes at affected text nodes, if paragraph
+ // style has the list style attribute set.
+ pSh->SetTextFormatColl( pStyle->GetCollection(), true );
+ }
+ break;
+ }
+ case SfxStyleFamily::Frame:
+ {
+ if ( pSh->IsFrameSelected() )
+ pSh->SetFrameFormat( pStyle->GetFrameFormat() );
+ break;
+ }
+ case SfxStyleFamily::Page:
+ {
+ pSh->SetPageStyle(pStyle->GetPageDesc()->GetName());
+ break;
+ }
+ case SfxStyleFamily::Pseudo:
+ {
+ // reset indent attribute on applying list style
+ // continue list of list style
+ const SwNumRule* pNumRule = pStyle->GetNumRule();
+ if (pNumRule->GetName() == SwResId(STR_POOLNUMRULE_NOLIST))
+ {
+ if (SfxViewFrame* pViewFrm = SfxViewFrame::Current())
+ pViewFrm->GetDispatcher()->Execute(FN_NUM_BULLET_OFF);
+ break;
+ }
+ const OUString sListIdForStyle =pNumRule->GetDefaultListId();
+ pSh->SetCurNumRule( *pNumRule, false, sListIdForStyle, true );
+ break;
+ }
+ case SfxStyleFamily::Table:
+ {
+ pSh->SetTableStyle(pStyle->GetName());
+ break;
+ }
+ default:
+ OSL_FAIL("Unknown family");
+ }
+ pSh->EndAllAction();
+
+ return nFamily;
+}
+
+// start watering-can
+SfxStyleFamily SwDocShell::DoWaterCan(const OUString &rName, SfxStyleFamily nFamily)
+{
+ assert( GetWrtShell() );
+
+ SwEditWin& rEdtWin = m_pView->GetEditWin();
+ SwApplyTemplate* pApply = rEdtWin.GetApplyTemplate();
+ bool bWaterCan = !(pApply && pApply->eType != SfxStyleFamily(0));
+
+ if( rName.isEmpty() )
+ bWaterCan = false;
+
+ SwApplyTemplate aTemplate;
+ aTemplate.eType = nFamily;
+
+ if(bWaterCan)
+ {
+ SwDocStyleSheet* pStyle =
+ static_cast<SwDocStyleSheet*>( m_xBasePool->Find(rName, nFamily) );
+
+ SAL_WARN_IF( !pStyle, "sw.ui", "Where's the StyleSheet" );
+
+ if(!pStyle) return nFamily;
+
+ switch(nFamily)
+ {
+ case SfxStyleFamily::Char:
+ aTemplate.aColl.pCharFormat = pStyle->GetCharFormat();
+ break;
+ case SfxStyleFamily::Para:
+ aTemplate.aColl.pTextColl = pStyle->GetCollection();
+ break;
+ case SfxStyleFamily::Frame:
+ aTemplate.aColl.pFrameFormat = pStyle->GetFrameFormat();
+ break;
+ case SfxStyleFamily::Page:
+ aTemplate.aColl.pPageDesc = const_cast<SwPageDesc*>(pStyle->GetPageDesc());
+ break;
+ case SfxStyleFamily::Pseudo:
+ aTemplate.aColl.pNumRule = const_cast<SwNumRule*>(pStyle->GetNumRule());
+ break;
+
+ default:
+ OSL_FAIL("Unknown family");
+ }
+ }
+ else
+ aTemplate.eType = SfxStyleFamily(0);
+
+ m_pView->GetEditWin().SetApplyTemplate(aTemplate);
+
+ return nFamily;
+}
+
+// update template
+void SwDocShell::UpdateStyle(const OUString &rName, SfxStyleFamily nFamily, SwWrtShell* pShell)
+{
+ SwWrtShell* pCurrWrtShell = pShell ? pShell : GetWrtShell();
+ assert( pCurrWrtShell );
+
+ SwDocStyleSheet* pStyle =
+ static_cast<SwDocStyleSheet*>( m_xBasePool->Find(rName, nFamily) );
+
+ if (!pStyle)
+ return;
+
+ switch(nFamily)
+ {
+ case SfxStyleFamily::Para:
+ {
+ SwTextFormatColl* pColl = pStyle->GetCollection();
+ if(pColl && !pColl->IsDefault())
+ {
+ GetWrtShell()->StartAllAction();
+
+ SwRewriter aRewriter;
+ aRewriter.AddRule(UndoArg1, pColl->GetName());
+
+ GetWrtShell()->StartUndo(SwUndoId::INSFMTATTR, &aRewriter);
+ GetWrtShell()->FillByEx(pColl);
+ // also apply template to remove hard set attributes
+ GetWrtShell()->SetTextFormatColl( pColl );
+ GetWrtShell()->EndUndo();
+ GetWrtShell()->EndAllAction();
+ }
+ break;
+ }
+ case SfxStyleFamily::Frame:
+ {
+ SwFrameFormat* pFrame = pStyle->GetFrameFormat();
+ if( pCurrWrtShell->IsFrameSelected() && pFrame && !pFrame->IsDefault() )
+ {
+ SfxItemSet aSet( GetPool(), aFrameFormatSetRange );
+ pCurrWrtShell->StartAllAction();
+ pCurrWrtShell->GetFlyFrameAttr( aSet );
+
+ // #i105535#
+ // no update of anchor attribute
+ aSet.ClearItem( RES_ANCHOR );
+
+ pFrame->SetFormatAttr( aSet );
+
+ // also apply template to remove hard set attributes
+ pCurrWrtShell->SetFrameFormat( pFrame, true );
+ pCurrWrtShell->EndAllAction();
+ }
+ }
+ break;
+ case SfxStyleFamily::Char:
+ {
+ SwCharFormat* pChar = pStyle->GetCharFormat();
+ if( pChar && !pChar->IsDefault() )
+ {
+ pCurrWrtShell->StartAllAction();
+ pCurrWrtShell->FillByEx(pChar);
+ // also apply template to remove hard set attributes
+ pCurrWrtShell->EndAllAction();
+ }
+
+ }
+ break;
+ case SfxStyleFamily::Pseudo:
+ {
+ const SwNumRule* pCurRule;
+ if( pStyle->GetNumRule() &&
+ nullptr != ( pCurRule = pCurrWrtShell->GetNumRuleAtCurrCursorPos() ))
+ {
+ SwNumRule aRule( *pCurRule );
+ // #i91400#
+ aRule.SetName( pStyle->GetNumRule()->GetName(),
+ pCurrWrtShell->GetDoc()->getIDocumentListsAccess() );
+ pCurrWrtShell->ChgNumRuleFormats( aRule );
+ }
+ }
+ break;
+ case SfxStyleFamily::Table:
+ {
+ if (SwFEShell* pFEShell = GetFEShell())
+ {
+ if(pFEShell->IsTableMode())
+ {
+ pFEShell->TableCursorToCursor();
+ }
+ }
+ SwTableAutoFormat aFormat(rName);
+ if (pCurrWrtShell->GetTableAutoFormat(aFormat))
+ {
+ pCurrWrtShell->StartAllAction();
+ pCurrWrtShell->GetDoc()->ChgTableStyle(rName, aFormat);
+ pCurrWrtShell->EndAllAction();
+ }
+
+ }
+ break;
+ default: break;
+ }
+
+ m_xDoc->BroadcastStyleOperation(rName, nFamily, SfxHintId::StyleSheetModified);
+}
+
+// NewByExample
+void SwDocShell::MakeByExample( const OUString &rName, SfxStyleFamily nFamily,
+ SfxStyleSearchBits nMask, SwWrtShell* pShell )
+{
+ SwWrtShell* pCurrWrtShell = pShell ? pShell : GetWrtShell();
+ SwDocStyleSheet* pStyle = static_cast<SwDocStyleSheet*>( m_xBasePool->Find(
+ rName, nFamily ) );
+ if(!pStyle)
+ {
+ // preserve the current mask of PI, then the new one is
+ // immediately merged with the viewable area
+ if( SfxStyleSearchBits::All == nMask || SfxStyleSearchBits::Used == nMask )
+ nMask = SfxStyleSearchBits::UserDefined;
+ else
+ nMask |= SfxStyleSearchBits::UserDefined;
+
+ if (nFamily == SfxStyleFamily::Para || nFamily == SfxStyleFamily::Char || nFamily == SfxStyleFamily::Frame)
+ {
+ // Prevent undo append from being done during paragraph, character, and frame style Make. Do it later
+ ::sw::UndoGuard const undoGuard(GetDoc()->GetIDocumentUndoRedo());
+ pStyle = static_cast<SwDocStyleSheet*>(&m_xBasePool->Make(rName, nFamily, nMask));
+ }
+ else
+ {
+ pStyle = static_cast<SwDocStyleSheet*>(&m_xBasePool->Make(rName, nFamily, nMask));
+ }
+ }
+
+ switch(nFamily)
+ {
+ case SfxStyleFamily::Para:
+ {
+ SwTextFormatColl* pColl = pStyle->GetCollection();
+ if(pColl && !pColl->IsDefault())
+ {
+ pCurrWrtShell->StartAllAction();
+ pCurrWrtShell->FillByEx(pColl);
+ // also apply template to remove hard set attributes
+ SwTextFormatColl * pDerivedFrom = pCurrWrtShell->GetCurTextFormatColl();
+ pColl->SetDerivedFrom(pDerivedFrom);
+
+ // set the mask at the Collection:
+ sal_uInt16 nId = pColl->GetPoolFormatId() & 0x87ff;
+ switch( nMask & static_cast<SfxStyleSearchBits>(0x0fff) )
+ {
+ case SfxStyleSearchBits::SwText:
+ nId |= COLL_TEXT_BITS;
+ break;
+ case SfxStyleSearchBits::SwChapter:
+ nId |= COLL_DOC_BITS;
+ break;
+ case SfxStyleSearchBits::SwList:
+ nId |= COLL_LISTS_BITS;
+ break;
+ case SfxStyleSearchBits::SwIndex:
+ nId |= COLL_REGISTER_BITS;
+ break;
+ case SfxStyleSearchBits::SwExtra:
+ nId |= COLL_EXTRA_BITS;
+ break;
+ case SfxStyleSearchBits::SwHtml:
+ nId |= COLL_HTML_BITS;
+ break;
+ default: break;
+ }
+ pColl->SetPoolFormatId(nId);
+
+ if (GetDoc()->GetIDocumentUndoRedo().DoesUndo())
+ {
+ GetDoc()->GetIDocumentUndoRedo().AppendUndo(
+ std::make_unique<SwUndoTextFormatCollCreate>(pColl, pDerivedFrom, *GetDoc()));
+ }
+ pCurrWrtShell->SetTextFormatColl(pColl);
+ pCurrWrtShell->EndAllAction();
+ }
+ }
+ break;
+ case SfxStyleFamily::Frame:
+ {
+ SwFrameFormat* pFrame = pStyle->GetFrameFormat();
+ if(pCurrWrtShell->IsFrameSelected() && pFrame && !pFrame->IsDefault())
+ {
+ pCurrWrtShell->StartAllAction();
+
+ SfxItemSet aSet(GetPool(), aFrameFormatSetRange );
+ pCurrWrtShell->GetFlyFrameAttr( aSet );
+ aSet.ClearItem(RES_ANCHOR); // tdf#112574 no anchor in styles
+
+ SwFrameFormat* pFFormat = pCurrWrtShell->GetSelectedFrameFormat();
+ pFrame->SetDerivedFrom( pFFormat );
+ pFrame->SetFormatAttr( aSet );
+ if (GetDoc()->GetIDocumentUndoRedo().DoesUndo())
+ {
+ GetDoc()->GetIDocumentUndoRedo().AppendUndo(
+ std::make_unique<SwUndoFrameFormatCreate>(pFrame, pFFormat, *GetDoc()));
+ }
+ // also apply template to remove hard set attributes
+ pCurrWrtShell->SetFrameFormat(pFrame);
+ pCurrWrtShell->EndAllAction();
+ }
+ }
+ break;
+ case SfxStyleFamily::Char:
+ {
+ SwCharFormat* pChar = pStyle->GetCharFormat();
+ if(pChar && !pChar->IsDefault())
+ {
+ pCurrWrtShell->StartAllAction();
+ pCurrWrtShell->FillByEx( pChar );
+ SwCharFormat * pDerivedFrom = pCurrWrtShell->GetCurCharFormat();
+ pChar->SetDerivedFrom( pDerivedFrom );
+ SwFormatCharFormat aFormat( pChar );
+
+ if (GetDoc()->GetIDocumentUndoRedo().DoesUndo())
+ {
+ // Looks like sometimes pDerivedFrom can be null and this is not supported by redo code
+ // So use default format as a derived from in such situations
+ GetDoc()->GetIDocumentUndoRedo().AppendUndo(
+ std::make_unique<SwUndoCharFormatCreate>(
+ pChar, pDerivedFrom ? pDerivedFrom : GetDoc()->GetDfltCharFormat(),
+ *GetDoc()));
+ }
+ pCurrWrtShell->SetAttrItem(aFormat);
+ pCurrWrtShell->EndAllAction();
+ }
+ }
+ break;
+
+ case SfxStyleFamily::Page:
+ {
+ pCurrWrtShell->StartAllAction();
+ size_t nPgDsc = pCurrWrtShell->GetCurPageDesc();
+ SwPageDesc& rSrc = const_cast<SwPageDesc&>(pCurrWrtShell->GetPageDesc( nPgDsc ));
+ SwPageDesc& rDest = *const_cast<SwPageDesc*>(pStyle->GetPageDesc());
+
+ sal_uInt16 nPoolId = rDest.GetPoolFormatId();
+ sal_uInt16 nHId = rDest.GetPoolHelpId();
+ sal_uInt8 nHFId = rDest.GetPoolHlpFileId();
+
+ pCurrWrtShell->GetDoc()->CopyPageDesc( rSrc, rDest );
+
+ // PoolId must NEVER be copied!
+ rDest.SetPoolFormatId( nPoolId );
+ rDest.SetPoolHelpId( nHId );
+ rDest.SetPoolHlpFileId( nHFId );
+
+ // when Headers/Footers are created, there is no Undo anymore!
+ pCurrWrtShell->GetDoc()->GetIDocumentUndoRedo().DelAllUndoObj();
+
+ pCurrWrtShell->EndAllAction();
+ }
+ break;
+
+ case SfxStyleFamily::Pseudo:
+ {
+ const SwNumRule* pCurRule = pCurrWrtShell->GetNumRuleAtCurrCursorPos();
+
+ if (pCurRule)
+ {
+ pCurrWrtShell->StartAllAction();
+
+ SwNumRule aRule( *pCurRule );
+ OUString sOrigRule( aRule.GetName() );
+ // #i91400#
+ aRule.SetName( pStyle->GetNumRule()->GetName(),
+ pCurrWrtShell->GetDoc()->getIDocumentListsAccess() );
+ pCurrWrtShell->ChgNumRuleFormats( aRule );
+
+ pCurrWrtShell->ReplaceNumRule( sOrigRule, aRule.GetName() );
+
+ pCurrWrtShell->EndAllAction();
+ }
+ }
+ break;
+
+ case SfxStyleFamily::Table:
+ {
+ SwTableAutoFormat* pFormat = pStyle->GetTableFormat();
+ if (pCurrWrtShell->GetTableAutoFormat(*pFormat))
+ {
+ pCurrWrtShell->StartAllAction();
+
+ pCurrWrtShell->SetTableStyle(rName);
+
+ pCurrWrtShell->EndAllAction();
+ }
+ }
+ break;
+
+ default: break;
+ }
+
+ m_xDoc->BroadcastStyleOperation(rName, nFamily, SfxHintId::StyleSheetCreated);
+}
+
+sfx::AccessibilityIssueCollection SwDocShell::runAccessibilityCheck()
+{
+#if !ENABLE_WASM_STRIP_ACCESSIBILITY
+ sw::AccessibilityCheck aCheck(m_xDoc.get());
+ aCheck.check();
+ return aCheck.getIssueCollection();
+#else
+ return sfx::AccessibilityIssueCollection();
+#endif
+}
+
+std::set<Color> SwDocShell::GetDocColors()
+{
+ return m_xDoc->GetDocColors();
+}
+
+std::shared_ptr<model::ColorSet> SwDocShell::GetThemeColors()
+{
+ SdrModel* pModel = m_xDoc->getIDocumentDrawModelAccess().GetDrawModel();
+ if (!pModel)
+ return {};
+ auto const& pTheme = pModel->getTheme();
+ if (!pTheme)
+ return {};
+ return pTheme->getColorSet();
+}
+
+void SwDocShell::LoadStyles( SfxObjectShell& rSource )
+{
+ LoadStyles_(rSource, false);
+}
+
+// bPreserveCurrentDocument determines whether SetFixFields() is called
+// This call modifies the source document. This mustn't happen when the source
+// is a document the user is working on.
+// Calls of ::LoadStyles() normally use files especially loaded for the purpose
+// of importing styles.
+void SwDocShell::LoadStyles_( SfxObjectShell& rSource, bool bPreserveCurrentDocument )
+{
+/* [Description]
+
+ This method is called by SFx if Styles have to be reloaded from a
+ document-template. Existing Styles should be overwritten by that.
+ That's why the document has to be reformatted. Therefore applications
+ will usually override this method and call the baseclass' implementation
+ in their implementation.
+*/
+ // When the source is our document, we do the checking ourselves
+ // (much quicker and doesn't use the crutch StxStylePool).
+ if( dynamic_cast<const SwDocShell*>( &rSource) != nullptr)
+ {
+ // in order for the Headers/Footers not to get the fixed content
+ // of the template, update all the Source's
+ // FixFields once.
+ if(!bPreserveCurrentDocument)
+ static_cast<SwDocShell&>(rSource).m_xDoc->getIDocumentFieldsAccess().SetFixFields(nullptr);
+ if (m_pWrtShell)
+ {
+ // rhbz#818557, fdo#58893: EndAllAction will call SelectShell(),
+ // which pushes a bunch of SfxShells that are not cleared
+ // (for unknown reasons) when closing the document, causing crash;
+ // setting g_bNoInterrupt appears to avoid the problem.
+ ::comphelper::FlagRestorationGuard g(g_bNoInterrupt, true);
+ m_pWrtShell->StartAllAction();
+ m_xDoc->ReplaceStyles( *static_cast<SwDocShell&>(rSource).m_xDoc );
+ m_pWrtShell->EndAllAction();
+ }
+ else
+ {
+ bool bModified = m_xDoc->getIDocumentState().IsModified();
+ m_xDoc->ReplaceStyles( *static_cast<SwDocShell&>(rSource).m_xDoc );
+ if (!bModified && m_xDoc->getIDocumentState().IsModified() && !m_pView)
+ {
+ // the View is created later, but overwrites the Modify-Flag.
+ // Undo doesn't work anymore anyways.
+ m_xDoc->GetIDocumentUndoRedo().SetUndoNoResetModified();
+ }
+ }
+ }
+ else
+ SfxObjectShell::LoadStyles( rSource );
+}
+
+void SwDocShell::FormatPage(
+ weld::Window* pDialogParent,
+ const OUString& rPage,
+ const OUString& rPageId,
+ SwWrtShell& rActShell,
+ SfxRequest* pRequest)
+{
+ Edit(pDialogParent, rPage, OUString(), SfxStyleFamily::Page, SfxStyleSearchBits::Auto, false, rPageId, &rActShell, pRequest);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/app/docstyle.cxx b/sw/source/uibase/app/docstyle.cxx
new file mode 100644
index 0000000000..a715bef70d
--- /dev/null
+++ b/sw/source/uibase/app/docstyle.cxx
@@ -0,0 +1,3380 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <sal/config.h>
+#include <sal/log.hxx>
+#include <osl/diagnose.h>
+
+#include <cstdlib>
+
+#include <hintids.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <svl/itemiter.hxx>
+#include <svl/eitem.hxx>
+#include <unotools/syslocale.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/numitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <drawdoc.hxx>
+#include <fmtcol.hxx>
+#include <uitool.hxx>
+#include <wrtsh.hxx>
+#include <docsh.hxx>
+#include <frmfmt.hxx>
+#include <charfmt.hxx>
+#include <tblafmt.hxx>
+#include <poolfmt.hxx>
+#include <pagedesc.hxx>
+#include <docstyle.hxx>
+#include <docary.hxx>
+#include <ccoll.hxx>
+#include <doc.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <IDocumentStylePoolAccess.hxx>
+#include <IDocumentSettingAccess.hxx>
+#include <IDocumentDrawModelAccess.hxx>
+#include <IDocumentState.hxx>
+#include <cmdid.h>
+#include <strings.hrc>
+#include <paratr.hxx>
+#include <SwStyleNameMapper.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/ctloptions.hxx>
+#include <unotools/intlwrapper.hxx>
+#include <numrule.hxx>
+#include <svx/xdef.hxx>
+#include <SwRewriter.hxx>
+#include <hints.hxx>
+#include <frameformats.hxx>
+#include <editeng/brushitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/eeitem.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/xflftrit.hxx>
+#include <svx/drawitem.hxx>
+
+using namespace com::sun::star;
+
+// At the names' publication, this character is removed again and the
+// family is newly generated.
+
+// In addition now there is the Bit bPhysical. In case this Bit is
+// TRUE, the Pool-Formatnames are not being submitted.
+
+namespace {
+
+class EEStyleSheet : public SfxStyleSheet
+{
+public:
+ using SfxStyleSheet::SfxStyleSheet;
+ bool IsUsed() const override
+ {
+ bool bResult = false;
+ ForAllListeners(
+ [&bResult] (SfxListener* pListener)
+ {
+ auto pUser(dynamic_cast<svl::StyleSheetUser*>(pListener));
+ bResult = pUser && pUser->isUsedByModel();
+ return bResult;
+ });
+ return bResult;
+ }
+ void Notify(SfxBroadcaster& rBC, const SfxHint& rHint) override
+ {
+ if (rHint.GetId() == SfxHintId::DataChanged)
+ Broadcast(rHint);
+ else
+ SfxStyleSheet::Notify(rBC, rHint);
+ }
+ bool SetParent(const OUString& rName) override
+ {
+ if (SfxStyleSheet::SetParent(rName))
+ {
+ auto pStyle = m_pPool->Find(rName, nFamily);
+ pSet->SetParent(pStyle ? &pStyle->GetItemSet() : nullptr);
+ return true;
+ }
+ return false;
+ }
+};
+
+class EEStyleSheetPool : public SfxStyleSheetPool, public SfxListener
+{
+ SfxStyleSheetBasePool* m_pOwner;
+
+public:
+ explicit EEStyleSheetPool(SfxStyleSheetBasePool* pOwner)
+ : SfxStyleSheetPool(pOwner->GetPool())
+ , m_pOwner(pOwner)
+ {
+ StartListening(*m_pOwner);
+ }
+
+ using SfxStyleSheetPool::Create;
+ rtl::Reference<SfxStyleSheetBase> Create(const OUString& rName, SfxStyleFamily eFamily,
+ SfxStyleSearchBits nMask) override
+ {
+ return new EEStyleSheet(rName, *this, eFamily, nMask);
+ }
+
+ void Notify(SfxBroadcaster&, const SfxHint& rHint) override
+ {
+ auto pHint = dynamic_cast<const SfxStyleSheetHint*>(&rHint);
+ if (!pHint)
+ return;
+
+ auto nId = pHint->GetId();
+ auto pDocStyleSheet = pHint->GetStyleSheet();
+ auto pExtendedHint = dynamic_cast<const SfxStyleSheetModifiedHint*>(&rHint);
+ const OUString aName = pExtendedHint ? pExtendedHint->GetOldName() : pDocStyleSheet->GetName();
+ auto pStyleSheet = SfxStyleSheetPool::Find(aName, pDocStyleSheet->GetFamily());
+ if (!pStyleSheet)
+ return;
+
+ if (nId == SfxHintId::StyleSheetModified)
+ {
+ pStyleSheet->SetName(pDocStyleSheet->GetName());
+ UpdateStyleHierarchyFrom(pStyleSheet, pDocStyleSheet);
+ static_cast<SfxStyleSheet*>(pStyleSheet)->Broadcast(SfxHint(SfxHintId::DataChanged));
+ }
+ else if (nId == SfxHintId::StyleSheetErased)
+ Remove(pStyleSheet);
+ }
+
+ SfxStyleSheetBase* Find(const OUString& rName, SfxStyleFamily eFamily,
+ SfxStyleSearchBits = SfxStyleSearchBits::All) override
+ {
+ auto pStyleSheet = SfxStyleSheetPool::Find(rName, eFamily);
+
+ if (auto pDocStyleSheet = pStyleSheet ? nullptr : m_pOwner->Find(rName, eFamily))
+ {
+ pStyleSheet = &Make(pDocStyleSheet->GetName(), pDocStyleSheet->GetFamily());
+ UpdateStyleHierarchyFrom(pStyleSheet, pDocStyleSheet);
+ }
+
+ return pStyleSheet;
+ }
+
+ void UpdateStyleHierarchyFrom(SfxStyleSheetBase* pStyleSheet, SfxStyleSheetBase* pDocStyleSheet)
+ {
+ FillItemSet(pStyleSheet, pDocStyleSheet);
+
+ // Remember now, as the next calls will invalidate pDocStyleSheet.
+ const OUString aParent = pDocStyleSheet->GetParent();
+ const OUString aFollow = pDocStyleSheet->GetFollow();
+
+ if (pStyleSheet->GetParent() != aParent)
+ pStyleSheet->SetParent(aParent);
+
+ if (pStyleSheet->GetFollow() != aFollow)
+ pStyleSheet->SetFollow(aFollow);
+ }
+
+ void FillItemSet(SfxStyleSheetBase* pDestSheet, SfxStyleSheetBase* pSourceSheet)
+ {
+ auto& rItemSet = pDestSheet->GetItemSet();
+ rItemSet.ClearItem();
+
+ auto pCol = static_cast<SwDocStyleSheet*>(pSourceSheet)->GetCollection();
+ SfxItemIter aIter(pCol->GetAttrSet());
+ std::optional<SvxLRSpaceItem> oLRSpaceItem;
+
+ for (auto pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem())
+ {
+ if (aIter.GetItemState(false) != SfxItemState::SET)
+ continue;
+
+ auto nWhich = pItem->Which();
+ auto nSlotId = rPool.GetSlotId(nWhich);
+ auto nNewWhich = rPool.GetSecondaryPool()->GetWhich(nSlotId);
+ if (nNewWhich != nSlotId)
+ rItemSet.Put(pItem->CloneSetWhich(nNewWhich));
+ else if (nWhich == RES_MARGIN_FIRSTLINE)
+ {
+ if (!oLRSpaceItem)
+ oLRSpaceItem.emplace(EE_PARA_LRSPACE);
+ auto pFirstLineItem = static_cast<const SvxFirstLineIndentItem*>(pItem);
+ (*oLRSpaceItem).SetTextFirstLineOffsetValue(pFirstLineItem->GetTextFirstLineOffset());
+ (*oLRSpaceItem).SetAutoFirst(pFirstLineItem->IsAutoFirst());
+ }
+ else if (nWhich == RES_MARGIN_TEXTLEFT)
+ {
+ if (!oLRSpaceItem)
+ oLRSpaceItem.emplace(EE_PARA_LRSPACE);
+ (*oLRSpaceItem).SetTextLeft(static_cast<const SvxTextLeftMarginItem*>(pItem)->GetTextLeft());
+ }
+ else if (nWhich == RES_MARGIN_RIGHT)
+ {
+ if (!oLRSpaceItem)
+ oLRSpaceItem.emplace(EE_PARA_LRSPACE);
+ (*oLRSpaceItem).SetRight(static_cast<const SvxRightMarginItem*>(pItem)->GetRight());
+ }
+ else if (nWhich == RES_CHRATR_BACKGROUND)
+ {
+ auto pBrushItem = static_cast<const SvxBrushItem*>(pItem);
+ rItemSet.Put(SvxColorItem(pBrushItem->GetColor(), EE_CHAR_BKGCOLOR));
+ }
+ }
+ if (oLRSpaceItem)
+ rItemSet.Put(*oLRSpaceItem);
+ }
+};
+
+class SwImplShellAction
+{
+ SwWrtShell* m_pSh;
+ std::unique_ptr<CurrShell> m_pCurrSh;
+public:
+ explicit SwImplShellAction( SwDoc& rDoc );
+ ~SwImplShellAction() COVERITY_NOEXCEPT_FALSE;
+ SwImplShellAction(const SwImplShellAction&) = delete;
+ SwImplShellAction& operator=(const SwImplShellAction&) = delete;
+};
+
+}
+
+SwImplShellAction::SwImplShellAction( SwDoc& rDoc )
+{
+ if( rDoc.GetDocShell() )
+ m_pSh = rDoc.GetDocShell()->GetWrtShell();
+ else
+ m_pSh = nullptr;
+
+ if( m_pSh )
+ {
+ m_pCurrSh.reset( new CurrShell( m_pSh ) );
+ m_pSh->StartAllAction();
+ }
+}
+
+SwImplShellAction::~SwImplShellAction() COVERITY_NOEXCEPT_FALSE
+{
+ if( m_pCurrSh )
+ {
+ m_pSh->EndAllAction();
+ m_pCurrSh.reset();
+ }
+}
+
+// find/create SwCharFormate
+// possibly fill Style
+static SwCharFormat* lcl_FindCharFormat( SwDoc& rDoc,
+ const OUString& rName,
+ SwDocStyleSheet* pStyle = nullptr,
+ bool bCreate = true )
+{
+ SwCharFormat* pFormat = nullptr;
+ if (!rName.isEmpty())
+ {
+ pFormat = rDoc.FindCharFormatByName( rName );
+ if( !pFormat && rName == SwResId(STR_POOLCHR_STANDARD))
+ {
+ // Standard-Character template
+ pFormat = rDoc.GetDfltCharFormat();
+ }
+
+ if( !pFormat && bCreate )
+ { // explore Pool
+ const sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(rName, SwGetPoolIdFromName::ChrFmt);
+ if(nId != USHRT_MAX)
+ pFormat = rDoc.getIDocumentStylePoolAccess().GetCharFormatFromPool(nId);
+ }
+ }
+ if(pStyle)
+ {
+ if(pFormat)
+ {
+ pStyle->SetPhysical(true);
+ SwFormat* p = pFormat->DerivedFrom();
+ if( p && !p->IsDefault() )
+ pStyle->PresetParent( p->GetName() );
+ else
+ pStyle->PresetParent( OUString() );
+ }
+ else
+ pStyle->SetPhysical(false);
+ }
+ return pFormat;
+}
+
+// find/create ParaFormats
+// fill Style
+static SwTextFormatColl* lcl_FindParaFormat( SwDoc& rDoc,
+ const OUString& rName,
+ SwDocStyleSheet* pStyle = nullptr,
+ bool bCreate = true )
+{
+ SwTextFormatColl* pColl = nullptr;
+
+ if (!rName.isEmpty())
+ {
+ pColl = rDoc.FindTextFormatCollByName( rName );
+ if( !pColl && bCreate )
+ { // explore Pool
+ const sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(rName, SwGetPoolIdFromName::TxtColl);
+ if(nId != USHRT_MAX)
+ pColl = rDoc.getIDocumentStylePoolAccess().GetTextCollFromPool(nId);
+ }
+ }
+
+ if(pStyle)
+ {
+ if(pColl)
+ {
+ pStyle->SetPhysical(true);
+ if( pColl->DerivedFrom() && !pColl->DerivedFrom()->IsDefault() )
+ pStyle->PresetParent( pColl->DerivedFrom()->GetName() );
+ else
+ pStyle->PresetParent( OUString() );
+
+ SwTextFormatColl& rNext = pColl->GetNextTextFormatColl();
+ pStyle->PresetFollow(rNext.GetName());
+ }
+ else
+ pStyle->SetPhysical(false);
+ }
+ return pColl;
+}
+
+// Border formats
+static SwFrameFormat* lcl_FindFrameFormat( SwDoc& rDoc,
+ const OUString& rName,
+ SwDocStyleSheet* pStyle = nullptr,
+ bool bCreate = true )
+{
+ SwFrameFormat* pFormat = nullptr;
+ if( !rName.isEmpty() )
+ {
+ pFormat = rDoc.FindFrameFormatByName( rName );
+ if( !pFormat && bCreate )
+ { // explore Pool
+ const sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(rName, SwGetPoolIdFromName::FrmFmt);
+ if(nId != USHRT_MAX)
+ pFormat = rDoc.getIDocumentStylePoolAccess().GetFrameFormatFromPool(nId);
+ }
+ }
+
+ if(pStyle)
+ {
+ if(pFormat)
+ {
+ pStyle->SetPhysical(true);
+ if( pFormat->DerivedFrom() && !pFormat->DerivedFrom()->IsDefault() )
+ pStyle->PresetParent( pFormat->DerivedFrom()->GetName() );
+ else
+ pStyle->PresetParent( OUString() );
+ }
+ else
+ pStyle->SetPhysical(false);
+ }
+ return pFormat;
+}
+
+// Page descriptors
+static const SwPageDesc* lcl_FindPageDesc( SwDoc& rDoc,
+ const OUString& rName,
+ SwDocStyleSheet* pStyle = nullptr,
+ bool bCreate = true )
+{
+ const SwPageDesc* pDesc = nullptr;
+
+ if (!rName.isEmpty())
+ {
+ pDesc = rDoc.FindPageDesc(rName);
+ if( !pDesc && bCreate )
+ {
+ sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(rName, SwGetPoolIdFromName::PageDesc);
+ if(nId != USHRT_MAX)
+ pDesc = rDoc.getIDocumentStylePoolAccess().GetPageDescFromPool(nId);
+ }
+ }
+
+ if(pStyle)
+ {
+ if(pDesc)
+ {
+ pStyle->SetPhysical(true);
+ if(pDesc->GetFollow())
+ pStyle->PresetFollow(pDesc->GetFollow()->GetName());
+ else
+ pStyle->PresetParent( OUString() );
+ }
+ else
+ pStyle->SetPhysical(false);
+ }
+ return pDesc;
+}
+
+static const SwNumRule* lcl_FindNumRule( SwDoc& rDoc,
+ const OUString& rName,
+ SwDocStyleSheet* pStyle = nullptr,
+ bool bCreate = true )
+{
+ const SwNumRule* pRule = nullptr;
+
+ if (!rName.isEmpty())
+ {
+ pRule = rDoc.FindNumRulePtr( rName );
+ if( !pRule && bCreate )
+ {
+ sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(rName, SwGetPoolIdFromName::NumRule);
+ if(nId != USHRT_MAX)
+ pRule = rDoc.getIDocumentStylePoolAccess().GetNumRuleFromPool(nId);
+ }
+ }
+
+ if(pStyle)
+ {
+ if(pRule)
+ {
+ pStyle->SetPhysical(true);
+ pStyle->PresetParent( OUString() );
+ }
+ else
+ pStyle->SetPhysical(false);
+ }
+ return pRule;
+}
+
+static SwTableAutoFormat* lcl_FindTableStyle(SwDoc& rDoc, const OUString& rName, SwDocStyleSheet *pStyle = nullptr, bool bCreate = true)
+{
+ SwTableAutoFormat* pFormat = nullptr;
+
+ if (!rName.isEmpty())
+ {
+ pFormat = rDoc.GetTableStyles().FindAutoFormat(rName);
+ if (!pFormat && bCreate)
+ {
+ SwTableAutoFormat aNew(rName);
+ rDoc.GetTableStyles().AddAutoFormat(aNew);
+ }
+ }
+
+ if(pStyle)
+ {
+ if(pFormat)
+ {
+ pStyle->SetPhysical(true);
+ pStyle->PresetParent(OUString());
+ }
+ else
+ pStyle->SetPhysical(false);
+ }
+ return pFormat;
+}
+
+static const SwBoxAutoFormat* lcl_FindCellStyle(SwDoc& rDoc, std::u16string_view rName, SwDocStyleSheet *pStyle)
+{
+ const SwBoxAutoFormat* pFormat = rDoc.GetCellStyles().GetBoxFormat(rName);
+
+ if (!pFormat)
+ {
+ const auto& aTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
+ SwTableAutoFormatTable& rTableStyles = rDoc.GetTableStyles();
+ for (size_t i=0; i < rTableStyles.size() && !pFormat; ++i)
+ {
+ const SwTableAutoFormat& rTableStyle = rTableStyles[i];
+ for (size_t nBoxFormat=0; nBoxFormat < aTableTemplateMap.size() && !pFormat; ++nBoxFormat)
+ {
+ const sal_uInt32 nBoxIndex = aTableTemplateMap[nBoxFormat];
+ const SwBoxAutoFormat& rBoxFormat = rTableStyle.GetBoxFormat(nBoxIndex);
+ OUString sBoxFormatName;
+ SwStyleNameMapper::FillProgName(rTableStyle.GetName(), sBoxFormatName, SwGetPoolIdFromName::TabStyle);
+ sBoxFormatName += rTableStyle.GetTableTemplateCellSubName(rBoxFormat);
+ if (rName == sBoxFormatName)
+ pFormat = &rBoxFormat;
+ }
+ }
+ }
+
+ if(pStyle)
+ {
+ if(pFormat)
+ {
+ pStyle->SetPhysical(true);
+ pStyle->PresetParent(OUString());
+ }
+ else
+ pStyle->SetPhysical(false);
+ }
+ return pFormat;
+}
+
+sal_uInt32 SwStyleSheetIterator::SwPoolFormatList::FindName(SfxStyleFamily eFam,
+ const OUString& rName)
+{
+ if(!maImpl.empty())
+ {
+ UniqueHash::const_iterator it = maUnique.find(std::pair<SfxStyleFamily,OUString>{eFam, rName});
+ if (it != maUnique.end())
+ {
+ sal_uInt32 nIdx = it->second;
+ assert (nIdx < maImpl.size());
+ assert (maImpl.size() == maUnique.size());
+ return nIdx;
+ }
+ }
+ return SAL_MAX_UINT32;
+}
+
+void SwStyleSheetIterator::SwPoolFormatList::rehash()
+{
+ maUnique.clear();
+ for (size_t i = 0; i < maImpl.size(); i++)
+ maUnique[maImpl[i]] = i;
+ assert (maImpl.size() == maUnique.size());
+}
+
+void SwStyleSheetIterator::SwPoolFormatList::RemoveName(SfxStyleFamily eFam,
+ const OUString& rName)
+{
+ sal_uInt32 nTmpPos = FindName( eFam, rName );
+ if (nTmpPos != SAL_MAX_UINT32)
+ maImpl.erase(maImpl.begin() + nTmpPos);
+
+ // assumption: this seldom occurs, the iterator is built, then emptied.
+ rehash();
+ assert (maImpl.size() == maUnique.size());
+}
+
+// Add Strings to the list of templates
+void SwStyleSheetIterator::SwPoolFormatList::Append( SfxStyleFamily eFam, const OUString& rStr )
+{
+ UniqueHash::const_iterator it = maUnique.find(std::pair<SfxStyleFamily,OUString>{eFam, rStr});
+ if (it != maUnique.end())
+ return;
+
+ maUnique.emplace(std::pair<SfxStyleFamily,OUString>{eFam, rStr}, static_cast<sal_uInt32>(maImpl.size()));
+ maImpl.push_back(std::pair<SfxStyleFamily,OUString>{eFam, rStr});
+}
+
+// UI-sided implementation of StyleSheets
+// uses the Core-Engine
+SwDocStyleSheet::SwDocStyleSheet( SwDoc& rDocument,
+ SwDocStyleSheetPool& rPool) :
+
+ SfxStyleSheetBase( OUString(), &rPool, SfxStyleFamily::Char, SfxStyleSearchBits::Auto ),
+ m_pCharFormat(nullptr),
+ m_pColl(nullptr),
+ m_pFrameFormat(nullptr),
+ m_pDesc(nullptr),
+ m_pNumRule(nullptr),
+ m_pTableFormat(nullptr),
+ m_pBoxFormat(nullptr),
+ m_rDoc(rDocument),
+ m_aCoreSet(
+ rPool.GetPool(),
+ svl::Items<
+ RES_CHRATR_BEGIN, RES_CHRATR_END - 1,
+ RES_PARATR_BEGIN, RES_FRMATR_END - 1,
+ RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END - 1,
+ // FillAttribute support:
+ XATTR_FILL_FIRST, XATTR_FILL_LAST,
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
+ SID_ATTR_PAGE, SID_ATTR_PAGE_EXT1,
+ SID_ATTR_PAGE_HEADERSET, SID_ATTR_PAGE_FOOTERSET,
+ SID_ATTR_PARA_MODEL, SID_ATTR_PARA_MODEL,
+ // Items to hand over XPropertyList things like XColorList,
+ // XHatchList, XGradientList, and XBitmapList to the Area TabPage:
+ SID_COLOR_TABLE, SID_PATTERN_LIST,
+ SID_SWREGISTER_COLLECTION, SID_SWREGISTER_COLLECTION,
+ SID_ATTR_PARA_PAGENUM, SID_ATTR_PARA_PAGENUM,
+ SID_SWREGISTER_MODE, SID_SWREGISTER_MODE,
+ SID_ATTR_BRUSH_CHAR, SID_ATTR_BRUSH_CHAR,
+ SID_ATTR_NUMBERING_RULE, SID_ATTR_NUMBERING_RULE,
+ SID_ATTR_CHAR_GRABBAG, SID_ATTR_CHAR_GRABBAG,
+ SID_ATTR_AUTO_STYLE_UPDATE, SID_ATTR_AUTO_STYLE_UPDATE,
+ FN_PARAM_FTN_INFO, FN_PARAM_FTN_INFO,
+ FN_KEEP_ASPECT_RATIO, FN_KEEP_ASPECT_RATIO,
+ FN_COND_COLL, FN_COND_COLL>),
+ m_bPhysical(false)
+{
+ nHelpId = UCHAR_MAX;
+}
+
+SwDocStyleSheet::SwDocStyleSheet( const SwDocStyleSheet& ) = default;
+
+SwDocStyleSheet::~SwDocStyleSheet() = default;
+
+void SwDocStyleSheet::Reset()
+{
+ aName.clear();
+ aFollow.clear();
+ aParent.clear();
+ SetPhysical(false);
+}
+
+void SwDocStyleSheet::SetGrabBagItem(const uno::Any& rVal)
+{
+ bool bChg = false;
+ if (!m_bPhysical)
+ FillStyleSheet(FillPhysical);
+
+ SwFormat* pFormat = nullptr;
+ switch (nFamily)
+ {
+ case SfxStyleFamily::Char:
+ pFormat = m_rDoc.FindCharFormatByName(aName);
+ if (pFormat)
+ {
+ pFormat->SetGrabBagItem(rVal);
+ bChg = true;
+ }
+ break;
+ case SfxStyleFamily::Para:
+ pFormat = m_rDoc.FindTextFormatCollByName(aName);
+ if (pFormat)
+ {
+ pFormat->SetGrabBagItem(rVal);
+ bChg = true;
+ }
+ break;
+ case SfxStyleFamily::Pseudo:
+ {
+ SwNumRule* pRule = m_rDoc.FindNumRulePtr(aName);
+ if (pRule)
+ {
+ pRule->SetGrabBagItem(rVal);
+ bChg = true;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (bChg)
+ {
+ dynamic_cast<SwDocStyleSheetPool&>(*m_pPool).InvalidateIterator();
+ m_pPool->Broadcast(SfxStyleSheetHint(SfxHintId::StyleSheetModified, *this));
+ if (SwEditShell* pSh = m_rDoc.GetEditShell())
+ pSh->CallChgLnk();
+ }
+}
+
+void SwDocStyleSheet::GetGrabBagItem(uno::Any& rVal) const
+{
+ SwFormat* pFormat = nullptr;
+ switch (nFamily)
+ {
+ case SfxStyleFamily::Char:
+ pFormat = m_rDoc.FindCharFormatByName(aName);
+ if (pFormat)
+ pFormat->GetGrabBagItem(rVal);
+ break;
+ case SfxStyleFamily::Para:
+ pFormat = m_rDoc.FindTextFormatCollByName(aName);
+ if (pFormat)
+ pFormat->GetGrabBagItem(rVal);
+ break;
+ case SfxStyleFamily::Pseudo:
+ {
+ SwNumRule* pRule = m_rDoc.FindNumRulePtr(aName);
+ if (pRule)
+ pRule->GetGrabBagItem(rVal);
+ }
+ break;
+ default:
+ break;
+ }
+}
+// virtual methods
+void SwDocStyleSheet::SetHidden( bool bValue )
+{
+ bool bChg = false;
+ if(!m_bPhysical)
+ FillStyleSheet( FillPhysical );
+
+ SwFormat* pFormat = nullptr;
+ switch(nFamily)
+ {
+ case SfxStyleFamily::Char:
+ pFormat = m_rDoc.FindCharFormatByName( aName );
+ if ( pFormat )
+ {
+ pFormat->SetHidden( bValue );
+ bChg = true;
+ }
+ break;
+
+ case SfxStyleFamily::Para:
+ pFormat = m_rDoc.FindTextFormatCollByName( aName );
+ if ( pFormat )
+ {
+ pFormat->SetHidden( bValue );
+ bChg = true;
+ }
+ break;
+
+ case SfxStyleFamily::Frame:
+ pFormat = m_rDoc.FindFrameFormatByName( aName );
+ if ( pFormat )
+ {
+ pFormat->SetHidden( bValue );
+ bChg = true;
+ }
+ break;
+
+ case SfxStyleFamily::Page:
+ {
+ SwPageDesc* pPgDesc = m_rDoc.FindPageDesc(aName);
+ if ( pPgDesc )
+ {
+ pPgDesc->SetHidden( bValue );
+ bChg = true;
+ }
+ }
+ break;
+
+ case SfxStyleFamily::Pseudo:
+ {
+ SwNumRule* pRule = m_rDoc.FindNumRulePtr( aName );
+ if ( pRule )
+ {
+ pRule->SetHidden( bValue );
+ bChg = true;
+ }
+ }
+ break;
+
+ case SfxStyleFamily::Table:
+ {
+ SwTableAutoFormat* pTableAutoFormat = m_rDoc.GetTableStyles().FindAutoFormat( aName );
+ if ( pTableAutoFormat )
+ {
+ pTableAutoFormat->SetHidden( bValue );
+ bChg = true;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if( bChg )
+ {
+ // calling pPool->First() here would be quite slow...
+ dynamic_cast<SwDocStyleSheetPool&>(*m_pPool).InvalidateIterator(); // internal list has to be updated
+ m_pPool->Broadcast( SfxStyleSheetHint( SfxHintId::StyleSheetModified, *this ) );
+ if (SwEditShell* pSh = m_rDoc.GetEditShell())
+ pSh->CallChgLnk();
+ }
+}
+
+bool SwDocStyleSheet::IsHidden( ) const
+{
+ bool bRet = false;
+
+ SwFormat* pFormat = nullptr;
+ switch(nFamily)
+ {
+ case SfxStyleFamily::Char:
+ pFormat = m_rDoc.FindCharFormatByName( aName );
+ bRet = pFormat && pFormat->IsHidden( );
+ break;
+
+ case SfxStyleFamily::Para:
+ pFormat = m_rDoc.FindTextFormatCollByName( aName );
+ bRet = pFormat && pFormat->IsHidden( );
+ break;
+
+ case SfxStyleFamily::Frame:
+ pFormat = m_rDoc.FindFrameFormatByName( aName );
+ bRet = pFormat && pFormat->IsHidden( );
+ break;
+
+ case SfxStyleFamily::Page:
+ {
+ SwPageDesc* pPgDesc = m_rDoc.FindPageDesc(aName);
+ bRet = pPgDesc && pPgDesc->IsHidden( );
+ }
+ break;
+ case SfxStyleFamily::Pseudo:
+ {
+ SwNumRule* pRule = m_rDoc.FindNumRulePtr( aName );
+ bRet = pRule && pRule->IsHidden( );
+ }
+ break;
+ case SfxStyleFamily::Table:
+ {
+ SwTableAutoFormat* pTableAutoFormat = m_rDoc.GetTableStyles().FindAutoFormat( aName );
+ bRet = pTableAutoFormat && pTableAutoFormat->IsHidden( );
+ }
+ break;
+ default:
+ break;
+ }
+
+ return bRet;
+}
+
+const OUString& SwDocStyleSheet::GetParent() const
+{
+ if( !m_bPhysical )
+ {
+ // check if it's already in document
+ SwFormat* pFormat = nullptr;
+ SwGetPoolIdFromName eGetType;
+ switch(nFamily)
+ {
+ case SfxStyleFamily::Char:
+ pFormat = m_rDoc.FindCharFormatByName( aName );
+ eGetType = SwGetPoolIdFromName::ChrFmt;
+ break;
+
+ case SfxStyleFamily::Para:
+ pFormat = m_rDoc.FindTextFormatCollByName( aName );
+ eGetType = SwGetPoolIdFromName::TxtColl;
+ break;
+
+ case SfxStyleFamily::Frame:
+ pFormat = m_rDoc.FindFrameFormatByName( aName );
+ eGetType = SwGetPoolIdFromName::FrmFmt;
+ break;
+
+ case SfxStyleFamily::Page:
+ case SfxStyleFamily::Pseudo:
+ default:
+ {
+ static const OUString sEmpty;
+ return sEmpty; // there's no parent
+ }
+ }
+
+ OUString sTmp;
+ if( !pFormat ) // not yet there, so default Parent
+ {
+ sal_uInt16 i = SwStyleNameMapper::GetPoolIdFromUIName( aName, eGetType );
+ i = ::GetPoolParent( i );
+ if( i && USHRT_MAX != i )
+ SwStyleNameMapper::FillUIName( i, sTmp );
+ }
+ else
+ {
+ SwFormat* p = pFormat->DerivedFrom();
+ if( p && !p->IsDefault() )
+ sTmp = p->GetName();
+ }
+ SwDocStyleSheet* pThis = const_cast<SwDocStyleSheet*>(this);
+ pThis->aParent = sTmp;
+ }
+ return aParent;
+}
+
+// Follower
+const OUString& SwDocStyleSheet::GetFollow() const
+{
+ if( !m_bPhysical )
+ {
+ SwDocStyleSheet* pThis = const_cast<SwDocStyleSheet*>(this);
+ pThis->FillStyleSheet( FillAllInfo );
+ }
+ return aFollow;
+}
+
+void SwDocStyleSheet::SetLink(const OUString& rStr)
+{
+ SwImplShellAction aTmpSh(m_rDoc);
+ switch (nFamily)
+ {
+ case SfxStyleFamily::Para:
+ {
+ if (m_pColl)
+ {
+ SwCharFormat* pLink = lcl_FindCharFormat(m_rDoc, rStr);
+ if (pLink)
+ {
+ m_pColl->SetLinkedCharFormat(pLink);
+ }
+ }
+ break;
+ }
+ case SfxStyleFamily::Char:
+ {
+ if (m_pCharFormat)
+ {
+ SwTextFormatColl* pLink = lcl_FindParaFormat(m_rDoc, rStr);
+ if (pLink)
+ {
+ m_pCharFormat->SetLinkedParaFormat(pLink);
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+const OUString& SwDocStyleSheet::GetLink() const
+{
+ if (!m_bPhysical)
+ {
+ SwDocStyleSheet* pThis = const_cast<SwDocStyleSheet*>(this);
+ pThis->FillStyleSheet(FillAllInfo);
+ }
+
+ return m_aLink;
+}
+
+// What Linkage is possible
+bool SwDocStyleSheet::HasFollowSupport() const
+{
+ switch(nFamily)
+ {
+ case SfxStyleFamily::Para :
+ case SfxStyleFamily::Page : return true;
+ case SfxStyleFamily::Frame:
+ case SfxStyleFamily::Char :
+ case SfxStyleFamily::Pseudo: return false;
+ default:
+ OSL_ENSURE(false, "unknown style family");
+ }
+ return false;
+}
+
+// Parent ?
+bool SwDocStyleSheet::HasParentSupport() const
+{
+ bool bRet = false;
+ switch(nFamily)
+ {
+ case SfxStyleFamily::Char :
+ case SfxStyleFamily::Para :
+ case SfxStyleFamily::Frame: bRet = true;
+ break;
+ default:; //prevent warning
+ }
+ return bRet;
+}
+
+bool SwDocStyleSheet::HasClearParentSupport() const
+{
+ bool bRet = false;
+ switch(nFamily)
+ {
+ case SfxStyleFamily::Para :
+ case SfxStyleFamily::Char :
+ case SfxStyleFamily::Frame: bRet = true;
+ break;
+ default:; //prevent warning
+ }
+ return bRet;
+}
+
+// determine textual description
+OUString SwDocStyleSheet::GetDescription(MapUnit eUnit)
+{
+ IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
+
+ static constexpr OUString sPlus(u" + "_ustr);
+ if ( SfxStyleFamily::Page == nFamily )
+ {
+ if( !pSet )
+ GetItemSet();
+
+ SfxItemIter aIter( *pSet );
+ OUStringBuffer aDesc;
+
+ for (const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem())
+ {
+ if(!IsInvalidItem(pItem))
+ {
+ switch ( pItem->Which() )
+ {
+ case RES_LR_SPACE:
+ case SID_ATTR_PAGE_SIZE:
+ case SID_ATTR_PAGE_MAXSIZE:
+ case SID_ATTR_PAGE_PAPERBIN:
+ case SID_ATTR_BORDER_INNER:
+ break;
+ default:
+ {
+ OUString aItemPresentation;
+ if ( !IsInvalidItem( pItem ) &&
+ m_pPool->GetPool().GetPresentation(
+ *pItem, eUnit, aItemPresentation, aIntlWrapper ) )
+ {
+ if ( !aDesc.isEmpty() && !aItemPresentation.isEmpty() )
+ aDesc.append(sPlus);
+ aDesc.append(aItemPresentation);
+ }
+ }
+ }
+ }
+ }
+ return aDesc.makeStringAndClear();
+ }
+
+ if ( SfxStyleFamily::Frame == nFamily || SfxStyleFamily::Para == nFamily || SfxStyleFamily::Char == nFamily )
+ {
+ if( !pSet )
+ GetItemSet();
+
+ SfxItemIter aIter( *pSet );
+ OUStringBuffer aDesc;
+ OUString sPageNum;
+ OUString sModel;
+ OUString sBreak;
+ bool bHasWesternFontPrefix = false;
+ bool bHasCJKFontPrefix = false;
+ bool bHasCTLFontPrefix = false;
+ SvtCTLOptions aCTLOptions;
+
+ // Get currently used FillStyle and remember, also need the XFillFloatTransparenceItem
+ // to decide if gradient transparence is used
+ const drawing::FillStyle eFillStyle(pSet->Get(XATTR_FILLSTYLE).GetValue());
+ const bool bUseFloatTransparence(pSet->Get(XATTR_FILLFLOATTRANSPARENCE).IsEnabled());
+
+ for (const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem())
+ {
+ if(!IsInvalidItem(pItem))
+ {
+ switch ( pItem->Which() )
+ {
+ case SID_ATTR_AUTO_STYLE_UPDATE:
+ case RES_PAGEDESC:
+ break;
+ default:
+ {
+ OUString aItemPresentation;
+ if ( !IsInvalidItem( pItem ) &&
+ m_pPool->GetPool().GetPresentation(
+ *pItem, eUnit, aItemPresentation, aIntlWrapper ) )
+ {
+ bool bIsDefault = false;
+ switch ( pItem->Which() )
+ {
+ case XATTR_FILLCOLOR:
+ {
+ // only use active FillStyle information
+ bIsDefault = (drawing::FillStyle_SOLID == eFillStyle);
+ break;
+ }
+ case XATTR_FILLGRADIENT:
+ {
+ // only use active FillStyle information
+ bIsDefault = (drawing::FillStyle_GRADIENT == eFillStyle);
+ break;
+ }
+ case XATTR_FILLHATCH:
+ {
+ // only use active FillStyle information
+ bIsDefault = (drawing::FillStyle_HATCH == eFillStyle);
+ break;
+ }
+ case XATTR_FILLBITMAP:
+ {
+ // only use active FillStyle information
+ bIsDefault = (drawing::FillStyle_BITMAP == eFillStyle);
+ break;
+ }
+ case XATTR_FILLTRANSPARENCE:
+ {
+ // only active when not FloatTransparence
+ bIsDefault = !bUseFloatTransparence;
+ break;
+ }
+ case XATTR_FILLFLOATTRANSPARENCE:
+ {
+ // only active when FloatTransparence
+ bIsDefault = bUseFloatTransparence;
+ break;
+ }
+
+ case SID_ATTR_PARA_PAGENUM:
+ sPageNum = aItemPresentation;
+ break;
+ case SID_ATTR_PARA_MODEL:
+ sModel = aItemPresentation;
+ break;
+ case RES_BREAK:
+ sBreak = aItemPresentation;
+ break;
+ case RES_CHRATR_CJK_FONT:
+ case RES_CHRATR_CJK_FONTSIZE:
+ case RES_CHRATR_CJK_LANGUAGE:
+ case RES_CHRATR_CJK_POSTURE:
+ case RES_CHRATR_CJK_WEIGHT:
+ if(SvtCJKOptions::IsCJKFontEnabled())
+ bIsDefault = true;
+ if(!bHasCJKFontPrefix)
+ {
+ aItemPresentation = SwResId(STR_CJK_FONT) + aItemPresentation;
+ bHasCJKFontPrefix = true;
+ }
+ break;
+ case RES_CHRATR_CTL_FONT:
+ case RES_CHRATR_CTL_FONTSIZE:
+ case RES_CHRATR_CTL_LANGUAGE:
+ case RES_CHRATR_CTL_POSTURE:
+ case RES_CHRATR_CTL_WEIGHT:
+ if(SvtCTLOptions::IsCTLFontEnabled())
+ bIsDefault = true;
+ if(!bHasCTLFontPrefix)
+ {
+ aItemPresentation = SwResId(STR_CTL_FONT) + aItemPresentation;
+ bHasCTLFontPrefix = true;
+ }
+ break;
+ case RES_CHRATR_FONT:
+ case RES_CHRATR_FONTSIZE:
+ case RES_CHRATR_LANGUAGE:
+ case RES_CHRATR_POSTURE:
+ case RES_CHRATR_WEIGHT:
+ if(!bHasWesternFontPrefix)
+ {
+ aItemPresentation = SwResId(STR_WESTERN_FONT) + aItemPresentation;
+ bHasWesternFontPrefix = true;
+ }
+ [[fallthrough]];
+ default:
+ bIsDefault = true;
+ }
+ if(bIsDefault)
+ {
+ if ( !aDesc.isEmpty() && !aItemPresentation.isEmpty() )
+ aDesc.append(sPlus);
+ aDesc.append(aItemPresentation);
+ }
+ }
+ }
+ }
+ }
+ }
+ // Special treatment for Break, Page template and Site offset
+ if (!sModel.isEmpty())
+ {
+ if (!aDesc.isEmpty())
+ aDesc.append(sPlus);
+ aDesc.append(SwResId(STR_PAGEBREAK) + sPlus + sModel);
+ if (sPageNum != "0")
+ {
+ aDesc.append(sPlus + SwResId(STR_PAGEOFFSET) + sPageNum);
+ }
+ }
+ else if (!sBreak.isEmpty()) // Break can be valid only when NO Model
+ {
+ if (!aDesc.isEmpty())
+ aDesc.append(sPlus);
+ aDesc.append(sBreak);
+ }
+ return aDesc.makeStringAndClear();
+ }
+
+ if( SfxStyleFamily::Pseudo == nFamily )
+ {
+ return OUString();
+ }
+
+ return SfxStyleSheetBase::GetDescription(eUnit);
+}
+
+// Set names
+bool SwDocStyleSheet::SetName(const OUString& rStr, bool bReindexNow)
+{
+ if( rStr.isEmpty() )
+ return false;
+
+ if( aName != rStr )
+ {
+ if( !SfxStyleSheetBase::SetName(rStr, bReindexNow))
+ return false;
+ }
+ else if(!m_bPhysical)
+ FillStyleSheet( FillPhysical );
+
+ bool bChg = false;
+ switch(nFamily)
+ {
+ case SfxStyleFamily::Char :
+ {
+ OSL_ENSURE(m_pCharFormat, "SwCharFormat missing!");
+ if( m_pCharFormat && m_pCharFormat->GetName() != rStr )
+ {
+ if (!m_pCharFormat->GetName().isEmpty())
+ m_rDoc.RenameFormat(*m_pCharFormat, rStr);
+ else
+ m_pCharFormat->SetFormatName(rStr);
+
+ bChg = true;
+ }
+ break;
+ }
+ case SfxStyleFamily::Para :
+ {
+ OSL_ENSURE(m_pColl, "Collection missing!");
+ if( m_pColl && m_pColl->GetName() != rStr )
+ {
+ if (!m_pColl->GetName().isEmpty())
+ m_rDoc.RenameFormat(*m_pColl, rStr);
+ else
+ m_pColl->SetFormatName(rStr);
+
+ bChg = true;
+ }
+ break;
+ }
+ case SfxStyleFamily::Frame:
+ {
+ OSL_ENSURE(m_pFrameFormat, "FrameFormat missing!");
+ if( m_pFrameFormat && m_pFrameFormat->GetName() != rStr )
+ {
+ if (!m_pFrameFormat->GetName().isEmpty())
+ m_rDoc.RenameFormat(*m_pFrameFormat, rStr);
+ else
+ m_pFrameFormat->SetFormatName( rStr );
+
+ bChg = true;
+ }
+ break;
+ }
+ case SfxStyleFamily::Page :
+ OSL_ENSURE(m_pDesc, "PageDesc missing!");
+ if( m_pDesc && m_pDesc->GetName() != rStr )
+ {
+ // Set PageDesc - copy with earlier one - probably not
+ // necessary for setting the name. So here we allow a
+ // cast.
+ SwPageDesc aPageDesc(*const_cast<SwPageDesc*>(m_pDesc));
+ const OUString aOldName(aPageDesc.GetName());
+
+ aPageDesc.SetName( rStr );
+ bool const bDoesUndo = m_rDoc.GetIDocumentUndoRedo().DoesUndo();
+
+ m_rDoc.GetIDocumentUndoRedo().DoUndo(!aOldName.isEmpty());
+ m_rDoc.ChgPageDesc(aOldName, aPageDesc);
+ m_rDoc.GetIDocumentUndoRedo().DoUndo(bDoesUndo);
+
+ m_rDoc.getIDocumentState().SetModified();
+ bChg = true;
+ }
+ break;
+ case SfxStyleFamily::Pseudo:
+ OSL_ENSURE(m_pNumRule, "NumRule missing!");
+
+ if (m_pNumRule)
+ {
+ OUString aOldName = m_pNumRule->GetName();
+
+ if (!aOldName.isEmpty())
+ {
+ if ( aOldName != rStr &&
+ m_rDoc.RenameNumRule(aOldName, rStr))
+ {
+ m_pNumRule = m_rDoc.FindNumRulePtr(rStr);
+ m_rDoc.getIDocumentState().SetModified();
+
+ bChg = true;
+ }
+ }
+ else
+ {
+ // #i91400#
+ const_cast<SwNumRule*>(m_pNumRule)->SetName( rStr, m_rDoc.getIDocumentListsAccess() );
+ m_rDoc.getIDocumentState().SetModified();
+
+ bChg = true;
+ }
+ }
+
+ break;
+
+ default:
+ OSL_ENSURE(false, "unknown style family");
+ }
+
+ if( bChg )
+ {
+ m_pPool->First(nFamily); // internal list has to be updated
+ m_pPool->Broadcast( SfxStyleSheetHint( SfxHintId::StyleSheetModified, *this ) );
+ if (SwEditShell* pSh = m_rDoc.GetEditShell())
+ pSh->CallChgLnk();
+ }
+ return true;
+}
+
+// hierarchy of deduction
+bool SwDocStyleSheet::SetParent( const OUString& rStr)
+{
+ SwFormat* pFormat = nullptr, *pParent = nullptr;
+ switch(nFamily)
+ {
+ case SfxStyleFamily::Char :
+ OSL_ENSURE( m_pCharFormat, "SwCharFormat missing!" );
+ if( nullptr != ( pFormat = m_pCharFormat ) && !rStr.isEmpty() )
+ pParent = lcl_FindCharFormat(m_rDoc, rStr);
+ break;
+
+ case SfxStyleFamily::Para :
+ OSL_ENSURE( m_pColl, "Collection missing!");
+ if( nullptr != ( pFormat = m_pColl ) && !rStr.isEmpty() )
+ pParent = lcl_FindParaFormat( m_rDoc, rStr );
+ break;
+
+ case SfxStyleFamily::Frame:
+ OSL_ENSURE(m_pFrameFormat, "FrameFormat missing!");
+ if( nullptr != ( pFormat = m_pFrameFormat ) && !rStr.isEmpty() )
+ pParent = lcl_FindFrameFormat( m_rDoc, rStr );
+ break;
+
+ case SfxStyleFamily::Page:
+ case SfxStyleFamily::Pseudo:
+ break;
+ default:
+ OSL_ENSURE(false, "unknown style family");
+ }
+
+ bool bRet = false;
+ if( pFormat && pFormat->DerivedFrom() &&
+ pFormat->DerivedFrom()->GetName() != rStr )
+ {
+ {
+ SwImplShellAction aTmp( m_rDoc );
+ bRet = pFormat->SetDerivedFrom( pParent );
+ }
+
+ if( bRet )
+ {
+ aParent = rStr;
+ m_pPool->Broadcast( SfxStyleSheetHint( SfxHintId::StyleSheetModified,
+ *this ) );
+ }
+ }
+
+ return bRet;
+}
+
+// Set Follower
+bool SwDocStyleSheet::SetFollow( const OUString& rStr)
+{
+ if( !rStr.isEmpty() && !SfxStyleSheetBase::SetFollow( rStr ))
+ return false;
+
+ SwImplShellAction aTmpSh( m_rDoc );
+ switch(nFamily)
+ {
+ case SfxStyleFamily::Para :
+ {
+ OSL_ENSURE(m_pColl, "Collection missing!");
+ if( m_pColl )
+ {
+ SwTextFormatColl* pFollow = m_pColl;
+ if( !rStr.isEmpty() && nullptr == (pFollow = lcl_FindParaFormat(m_rDoc, rStr) ))
+ pFollow = m_pColl;
+
+ m_pColl->SetNextTextFormatColl(*pFollow);
+ }
+ break;
+ }
+ case SfxStyleFamily::Page :
+ {
+ OSL_ENSURE(m_pDesc, "PageDesc missing!");
+ if( m_pDesc )
+ {
+ const SwPageDesc* pFollowDesc = !rStr.isEmpty()
+ ? lcl_FindPageDesc(m_rDoc, rStr)
+ : nullptr;
+ size_t nId = 0;
+ if (pFollowDesc != m_pDesc->GetFollow() && m_rDoc.FindPageDesc(m_pDesc->GetName(), &nId))
+ {
+ SwPageDesc aDesc( *m_pDesc );
+ aDesc.SetFollow( pFollowDesc );
+ m_rDoc.ChgPageDesc( nId, aDesc );
+ m_pDesc = &m_rDoc.GetPageDesc( nId );
+ }
+ }
+ break;
+ }
+ case SfxStyleFamily::Char:
+ case SfxStyleFamily::Frame:
+ case SfxStyleFamily::Pseudo:
+ break;
+ default:
+ OSL_ENSURE(false, "unknown style family");
+ }
+
+ return true;
+}
+
+static
+void lcl_SwFormatToFlatItemSet(SwFormat const *const pFormat, std::optional<SfxItemSet>& pRet)
+{
+ // note: we don't add the odd items that GetItemSet() would add
+ // because they don't seem relevant for preview
+ std::vector<SfxItemSet const*> sets;
+ sets.push_back(&pFormat->GetAttrSet());
+ while (SfxItemSet const*const pParent = sets.back()->GetParent())
+ {
+ sets.push_back(pParent);
+ }
+ // start by copying top-level parent set
+ pRet.emplace(*sets.back());
+ sets.pop_back();
+ for (auto iter = sets.rbegin(); iter != sets.rend(); ++iter)
+ { // in reverse so child overrides parent
+ pRet->Put(**iter);
+ }
+}
+
+std::optional<SfxItemSet> SwDocStyleSheet::GetItemSetForPreview()
+{
+ if (SfxStyleFamily::Page == nFamily || SfxStyleFamily::Pseudo == nFamily || SfxStyleFamily::Table == nFamily)
+ {
+ SAL_WARN("sw.ui", "GetItemSetForPreview not implemented for page or number or table style");
+ return std::optional<SfxItemSet>();
+ }
+ if (!m_bPhysical)
+ {
+ // because not only this style, but also any number of its parents
+ // (or follow style) may not actually exist in the document at this
+ // time, return one "flattened" item set that contains all items from
+ // all parents.
+ std::optional<SfxItemSet> pRet;
+
+ bool bModifiedEnabled = m_rDoc.getIDocumentState().IsEnableSetModified();
+ m_rDoc.getIDocumentState().SetEnableSetModified(false);
+
+ FillStyleSheet(FillPreview, &pRet);
+
+ m_rDoc.getIDocumentState().SetEnableSetModified(bModifiedEnabled);
+
+ assert(pRet);
+ return pRet;
+ }
+ else
+ {
+ std::optional<SfxItemSet> pRet;
+ switch (nFamily)
+ {
+ case SfxStyleFamily::Char:
+ lcl_SwFormatToFlatItemSet(m_pCharFormat, pRet);
+ break;
+ case SfxStyleFamily::Para:
+ lcl_SwFormatToFlatItemSet(m_pColl, pRet);
+ break;
+ case SfxStyleFamily::Frame:
+ lcl_SwFormatToFlatItemSet(m_pFrameFormat, pRet);
+ break;
+ default:
+ std::abort();
+ }
+ return pRet;
+ }
+}
+
+// extract ItemSet to Name and Family, Mask
+
+SfxItemSet& SwDocStyleSheet::GetItemSet()
+{
+ if(!m_bPhysical)
+ FillStyleSheet( FillPhysical );
+
+ switch(nFamily)
+ {
+ case SfxStyleFamily::Char:
+ case SfxStyleFamily::Para:
+ case SfxStyleFamily::Frame:
+ {
+ SvxBoxInfoItem aBoxInfo( SID_ATTR_BORDER_INNER );
+ aBoxInfo.SetTable( false );
+ aBoxInfo.SetDist( true ); // always show gap field
+ aBoxInfo.SetMinDist( true );// set minimum size in tables and paragraphs
+ aBoxInfo.SetDefDist( MIN_BORDER_DIST );// always set Default-Gap
+ // Single lines can only have DontCare-Status in tables
+ aBoxInfo.SetValid( SvxBoxInfoItemValidFlags::DISABLE );
+
+ if( nFamily == SfxStyleFamily::Char )
+ {
+ SAL_WARN_IF(!m_pCharFormat, "sw.ui", "Where's SwCharFormat");
+ m_aCoreSet.Put(m_pCharFormat->GetAttrSet());
+ m_aCoreSet.Put( aBoxInfo );
+
+ if(m_pCharFormat->DerivedFrom())
+ m_aCoreSet.SetParent(&m_pCharFormat->DerivedFrom()->GetAttrSet());
+ }
+ else if ( nFamily == SfxStyleFamily::Para )
+ {
+ OSL_ENSURE(m_pColl, "Where's Collection");
+ m_aCoreSet.Put(m_pColl->GetAttrSet());
+ m_aCoreSet.Put( aBoxInfo );
+ m_aCoreSet.Put(SfxBoolItem(SID_ATTR_AUTO_STYLE_UPDATE, m_pColl->IsAutoUpdateOnDirectFormat()));
+
+ if(m_pColl->DerivedFrom())
+ m_aCoreSet.SetParent(&m_pColl->DerivedFrom()->GetAttrSet());
+ }
+ else
+ {
+ OSL_ENSURE(m_pFrameFormat, "Where's FrameFormat");
+ m_aCoreSet.Put(m_pFrameFormat->GetAttrSet());
+ m_aCoreSet.Put( aBoxInfo );
+ m_aCoreSet.Put(SfxBoolItem(SID_ATTR_AUTO_STYLE_UPDATE, m_pFrameFormat->IsAutoUpdateOnDirectFormat()));
+
+ if(m_pFrameFormat->DerivedFrom())
+ m_aCoreSet.SetParent(&m_pFrameFormat->DerivedFrom()->GetAttrSet());
+
+ // create needed items for XPropertyList entries from the DrawModel so that
+ // the Area TabPage can access them
+ const SwDrawModel* pDrawModel = m_rDoc.getIDocumentDrawModelAccess().GetDrawModel();
+
+ m_aCoreSet.Put(SvxColorListItem(pDrawModel->GetColorList(), SID_COLOR_TABLE));
+ m_aCoreSet.Put(SvxGradientListItem(pDrawModel->GetGradientList(), SID_GRADIENT_LIST));
+ m_aCoreSet.Put(SvxHatchListItem(pDrawModel->GetHatchList(), SID_HATCH_LIST));
+ m_aCoreSet.Put(SvxBitmapListItem(pDrawModel->GetBitmapList(), SID_BITMAP_LIST));
+ m_aCoreSet.Put(SvxPatternListItem(pDrawModel->GetPatternList(), SID_PATTERN_LIST));
+ }
+ }
+ break;
+
+ case SfxStyleFamily::Page :
+ {
+ // set correct parent to get the drawing::FillStyle_NONE FillStyle as needed
+ if(!m_aCoreSet.GetParent())
+ {
+ m_aCoreSet.SetParent(&m_rDoc.GetDfltFrameFormat()->GetAttrSet());
+ }
+
+ OSL_ENSURE(m_pDesc, "No PageDescriptor");
+ ::PageDescToItemSet(*const_cast<SwPageDesc*>(m_pDesc), m_aCoreSet);
+ }
+ break;
+
+ case SfxStyleFamily::Pseudo:
+ {
+ OSL_ENSURE(m_pNumRule, "No NumRule");
+ SvxNumRule aRule = m_pNumRule->MakeSvxNumRule();
+ m_aCoreSet.Put(SvxNumBulletItem(std::move(aRule)));
+ }
+ break;
+
+ default:
+ OSL_ENSURE(false, "unknown style family");
+ }
+ // Member of Baseclass
+ pSet = &m_aCoreSet;
+
+ return m_aCoreSet;
+}
+
+void SwDocStyleSheet::MergeIndentAttrsOfListStyle( SfxItemSet& rSet )
+{
+ if ( nFamily != SfxStyleFamily::Para )
+ {
+ return;
+ }
+
+ OSL_ENSURE( m_pColl, "<SwDocStyleSheet::MergeIndentAttrsOfListStyle(..)> - missing paragraph style");
+ ::sw::ListLevelIndents const indents(m_pColl->AreListLevelIndentsApplicable());
+ if (indents == ::sw::ListLevelIndents::No)
+ return;
+
+ OSL_ENSURE( m_pColl->GetItemState( RES_PARATR_NUMRULE ) == SfxItemState::SET,
+ "<SwDocStyleSheet::MergeIndentAttrsOfListStyle(..)> - list level indents are applicable at paragraph style, but no list style found. Serious defect." );
+ const OUString sNumRule = m_pColl->GetNumRule().GetValue();
+ if (sNumRule.isEmpty())
+ return;
+
+ const SwNumRule* pRule = m_rDoc.FindNumRulePtr( sNumRule );
+ if( pRule )
+ {
+ const SwNumFormat& rFormat = pRule->Get( 0 );
+ if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
+ {
+ if (indents & ::sw::ListLevelIndents::FirstLine)
+ {
+ SvxFirstLineIndentItem const firstLine(static_cast<short>(rFormat.GetFirstLineIndent()), RES_MARGIN_FIRSTLINE);
+ rSet.Put(firstLine);
+ }
+ if (indents & ::sw::ListLevelIndents::LeftMargin)
+ {
+ SvxTextLeftMarginItem const leftMargin(rFormat.GetIndentAt(), RES_MARGIN_TEXTLEFT);
+ rSet.Put(leftMargin);
+ }
+ }
+ }
+}
+
+// handling of parameter <bResetIndentAttrsAtParagraphStyle>
+void SwDocStyleSheet::SetItemSet( const SfxItemSet& rSet, const bool bBroadcast,
+ const bool bResetIndentAttrsAtParagraphStyle )
+{
+ // if applicable determine format first
+ if(!m_bPhysical)
+ FillStyleSheet( FillPhysical );
+
+ SwImplShellAction aTmpSh( m_rDoc );
+
+ OSL_ENSURE( &rSet != &m_aCoreSet, "SetItemSet with own Set is not allowed" );
+
+ if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
+ {
+ SwRewriter aRewriter;
+ aRewriter.AddRule( UndoArg1, GetName() );
+ m_rDoc.GetIDocumentUndoRedo().StartUndo( SwUndoId::INSFMTATTR, &aRewriter );
+ }
+
+ SwFormat* pFormat = nullptr;
+ std::vector<sal_uInt16> aWhichIdsToReset;
+ std::unique_ptr<SwPageDesc> pNewDsc;
+ size_t nPgDscPos = 0;
+
+ switch(nFamily)
+ {
+ case SfxStyleFamily::Char :
+ {
+ OSL_ENSURE(m_pCharFormat, "Where's CharFormat");
+ pFormat = m_pCharFormat;
+ }
+ break;
+
+ case SfxStyleFamily::Para :
+ {
+ OSL_ENSURE(m_pColl, "Where's Collection");
+ if(const SfxBoolItem* pAutoUpdate = rSet.GetItemIfSet(SID_ATTR_AUTO_STYLE_UPDATE,false))
+ {
+ m_pColl->SetAutoUpdateOnDirectFormat(pAutoUpdate->GetValue());
+ }
+
+ const SwCondCollItem* pCondItem = rSet.GetItemIfSet( FN_COND_COLL, false );
+
+ if( RES_CONDTXTFMTCOLL == m_pColl->Which() && pCondItem )
+ {
+ const CommandStruct* pCmds = SwCondCollItem::GetCmds();
+ for(sal_uInt16 i = 0; i < COND_COMMAND_COUNT; i++)
+ {
+ SwCollCondition aCond( nullptr, pCmds[ i ].nCnd, pCmds[ i ].nSubCond );
+ static_cast<SwConditionTextFormatColl*>(m_pColl)->RemoveCondition( aCond );
+ const OUString sStyle = pCondItem->GetStyle( i );
+ if (sStyle.isEmpty())
+ continue;
+ SwFormat *const pFindFormat = lcl_FindParaFormat( m_rDoc, sStyle );
+ if (pFindFormat)
+ {
+ aCond.RegisterToFormat( *pFindFormat );
+ static_cast<SwConditionTextFormatColl*>(m_pColl)->InsertCondition( aCond );
+ }
+ }
+
+ m_pColl->GetNotifier().Broadcast(sw::CondCollCondChg(*m_pColl));
+ }
+ else if( pCondItem && !m_pColl->HasWriterListeners() )
+ {
+ // no conditional template, then first create and adopt
+ // all important values
+ SwConditionTextFormatColl* pCColl = m_rDoc.MakeCondTextFormatColl(
+ m_pColl->GetName(), static_cast<SwTextFormatColl*>(m_pColl->DerivedFrom()) );
+ if( m_pColl != &m_pColl->GetNextTextFormatColl() )
+ pCColl->SetNextTextFormatColl( m_pColl->GetNextTextFormatColl() );
+
+ if( m_pColl->IsAssignedToListLevelOfOutlineStyle())
+ pCColl->AssignToListLevelOfOutlineStyle(m_pColl->GetAssignedOutlineStyleLevel());
+ else
+ pCColl->DeleteAssignmentToListLevelOfOutlineStyle();
+
+ const CommandStruct* pCmds = SwCondCollItem::GetCmds();
+ for( sal_uInt16 i = 0; i < COND_COMMAND_COUNT; ++i )
+ {
+ const OUString sStyle = pCondItem->GetStyle( i );
+ if (sStyle.isEmpty())
+ continue;
+ SwTextFormatColl *const pFindFormat = lcl_FindParaFormat( m_rDoc, sStyle );
+ if (pFindFormat)
+ {
+ pCColl->InsertCondition( SwCollCondition( pFindFormat,
+ pCmds[ i ].nCnd, pCmds[ i ].nSubCond ) );
+ }
+ }
+
+ m_rDoc.DelTextFormatColl( m_pColl );
+ m_pColl = pCColl;
+ }
+ if ( bResetIndentAttrsAtParagraphStyle &&
+ rSet.GetItemState( RES_PARATR_NUMRULE, false ) == SfxItemState::SET &&
+ rSet.GetItemState(RES_MARGIN_FIRSTLINE, false) != SfxItemState::SET &&
+ m_pColl->GetItemState(RES_MARGIN_FIRSTLINE, false) == SfxItemState::SET)
+ {
+ aWhichIdsToReset.emplace_back(RES_MARGIN_FIRSTLINE);
+ }
+ if ( bResetIndentAttrsAtParagraphStyle &&
+ rSet.GetItemState( RES_PARATR_NUMRULE, false ) == SfxItemState::SET &&
+ rSet.GetItemState(RES_MARGIN_TEXTLEFT, false) != SfxItemState::SET &&
+ m_pColl->GetItemState(RES_MARGIN_TEXTLEFT, false) == SfxItemState::SET)
+ {
+ aWhichIdsToReset.emplace_back(RES_MARGIN_TEXTLEFT);
+ }
+
+ // #i56252: If a standard numbering style is assigned to a standard paragraph style
+ // we have to create a physical instance of the numbering style. If we do not and
+ // neither the paragraph style nor the numbering style is used in the document
+ // the numbering style will not be saved with the document and the assignment got lost.
+ if( const SfxPoolItem* pNumRuleItem = rSet.GetItemIfSet( RES_PARATR_NUMRULE, false ) )
+ { // Setting a numbering rule?
+ const OUString sNumRule = static_cast<const SwNumRuleItem*>(pNumRuleItem)->GetValue();
+ if (!sNumRule.isEmpty())
+ {
+ SwNumRule* pRule = m_rDoc.FindNumRulePtr( sNumRule );
+ if( !pRule )
+ { // Numbering rule not in use yet.
+ sal_uInt16 nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( sNumRule, SwGetPoolIdFromName::NumRule );
+ if( USHRT_MAX != nPoolId ) // It's a standard numbering rule
+ {
+ m_rDoc.getIDocumentStylePoolAccess().GetNumRuleFromPool( nPoolId ); // Create numbering rule (physical)
+ }
+ }
+ }
+ }
+
+ pFormat = m_pColl;
+
+ sal_uInt16 nId = m_pColl->GetPoolFormatId() &
+ ~ ( COLL_GET_RANGE_BITS | POOLGRP_NOCOLLID );
+ switch( GetMask() & ( static_cast<SfxStyleSearchBits>(0x0fff) & ~SfxStyleSearchBits::SwCondColl ) )
+ {
+ case SfxStyleSearchBits::SwText:
+ nId |= COLL_TEXT_BITS;
+ break;
+ case SfxStyleSearchBits::SwChapter:
+ nId |= COLL_DOC_BITS;
+ break;
+ case SfxStyleSearchBits::SwList:
+ nId |= COLL_LISTS_BITS;
+ break;
+ case SfxStyleSearchBits::SwIndex:
+ nId |= COLL_REGISTER_BITS;
+ break;
+ case SfxStyleSearchBits::SwExtra:
+ nId |= COLL_EXTRA_BITS;
+ break;
+ case SfxStyleSearchBits::SwHtml:
+ nId |= COLL_HTML_BITS;
+ break;
+ default: break;
+ }
+ m_pColl->SetPoolFormatId( nId );
+ break;
+ }
+ case SfxStyleFamily::Frame:
+ {
+ OSL_ENSURE(m_pFrameFormat, "Where's FrameFormat");
+
+ if(const SfxPoolItem* pAutoUpdate = rSet.GetItemIfSet(SID_ATTR_AUTO_STYLE_UPDATE,false))
+ {
+ m_pFrameFormat->SetAutoUpdateOnDirectFormat(static_cast<const SfxBoolItem*>(pAutoUpdate)->GetValue());
+ }
+ pFormat = m_pFrameFormat;
+ }
+ break;
+
+ case SfxStyleFamily::Page :
+ {
+ OSL_ENSURE(m_pDesc, "Where's PageDescriptor");
+
+ if (m_rDoc.FindPageDesc(m_pDesc->GetName(), &nPgDscPos))
+ {
+ pNewDsc.reset( new SwPageDesc( *m_pDesc ) );
+ // #i48949# - no undo actions for the
+ // copy of the page style
+ ::sw::UndoGuard const ug(m_rDoc.GetIDocumentUndoRedo());
+ m_rDoc.CopyPageDesc(*m_pDesc, *pNewDsc); // #i7983#
+
+ pFormat = &pNewDsc->GetMaster();
+ }
+ }
+ break;
+
+ case SfxStyleFamily::Pseudo:
+ {
+ OSL_ENSURE(m_pNumRule, "Where's NumRule");
+
+ if (!m_pNumRule)
+ break;
+
+ const SfxPoolItem* pItem;
+ switch( rSet.GetItemState( SID_ATTR_NUMBERING_RULE, false, &pItem ))
+ {
+ case SfxItemState::SET:
+ {
+ SvxNumRule& rSetRule = const_cast<SvxNumRule&>(static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule());
+ rSetRule.UnLinkGraphics();
+ SwNumRule aSetRule(*m_pNumRule);
+ aSetRule.SetSvxRule(rSetRule, &m_rDoc);
+ m_rDoc.ChgNumRuleFormats( aSetRule );
+ }
+ break;
+ case SfxItemState::DONTCARE:
+ // set NumRule to default values
+ // what are the default values?
+ {
+ SwNumRule aRule( m_pNumRule->GetName(),
+ // #i89178#
+ numfunc::GetDefaultPositionAndSpaceMode() );
+ m_rDoc.ChgNumRuleFormats( aRule );
+ }
+ break;
+ default: break;
+ }
+ }
+ break;
+
+ default:
+ OSL_ENSURE(false, "unknown style family");
+ }
+
+ if( pFormat && rSet.Count())
+ {
+ SfxItemIter aIter( rSet );
+ const SfxPoolItem* pItem = aIter.GetCurItem();
+ do
+ {
+ if( IsInvalidItem( pItem ) ) // Clear
+ {
+ // use method <SwDoc::ResetAttrAtFormat(..)> in order to
+ // create an Undo object for the attribute reset.
+ aWhichIdsToReset.emplace_back(rSet.GetWhichByOffset(aIter.GetCurPos()));
+ }
+
+ pItem = aIter.NextItem();
+ } while (pItem);
+
+ m_rDoc.ResetAttrAtFormat(aWhichIdsToReset, *pFormat);
+
+ SfxItemSet aSet(rSet);
+ aSet.ClearInvalidItems();
+
+ if(SfxStyleFamily::Frame == nFamily)
+ {
+ // Need to check for unique item for DrawingLayer items of type NameOrIndex
+ // and evtl. correct that item to ensure unique names for that type. This call may
+ // modify/correct entries inside of the given SfxItemSet
+ m_rDoc.CheckForUniqueItemForLineFillNameOrIndex(aSet);
+ }
+
+ m_aCoreSet.ClearItem();
+
+ if( pNewDsc )
+ {
+ ::ItemSetToPageDesc( aSet, *pNewDsc );
+ m_rDoc.ChgPageDesc( nPgDscPos, *pNewDsc );
+ m_pDesc = &m_rDoc.GetPageDesc( nPgDscPos );
+ m_rDoc.PreDelPageDesc(pNewDsc.get()); // #i7983#
+ pNewDsc.reset();
+ }
+ else
+ {
+ m_rDoc.ChgFormat(*pFormat, aSet); // put all that is set
+ if (bBroadcast)
+ m_pPool->Broadcast(SfxStyleSheetHint(SfxHintId::StyleSheetModified, *this));
+ }
+ }
+ else
+ {
+ m_aCoreSet.ClearItem();
+ if( pNewDsc ) // we still need to delete it
+ {
+ m_rDoc.PreDelPageDesc(pNewDsc.get()); // #i7983#
+ pNewDsc.reset();
+ }
+ }
+
+ if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
+ {
+ m_rDoc.GetIDocumentUndoRedo().EndUndo(SwUndoId::END, nullptr);
+ }
+}
+
+static void lcl_SaveStyles( SfxStyleFamily nFamily, std::vector<void*>& rArr, SwDoc& rDoc )
+{
+ switch( nFamily )
+ {
+ case SfxStyleFamily::Char:
+ {
+ const SwCharFormats& rTable = *rDoc.GetCharFormats();
+ for(auto const& rChar: rTable)
+ {
+ rArr.push_back(rChar);
+ }
+ }
+ break;
+ case SfxStyleFamily::Para:
+ {
+ const SwTextFormatColls& rTable = *rDoc.GetTextFormatColls();
+ for(auto const& rPara : rTable)
+ {
+ rArr.push_back(rPara);
+ }
+ }
+ break;
+ case SfxStyleFamily::Frame:
+ {
+ for(auto const& rFrame: *rDoc.GetFrameFormats())
+ {
+ rArr.push_back(rFrame);
+ }
+ }
+ break;
+
+ case SfxStyleFamily::Page:
+ {
+ for( size_t n = 0, nCnt = rDoc.GetPageDescCnt(); n < nCnt; ++n )
+ {
+ rArr.push_back( &rDoc.GetPageDesc( n ) );
+ }
+ }
+ break;
+
+ case SfxStyleFamily::Pseudo:
+ {
+ const SwNumRuleTable& rTable = rDoc.GetNumRuleTable();
+ for(auto const& rPseudo: rTable)
+ {
+ rArr.push_back(rPseudo);
+ }
+ }
+ break;
+ default: break;
+ }
+}
+
+static bool lcl_Contains(const std::vector<void*>& rArr, const void* p)
+{
+ return std::find( rArr.begin(), rArr.end(), p ) != rArr.end();
+}
+
+static void lcl_DeleteInfoStyles( SfxStyleFamily nFamily, std::vector<void*> const & rArr, SwDoc& rDoc )
+{
+ size_t n, nCnt;
+ switch( nFamily )
+ {
+ case SfxStyleFamily::Char:
+ {
+ std::deque<sal_uInt16> aDelArr;
+ const SwCharFormats& rTable = *rDoc.GetCharFormats();
+ for( n = 0, nCnt = rTable.size(); n < nCnt; ++n )
+ {
+ if( !lcl_Contains( rArr, rTable[ n ] ))
+ aDelArr.push_front( n );
+ }
+ for(auto const& rDelArr: aDelArr)
+ rDoc.DelCharFormat( rDelArr );
+ }
+ break;
+
+ case SfxStyleFamily::Para :
+ {
+ std::deque<sal_uInt16> aDelArr;
+ const SwTextFormatColls& rTable = *rDoc.GetTextFormatColls();
+ for( n = 0, nCnt = rTable.size(); n < nCnt; ++n )
+ {
+ if( !lcl_Contains( rArr, rTable[ n ] ))
+ aDelArr.push_front( n );
+ }
+ for(auto const& rDelArr: aDelArr)
+ rDoc.DelTextFormatColl( rDelArr );
+ }
+ break;
+
+ case SfxStyleFamily::Frame:
+ {
+ std::deque<SwFrameFormat*> aDelArr;
+ for(auto const& rFrame: *rDoc.GetFrameFormats())
+ {
+ if( !lcl_Contains( rArr, rFrame ))
+ aDelArr.push_front( rFrame );
+ }
+ for( auto const& rDelArr: aDelArr)
+ rDoc.DelFrameFormat( rDelArr );
+ }
+ break;
+
+ case SfxStyleFamily::Page:
+ {
+ std::deque<size_t> aDelArr;
+ for( n = 0, nCnt = rDoc.GetPageDescCnt(); n < nCnt; ++n )
+ {
+ if( !lcl_Contains( rArr, &rDoc.GetPageDesc( n ) ))
+ aDelArr.push_front( n );
+ }
+ for( auto const& rDelArr: aDelArr )
+ rDoc.DelPageDesc( rDelArr);
+ }
+ break;
+
+ case SfxStyleFamily::Pseudo:
+ {
+ std::deque<SwNumRule*> aDelArr;
+ const SwNumRuleTable& rTable = rDoc.GetNumRuleTable();
+ for( auto const& rPseudo: rTable)
+ {
+ if( !lcl_Contains( rArr, rPseudo ))
+ aDelArr.push_front( rPseudo );
+ }
+ for( auto const& rDelArr: aDelArr)
+ rDoc.DelNumRule( rDelArr->GetName() );
+ }
+ break;
+ default: break;
+ }
+}
+
+// determine the format
+bool SwDocStyleSheet::FillStyleSheet(
+ FillStyleType const eFType, std::optional<SfxItemSet> *const o_ppFlatSet)
+{
+ bool bRet = false;
+ sal_uInt16 nPoolId = USHRT_MAX;
+ SwFormat* pFormat = nullptr;
+
+ bool bCreate = FillPhysical == eFType;
+ bool bDeleteInfo = false;
+ bool bFillOnlyInfo = FillAllInfo == eFType || FillPreview == eFType;
+ std::vector<void*> aDelArr;
+ bool const isModified(m_rDoc.getIDocumentState().IsModified());
+
+ switch(nFamily)
+ {
+ case SfxStyleFamily::Char:
+ m_pCharFormat = lcl_FindCharFormat(m_rDoc, aName, this, bCreate );
+ m_bPhysical = nullptr != m_pCharFormat;
+ if( bFillOnlyInfo && !m_bPhysical )
+ {
+ // create style (plus all needed parents) and clean it up
+ // later - without affecting the undo/redo stack
+ ::sw::UndoGuard const ug(m_rDoc.GetIDocumentUndoRedo());
+ bDeleteInfo = true;
+ ::lcl_SaveStyles( nFamily, aDelArr, m_rDoc );
+ m_pCharFormat = lcl_FindCharFormat(m_rDoc, aName, this );
+ }
+
+ pFormat = m_pCharFormat;
+ m_aLink.clear();
+ if( !bCreate && !pFormat )
+ {
+ if( aName == SwResId(STR_POOLCHR_STANDARD))
+ nPoolId = 0;
+ else
+ nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( aName, SwGetPoolIdFromName::ChrFmt );
+ }
+
+ if (m_pCharFormat)
+ {
+ const SwTextFormatColl* pParaFormat = m_pCharFormat->GetLinkedParaFormat();
+ if (pParaFormat)
+ {
+ m_aLink = pParaFormat->GetName();
+ }
+ }
+
+ bRet = nullptr != m_pCharFormat || USHRT_MAX != nPoolId;
+
+ if( bDeleteInfo )
+ m_pCharFormat = nullptr;
+ break;
+
+ case SfxStyleFamily::Para:
+ {
+ m_pColl = lcl_FindParaFormat(m_rDoc, aName, this, bCreate);
+ m_bPhysical = nullptr != m_pColl;
+ if( bFillOnlyInfo && !m_bPhysical )
+ {
+ ::sw::UndoGuard const ug(m_rDoc.GetIDocumentUndoRedo());
+ bDeleteInfo = true;
+ ::lcl_SaveStyles( nFamily, aDelArr, m_rDoc );
+ m_pColl = lcl_FindParaFormat(m_rDoc, aName, this );
+ }
+
+ pFormat = m_pColl;
+ m_aLink.clear();
+ if( m_pColl )
+ {
+ PresetFollow( m_pColl->GetNextTextFormatColl().GetName() );
+ const SwCharFormat* pCharFormat = m_pColl->GetLinkedCharFormat();
+ if (pCharFormat)
+ {
+ m_aLink = pCharFormat->GetName();
+ }
+ }
+ else if( !bCreate )
+ nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( aName, SwGetPoolIdFromName::TxtColl );
+
+ bRet = nullptr != m_pColl || USHRT_MAX != nPoolId;
+
+ if( bDeleteInfo )
+ m_pColl = nullptr;
+ }
+ break;
+
+ case SfxStyleFamily::Frame:
+ m_pFrameFormat = lcl_FindFrameFormat(m_rDoc, aName, this, bCreate);
+ m_bPhysical = nullptr != m_pFrameFormat;
+ if (bFillOnlyInfo && !m_bPhysical)
+ {
+ ::sw::UndoGuard const ug(m_rDoc.GetIDocumentUndoRedo());
+ bDeleteInfo = true;
+ ::lcl_SaveStyles( nFamily, aDelArr, m_rDoc );
+ m_pFrameFormat = lcl_FindFrameFormat(m_rDoc, aName, this );
+ }
+ pFormat = m_pFrameFormat;
+ if( !bCreate && !pFormat )
+ nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( aName, SwGetPoolIdFromName::FrmFmt );
+
+ bRet = nullptr != m_pFrameFormat || USHRT_MAX != nPoolId;
+
+ if( bDeleteInfo )
+ m_pFrameFormat = nullptr;
+ break;
+
+ case SfxStyleFamily::Page:
+ m_pDesc = lcl_FindPageDesc(m_rDoc, aName, this, bCreate);
+ m_bPhysical = nullptr != m_pDesc;
+ if( bFillOnlyInfo && !m_pDesc )
+ {
+ ::sw::UndoGuard const ug(m_rDoc.GetIDocumentUndoRedo());
+ bDeleteInfo = true;
+ ::lcl_SaveStyles( nFamily, aDelArr, m_rDoc );
+ m_pDesc = lcl_FindPageDesc( m_rDoc, aName, this );
+ }
+
+ if( m_pDesc )
+ {
+ nPoolId = m_pDesc->GetPoolFormatId();
+ nHelpId = m_pDesc->GetPoolHelpId();
+ if (const OUString* pattern = m_pDesc->GetPoolHlpFileId() != UCHAR_MAX
+ ? m_rDoc.GetDocPattern(m_pDesc->GetPoolHlpFileId())
+ : nullptr)
+ aHelpFile = *pattern;
+ else
+ aHelpFile.clear();
+ }
+ else if( !bCreate )
+ nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( aName, SwGetPoolIdFromName::PageDesc );
+ SetMask( (USER_FMT & nPoolId) ? SfxStyleSearchBits::UserDefined : SfxStyleSearchBits::Auto );
+
+ bRet = nullptr != m_pDesc || USHRT_MAX != nPoolId;
+ if( bDeleteInfo )
+ m_pDesc = nullptr;
+ break;
+
+ case SfxStyleFamily::Pseudo:
+ m_pNumRule = lcl_FindNumRule(m_rDoc, aName, this, bCreate);
+ m_bPhysical = nullptr != m_pNumRule;
+ if( bFillOnlyInfo && !m_pNumRule )
+ {
+ ::sw::UndoGuard const ug(m_rDoc.GetIDocumentUndoRedo());
+ bDeleteInfo = true;
+ ::lcl_SaveStyles( nFamily, aDelArr, m_rDoc );
+ m_pNumRule = lcl_FindNumRule( m_rDoc, aName, this );
+ }
+
+ if( m_pNumRule )
+ {
+ nPoolId = m_pNumRule->GetPoolFormatId();
+ nHelpId = m_pNumRule->GetPoolHelpId();
+ if (const OUString* pattern = m_pNumRule->GetPoolHlpFileId() != UCHAR_MAX
+ ? m_rDoc.GetDocPattern(m_pNumRule->GetPoolHlpFileId())
+ : nullptr)
+ aHelpFile = *pattern;
+ else
+ aHelpFile.clear();
+ }
+ else if( !bCreate )
+ nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( aName, SwGetPoolIdFromName::NumRule );
+ SetMask( (USER_FMT & nPoolId) ? SfxStyleSearchBits::UserDefined : SfxStyleSearchBits::Auto );
+
+ bRet = nullptr != m_pNumRule || USHRT_MAX != nPoolId;
+
+ if( bDeleteInfo )
+ m_pNumRule = nullptr;
+ break;
+
+ case SfxStyleFamily::Table:
+ m_pTableFormat = lcl_FindTableStyle(m_rDoc, aName, this, bCreate);
+ SetMask((m_pTableFormat && m_pTableFormat->IsUserDefined()) ? SfxStyleSearchBits::UserDefined : SfxStyleSearchBits::Auto);
+ bRet = m_bPhysical = (nullptr != m_pTableFormat);
+ break;
+
+ case SfxStyleFamily::Cell:
+ m_pBoxFormat = lcl_FindCellStyle(m_rDoc, aName, this);
+ bRet = m_bPhysical = (nullptr != m_pBoxFormat);
+ break;
+ default:; //prevent warning
+ }
+
+ if( SfxStyleFamily::Char == nFamily ||
+ SfxStyleFamily::Para == nFamily ||
+ SfxStyleFamily::Frame == nFamily )
+ {
+ if( pFormat )
+ nPoolId = pFormat->GetPoolFormatId();
+
+ SfxStyleSearchBits _nMask = SfxStyleSearchBits::Auto;
+ if( pFormat == m_rDoc.GetDfltCharFormat() )
+ _nMask |= SfxStyleSearchBits::ReadOnly;
+ else if( USER_FMT & nPoolId )
+ _nMask |= SfxStyleSearchBits::UserDefined;
+
+ switch ( COLL_GET_RANGE_BITS & nPoolId )
+ {
+ case COLL_TEXT_BITS: _nMask |= SfxStyleSearchBits::SwText; break;
+ case COLL_DOC_BITS : _nMask |= SfxStyleSearchBits::SwChapter; break;
+ case COLL_LISTS_BITS: _nMask |= SfxStyleSearchBits::SwList; break;
+ case COLL_REGISTER_BITS: _nMask |= SfxStyleSearchBits::SwIndex; break;
+ case COLL_EXTRA_BITS: _nMask |= SfxStyleSearchBits::SwExtra; break;
+ case COLL_HTML_BITS: _nMask |= SfxStyleSearchBits::SwHtml; break;
+ }
+
+ if( pFormat )
+ {
+ OSL_ENSURE( m_bPhysical, "Format not found" );
+
+ nHelpId = pFormat->GetPoolHelpId();
+ if (const OUString* pattern = pFormat->GetPoolHlpFileId() != UCHAR_MAX
+ ? m_rDoc.GetDocPattern(pFormat->GetPoolHlpFileId())
+ : nullptr)
+ aHelpFile = *pattern;
+ else
+ aHelpFile.clear();
+
+ if( RES_CONDTXTFMTCOLL == pFormat->Which() )
+ _nMask |= SfxStyleSearchBits::SwCondColl;
+
+ if (FillPreview == eFType)
+ {
+ assert(o_ppFlatSet);
+ lcl_SwFormatToFlatItemSet(pFormat, *o_ppFlatSet);
+ }
+ }
+
+ SetMask( _nMask );
+ }
+ if( bDeleteInfo && bFillOnlyInfo )
+ {
+ ::sw::UndoGuard const ug(m_rDoc.GetIDocumentUndoRedo());
+ ::lcl_DeleteInfoStyles( nFamily, aDelArr, m_rDoc );
+ if (!isModified)
+ {
+ m_rDoc.getIDocumentState().ResetModified();
+ }
+ }
+ return bRet;
+}
+
+// Create new format in Core
+void SwDocStyleSheet::Create()
+{
+ switch(nFamily)
+ {
+ case SfxStyleFamily::Char :
+ m_pCharFormat = lcl_FindCharFormat( m_rDoc, aName );
+ if( !m_pCharFormat )
+ m_pCharFormat = m_rDoc.MakeCharFormat(aName,
+ m_rDoc.GetDfltCharFormat());
+ m_pCharFormat->SetAuto(false);
+ break;
+
+ case SfxStyleFamily::Para :
+ m_pColl = lcl_FindParaFormat( m_rDoc, aName );
+ if( !m_pColl )
+ {
+ SwTextFormatColl *pPar = (*m_rDoc.GetTextFormatColls())[0];
+ if( nMask & SfxStyleSearchBits::SwCondColl )
+ m_pColl = m_rDoc.MakeCondTextFormatColl( aName, pPar );
+ else
+ m_pColl = m_rDoc.MakeTextFormatColl( aName, pPar );
+ }
+ break;
+
+ case SfxStyleFamily::Frame:
+ m_pFrameFormat = lcl_FindFrameFormat( m_rDoc, aName );
+ if( !m_pFrameFormat )
+ m_pFrameFormat = m_rDoc.MakeFrameFormat(aName, m_rDoc.GetDfltFrameFormat(), false, false);
+
+ break;
+
+ case SfxStyleFamily::Page :
+ m_pDesc = lcl_FindPageDesc( m_rDoc, aName );
+ if( !m_pDesc )
+ {
+ m_pDesc = m_rDoc.MakePageDesc(aName);
+ }
+ break;
+
+ case SfxStyleFamily::Pseudo:
+ m_pNumRule = lcl_FindNumRule( m_rDoc, aName );
+ if( !m_pNumRule )
+ {
+ const OUString sTmpNm( aName.isEmpty() ? m_rDoc.GetUniqueNumRuleName() : aName );
+ SwNumRule* pRule = m_rDoc.GetNumRuleTable()[
+ m_rDoc.MakeNumRule( sTmpNm, nullptr, false,
+ // #i89178#
+ numfunc::GetDefaultPositionAndSpaceMode() ) ];
+ pRule->SetAutoRule( false );
+ if( aName.isEmpty() )
+ {
+ // #i91400#
+ pRule->SetName( aName, m_rDoc.getIDocumentListsAccess() );
+ }
+ m_pNumRule = pRule;
+ }
+ break;
+
+ case SfxStyleFamily::Table:
+ if (aName.isEmpty())
+ return;
+ m_pTableFormat = lcl_FindTableStyle(m_rDoc, aName);
+ if (!m_pTableFormat)
+ {
+ m_rDoc.MakeTableStyle(aName);
+ m_pTableFormat = m_rDoc.GetTableStyles().FindAutoFormat(aName);
+ SAL_WARN_IF(!m_pTableFormat, "sw.ui", "Recently added auto format not found");
+ }
+ break;
+ default:; //prevent warning
+ }
+ m_bPhysical = true;
+ m_aCoreSet.ClearItem();
+}
+
+SwCharFormat* SwDocStyleSheet::GetCharFormat()
+{
+ if(!m_bPhysical)
+ FillStyleSheet( FillPhysical );
+ return m_pCharFormat;
+}
+
+SwTextFormatColl* SwDocStyleSheet::GetCollection()
+{
+ if(!m_bPhysical)
+ FillStyleSheet( FillPhysical );
+ return m_pColl;
+}
+
+const SwPageDesc* SwDocStyleSheet::GetPageDesc()
+{
+ if(!m_bPhysical)
+ FillStyleSheet( FillPhysical );
+ return m_pDesc;
+}
+
+const SwNumRule * SwDocStyleSheet::GetNumRule()
+{
+ if(!m_bPhysical)
+ FillStyleSheet( FillPhysical );
+ return m_pNumRule;
+}
+
+
+void SwDocStyleSheet::SetNumRule(const SwNumRule& rRule)
+{
+ OSL_ENSURE(m_pNumRule, "Where is the NumRule");
+ m_rDoc.ChgNumRuleFormats( rRule );
+}
+
+SwTableAutoFormat* SwDocStyleSheet::GetTableFormat()
+{
+ if(!m_bPhysical)
+ FillStyleSheet( FillPhysical );
+ assert(m_pTableFormat && "SwDocStyleSheet table style, SwTableAutoFormat not found");
+ return m_pTableFormat;
+}
+
+// re-generate Name AND Family from String
+// First() and Next() (see below) insert an identification letter at Pos.1
+
+void SwDocStyleSheet::PresetNameAndFamily(SfxStyleFamily eFamily, const OUString& rName)
+{
+ this->nFamily = eFamily;
+ this->aName = rName;
+}
+
+// Is the format physically present yet
+void SwDocStyleSheet::SetPhysical(bool bPhys)
+{
+ m_bPhysical = bPhys;
+
+ if(!bPhys)
+ {
+ m_pCharFormat = nullptr;
+ m_pColl = nullptr;
+ m_pFrameFormat = nullptr;
+ m_pDesc = nullptr;
+ }
+}
+
+SwFrameFormat* SwDocStyleSheet::GetFrameFormat()
+{
+ if(!m_bPhysical)
+ FillStyleSheet( FillPhysical );
+ return m_pFrameFormat;
+}
+
+bool SwDocStyleSheet::IsUsed() const
+{
+ if( !m_bPhysical )
+ {
+ SwDocStyleSheet* pThis = const_cast<SwDocStyleSheet*>(this);
+ pThis->FillStyleSheet( FillOnlyName );
+ }
+
+ if( !m_bPhysical )
+ return false;
+
+ const sw::BroadcastingModify* pMod;
+ switch( nFamily )
+ {
+ case SfxStyleFamily::Char : pMod = m_pCharFormat; break;
+ case SfxStyleFamily::Para : pMod = m_pColl; break;
+ case SfxStyleFamily::Frame: pMod = m_pFrameFormat; break;
+ case SfxStyleFamily::Page : pMod = m_pDesc; break;
+
+ case SfxStyleFamily::Pseudo:
+ return m_pNumRule && m_rDoc.IsUsed(*m_pNumRule);
+
+ case SfxStyleFamily::Table:
+ return m_pTableFormat && m_rDoc.IsUsed( *m_pTableFormat );
+
+ default:
+ OSL_ENSURE(false, "unknown style family");
+ return false;
+ }
+
+ if (m_rDoc.IsUsed(*pMod))
+ return true;
+
+ SfxStyleSheetIterator aIter(static_cast<SwDocStyleSheetPool*>(m_pPool)->GetEEStyleSheetPool(), nFamily,
+ SfxStyleSearchBits::Used);
+ return aIter.Find(GetName()) != nullptr;
+}
+
+OUString SwDocStyleSheet::GetUsedBy()
+{
+ return m_pNumRule ? m_pNumRule->MakeParagraphStyleListString() : OUString();
+}
+
+sal_uLong SwDocStyleSheet::GetHelpId( OUString& rFile )
+{
+ sal_uInt16 nId = 0;
+ sal_uInt16 nPoolId = 0;
+ unsigned char nFileId = UCHAR_MAX;
+
+ rFile = "swrhlppi.hlp";
+
+ const SwFormat* pTmpFormat = nullptr;
+ switch( nFamily )
+ {
+ case SfxStyleFamily::Char :
+ if( !m_pCharFormat &&
+ nullptr == (m_pCharFormat = lcl_FindCharFormat( m_rDoc, aName, nullptr, false )) )
+ {
+ nId = SwStyleNameMapper::GetPoolIdFromUIName( aName, SwGetPoolIdFromName::ChrFmt );
+ return USHRT_MAX == nId ? 0 : nId;
+ }
+ pTmpFormat = m_pCharFormat;
+ break;
+
+ case SfxStyleFamily::Para:
+ if( !m_pColl &&
+ nullptr == ( m_pColl = lcl_FindParaFormat( m_rDoc, aName, nullptr, false )) )
+ {
+ nId = SwStyleNameMapper::GetPoolIdFromUIName( aName, SwGetPoolIdFromName::TxtColl );
+ return USHRT_MAX == nId ? 0 : nId;
+ }
+ pTmpFormat = m_pColl;
+ break;
+
+ case SfxStyleFamily::Frame:
+ if( !m_pFrameFormat &&
+ nullptr == ( m_pFrameFormat = lcl_FindFrameFormat( m_rDoc, aName, nullptr, false ) ) )
+ {
+ nId = SwStyleNameMapper::GetPoolIdFromUIName( aName, SwGetPoolIdFromName::FrmFmt );
+ return USHRT_MAX == nId ? 0 : nId;
+ }
+ pTmpFormat = m_pFrameFormat;
+ break;
+
+ case SfxStyleFamily::Page:
+ if( !m_pDesc &&
+ nullptr == ( m_pDesc = lcl_FindPageDesc( m_rDoc, aName, nullptr, false ) ) )
+ {
+ nId = SwStyleNameMapper::GetPoolIdFromUIName( aName, SwGetPoolIdFromName::PageDesc );
+ return USHRT_MAX == nId ? 0 : nId;
+ }
+
+ nId = m_pDesc->GetPoolHelpId();
+ nFileId = m_pDesc->GetPoolHlpFileId();
+ nPoolId = m_pDesc->GetPoolFormatId();
+ break;
+
+ case SfxStyleFamily::Pseudo:
+ if( !m_pNumRule &&
+ nullptr == ( m_pNumRule = lcl_FindNumRule( m_rDoc, aName, nullptr, false ) ) )
+ {
+ nId = SwStyleNameMapper::GetPoolIdFromUIName( aName, SwGetPoolIdFromName::NumRule );
+ return USHRT_MAX == nId ? 0 : nId;
+ }
+
+ nId = m_pNumRule->GetPoolHelpId();
+ nFileId = m_pNumRule->GetPoolHlpFileId();
+ nPoolId = m_pNumRule->GetPoolFormatId();
+ break;
+
+ default:
+ OSL_ENSURE(false, "unknown style family");
+ return 0;
+ }
+
+ if( pTmpFormat )
+ {
+ nId = pTmpFormat->GetPoolHelpId();
+ nFileId = pTmpFormat->GetPoolHlpFileId();
+ nPoolId = pTmpFormat->GetPoolFormatId();
+ }
+
+ if( UCHAR_MAX != nFileId )
+ {
+ const OUString *pTemplate = m_rDoc.GetDocPattern( nFileId );
+ if( pTemplate )
+ {
+ rFile = *pTemplate;
+ }
+ }
+ else if( !IsPoolUserFormat( nPoolId ) )
+ {
+ nId = nPoolId;
+ }
+
+ // because SFX acts like that, with HelpId:
+ if( USHRT_MAX == nId )
+ nId = 0; // don't show Help accordingly
+
+ return nId;
+}
+
+void SwDocStyleSheet::SetHelpId( const OUString& r, sal_uLong nId )
+{
+ sal_uInt8 nFileId = static_cast< sal_uInt8 >(m_rDoc.SetDocPattern( r ));
+ sal_uInt16 nHId = static_cast< sal_uInt16 >(nId); //!! SFX changed over to ULONG arbitrarily!
+
+ SwFormat* pTmpFormat = nullptr;
+ switch( nFamily )
+ {
+ case SfxStyleFamily::Char : pTmpFormat = m_pCharFormat; break;
+ case SfxStyleFamily::Para : pTmpFormat = m_pColl; break;
+ case SfxStyleFamily::Frame: pTmpFormat = m_pFrameFormat; break;
+ case SfxStyleFamily::Page :
+ const_cast<SwPageDesc*>(m_pDesc)->SetPoolHelpId( nHId );
+ const_cast<SwPageDesc*>(m_pDesc)->SetPoolHlpFileId( nFileId );
+ break;
+
+ case SfxStyleFamily::Pseudo:
+ const_cast<SwNumRule*>(m_pNumRule)->SetPoolHelpId( nHId );
+ const_cast<SwNumRule*>(m_pNumRule)->SetPoolHlpFileId( nFileId );
+ break;
+
+ default:
+ OSL_ENSURE(false, "unknown style family");
+ return ;
+ }
+ if( pTmpFormat )
+ {
+ pTmpFormat->SetPoolHelpId( nHId );
+ pTmpFormat->SetPoolHlpFileId( nFileId );
+ }
+}
+
+// methods for DocStyleSheetPool
+SwDocStyleSheetPool::SwDocStyleSheetPool( SwDoc& rDocument, bool bOrg )
+ : SfxStyleSheetBasePool(rDocument.GetAttrPool())
+ , mxStyleSheet(new SwDocStyleSheet(rDocument, *this))
+ , mxEEStyleSheetPool(new EEStyleSheetPool(this))
+ , m_rDoc(rDocument)
+{
+ m_bOrganizer = bOrg;
+}
+
+SwDocStyleSheetPool::~SwDocStyleSheetPool()
+{
+}
+
+SfxStyleSheetBase& SwDocStyleSheetPool::Make( const OUString& rName,
+ SfxStyleFamily eFam,
+ SfxStyleSearchBits _nMask)
+{
+ mxStyleSheet->PresetName(rName);
+ mxStyleSheet->PresetParent(OUString());
+ mxStyleSheet->PresetFollow(OUString());
+ mxStyleSheet->SetMask(_nMask) ;
+ mxStyleSheet->SetFamily(eFam);
+ mxStyleSheet->SetPhysical(true);
+ mxStyleSheet->Create();
+
+ return *mxStyleSheet;
+}
+
+rtl::Reference<SfxStyleSheetBase> SwDocStyleSheetPool::Create( const SfxStyleSheetBase& /*rOrg*/)
+{
+ OSL_ENSURE(false , "Create in SW-Stylesheet-Pool not possible" );
+ return nullptr;
+}
+
+rtl::Reference<SfxStyleSheetBase> SwDocStyleSheetPool::Create( const OUString &,
+ SfxStyleFamily, SfxStyleSearchBits )
+{
+ OSL_ENSURE( false, "Create in SW-Stylesheet-Pool not possible" );
+ return nullptr;
+}
+
+std::unique_ptr<SfxStyleSheetIterator> SwDocStyleSheetPool::CreateIterator( SfxStyleFamily eFam, SfxStyleSearchBits _nMask )
+{
+ return std::make_unique<SwStyleSheetIterator>(*this, eFam, _nMask);
+}
+
+void SwDocStyleSheetPool::dispose()
+{
+ mxStyleSheet.clear();
+ mxEEStyleSheetPool.clear();
+}
+
+void SwDocStyleSheetPool::Remove( SfxStyleSheetBase* pStyle)
+{
+ if( !pStyle )
+ return;
+
+ bool bBroadcast = true;
+ SwImplShellAction aTmpSh( m_rDoc );
+ const OUString sName = pStyle->GetName();
+ switch( pStyle->GetFamily() )
+ {
+ case SfxStyleFamily::Char:
+ {
+ SwCharFormat* pFormat = lcl_FindCharFormat(m_rDoc, sName, nullptr, false );
+ if(pFormat)
+ m_rDoc.DelCharFormat(pFormat);
+ }
+ break;
+ case SfxStyleFamily::Para:
+ {
+ SwTextFormatColl* pColl = lcl_FindParaFormat(m_rDoc, sName, nullptr, false );
+ if(pColl)
+ m_rDoc.DelTextFormatColl(pColl);
+ }
+ break;
+ case SfxStyleFamily::Frame:
+ {
+ SwFrameFormat* pFormat = lcl_FindFrameFormat(m_rDoc, sName, nullptr, false );
+ if(pFormat)
+ m_rDoc.DelFrameFormat(pFormat);
+ }
+ break;
+ case SfxStyleFamily::Page :
+ {
+ m_rDoc.DelPageDesc(sName);
+ }
+ break;
+
+ case SfxStyleFamily::Pseudo:
+ {
+ if( !m_rDoc.DelNumRule( sName ) )
+ // Only send Broadcast, when something was deleted
+ bBroadcast = false;
+ }
+ break;
+
+ case SfxStyleFamily::Table:
+ {
+ m_rDoc.DelTableStyle(sName);
+ }
+ break;
+
+ default:
+ OSL_ENSURE(false, "unknown style family");
+ bBroadcast = false;
+ }
+
+ if( bBroadcast )
+ Broadcast( SfxStyleSheetHint( SfxHintId::StyleSheetErased, *pStyle ) );
+}
+
+SfxStyleSheetBase* SwDocStyleSheetPool::Find(const OUString& rName,
+ SfxStyleFamily eFam, SfxStyleSearchBits n)
+{
+ SfxStyleSearchBits nSMask = n;
+ if( SfxStyleFamily::Para == eFam && m_rDoc.getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE) )
+ {
+ // then only HTML-Templates are of interest
+ if( SfxStyleSearchBits::All == nSMask )
+ nSMask = SfxStyleSearchBits::SwHtml | SfxStyleSearchBits::UserDefined | SfxStyleSearchBits::Used;
+ else
+ nSMask &= SfxStyleSearchBits::Used | SfxStyleSearchBits::UserDefined |
+ SfxStyleSearchBits::SwCondColl | SfxStyleSearchBits::SwHtml;
+ if( nSMask == SfxStyleSearchBits::Auto )
+ nSMask = SfxStyleSearchBits::SwHtml;
+ }
+
+ const bool bSearchUsed = ( n != SfxStyleSearchBits::All && n & SfxStyleSearchBits::Used );
+ const sw::BroadcastingModify* pMod = nullptr;
+
+ mxStyleSheet->SetPhysical( false );
+ mxStyleSheet->PresetName( rName );
+ mxStyleSheet->SetFamily( eFam );
+ bool bFnd = mxStyleSheet->FillStyleSheet( SwDocStyleSheet::FillOnlyName );
+
+ if( mxStyleSheet->IsPhysical() )
+ {
+ switch( eFam )
+ {
+ case SfxStyleFamily::Char:
+ pMod = mxStyleSheet->GetCharFormat();
+ break;
+
+ case SfxStyleFamily::Para:
+ pMod = mxStyleSheet->GetCollection();
+ break;
+
+ case SfxStyleFamily::Frame:
+ pMod = mxStyleSheet->GetFrameFormat();
+ break;
+
+ case SfxStyleFamily::Page:
+ pMod = mxStyleSheet->GetPageDesc();
+ break;
+
+ case SfxStyleFamily::Pseudo:
+ {
+ const SwNumRule* pRule = mxStyleSheet->GetNumRule();
+ if( pRule &&
+ !bSearchUsed &&
+ (( nSMask & ~SfxStyleSearchBits::Used) == SfxStyleSearchBits::UserDefined
+ ? !(pRule->GetPoolFormatId() & USER_FMT)
+ // searched for used and found none
+ : bSearchUsed ))
+ bFnd = false;
+ }
+ break;
+
+ case SfxStyleFamily::Table:
+ case SfxStyleFamily::Cell:
+ break;
+ default:
+ OSL_ENSURE(false, "unknown style family");
+ }
+ }
+
+ // then evaluate the mask:
+ if( pMod && !bSearchUsed )
+ {
+ const sal_uInt16 nId = SfxStyleFamily::Page == eFam
+ ? static_cast<const SwPageDesc*>(pMod)->GetPoolFormatId()
+ : static_cast<const SwFormat*>(pMod)->GetPoolFormatId();
+
+ if( ( nSMask & ~SfxStyleSearchBits::Used) == SfxStyleSearchBits::UserDefined
+ && !(nId & USER_FMT) )
+ // searched for used and found none
+ bFnd = false;
+ }
+ return bFnd ? mxStyleSheet.get() : nullptr;
+}
+
+SwStyleSheetIterator::SwStyleSheetIterator(SwDocStyleSheetPool& rBase,
+ SfxStyleFamily eFam, SfxStyleSearchBits n )
+ : SfxStyleSheetIterator(&rBase, eFam, n)
+ , mxIterSheet(new SwDocStyleSheet(rBase.GetDoc(), rBase))
+ , mxStyleSheet(new SwDocStyleSheet(rBase.GetDoc(), rBase))
+{
+ m_bFirstCalled = false;
+ m_nLastPos = 0;
+ StartListening(rBase);
+}
+
+SwStyleSheetIterator::~SwStyleSheetIterator()
+{
+ EndListening( *mxIterSheet->GetPool() );
+}
+
+sal_Int32 SwStyleSheetIterator::Count()
+{
+ // let the list fill correctly!!
+ if( !m_bFirstCalled )
+ First();
+ return m_aLst.size();
+}
+
+SfxStyleSheetBase* SwStyleSheetIterator::operator[]( sal_Int32 nIdx )
+{
+ // found
+ if( !m_bFirstCalled )
+ First();
+ auto const & rEntry = m_aLst[ nIdx ];
+ mxStyleSheet->PresetNameAndFamily( rEntry.first, rEntry.second );
+ mxStyleSheet->SetPhysical( false );
+ mxStyleSheet->FillStyleSheet( SwDocStyleSheet::FillOnlyName );
+
+ return mxStyleSheet.get();
+}
+
+SfxStyleSheetBase* SwStyleSheetIterator::First()
+{
+ // Delete old list
+ m_bFirstCalled = true;
+ m_nLastPos = 0;
+ m_aLst.clear();
+
+ // Delete current
+ mxIterSheet->Reset();
+
+ const SwDoc& rDoc = static_cast<const SwDocStyleSheetPool*>(pBasePool)->GetDoc();
+ const SfxStyleSearchBits nSrchMask = nMask;
+ const bool bIsSearchUsed = SearchUsed();
+
+ bool bSearchHidden( nMask & SfxStyleSearchBits::Hidden );
+ bool bOnlyHidden = nMask == SfxStyleSearchBits::Hidden;
+
+ const bool bOrganizer = static_cast<const SwDocStyleSheetPool*>(pBasePool)->IsOrganizerMode();
+ bool bAll = ( nSrchMask & SfxStyleSearchBits::AllVisible ) == SfxStyleSearchBits::AllVisible;
+
+ if( nSearchFamily == SfxStyleFamily::Char
+ || nSearchFamily == SfxStyleFamily::All )
+ {
+ const size_t nArrLen = rDoc.GetCharFormats()->size();
+ for( size_t i = 0; i < nArrLen; i++ )
+ {
+ SwCharFormat* pFormat = (*rDoc.GetCharFormats())[ i ];
+
+ const bool bUsed = bIsSearchUsed && (bOrganizer || rDoc.IsUsed(*pFormat));
+ if( ( !bSearchHidden && pFormat->IsHidden() && !bUsed ) || ( pFormat->IsDefault() && pFormat != rDoc.GetDfltCharFormat() ) )
+ continue;
+
+ if ( nSrchMask == SfxStyleSearchBits::Hidden && !pFormat->IsHidden( ) )
+ continue;
+
+ if( !bUsed )
+ {
+ // Standard is no User template
+ const sal_uInt16 nId = rDoc.GetDfltCharFormat() == pFormat ?
+ sal_uInt16( RES_POOLCHR_INET_NORMAL ):
+ pFormat->GetPoolFormatId();
+ if( (nSrchMask & ~SfxStyleSearchBits::Used) == SfxStyleSearchBits::UserDefined
+ ? !(nId & USER_FMT)
+ // searched for used and found none
+ : bIsSearchUsed )
+ {
+ continue;
+ }
+
+ if( rDoc.getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE) && !(nId & USER_FMT) &&
+ ( RES_POOLCHR_HTML_BEGIN > nId || nId >= RES_POOLCHR_HTML_END ) &&
+ RES_POOLCHR_INET_NORMAL != nId &&
+ RES_POOLCHR_INET_VISIT != nId &&
+ RES_POOLCHR_FOOTNOTE != nId &&
+ RES_POOLCHR_ENDNOTE != nId )
+ continue;
+ }
+
+ m_aLst.Append( SfxStyleFamily::Char, pFormat == rDoc.GetDfltCharFormat()
+ ? SwResId(STR_POOLCHR_STANDARD)
+ : pFormat->GetName() );
+ }
+
+ // PoolFormat
+ if( bAll )
+ {
+ if( ! rDoc.getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE) )
+ AppendStyleList(SwStyleNameMapper::GetChrFormatUINameArray(),
+ bIsSearchUsed, bSearchHidden, bOnlyHidden,
+ SwGetPoolIdFromName::ChrFmt, SfxStyleFamily::Char);
+ else
+ {
+ m_aLst.Append( SfxStyleFamily::Char, SwStyleNameMapper::GetChrFormatUINameArray()[
+ RES_POOLCHR_INET_NORMAL - RES_POOLCHR_BEGIN ] );
+ m_aLst.Append( SfxStyleFamily::Char, SwStyleNameMapper::GetChrFormatUINameArray()[
+ RES_POOLCHR_INET_VISIT - RES_POOLCHR_BEGIN ] );
+ m_aLst.Append( SfxStyleFamily::Char, SwStyleNameMapper::GetChrFormatUINameArray()[
+ RES_POOLCHR_ENDNOTE - RES_POOLCHR_BEGIN ] );
+ m_aLst.Append( SfxStyleFamily::Char, SwStyleNameMapper::GetChrFormatUINameArray()[
+ RES_POOLCHR_FOOTNOTE - RES_POOLCHR_BEGIN ] );
+ }
+ AppendStyleList(SwStyleNameMapper::GetHTMLChrFormatUINameArray(),
+ bIsSearchUsed, bSearchHidden, bOnlyHidden,
+ SwGetPoolIdFromName::ChrFmt, SfxStyleFamily::Char);
+ }
+ }
+
+ if( nSearchFamily == SfxStyleFamily::Para ||
+ nSearchFamily == SfxStyleFamily::All )
+ {
+ SfxStyleSearchBits nSMask = nSrchMask;
+ if( rDoc.getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE) )
+ {
+ // then only HTML-Template are of interest
+ if( SfxStyleSearchBits::AllVisible == ( nSMask & SfxStyleSearchBits::AllVisible ) )
+ nSMask = SfxStyleSearchBits::SwHtml | SfxStyleSearchBits::UserDefined |
+ SfxStyleSearchBits::Used;
+ else
+ nSMask &= SfxStyleSearchBits::Used | SfxStyleSearchBits::UserDefined |
+ SfxStyleSearchBits::SwCondColl | SfxStyleSearchBits::SwHtml;
+ if( nSMask == SfxStyleSearchBits::Auto )
+ nSMask = SfxStyleSearchBits::SwHtml;
+ }
+
+ const size_t nArrLen = rDoc.GetTextFormatColls()->size();
+ for( size_t i = 0; i < nArrLen; i++ )
+ {
+ SwTextFormatColl* pColl = (*rDoc.GetTextFormatColls())[ i ];
+
+ const bool bUsed = bOrganizer || rDoc.IsUsed(*pColl) || IsUsedInComments(pColl->GetName());
+ if ( ( !bSearchHidden && pColl->IsHidden( ) && !bUsed ) || pColl->IsDefault() )
+ continue;
+
+ if ( nSMask == SfxStyleSearchBits::Hidden && !pColl->IsHidden( ) )
+ continue;
+
+ if( !(bIsSearchUsed && bUsed ))
+ {
+ const sal_uInt16 nId = pColl->GetPoolFormatId();
+ auto tmpMask = nSMask & ~SfxStyleSearchBits::Used;
+ if (tmpMask == SfxStyleSearchBits::UserDefined)
+ {
+ if(!IsPoolUserFormat(nId)) continue;
+ }
+ else if (tmpMask == SfxStyleSearchBits::SwText)
+ {
+ if((nId & COLL_GET_RANGE_BITS) != COLL_TEXT_BITS) continue;
+ }
+ else if (tmpMask == SfxStyleSearchBits::SwChapter)
+ {
+ if((nId & COLL_GET_RANGE_BITS) != COLL_DOC_BITS) continue;
+ }
+ else if (tmpMask == SfxStyleSearchBits::SwList)
+ {
+ if((nId & COLL_GET_RANGE_BITS) != COLL_LISTS_BITS) continue;
+ }
+ else if (tmpMask == SfxStyleSearchBits::SwIndex)
+ {
+ if((nId & COLL_GET_RANGE_BITS) != COLL_REGISTER_BITS) continue;
+ }
+ else if (tmpMask == SfxStyleSearchBits::SwExtra)
+ {
+ if((nId & COLL_GET_RANGE_BITS) != COLL_EXTRA_BITS) continue;
+ }
+ else if (tmpMask == (SfxStyleSearchBits::SwHtml | SfxStyleSearchBits::UserDefined)
+ || tmpMask == SfxStyleSearchBits::SwHtml)
+ {
+ if((tmpMask & SfxStyleSearchBits::UserDefined) && IsPoolUserFormat(nId))
+ ; // do nothing
+ else if( (nId & COLL_GET_RANGE_BITS) != COLL_HTML_BITS)
+ {
+ // but some we also want to see in this section
+ bool bContinue = true;
+ switch( nId )
+ {
+ case RES_POOLCOLL_SEND_ADDRESS: // --> ADDRESS
+ case RES_POOLCOLL_TABLE_HDLN: // --> TH
+ case RES_POOLCOLL_TABLE: // --> TD
+ case RES_POOLCOLL_TEXT: // --> P
+ case RES_POOLCOLL_HEADLINE_BASE:// --> H
+ case RES_POOLCOLL_HEADLINE1: // --> H1
+ case RES_POOLCOLL_HEADLINE2: // --> H2
+ case RES_POOLCOLL_HEADLINE3: // --> H3
+ case RES_POOLCOLL_HEADLINE4: // --> H4
+ case RES_POOLCOLL_HEADLINE5: // --> H5
+ case RES_POOLCOLL_HEADLINE6: // --> H6
+ case RES_POOLCOLL_STANDARD: // --> P
+ case RES_POOLCOLL_FOOTNOTE:
+ case RES_POOLCOLL_ENDNOTE:
+ bContinue = false;
+ break;
+ }
+ if( bContinue )
+ continue;
+ }
+ }
+ else if (tmpMask == SfxStyleSearchBits::SwCondColl)
+ {
+ if( RES_CONDTXTFMTCOLL != pColl->Which() ) continue;
+ }
+ else
+ {
+ // searched for used and found none
+ if( bIsSearchUsed )
+ continue;
+ }
+ }
+ m_aLst.Append( SfxStyleFamily::Para, pColl->GetName() );
+ }
+
+ bAll = ( nSMask & SfxStyleSearchBits::AllVisible ) == SfxStyleSearchBits::AllVisible;
+ if ( bAll || (nSMask & ~SfxStyleSearchBits::Used) == SfxStyleSearchBits::SwText )
+ AppendStyleList(SwStyleNameMapper::GetTextUINameArray(),
+ bIsSearchUsed, bSearchHidden, bOnlyHidden, SwGetPoolIdFromName::TxtColl, SfxStyleFamily::Para );
+ if ( bAll || (nSMask & ~SfxStyleSearchBits::Used) == SfxStyleSearchBits::SwChapter )
+ AppendStyleList(SwStyleNameMapper::GetDocUINameArray(),
+ bIsSearchUsed, bSearchHidden, bOnlyHidden, SwGetPoolIdFromName::TxtColl, SfxStyleFamily::Para ) ;
+ if ( bAll || (nSMask & ~SfxStyleSearchBits::Used) == SfxStyleSearchBits::SwList )
+ AppendStyleList(SwStyleNameMapper::GetListsUINameArray(),
+ bIsSearchUsed, bSearchHidden, bOnlyHidden, SwGetPoolIdFromName::TxtColl, SfxStyleFamily::Para ) ;
+ if ( bAll || (nSMask & ~SfxStyleSearchBits::Used) == SfxStyleSearchBits::SwIndex )
+ AppendStyleList(SwStyleNameMapper::GetRegisterUINameArray(),
+ bIsSearchUsed, bSearchHidden, bOnlyHidden, SwGetPoolIdFromName::TxtColl, SfxStyleFamily::Para ) ;
+ if ( bAll || (nSMask & ~SfxStyleSearchBits::Used) == SfxStyleSearchBits::SwExtra )
+ AppendStyleList(SwStyleNameMapper::GetExtraUINameArray(),
+ bIsSearchUsed, bSearchHidden, bOnlyHidden, SwGetPoolIdFromName::TxtColl, SfxStyleFamily::Para ) ;
+ if ( bAll || (nSMask & ~SfxStyleSearchBits::Used) == SfxStyleSearchBits::SwCondColl )
+ {
+ if( !bIsSearchUsed ||
+ rDoc.getIDocumentStylePoolAccess().IsPoolTextCollUsed( RES_POOLCOLL_TEXT ))
+ m_aLst.Append( SfxStyleFamily::Para, SwStyleNameMapper::GetTextUINameArray()[
+ RES_POOLCOLL_TEXT - RES_POOLCOLL_TEXT_BEGIN ] );
+ }
+ if ( bAll ||
+ (nSMask & ~SfxStyleSearchBits::Used) == SfxStyleSearchBits::SwHtml ||
+ (nSMask & ~SfxStyleSearchBits::Used) ==
+ (SfxStyleSearchBits::SwHtml | SfxStyleSearchBits::UserDefined) )
+ {
+ AppendStyleList(SwStyleNameMapper::GetHTMLUINameArray(),
+ bIsSearchUsed, bSearchHidden, bOnlyHidden, SwGetPoolIdFromName::TxtColl, SfxStyleFamily::Para ) ;
+ if( !bAll )
+ {
+ // then also the ones, that we are mapping:
+ static sal_uInt16 aPoolIds[] = {
+ RES_POOLCOLL_SEND_ADDRESS, // --> ADDRESS
+ RES_POOLCOLL_TABLE_HDLN, // --> TH
+ RES_POOLCOLL_TABLE, // --> TD
+ RES_POOLCOLL_STANDARD, // --> P
+ RES_POOLCOLL_TEXT, // --> P
+ RES_POOLCOLL_HEADLINE_BASE, // --> H
+ RES_POOLCOLL_HEADLINE1, // --> H1
+ RES_POOLCOLL_HEADLINE2, // --> H2
+ RES_POOLCOLL_HEADLINE3, // --> H3
+ RES_POOLCOLL_HEADLINE4, // --> H4
+ RES_POOLCOLL_HEADLINE5, // --> H5
+ RES_POOLCOLL_HEADLINE6, // --> H6
+ RES_POOLCOLL_FOOTNOTE,
+ RES_POOLCOLL_ENDNOTE,
+ 0
+ };
+
+ sal_uInt16* pPoolIds = aPoolIds;
+ OUString s;
+ while( *pPoolIds )
+ {
+ if( !bIsSearchUsed || rDoc.getIDocumentStylePoolAccess().IsPoolTextCollUsed( *pPoolIds ) )
+ {
+ s = SwStyleNameMapper::GetUIName( *pPoolIds, s );
+ m_aLst.Append( SfxStyleFamily::Para, s);
+ }
+ ++pPoolIds;
+ }
+ }
+ }
+ }
+
+ if( nSearchFamily == SfxStyleFamily::Frame ||
+ nSearchFamily == SfxStyleFamily::All )
+ {
+ const size_t nArrLen = rDoc.GetFrameFormats()->size();
+ for( size_t i = 0; i < nArrLen; i++ )
+ {
+ const SwFrameFormat* pFormat = (*rDoc.GetFrameFormats())[ i ];
+
+ bool bUsed = bIsSearchUsed && ( bOrganizer || rDoc.IsUsed(*pFormat));
+ if( ( !bSearchHidden && pFormat->IsHidden( ) && !bUsed ) || pFormat->IsDefault() || pFormat->IsAuto() )
+ continue;
+
+ if ( nSrchMask == SfxStyleSearchBits::Hidden && !pFormat->IsHidden( ) )
+ continue;
+
+ const sal_uInt16 nId = pFormat->GetPoolFormatId();
+ if( !bUsed )
+ {
+ if( (nSrchMask & ~SfxStyleSearchBits::Used) == SfxStyleSearchBits::UserDefined
+ ? !(nId & USER_FMT)
+ // searched for used and found none
+ : bIsSearchUsed )
+ {
+ continue;
+ }
+ }
+
+ m_aLst.Append( SfxStyleFamily::Frame, pFormat->GetName() );
+ }
+
+ // PoolFormat
+ if ( bAll )
+ AppendStyleList(SwStyleNameMapper::GetFrameFormatUINameArray(),
+ bIsSearchUsed, bSearchHidden, bOnlyHidden, SwGetPoolIdFromName::FrmFmt, SfxStyleFamily::Frame);
+ }
+
+ if( nSearchFamily == SfxStyleFamily::Page ||
+ nSearchFamily == SfxStyleFamily::All )
+ {
+ const size_t nCount = rDoc.GetPageDescCnt();
+ for(size_t i = 0; i < nCount; ++i)
+ {
+ const SwPageDesc& rDesc = rDoc.GetPageDesc(i);
+ const sal_uInt16 nId = rDesc.GetPoolFormatId();
+ bool bUsed = bIsSearchUsed && ( bOrganizer || rDoc.IsUsed(rDesc));
+ if( !bUsed )
+ {
+ if ( ( !bSearchHidden && rDesc.IsHidden() ) ||
+ ( (nSrchMask & ~SfxStyleSearchBits::Used) == SfxStyleSearchBits::UserDefined
+ ? !(nId & USER_FMT)
+ // searched for used and found none
+ : bIsSearchUsed ) )
+ continue;
+ }
+
+ if ( nSrchMask == SfxStyleSearchBits::Hidden && !rDesc.IsHidden( ) )
+ continue;
+
+ m_aLst.Append( SfxStyleFamily::Page, rDesc.GetName() );
+ }
+ if ( bAll )
+ AppendStyleList(SwStyleNameMapper::GetPageDescUINameArray(),
+ bIsSearchUsed, bSearchHidden, bOnlyHidden, SwGetPoolIdFromName::PageDesc, SfxStyleFamily::Page);
+ }
+
+ if( nSearchFamily == SfxStyleFamily::Pseudo ||
+ nSearchFamily == SfxStyleFamily::All )
+ {
+ const SwNumRuleTable& rNumTable = rDoc.GetNumRuleTable();
+ for(auto const& rNum: rNumTable)
+ {
+ const SwNumRule& rRule = *rNum;
+ if( !rRule.IsAutoRule() )
+ {
+ if ( nSrchMask == SfxStyleSearchBits::Hidden && !rRule.IsHidden( ) )
+ continue;
+
+ bool bUsed = bIsSearchUsed && (bOrganizer || rDoc.IsUsed(rRule));
+ if( !bUsed )
+ {
+ if( ( !bSearchHidden && rRule.IsHidden() ) ||
+ ( (nSrchMask & ~SfxStyleSearchBits::Used) == SfxStyleSearchBits::UserDefined
+ ? !(rRule.GetPoolFormatId() & USER_FMT)
+ // searched for used and found none
+ : bIsSearchUsed ) )
+ continue;
+ }
+
+ m_aLst.Append( SfxStyleFamily::Pseudo, rRule.GetName() );
+ }
+ }
+ if ( bAll )
+ AppendStyleList(SwStyleNameMapper::GetNumRuleUINameArray(),
+ bIsSearchUsed, bSearchHidden, bOnlyHidden, SwGetPoolIdFromName::NumRule, SfxStyleFamily::Pseudo);
+ }
+
+ if( nSearchFamily == SfxStyleFamily::Table ||
+ nSearchFamily == SfxStyleFamily::All )
+ {
+ const SwTableAutoFormatTable& rTableStyles = rDoc.GetTableStyles();
+ for(size_t i = 0; i < rTableStyles.size(); ++i)
+ {
+ const SwTableAutoFormat& rTableStyle = rTableStyles[i];
+
+ bool bUsed = bIsSearchUsed && (bOrganizer || rDoc.IsUsed(rTableStyle));
+ if(!bUsed)
+ {
+ if(nSrchMask == SfxStyleSearchBits::Hidden && !rTableStyle.IsHidden())
+ continue;
+
+ if( (!bSearchHidden && rTableStyle.IsHidden() ) ||
+ ( (nSrchMask & ~SfxStyleSearchBits::Used) == SfxStyleSearchBits::UserDefined
+ ? !rTableStyle.IsUserDefined()
+ // searched for used and found none
+ : bIsSearchUsed ) )
+ continue;
+ }
+
+ m_aLst.Append( SfxStyleFamily::Table, rTableStyle.GetName() );
+ }
+ }
+
+ if( nSearchFamily == SfxStyleFamily::Cell ||
+ nSearchFamily == SfxStyleFamily::All )
+ {
+ const auto& aTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
+ if (rDoc.HasTableStyles())
+ {
+ const SwTableAutoFormatTable& rTableStyles = rDoc.GetTableStyles();
+ for(size_t i = 0; i < rTableStyles.size(); ++i)
+ {
+ const SwTableAutoFormat& rTableStyle = rTableStyles[i];
+ for(size_t nBoxFormat = 0; nBoxFormat < aTableTemplateMap.size(); ++nBoxFormat)
+ {
+ const sal_uInt32 nBoxIndex = aTableTemplateMap[nBoxFormat];
+ const SwBoxAutoFormat& rBoxFormat = rTableStyle.GetBoxFormat(nBoxIndex);
+ OUString sBoxFormatName;
+ SwStyleNameMapper::FillProgName(rTableStyle.GetName(), sBoxFormatName, SwGetPoolIdFromName::TabStyle);
+ sBoxFormatName += rTableStyle.GetTableTemplateCellSubName(rBoxFormat);
+ m_aLst.Append( SfxStyleFamily::Cell, sBoxFormatName );
+ }
+ }
+ }
+ const SwCellStyleTable& rCellStyles = rDoc.GetCellStyles();
+ for(size_t i = 0; i < rCellStyles.size(); ++i)
+ m_aLst.Append( SfxStyleFamily::Cell, rCellStyles[i].GetName() );
+ }
+
+ if(!m_aLst.empty())
+ {
+ m_nLastPos = SAL_MAX_UINT32;
+ return Next();
+ }
+ return nullptr;
+}
+
+SfxStyleSheetBase* SwStyleSheetIterator::Next()
+{
+ assert(m_bFirstCalled);
+ ++m_nLastPos;
+ if(m_nLastPos < m_aLst.size())
+ {
+ auto const & rEntry = m_aLst[m_nLastPos];
+ mxIterSheet->PresetNameAndFamily(rEntry.first, rEntry.second);
+ mxIterSheet->SetPhysical( false );
+ mxIterSheet->SetMask( nMask );
+ if(mxIterSheet->pSet)
+ {
+ mxIterSheet->pSet->ClearItem();
+ mxIterSheet->pSet= nullptr;
+ }
+ return mxIterSheet.get();
+ }
+ return nullptr;
+}
+
+SfxStyleSheetBase* SwStyleSheetIterator::Find(const OUString& rName)
+{
+ // searching
+ if( !m_bFirstCalled )
+ First();
+
+ m_nLastPos = m_aLst.FindName( nSearchFamily, rName );
+ if( SAL_MAX_UINT32 != m_nLastPos )
+ {
+ // found
+ auto const & rEntry = m_aLst[m_nLastPos];
+ mxStyleSheet->PresetNameAndFamily(rEntry.first, rEntry.second);
+ // new name is set, so determine its Data
+ mxStyleSheet->FillStyleSheet( SwDocStyleSheet::FillOnlyName );
+ if( !mxStyleSheet->IsPhysical() )
+ mxStyleSheet->SetPhysical( false );
+
+ return mxStyleSheet.get();
+ }
+ return nullptr;
+}
+
+void SwStyleSheetIterator::AppendStyleList(const std::vector<OUString>& rList,
+ bool bTestUsed, bool bTestHidden, bool bOnlyHidden,
+ SwGetPoolIdFromName nSection, SfxStyleFamily eFamily )
+{
+ const SwDoc& rDoc = static_cast<const SwDocStyleSheetPool*>(pBasePool)->GetDoc();
+ bool bUsed = false;
+ for (const auto & i : rList)
+ {
+ bool bHidden = false;
+ sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(i, nSection);
+ switch ( nSection )
+ {
+ case SwGetPoolIdFromName::TxtColl:
+ {
+ bUsed = rDoc.getIDocumentStylePoolAccess().IsPoolTextCollUsed( nId );
+ SwFormat* pFormat = rDoc.FindTextFormatCollByName( i );
+ bHidden = pFormat && pFormat->IsHidden( );
+ }
+ break;
+ case SwGetPoolIdFromName::ChrFmt:
+ {
+ bUsed = rDoc.getIDocumentStylePoolAccess().IsPoolFormatUsed( nId );
+ SwFormat* pFormat = rDoc.FindCharFormatByName( i );
+ bHidden = pFormat && pFormat->IsHidden( );
+ }
+ break;
+ case SwGetPoolIdFromName::FrmFmt:
+ {
+ bUsed = rDoc.getIDocumentStylePoolAccess().IsPoolFormatUsed( nId );
+ SwFormat* pFormat = rDoc.FindFrameFormatByName( i );
+ bHidden = pFormat && pFormat->IsHidden( );
+ }
+ break;
+ case SwGetPoolIdFromName::PageDesc:
+ {
+ bUsed = rDoc.getIDocumentStylePoolAccess().IsPoolPageDescUsed( nId );
+ SwPageDesc* pPgDesc = rDoc.FindPageDesc(i);
+ bHidden = pPgDesc && pPgDesc->IsHidden( );
+ }
+ break;
+ case SwGetPoolIdFromName::NumRule:
+ {
+ SwNumRule* pRule = rDoc.FindNumRulePtr( i );
+ bUsed = pRule && rDoc.IsUsed(*pRule);
+ bHidden = pRule && pRule->IsHidden( );
+ }
+ break;
+ default:
+ OSL_ENSURE( false, "unknown PoolFormat-Id" );
+ }
+
+ bool bMatchHidden = ( bTestHidden && ( bHidden || !bOnlyHidden ) ) || ( !bTestHidden && ( !bHidden || bUsed ) );
+ if ( ( !bTestUsed && bMatchHidden ) || ( bTestUsed && bUsed ) )
+ m_aLst.Append( eFamily, i );
+ }
+}
+
+bool SwStyleSheetIterator::IsUsedInComments(const OUString& rName) const
+{
+ auto pPool = static_cast<const SwDocStyleSheetPool*>(pBasePool)->GetEEStyleSheetPool();
+ SfxStyleSheetIterator aIter(pPool, GetSearchFamily(), SfxStyleSearchBits::Used);
+ return aIter.Find(rName) != nullptr;
+}
+
+void SwDocStyleSheetPool::InvalidateIterator()
+{
+ if (SfxStyleSheetIterator* pIter = GetCachedIterator())
+ dynamic_cast<SwStyleSheetIterator&>(*pIter).InvalidateIterator();
+}
+
+void SwStyleSheetIterator::InvalidateIterator()
+{
+ // potentially we could send an SfxHint to Notify but currently it's
+ // iterating over the vector anyway so would still be slow - why does
+ // this iterator not use a map?
+ m_bFirstCalled = false;
+ m_nLastPos = 0;
+ m_aLst.clear();
+}
+
+void SwStyleSheetIterator::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ // search and remove from View-List!!
+ const SfxStyleSheetHint* pStyleSheetHint = dynamic_cast<const SfxStyleSheetHint*>(&rHint);
+ if( pStyleSheetHint &&
+ SfxHintId::StyleSheetErased == pStyleSheetHint->GetId() )
+ {
+ SfxStyleSheetBase* pStyle = pStyleSheetHint->GetStyleSheet();
+
+ if (pStyle)
+ m_aLst.RemoveName(pStyle->GetFamily(), pStyle->GetName());
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/app/mainwn.cxx b/sw/source/uibase/app/mainwn.cxx
new file mode 100644
index 0000000000..7c21797f8e
--- /dev/null
+++ b/sw/source/uibase/app/mainwn.cxx
@@ -0,0 +1,133 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <mdiexp.hxx>
+#include <sfx2/progress.hxx>
+#include <docsh.hxx>
+#include <swmodule.hxx>
+#include <swtypes.hxx>
+
+class SwDocShell;
+
+namespace {
+
+struct SwProgress
+{
+ tools::Long nStartValue,
+ nStartCount;
+ SwDocShell *pDocShell;
+ std::unique_ptr<SfxProgress> pProgress;
+};
+
+}
+
+static std::vector<std::unique_ptr<SwProgress>> *pProgressContainer = nullptr;
+
+static SwProgress *lcl_SwFindProgress( SwDocShell const *pDocShell )
+{
+ for (const auto& pTmp : *pProgressContainer)
+ {
+ if ( pTmp->pDocShell == pDocShell )
+ return pTmp.get();
+ }
+ return nullptr;
+}
+
+void StartProgress( TranslateId pMessResId, tools::Long nStartValue, tools::Long nEndValue,
+ SwDocShell *pDocShell )
+{
+ if( SW_MOD()->IsEmbeddedLoadSave() )
+ return;
+
+ SwProgress *pProgress = nullptr;
+
+ if ( !pProgressContainer )
+ pProgressContainer = new std::vector<std::unique_ptr<SwProgress>>;
+ else
+ {
+ pProgress = lcl_SwFindProgress( pDocShell );
+ if ( pProgress )
+ ++pProgress->nStartCount;
+ }
+
+ if ( !pProgress )
+ {
+ pProgress = new SwProgress;
+ pProgress->pProgress.reset( new SfxProgress( pDocShell,
+ SwResId(pMessResId),
+ nEndValue - nStartValue ) );
+ pProgress->nStartCount = 1;
+ pProgress->pDocShell = pDocShell;
+ pProgressContainer->insert( pProgressContainer->begin(), std::unique_ptr<SwProgress>(pProgress) );
+ }
+ pProgress->nStartValue = nStartValue;
+}
+
+void SetProgressState( tools::Long nPosition, SwDocShell const *pDocShell )
+{
+ if( pProgressContainer && !SW_MOD()->IsEmbeddedLoadSave() )
+ {
+ SwProgress *pProgress = lcl_SwFindProgress( pDocShell );
+ if ( pProgress )
+ pProgress->pProgress->SetState(nPosition - pProgress->nStartValue);
+ }
+}
+
+void EndProgress( SwDocShell const *pDocShell )
+{
+ if( !pProgressContainer || SW_MOD()->IsEmbeddedLoadSave() )
+ return;
+
+ SwProgress *pProgress = nullptr;
+ std::vector<SwProgress *>::size_type i;
+ for ( i = 0; i < pProgressContainer->size(); ++i )
+ {
+ SwProgress *pTmp = (*pProgressContainer)[i].get();
+ if ( pTmp->pDocShell == pDocShell )
+ {
+ pProgress = pTmp;
+ break;
+ }
+ }
+
+ if ( pProgress && 0 == --pProgress->nStartCount )
+ {
+ pProgress->pProgress->Stop();
+ pProgressContainer->erase( pProgressContainer->begin() + i );
+ //#112337# it may happen that the container has been removed
+ //while rescheduling
+ if ( pProgressContainer && pProgressContainer->empty() )
+ {
+ delete pProgressContainer;
+ pProgressContainer = nullptr;
+ }
+ }
+}
+
+void RescheduleProgress( SwDocShell const *pDocShell )
+{
+ if( pProgressContainer && !SW_MOD()->IsEmbeddedLoadSave() )
+ {
+ SwProgress *pProgress = lcl_SwFindProgress( pDocShell );
+ if ( pProgress )
+ SfxProgress::Reschedule();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/app/swdll.cxx b/sw/source/uibase/app/swdll.cxx
new file mode 100644
index 0000000000..c4564a4741
--- /dev/null
+++ b/sw/source/uibase/app/swdll.cxx
@@ -0,0 +1,184 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+
+#include <svx/svdobj.hxx>
+
+#include <swdll.hxx>
+#include <wdocsh.hxx>
+#include <globdoc.hxx>
+#include <initui.hxx>
+#include <swmodule.hxx>
+#include <init.hxx>
+#include <dobjfac.hxx>
+
+#include <com/sun/star/frame/Desktop.hpp>
+#include <unotools/configmgr.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <comphelper/unique_disposing_ptr.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include <sal/log.hxx>
+#include <svx/fmobjfac.hxx>
+#include <svx/objfac3d.hxx>
+#include <editeng/acorrcfg.hxx>
+
+#include <swacorr.hxx>
+#include <swabstdlg.hxx>
+
+#include "swdllimpl.hxx"
+
+using namespace com::sun::star;
+
+namespace
+{
+ //Holds a SwDLL and release it on exit, or dispose of the
+ //default XComponent, whichever comes first
+ class SwDLLInstance : public comphelper::unique_disposing_solar_mutex_reset_ptr<SwDLL>
+ {
+ public:
+ SwDLLInstance() : comphelper::unique_disposing_solar_mutex_reset_ptr<SwDLL>(uno::Reference<lang::XComponent>( frame::Desktop::create(comphelper::getProcessComponentContext()), uno::UNO_QUERY_THROW), new SwDLL, true)
+ {
+ }
+ };
+
+ SwDLLInstance& theSwDLLInstance()
+ {
+ static SwDLLInstance aInstance;
+ return aInstance;
+ }
+}
+
+namespace SwGlobals
+{
+ void ensure()
+ {
+ // coverity[side_effect_free : FALSE] - not actually side-effect-free
+ theSwDLLInstance();
+ }
+
+ sw::Filters & getFilters()
+ {
+ return theSwDLLInstance()->getFilters();
+ }
+}
+
+SwDLL::SwDLL()
+ : m_pAutoCorrCfg(nullptr)
+{
+ if ( SfxApplication::GetModule(SfxToolsModule::Writer) ) // Module already active
+ return;
+
+ std::unique_ptr<SvtModuleOptions> xOpt;
+ if (!utl::ConfigManager::IsFuzzing())
+ xOpt.reset(new SvtModuleOptions);
+ SfxObjectFactory* pDocFact = nullptr;
+ SfxObjectFactory* pGlobDocFact = nullptr;
+ if (!xOpt || xOpt->IsWriter())
+ {
+ pDocFact = &SwDocShell::Factory();
+ pGlobDocFact = &SwGlobalDocShell::Factory();
+ }
+
+ SfxObjectFactory* pWDocFact = &SwWebDocShell::Factory();
+
+ auto pUniqueModule = std::make_unique<SwModule>(pWDocFact, pDocFact, pGlobDocFact);
+ SwModule* pModule = pUniqueModule.get();
+ SfxApplication::SetModule(SfxToolsModule::Writer, std::move(pUniqueModule));
+
+ pWDocFact->SetDocumentServiceName("com.sun.star.text.WebDocument");
+
+ if (!xOpt || xOpt->IsWriter())
+ {
+ pGlobDocFact->SetDocumentServiceName("com.sun.star.text.GlobalDocument");
+ pDocFact->SetDocumentServiceName("com.sun.star.text.TextDocument");
+ }
+
+ // register 3D-object-Factory
+ E3dObjFactory();
+
+ // register form::component::Form-object-Factory
+ FmFormObjFactory();
+
+ SdrObjFactory::InsertMakeObjectHdl( LINK( &aSwObjectFactory, SwObjectFactory, MakeObject ) );
+
+ SAL_INFO( "sw.ui", "Init Core/UI/Filter" );
+ // Initialisation of Statics
+ ::InitCore();
+ m_pFilters.reset(new sw::Filters);
+ ::InitUI();
+
+ pModule->InitAttrPool();
+ // now SWModule can create its Pool
+
+ // register your view-factories here
+ RegisterFactories();
+
+ // register your shell-interfaces here
+ RegisterInterfaces();
+
+ // register your controllers here
+ RegisterControls();
+
+ if (!utl::ConfigManager::IsFuzzing())
+ {
+ // replace SvxAutocorrect with SwAutocorrect
+ SvxAutoCorrCfg& rACfg = SvxAutoCorrCfg::Get();
+ const SvxAutoCorrect* pOld = rACfg.GetAutoCorrect();
+ rACfg.SetAutoCorrect(new SwAutoCorrect( *pOld ));
+ m_pAutoCorrCfg = &rACfg;
+ }
+}
+
+SwDLL::~SwDLL() COVERITY_NOEXCEPT_FALSE
+{
+ if (m_pAutoCorrCfg)
+ {
+ // fdo#86494 SwAutoCorrect must be deleted before FinitCore
+ m_pAutoCorrCfg->SetAutoCorrect(nullptr); // delete SwAutoCorrect before exit handlers
+ }
+
+ // Pool has to be deleted before statics are
+ SW_MOD()->RemoveAttrPool();
+
+ ::FinitUI();
+ m_pFilters.reset();
+ ::FinitCore();
+ // sign out object-Factory
+ SdrObjFactory::RemoveMakeObjectHdl(LINK(&aSwObjectFactory, SwObjectFactory, MakeObject ));
+}
+
+sw::Filters & SwDLL::getFilters()
+{
+ assert(m_pFilters);
+ return *m_pFilters;
+}
+
+#ifndef DISABLE_DYNLOADING
+
+extern "C" SAL_DLLPUBLIC_EXPORT
+void lok_preload_hook()
+{
+ SwAbstractDialogFactory::Create();
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/app/swdllimpl.hxx b/sw/source/uibase/app/swdllimpl.hxx
new file mode 100644
index 0000000000..7dab66d6ce
--- /dev/null
+++ b/sw/source/uibase/app/swdllimpl.hxx
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <sal/types.h>
+
+#include <memory>
+
+namespace sw
+{
+class Filters;
+}
+
+class SvxAutoCorrCfg;
+
+class SwDLL
+{
+public:
+ static void RegisterFactories();
+ static void RegisterInterfaces();
+ static void RegisterControls();
+
+ SwDLL();
+ ~SwDLL() COVERITY_NOEXCEPT_FALSE;
+
+ sw::Filters& getFilters();
+
+private:
+ SwDLL(SwDLL const&) = delete;
+ SwDLL& operator=(SwDLL const&) = delete;
+
+ std::unique_ptr<sw::Filters> m_pFilters;
+ SvxAutoCorrCfg* m_pAutoCorrCfg;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/app/swmodul1.cxx b/sw/source/uibase/app/swmodul1.cxx
new file mode 100644
index 0000000000..64bd38f444
--- /dev/null
+++ b/sw/source/uibase/app/swmodul1.cxx
@@ -0,0 +1,693 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <memory>
+
+#include <hintids.hxx>
+#include <sfx2/request.hxx>
+#include <unotools/useroptions.hxx>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <svx/colorwindow.hxx>
+#include <svx/dataaccessdescriptor.hxx>
+#include <editeng/editids.hrc>
+#include <editeng/wghtitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/crossedoutitem.hxx>
+#include <editeng/cmapitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/brushitem.hxx>
+#include <svl/cjkoptions.hxx>
+#include <osl/diagnose.h>
+#include <swmodule.hxx>
+#include <swtypes.hxx>
+#include <usrpref.hxx>
+#include <modcfg.hxx>
+#include <view.hxx>
+#include <pview.hxx>
+#include <wview.hxx>
+#include <wrtsh.hxx>
+#include <docsh.hxx>
+#include <uinums.hxx>
+#include <prtopt.hxx>
+#include <navicfg.hxx>
+#include <doc.hxx>
+#include <strings.hrc>
+#include <IDocumentLayoutAccess.hxx>
+
+#include <tools/color.hxx>
+#include <tools/json_writer.hxx>
+#include <PostItMgr.hxx>
+
+using namespace ::svx;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::view;
+using namespace ::com::sun::star::lang;
+
+static void lcl_SetUIPrefs(const SwViewOption &rPref, SwView* pView, SwViewShell* pSh )
+{
+ // in FrameSets the actual visibility can differ from the ViewOption's setting
+ bool bVScrollChanged = rPref.IsViewVScrollBar() != pSh->GetViewOptions()->IsViewVScrollBar();
+ bool bHScrollChanged = rPref.IsViewHScrollBar() != pSh->GetViewOptions()->IsViewHScrollBar();
+ bool bVAlignChanged = rPref.IsVRulerRight() != pSh->GetViewOptions()->IsVRulerRight();
+
+ pSh->SetUIOptions(rPref);
+ const SwViewOption* pNewPref = pSh->GetViewOptions();
+
+ // Scrollbars on / off
+ if(bVScrollChanged)
+ {
+ pView->EnableVScrollbar(pNewPref->IsViewVScrollBar());
+ }
+ if(bHScrollChanged)
+ {
+ pView->EnableHScrollbar( pNewPref->IsViewHScrollBar() || pNewPref->getBrowseMode() );
+ }
+ //if only the position of the vertical ruler has been changed initiate an update
+ if(bVAlignChanged && !bHScrollChanged && !bVScrollChanged)
+ pView->InvalidateBorder();
+
+ // Rulers on / off
+ if(pNewPref->IsViewVRuler())
+ pView->CreateVRuler();
+ else
+ pView->KillVRuler();
+
+ // TabWindow on / off
+ if(pNewPref->IsViewHRuler())
+ pView->CreateTab();
+ else
+ pView->KillTab();
+
+ pView->GetPostItMgr()->PrepareView(true);
+}
+
+SwWrtShell* GetActiveWrtShell()
+{
+ if (SwView *pActive = GetActiveView())
+ return &pActive->GetWrtShell();
+ return nullptr;
+}
+
+SwView* GetActiveView()
+{
+ SfxViewShell* pView = SfxViewShell::Current();
+ return dynamic_cast<SwView*>( pView );
+}
+
+SwView* SwModule::GetFirstView()
+{
+ // returns only visible SwView
+ SwView* pView = static_cast<SwView*>(SfxViewShell::GetFirst(true, checkSfxViewShell<SwView>));
+ return pView;
+}
+
+SwView* SwModule::GetNextView(SwView const * pView)
+{
+ OSL_ENSURE( pView,"return no SwView" );
+ SwView* pNView = static_cast<SwView*>(SfxViewShell::GetNext(*pView, true, checkSfxViewShell<SwView>));
+ return pNView;
+}
+
+// New Master for the settings is set; this affects the current view and all following.
+void SwModule::ApplyUsrPref(const SwViewOption &rUsrPref, SwView* pActView,
+ SvViewOpt nDest )
+{
+ SwView* pCurrView = pActView;
+ SwViewShell* pSh = pCurrView ? &pCurrView->GetWrtShell() : nullptr;
+
+ SwMasterUsrPref* pPref = const_cast<SwMasterUsrPref*>(GetUsrPref(
+ nDest == SvViewOpt::DestWeb
+ || (nDest != SvViewOpt::DestText
+ && dynamic_cast< const SwWebView *>( pCurrView )) ));
+
+ // with Uno, only sdbcx::View, but not the Module should be changed
+ bool bViewOnly = SvViewOpt::DestViewOnly == nDest;
+ // fob Preview off
+ SwPagePreview* pPPView;
+ if( !pCurrView && nullptr != (pPPView = dynamic_cast<SwPagePreview*>( SfxViewShell::Current())) )
+ {
+ if(!bViewOnly)
+ pPref->SetUIOptions( rUsrPref );
+ pPPView->EnableVScrollbar(pPref->IsViewVScrollBar());
+ pPPView->EnableHScrollbar(pPref->IsViewHScrollBar());
+ if(!bViewOnly)
+ {
+ pPref->SetPagePrevRow(rUsrPref.GetPagePrevRow());
+ pPref->SetPagePrevCol(rUsrPref.GetPagePrevCol());
+ }
+ return;
+ }
+
+ if(!bViewOnly)
+ {
+ pPref->SetUsrPref( rUsrPref );
+ pPref->SetModified();
+ }
+
+ if( !pCurrView )
+ return;
+
+ // Passing on to CORE
+ bool bReadonly;
+ const SwDocShell* pDocSh = pCurrView->GetDocShell();
+ if (pDocSh)
+ bReadonly = pDocSh->IsReadOnly();
+ else //Use existing option if DocShell missing
+ bReadonly = pSh->GetViewOptions()->IsReadonly();
+ std::unique_ptr<SwViewOption> xViewOpt;
+ if (!bViewOnly)
+ xViewOpt.reset(new SwViewOption(*pPref));
+ else
+ xViewOpt.reset(new SwViewOption(rUsrPref));
+ xViewOpt->SetReadonly( bReadonly );
+ if( !(*pSh->GetViewOptions() == *xViewOpt) )
+ {
+ //is maybe only a SwViewShell
+ pSh->StartAction();
+ pSh->ApplyViewOptions( *xViewOpt );
+ static_cast<SwWrtShell*>(pSh)->SetReadOnlyAvailable(xViewOpt->IsCursorInProtectedArea());
+ pSh->EndAction();
+ }
+ if ( pSh->GetViewOptions()->IsReadonly() != bReadonly )
+ pSh->SetReadonlyOption(bReadonly);
+
+ lcl_SetUIPrefs(*xViewOpt, pCurrView, pSh);
+
+ // in the end the Idle-Flag is set again
+ pPref->SetIdle(true);
+}
+
+void SwModule::ApplyUserMetric( FieldUnit eMetric, bool bWeb )
+{
+ SwMasterUsrPref* pPref;
+ if(bWeb)
+ {
+ if(!m_pWebUsrPref)
+ GetUsrPref(true);
+ pPref = m_pWebUsrPref.get();
+ }
+ else
+ {
+ if(!m_pUsrPref)
+ GetUsrPref(false);
+ pPref = m_pUsrPref.get();
+ }
+ assert(pPref && "pPref is set by here");
+ FieldUnit eOldMetric = pPref->GetMetric();
+ if(eOldMetric != eMetric)
+ pPref->SetMetric(eMetric);
+
+ FieldUnit eHScrollMetric = pPref->IsHScrollMetric() ? pPref->GetHScrollMetric() : eMetric;
+ FieldUnit eVScrollMetric = pPref->IsVScrollMetric() ? pPref->GetVScrollMetric() : eMetric;
+
+ SwView* pTmpView = SwModule::GetFirstView();
+ // switch the ruler for all MDI-Windows
+ while(pTmpView)
+ {
+ if(bWeb == (dynamic_cast<SwWebView*>( pTmpView) != nullptr) )
+ {
+ pTmpView->ChangeVRulerMetric(eVScrollMetric);
+ pTmpView->ChangeTabMetric(eHScrollMetric);
+ }
+
+ pTmpView = SwModule::GetNextView(pTmpView);
+ }
+}
+
+void SwModule::ApplyRulerMetric( FieldUnit eMetric, bool bHorizontal, bool bWeb )
+{
+ SwMasterUsrPref* pPref;
+ if(bWeb)
+ {
+ if(!m_pWebUsrPref)
+ GetUsrPref(true);
+ pPref = m_pWebUsrPref.get();
+ }
+ else
+ {
+ if(!m_pUsrPref)
+ GetUsrPref(false);
+ pPref = m_pUsrPref.get();
+ }
+ assert(pPref && "pPref will be set by now");
+ if( bHorizontal )
+ pPref->SetHScrollMetric(eMetric);
+ else
+ pPref->SetVScrollMetric(eMetric);
+
+ SwView* pTmpView = SwModule::GetFirstView();
+ // switch metric at the appropriate rulers
+ while(pTmpView)
+ {
+ if(bWeb == (dynamic_cast<SwWebView *>( pTmpView ) != nullptr))
+ {
+ if( bHorizontal )
+ pTmpView->ChangeTabMetric(eMetric);
+ else
+ pTmpView->ChangeVRulerMetric(eMetric);
+ }
+ pTmpView = SwModule::GetNextView(pTmpView);
+ }
+}
+
+//set the usrpref 's char unit attribute and set rulers unit as char if the "apply char unit" is checked
+void SwModule::ApplyUserCharUnit(bool bApplyChar, bool bWeb)
+{
+ SwMasterUsrPref* pPref;
+ if(bWeb)
+ {
+ if(!m_pWebUsrPref)
+ GetUsrPref(true);
+ pPref = m_pWebUsrPref.get();
+ }
+ else
+ {
+ if(!m_pUsrPref)
+ GetUsrPref(false);
+ pPref = m_pUsrPref.get();
+ }
+ assert(pPref && "pPref is set by here");
+ bool bOldApplyCharUnit = pPref->IsApplyCharUnit();
+ bool bHasChanged = false;
+ if(bOldApplyCharUnit != bApplyChar)
+ {
+ pPref->SetApplyCharUnit(bApplyChar);
+ bHasChanged = true;
+ }
+
+ if( !bHasChanged )
+ return;
+
+ FieldUnit eHScrollMetric = pPref->IsHScrollMetric() ? pPref->GetHScrollMetric() : pPref->GetMetric();
+ FieldUnit eVScrollMetric = pPref->IsVScrollMetric() ? pPref->GetVScrollMetric() : pPref->GetMetric();
+ if(bApplyChar)
+ {
+ eHScrollMetric = FieldUnit::CHAR;
+ eVScrollMetric = FieldUnit::LINE;
+ }
+ else
+ {
+ if ( !SvtCJKOptions::IsAsianTypographyEnabled() && ( eHScrollMetric == FieldUnit::CHAR ))
+ eHScrollMetric = FieldUnit::INCH;
+ else if ( eHScrollMetric == FieldUnit::CHAR )
+ eHScrollMetric = FieldUnit::CM;
+ if ( !SvtCJKOptions::IsAsianTypographyEnabled() && ( eVScrollMetric == FieldUnit::LINE ))
+ eVScrollMetric = FieldUnit::INCH;
+ else if ( eVScrollMetric == FieldUnit::LINE )
+ eVScrollMetric = FieldUnit::CM;
+ }
+ SwView* pTmpView = SwModule::GetFirstView();
+ // switch rulers for all MDI-Windows
+ while(pTmpView)
+ {
+ if(bWeb == (dynamic_cast<SwWebView*>( pTmpView) != nullptr) )
+ {
+ pTmpView->ChangeVRulerMetric(eVScrollMetric);
+ pTmpView->ChangeTabMetric(eHScrollMetric);
+ }
+
+ pTmpView = SwModule::GetNextView(pTmpView);
+ }
+}
+
+SwNavigationConfig* SwModule::GetNavigationConfig()
+{
+ if(!m_pNavigationConfig)
+ {
+ m_pNavigationConfig.reset( new SwNavigationConfig );
+ }
+ return m_pNavigationConfig.get();
+}
+
+SwPrintOptions* SwModule::GetPrtOptions(bool bWeb)
+{
+ if(bWeb && !m_pWebPrintOptions)
+ {
+ m_pWebPrintOptions.reset(new SwPrintOptions(true));
+ }
+ else if(!bWeb && !m_pPrintOptions)
+ {
+ m_pPrintOptions.reset(new SwPrintOptions(false));
+ }
+
+ return bWeb ? m_pWebPrintOptions.get() : m_pPrintOptions.get();
+}
+
+SwChapterNumRules* SwModule::GetChapterNumRules()
+{
+ if(!m_pChapterNumRules)
+ m_pChapterNumRules.reset(new SwChapterNumRules);
+ return m_pChapterNumRules.get();
+}
+
+void SwModule::ShowDBObj(SwView const & rView, const SwDBData& rData)
+{
+ Reference<XFrame> xFrame = rView.GetViewFrame().GetFrame().GetFrameInterface();
+
+ uno::Reference<XFrame> xBeamerFrame = xFrame->findFrame("_beamer", FrameSearchFlag::CHILDREN);
+ if (!xBeamerFrame.is())
+ return;
+
+// the beamer has been opened by the SfxViewFrame
+ Reference<XController> xController = xBeamerFrame->getController();
+ Reference<XSelectionSupplier> xControllerSelection(xController, UNO_QUERY);
+ if (xControllerSelection.is())
+ {
+
+ ODataAccessDescriptor aSelection;
+ aSelection.setDataSource(rData.sDataSource);
+ aSelection[DataAccessDescriptorProperty::Command] <<= rData.sCommand;
+ aSelection[DataAccessDescriptorProperty::CommandType] <<= rData.nCommandType;
+ xControllerSelection->select(Any(aSelection.createPropertyValueSequence()));
+ }
+ else {
+ OSL_FAIL("no selection supplier in the beamer!");
+ }
+}
+
+std::size_t SwModule::GetRedlineAuthor()
+{
+ if (!m_bAuthorInitialised)
+ {
+ const SvtUserOptions& rOpt = GetUserOptions();
+ m_sActAuthor = rOpt.GetFullName();
+ if (m_sActAuthor.isEmpty())
+ {
+ m_sActAuthor = rOpt.GetID();
+ if (m_sActAuthor.isEmpty())
+ m_sActAuthor = SwResId( STR_REDLINE_UNKNOWN_AUTHOR );
+ }
+ m_bAuthorInitialised = true;
+ }
+ return InsertRedlineAuthor( m_sActAuthor );
+}
+
+void SwModule::SetRedlineAuthor(const OUString &rAuthor)
+{
+ m_bAuthorInitialised = true;
+ m_sActAuthor = rAuthor;
+ InsertRedlineAuthor( m_sActAuthor );
+}
+
+OUString const & SwModule::GetRedlineAuthor(std::size_t nPos)
+{
+ OSL_ENSURE(nPos < m_pAuthorNames.size(), "author not found!"); //#i45342# RTF doc with no author table caused reader to crash
+ while(nPos >= m_pAuthorNames.size())
+ {
+ InsertRedlineAuthor("nn");
+ }
+ return m_pAuthorNames[nPos];
+}
+
+void SwModule::ClearRedlineAuthors()
+{
+ m_pAuthorNames.clear();
+}
+
+static Color lcl_GetAuthorColor(std::size_t nPos)
+{
+ static const Color aColArr[] =
+ {
+ COL_AUTHOR1_DARK, COL_AUTHOR2_DARK, COL_AUTHOR3_DARK,
+ COL_AUTHOR4_DARK, COL_AUTHOR5_DARK, COL_AUTHOR6_DARK,
+ COL_AUTHOR7_DARK, COL_AUTHOR8_DARK, COL_AUTHOR9_DARK
+ };
+
+ return aColArr[nPos % SAL_N_ELEMENTS(aColArr)];
+}
+
+/// Returns a JSON representation of a redline author.
+void SwModule::GetRedlineAuthorInfo(tools::JsonWriter& rJsonWriter)
+{
+ auto authorsNode = rJsonWriter.startArray("authors");
+ for (std::size_t nAuthor = 0; nAuthor < m_pAuthorNames.size(); ++nAuthor)
+ {
+ auto authorNode = rJsonWriter.startStruct();
+ rJsonWriter.put("index", static_cast<sal_Int64>(nAuthor));
+ rJsonWriter.put("name", m_pAuthorNames[nAuthor]);
+ rJsonWriter.put("color", sal_uInt32(lcl_GetAuthorColor(nAuthor)));
+ }
+}
+
+std::size_t SwModule::InsertRedlineAuthor(const OUString& rAuthor)
+{
+ std::size_t nPos = 0;
+
+ while(nPos < m_pAuthorNames.size() && m_pAuthorNames[nPos] != rAuthor)
+ ++nPos;
+
+ if (nPos == m_pAuthorNames.size())
+ m_pAuthorNames.push_back(rAuthor);
+
+ return nPos;
+}
+
+static void lcl_FillAuthorAttr( std::size_t nAuthor, SfxItemSet &rSet,
+ const AuthorCharAttr &rAttr )
+{
+ Color aCol( rAttr.m_nColor );
+
+ if( rAttr.m_nColor == COL_TRANSPARENT )
+ aCol = lcl_GetAuthorColor(nAuthor);
+
+ bool bBackGr = rAttr.m_nColor == COL_NONE_COLOR;
+
+ switch (rAttr.m_nItemId)
+ {
+ case SID_ATTR_CHAR_WEIGHT:
+ {
+ SvxWeightItem aW( static_cast<FontWeight>(rAttr.m_nAttr), RES_CHRATR_WEIGHT );
+ rSet.Put( aW );
+ aW.SetWhich( RES_CHRATR_CJK_WEIGHT );
+ rSet.Put( aW );
+ aW.SetWhich( RES_CHRATR_CTL_WEIGHT );
+ rSet.Put( aW );
+ }
+ break;
+
+ case SID_ATTR_CHAR_POSTURE:
+ {
+ SvxPostureItem aP( static_cast<FontItalic>(rAttr.m_nAttr), RES_CHRATR_POSTURE );
+ rSet.Put( aP );
+ aP.SetWhich( RES_CHRATR_CJK_POSTURE );
+ rSet.Put( aP );
+ aP.SetWhich( RES_CHRATR_CTL_POSTURE );
+ rSet.Put( aP );
+ }
+ break;
+
+ case SID_ATTR_CHAR_UNDERLINE:
+ rSet.Put( SvxUnderlineItem( static_cast<FontLineStyle>(rAttr.m_nAttr),
+ RES_CHRATR_UNDERLINE));
+ break;
+
+ case SID_ATTR_CHAR_STRIKEOUT:
+ rSet.Put(SvxCrossedOutItem( static_cast<FontStrikeout>(rAttr.m_nAttr),
+ RES_CHRATR_CROSSEDOUT));
+ break;
+
+ case SID_ATTR_CHAR_CASEMAP:
+ rSet.Put( SvxCaseMapItem( static_cast<SvxCaseMap>(rAttr.m_nAttr),
+ RES_CHRATR_CASEMAP));
+ break;
+
+ case SID_ATTR_BRUSH:
+ rSet.Put( SvxBrushItem( aCol, RES_CHRATR_BACKGROUND ));
+ bBackGr = true;
+ break;
+ }
+
+ if( !bBackGr )
+ rSet.Put( SvxColorItem( aCol, RES_CHRATR_COLOR ) );
+}
+
+void SwModule::GetInsertAuthorAttr(std::size_t nAuthor, SfxItemSet &rSet)
+{
+ lcl_FillAuthorAttr(nAuthor, rSet, m_pModuleConfig->GetInsertAuthorAttr());
+}
+
+void SwModule::GetDeletedAuthorAttr(std::size_t nAuthor, SfxItemSet &rSet)
+{
+ lcl_FillAuthorAttr(nAuthor, rSet, m_pModuleConfig->GetDeletedAuthorAttr());
+}
+
+// For future extension:
+void SwModule::GetFormatAuthorAttr( std::size_t nAuthor, SfxItemSet &rSet )
+{
+ lcl_FillAuthorAttr( nAuthor, rSet, m_pModuleConfig->GetFormatAuthorAttr() );
+}
+
+sal_uInt16 SwModule::GetRedlineMarkPos() const
+{
+ return m_pModuleConfig->GetMarkAlignMode();
+}
+
+bool SwModule::IsInsTableFormatNum(bool bHTML) const
+{
+ return m_pModuleConfig->IsInsTableFormatNum(bHTML);
+}
+
+bool SwModule::IsInsTableChangeNumFormat(bool bHTML) const
+{
+ return m_pModuleConfig->IsInsTableChangeNumFormat(bHTML);
+}
+
+bool SwModule::IsInsTableAlignNum(bool bHTML) const
+{
+ return m_pModuleConfig->IsInsTableAlignNum(bHTML);
+}
+
+bool SwModule::IsSplitVerticalByDefault(bool bHTML) const
+{
+ return m_pModuleConfig->IsSplitVerticalByDefault(bHTML);
+}
+
+void SwModule::SetSplitVerticalByDefault(bool bHTML, bool value)
+{
+ m_pModuleConfig->SetSplitVerticalByDefault(bHTML, value);
+}
+
+const Color &SwModule::GetRedlineMarkColor() const
+{
+ return m_pModuleConfig->GetMarkAlignColor();
+}
+
+const SwViewOption* SwModule::GetViewOption(bool bWeb)
+{
+ return GetUsrPref( bWeb );
+}
+
+OUString const & SwModule::GetDocStatWordDelim() const
+{
+ return m_pModuleConfig->GetWordDelimiter();
+}
+
+// Passing-through of the ModuleConfig's Metric (for HTML-Export)
+FieldUnit SwModule::GetMetric( bool bWeb ) const
+{
+ SwMasterUsrPref* pPref;
+ if(bWeb)
+ {
+ if(!m_pWebUsrPref)
+ GetUsrPref(true);
+ pPref = m_pWebUsrPref.get();
+ }
+ else
+ {
+ if(!m_pUsrPref)
+ GetUsrPref(false);
+ pPref = m_pUsrPref.get();
+ }
+ assert(pPref && "pPref is set by here");
+ return pPref->GetMetric();
+}
+
+// Pass-through Update-Status
+sal_uInt16 SwModule::GetLinkUpdMode() const
+{
+ if (!m_pUsrPref)
+ GetUsrPref(false);
+ assert(m_pUsrPref && "m_pUsrPref is set by here");
+ return o3tl::narrowing<sal_uInt16>(m_pUsrPref->GetUpdateLinkMode());
+}
+
+SwFieldUpdateFlags SwModule::GetFieldUpdateFlags() const
+{
+ if (!m_pUsrPref)
+ GetUsrPref(false);
+ assert(m_pUsrPref && "m_pUsrPref is set by here");
+ return m_pUsrPref->GetFieldUpdateFlags();
+}
+
+void SwModule::ApplyFieldUpdateFlags(SwFieldUpdateFlags eFieldFlags)
+{
+ if (!m_pUsrPref)
+ GetUsrPref(false);
+ assert(m_pUsrPref && "m_pUsrPref is set by here");
+ m_pUsrPref->SetFieldUpdateFlags(eFieldFlags);
+}
+
+void SwModule::ApplyLinkMode(sal_Int32 nNewLinkMode)
+{
+ if (!m_pUsrPref)
+ GetUsrPref(false);
+ assert(m_pUsrPref && "m_pUsrPref is set by here");
+ m_pUsrPref->SetUpdateLinkMode(nNewLinkMode);
+}
+
+void SwModule::CheckSpellChanges( bool bOnlineSpelling,
+ bool bIsSpellWrongAgain, bool bIsSpellAllAgain, bool bSmartTags )
+{
+ bool bOnlyWrong = bIsSpellWrongAgain && !bIsSpellAllAgain;
+ bool bInvalid = bOnlyWrong || bIsSpellAllAgain;
+ if( !(bOnlineSpelling || bInvalid) )
+ return;
+
+ for( SwDocShell *pDocSh = static_cast<SwDocShell*>(SfxObjectShell::GetFirst(checkSfxObjectShell<SwDocShell>));
+ pDocSh;
+ pDocSh = static_cast<SwDocShell*>(SfxObjectShell::GetNext( *pDocSh, checkSfxObjectShell<SwDocShell> ) ) )
+ {
+ SwDoc* pTmp = pDocSh->GetDoc();
+ if ( pTmp->getIDocumentLayoutAccess().GetCurrentViewShell() )
+ {
+ pTmp->SpellItAgainSam( bInvalid, bOnlyWrong, bSmartTags );
+ SwViewShell* pViewShell = pTmp->getIDocumentLayoutAccess().GetCurrentViewShell();
+ if ( bSmartTags && pViewShell && pViewShell->GetWin() )
+ pViewShell->GetWin()->Invalidate();
+ }
+ }
+}
+
+void SwModule::ApplyDefaultPageMode(bool bIsSquaredPageMode)
+{
+ if (!m_pUsrPref)
+ GetUsrPref(false);
+ assert(m_pUsrPref && "pPref is set by here");
+ m_pUsrPref->SetDefaultPageMode(bIsSquaredPageMode);
+}
+
+SwCompareMode SwModule::GetCompareMode() const
+{
+ return m_pModuleConfig->GetCompareMode();
+}
+
+bool SwModule::IsUseRsid() const
+{
+ return m_pModuleConfig->IsUseRsid();
+}
+
+bool SwModule::IsIgnorePieces() const
+{
+ return m_pModuleConfig->IsIgnorePieces();
+}
+
+sal_uInt16 SwModule::GetPieceLen() const
+{
+ return m_pModuleConfig->GetPieceLen();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/app/swmodule.cxx b/sw/source/uibase/app/swmodule.cxx
new file mode 100644
index 0000000000..e7a97f4b8c
--- /dev/null
+++ b/sw/source/uibase/app/swmodule.cxx
@@ -0,0 +1,401 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_features.h>
+
+#include <svtools/ehdl.hxx>
+#include <svtools/accessibilityoptions.hxx>
+#include <unotools/resmgr.hxx>
+#include <unotools/useroptions.hxx>
+#include <svl/ctloptions.hxx>
+#include <svx/ParaSpacingControl.hxx>
+#include <svx/pszctrl.hxx>
+#include <svx/insctrl.hxx>
+#include <svx/selctrl.hxx>
+#include <svx/linectrl.hxx>
+#include <svx/tbxctl.hxx>
+#include <svx/fillctrl.hxx>
+#include <svx/formatpaintbrushctrl.hxx>
+#include <svx/contdlg.hxx>
+#include <svx/fontwork.hxx>
+#include <SwSpellDialogChildWindow.hxx>
+#include <svx/grafctrl.hxx>
+#include <svx/clipboardctl.hxx>
+#include <svx/imapdlg.hxx>
+#include <svx/srchdlg.hxx>
+#include <svx/hyperdlg.hxx>
+#include <svx/modctrl.hxx>
+#include <com/sun/star/scanner/ScannerManager.hpp>
+#include <com/sun/star/linguistic2/LanguageGuessing.hpp>
+#include <ooo/vba/XSinkCaller.hpp>
+#include <comphelper/lok.hxx>
+#include <comphelper/processfactory.hxx>
+#include <docsh.hxx>
+#include <swmodule.hxx>
+#include <cmdid.h>
+#include <pview.hxx>
+#include <wview.hxx>
+#include <wdocsh.hxx>
+#include <srcview.hxx>
+#include <glshell.hxx>
+#include <tabsh.hxx>
+#include <listsh.hxx>
+#include <grfsh.hxx>
+#include <mediash.hxx>
+#include <olesh.hxx>
+#include <drawsh.hxx>
+#include <wformsh.hxx>
+#include <drwtxtsh.hxx>
+#include <beziersh.hxx>
+#include <wtextsh.hxx>
+#include <wfrmsh.hxx>
+#include <drformsh.hxx>
+#include <wgrfsh.hxx>
+#include <wolesh.hxx>
+#include <wlistsh.hxx>
+#include <wtabsh.hxx>
+#include <navipi.hxx>
+#include <inputwin.hxx>
+#include <usrpref.hxx>
+#include <uinums.hxx>
+#include <prtopt.hxx>
+#include <bookctrl.hxx>
+#include <tmplctrl.hxx>
+#include <viewlayoutctrl.hxx>
+#include <svx/zoomsliderctrl.hxx>
+#include <zoomctrl.hxx>
+#include <wordcountctrl.hxx>
+#include <AccessibilityStatusBarControl.hxx>
+#include <workctrl.hxx>
+#include <fldwrap.hxx>
+#include <redlndlg.hxx>
+#include <syncbtn.hxx>
+#include <modcfg.hxx>
+#include <fontcfg.hxx>
+#include <sfx2/sidebar/SidebarChildWindow.hxx>
+#include <sfx2/devtools/DevelopmentToolChildWindow.hxx>
+#include <swatrset.hxx>
+#include <idxmrk.hxx>
+#include <wordcountdialog.hxx>
+#include <dlelstnr.hxx>
+#include <barcfg.hxx>
+#include <svx/rubydialog.hxx>
+#include <svtools/colorcfg.hxx>
+
+#include <unotools/configmgr.hxx>
+#include <unotools/moduleoptions.hxx>
+
+#include <avmedia/mediaplayer.hxx>
+#include <avmedia/mediatoolbox.hxx>
+
+#include <annotsh.hxx>
+#include <navsh.hxx>
+
+#include <app.hrc>
+#include <error.hrc>
+#include <strings.hrc>
+#include <bitmaps.hlst>
+#include <svx/xmlsecctrl.hxx>
+bool g_bNoInterrupt = false;
+
+#include <sfx2/app.hxx>
+
+#include <svx/svxerr.hxx>
+
+#include "swdllimpl.hxx"
+#include <dbconfig.hxx>
+#include <navicfg.hxx>
+
+using namespace com::sun::star;
+using namespace ::com::sun::star::uno;
+
+SwModule::SwModule( SfxObjectFactory* pWebFact,
+ SfxObjectFactory* pFact,
+ SfxObjectFactory* pGlobalFact )
+ : SfxModule("sw"_ostr, {pWebFact, pFact, pGlobalFact}),
+ m_pView(nullptr),
+ m_bAuthorInitialised(false),
+ m_bEmbeddedLoadSave( false ),
+ m_pDragDrop( nullptr ),
+ m_pXSelection( nullptr )
+{
+ SetName( "StarWriter" );
+ SvxErrorHandler::ensure();
+ m_pErrorHandler.reset( new SfxErrorHandler( RID_SW_ERRHDL,
+ ErrCodeArea::Sw,
+ ErrCodeArea::Sw,
+ GetResLocale() ) );
+
+ m_pModuleConfig.reset(new SwModuleOptions);
+
+ // We need them anyways
+ m_pToolbarConfig.reset(new SwToolbarConfigItem( false ));
+ m_pWebToolbarConfig.reset(new SwToolbarConfigItem( true ));
+
+ m_pStdFontConfig.reset(new SwStdFontConfig);
+
+ {
+ SolarMutexGuard g;
+ StartListening( *SfxGetpApp() );
+ }
+
+ if (!utl::ConfigManager::IsFuzzing())
+ {
+ // init color configuration
+ // member <pColorConfig> is created and the color configuration is applied
+ // at the view options.
+ GetColorConfig();
+ m_xLinguServiceEventListener = new SwLinguServiceEventListener;
+ }
+}
+
+OUString SwResId(TranslateId aId)
+{
+ return Translate::get(aId, SW_MOD()->GetResLocale());
+}
+
+OUString SwResId(TranslateNId aContextSingularPlural, int nCardinality)
+{
+ return Translate::nget(aContextSingularPlural, nCardinality, SW_MOD()->GetResLocale());
+}
+
+uno::Reference< scanner::XScannerManager2 > const &
+SwModule::GetScannerManager()
+{
+ static bool bTestScannerManager = true;
+ if (bTestScannerManager && !m_xScannerManager.is())
+ {
+ try {
+ m_xScannerManager = scanner::ScannerManager::create( comphelper::getProcessComponentContext() );
+ }
+ catch (...) {}
+ bTestScannerManager = false;
+ }
+ return m_xScannerManager;
+}
+
+uno::Reference< linguistic2::XLanguageGuessing > const & SwModule::GetLanguageGuesser()
+{
+ if (!m_xLanguageGuesser.is())
+ {
+ m_xLanguageGuesser = linguistic2::LanguageGuessing::create( comphelper::getProcessComponentContext() );
+ }
+ return m_xLanguageGuesser;
+}
+
+SwModule::~SwModule()
+{
+ css::uno::Sequence< css::uno::Any > aArgs;
+ CallAutomationApplicationEventSinks( "Quit", aArgs );
+ m_pErrorHandler.reset();
+ EndListening( *SfxGetpApp() );
+}
+
+void SwDLL::RegisterFactories()
+{
+ // These Id's must not be changed. Through these Id's the View (resume Documentview)
+ // is created by Sfx.
+ if (utl::ConfigManager::IsFuzzing() || SvtModuleOptions().IsWriter())
+ SwView::RegisterFactory ( SFX_INTERFACE_SFXDOCSH );
+
+#if HAVE_FEATURE_DESKTOP
+ SwWebView::RegisterFactory ( SFX_INTERFACE_SFXMODULE );
+
+ if (utl::ConfigManager::IsFuzzing() || SvtModuleOptions().IsWriter())
+ {
+ SwSrcView::RegisterFactory ( SfxInterfaceId(6) );
+ SwPagePreview::RegisterFactory ( SfxInterfaceId(7) );
+ }
+#endif
+}
+
+void SwDLL::RegisterInterfaces()
+{
+ SwModule* pMod = SW_MOD();
+ SwModule::RegisterInterface( pMod );
+ SwDocShell::RegisterInterface( pMod );
+ SwWebDocShell::RegisterInterface( pMod );
+ SwGlosDocShell::RegisterInterface( pMod );
+ SwWebGlosDocShell::RegisterInterface( pMod );
+ SwView::RegisterInterface( pMod );
+ SwWebView::RegisterInterface( pMod );
+ SwPagePreview::RegisterInterface( pMod );
+ SwSrcView::RegisterInterface( pMod );
+
+ SwBaseShell::RegisterInterface(pMod);
+ SwTextShell::RegisterInterface(pMod);
+ SwTableShell::RegisterInterface(pMod);
+ SwListShell::RegisterInterface(pMod);
+ SwFrameShell::RegisterInterface(pMod);
+ SwDrawBaseShell::RegisterInterface(pMod);
+ SwDrawShell::RegisterInterface(pMod);
+ SwDrawFormShell::RegisterInterface(pMod);
+ SwDrawTextShell::RegisterInterface(pMod);
+ SwBezierShell::RegisterInterface(pMod);
+ SwGrfShell::RegisterInterface(pMod);
+ SwOleShell::RegisterInterface(pMod);
+ SwNavigationShell::RegisterInterface(pMod);
+ SwWebTextShell::RegisterInterface(pMod);
+ SwWebFrameShell::RegisterInterface(pMod);
+ SwWebGrfShell::RegisterInterface(pMod);
+ SwWebListShell::RegisterInterface(pMod);
+ SwWebTableShell::RegisterInterface(pMod);
+ SwWebDrawFormShell::RegisterInterface(pMod);
+ SwWebOleShell::RegisterInterface(pMod);
+ SwMediaShell::RegisterInterface(pMod);
+ SwAnnotationShell::RegisterInterface(pMod);
+}
+
+void SwDLL::RegisterControls()
+{
+ SwModule* pMod = SW_MOD();
+
+ SvxTbxCtlDraw::RegisterControl(SID_INSERT_DRAW, pMod );
+ SvxTbxCtlDraw::RegisterControl(SID_TRACK_CHANGES_BAR, pMod );
+ SwTbxAutoTextCtrl::RegisterControl(FN_GLOSSARY_DLG, pMod );
+ svx::ParaAboveSpacingControl::RegisterControl(SID_ATTR_PARA_ABOVESPACE, pMod);
+ svx::ParaBelowSpacingControl::RegisterControl(SID_ATTR_PARA_BELOWSPACE, pMod);
+ svx::ParaLeftSpacingControl::RegisterControl(SID_ATTR_PARA_LEFTSPACE, pMod);
+ svx::ParaRightSpacingControl::RegisterControl(SID_ATTR_PARA_RIGHTSPACE, pMod);
+ svx::ParaFirstLineSpacingControl::RegisterControl(SID_ATTR_PARA_FIRSTLINESPACE, pMod);
+
+ SvxClipBoardControl::RegisterControl(SID_PASTE, pMod );
+ svx::FormatPaintBrushToolBoxControl::RegisterControl(SID_FORMATPAINTBRUSH, pMod );
+
+ SvxFillToolBoxControl::RegisterControl(SID_ATTR_FILL_STYLE, pMod );
+ SvxLineWidthToolBoxControl::RegisterControl(SID_ATTR_LINE_WIDTH, pMod );
+
+ SwZoomControl::RegisterControl(SID_ATTR_ZOOM, pMod );
+ SwPreviewZoomControl::RegisterControl(FN_PREVIEW_ZOOM, pMod);
+ SvxPosSizeStatusBarControl::RegisterControl(0, pMod );
+ SvxInsertStatusBarControl::RegisterControl(SID_ATTR_INSERT, pMod );
+ SvxSelectionModeControl::RegisterControl(FN_STAT_SELMODE, pMod );
+ XmlSecStatusBarControl::RegisterControl( SID_SIGNATURE, pMod );
+ SwWordCountStatusBarControl::RegisterControl(FN_STAT_WORDCOUNT, pMod);
+ sw::AccessibilityStatusBarControl::RegisterControl(FN_STAT_ACCESSIBILITY_CHECK, pMod);
+
+ SwBookmarkControl::RegisterControl(FN_STAT_PAGE, pMod );
+ SwTemplateControl::RegisterControl(FN_STAT_TEMPLATE, pMod );
+ SwViewLayoutControl::RegisterControl( SID_ATTR_VIEWLAYOUT, pMod );
+ SvxModifyControl::RegisterControl( SID_DOC_MODIFIED, pMod );
+ SvxZoomSliderControl::RegisterControl( SID_ATTR_ZOOMSLIDER, pMod );
+
+ SvxIMapDlgChildWindow::RegisterChildWindow( false, pMod );
+ SvxSearchDialogWrapper::RegisterChildWindow( false, pMod );
+ SvxHlinkDlgWrapper::RegisterChildWindow( false, pMod );
+ SvxFontWorkChildWindow::RegisterChildWindow( false, pMod );
+ SwFieldDlgWrapper::RegisterChildWindow( false, pMod );
+ SwFieldDataOnlyDlgWrapper::RegisterChildWindow( false, pMod );
+ SvxContourDlgChildWindow::RegisterChildWindow( false, pMod );
+ SwInputChild::RegisterChildWindow( false, pMod, SfxChildWindowFlags::FORCEDOCK );
+ SwRedlineAcceptChild::RegisterChildWindow( false, pMod );
+ SwSyncChildWin::RegisterChildWindow( true, pMod );
+ SwInsertIdxMarkWrapper::RegisterChildWindow( false, pMod );
+ SwInsertAuthMarkWrapper::RegisterChildWindow( false, pMod );
+ SwWordCountWrapper::RegisterChildWindow( false, pMod );
+ SvxRubyChildWindow::RegisterChildWindow( false, pMod);
+ SwSpellDialogChildWindow::RegisterChildWindow(
+ false, pMod, comphelper::LibreOfficeKit::isActive() ? SfxChildWindowFlags::NEVERCLONE
+ : SfxChildWindowFlags::NONE);
+ DevelopmentToolChildWindow::RegisterChildWindow(false, pMod);
+
+ SvxGrafRedToolBoxControl::RegisterControl( SID_ATTR_GRAF_RED, pMod );
+ SvxGrafGreenToolBoxControl::RegisterControl( SID_ATTR_GRAF_GREEN, pMod );
+ SvxGrafBlueToolBoxControl::RegisterControl( SID_ATTR_GRAF_BLUE, pMod );
+ SvxGrafLuminanceToolBoxControl::RegisterControl( SID_ATTR_GRAF_LUMINANCE, pMod );
+ SvxGrafContrastToolBoxControl::RegisterControl( SID_ATTR_GRAF_CONTRAST, pMod );
+ SvxGrafGammaToolBoxControl::RegisterControl( SID_ATTR_GRAF_GAMMA, pMod );
+ SvxGrafTransparenceToolBoxControl::RegisterControl( SID_ATTR_GRAF_TRANSPARENCE, pMod );
+ SvxGrafModeToolBoxControl::RegisterControl( SID_ATTR_GRAF_MODE, pMod );
+
+#if HAVE_FEATURE_AVMEDIA
+ ::avmedia::MediaToolBoxControl::RegisterControl(SID_AVMEDIA_TOOLBOX, pMod);
+ ::avmedia::MediaPlayer::RegisterChildWindow(false, pMod);
+#endif
+
+ ::sfx2::sidebar::SidebarChildWindow::RegisterChildWindow(false, pMod);
+
+ SwNavigatorWrapper::RegisterChildWindow(false, pMod, SfxChildWindowFlags::NEVERHIDE);
+
+ SwJumpToSpecificPageControl::RegisterControl(SID_JUMP_TO_SPECIFIC_PAGE, pMod);
+}
+
+// Load Module (only dummy for linking of the DLL)
+void SwModule::InitAttrPool()
+{
+ OSL_ENSURE(!m_pAttrPool, "Pool already exists!");
+ m_pAttrPool = new SwAttrPool(nullptr);
+ SetPool(m_pAttrPool.get());
+}
+
+void SwModule::RemoveAttrPool()
+{
+ SetPool(nullptr);
+ m_pAttrPool.clear();
+}
+
+std::optional<SfxStyleFamilies> SwModule::CreateStyleFamilies()
+{
+ SfxStyleFamilies aStyleFamilies;
+
+ aStyleFamilies.emplace_back(SfxStyleFamily::Para,
+ SwResId(STR_PARAGRAPHSTYLEFAMILY),
+ BMP_STYLES_FAMILY_PARA,
+ RID_PARAGRAPHSTYLEFAMILY, GetResLocale());
+
+ aStyleFamilies.emplace_back(SfxStyleFamily::Char,
+ SwResId(STR_CHARACTERSTYLEFAMILY),
+ BMP_STYLES_FAMILY_CHAR,
+ RID_CHARACTERSTYLEFAMILY, GetResLocale());
+
+ aStyleFamilies.emplace_back(SfxStyleFamily::Frame,
+ SwResId(STR_FRAMESTYLEFAMILY),
+ BMP_STYLES_FAMILY_FRAME,
+ RID_FRAMESTYLEFAMILY, GetResLocale());
+
+ aStyleFamilies.emplace_back(SfxStyleFamily::Page,
+ SwResId(STR_PAGESTYLEFAMILY),
+ BMP_STYLES_FAMILY_PAGE,
+ RID_PAGESTYLEFAMILY, GetResLocale());
+
+ aStyleFamilies.emplace_back(SfxStyleFamily::Pseudo,
+ SwResId(STR_LISTSTYLEFAMILY),
+ BMP_STYLES_FAMILY_LIST,
+ RID_LISTSTYLEFAMILY, GetResLocale());
+
+ aStyleFamilies.emplace_back(SfxStyleFamily::Table,
+ SwResId(STR_TABLESTYLEFAMILY),
+ BMP_STYLES_FAMILY_TABLE,
+ RID_TABLESTYLEFAMILY, GetResLocale());
+
+ return aStyleFamilies;
+}
+
+void SwModule::RegisterAutomationApplicationEventsCaller(css::uno::Reference< ooo::vba::XSinkCaller > const& xCaller)
+{
+ mxAutomationApplicationEventsCaller = xCaller;
+}
+
+void SwModule::CallAutomationApplicationEventSinks(const OUString& Method, css::uno::Sequence< css::uno::Any >& Arguments)
+{
+ if (mxAutomationApplicationEventsCaller.is())
+ mxAutomationApplicationEventsCaller->CallSinks(Method, Arguments);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/app/swwait.cxx b/sw/source/uibase/app/swwait.cxx
new file mode 100644
index 0000000000..62d8b277d6
--- /dev/null
+++ b/sw/source/uibase/app/swwait.cxx
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <swwait.hxx>
+#include <docsh.hxx>
+
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/dispatch.hxx>
+
+#include <vcl/window.hxx>
+
+SwWait::SwWait(
+ SwDocShell &rDocShell,
+ const bool bLockUnlockDispatcher )
+ : mrDoc ( rDocShell )
+ , mbLockUnlockDispatcher( bLockUnlockDispatcher )
+{
+ EnterWaitAndLockDispatcher();
+}
+
+SwWait::~SwWait()
+{
+ LeaveWaitAndUnlockDispatcher();
+}
+
+void SwWait::EnterWaitAndLockDispatcher()
+{
+ SfxViewFrame *pFrame = SfxViewFrame::GetFirst( &mrDoc, false );
+ while ( pFrame )
+ {
+ pFrame->GetWindow().EnterWait();
+ if ( mbLockUnlockDispatcher )
+ {
+ // do not look already locked dispatchers
+ SfxDispatcher* pDispatcher = pFrame->GetDispatcher();
+ if ( !pDispatcher->IsLocked() )
+ {
+ pDispatcher->Lock( true );
+ mpLockedDispatchers.insert( pDispatcher );
+ }
+ }
+
+ pFrame = SfxViewFrame::GetNext( *pFrame, &mrDoc, false );
+ }
+}
+
+void SwWait::LeaveWaitAndUnlockDispatcher()
+{
+ SfxViewFrame *pFrame = SfxViewFrame::GetFirst( &mrDoc, false );
+ while ( pFrame )
+ {
+ pFrame->GetWindow().LeaveWait();
+ if ( mbLockUnlockDispatcher )
+ {
+ // only unlock dispatchers which had been locked
+ SfxDispatcher* pDispatcher = pFrame->GetDispatcher();
+ if ( mpLockedDispatchers.erase( pDispatcher ) )
+ {
+ pDispatcher->Lock( false );
+ }
+ }
+
+ pFrame = SfxViewFrame::GetNext( *pFrame, &mrDoc, false );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */