summaryrefslogtreecommitdiffstats
path: root/sw/source/uibase/shells
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/shells
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/shells')
-rw-r--r--sw/source/uibase/shells/annotsh.cxx1855
-rw-r--r--sw/source/uibase/shells/basesh.cxx3372
-rw-r--r--sw/source/uibase/shells/beziersh.cxx325
-rw-r--r--sw/source/uibase/shells/drawdlg.cxx368
-rw-r--r--sw/source/uibase/shells/drawsh.cxx629
-rw-r--r--sw/source/uibase/shells/drformsh.cxx251
-rw-r--r--sw/source/uibase/shells/drwbassh.cxx1245
-rw-r--r--sw/source/uibase/shells/drwtxtex.cxx1241
-rw-r--r--sw/source/uibase/shells/drwtxtsh.cxx849
-rw-r--r--sw/source/uibase/shells/frmsh.cxx1463
-rw-r--r--sw/source/uibase/shells/grfsh.cxx1018
-rw-r--r--sw/source/uibase/shells/grfshex.cxx155
-rw-r--r--sw/source/uibase/shells/langhelper.cxx549
-rw-r--r--sw/source/uibase/shells/listsh.cxx264
-rw-r--r--sw/source/uibase/shells/mediash.cxx99
-rw-r--r--sw/source/uibase/shells/navsh.cxx100
-rw-r--r--sw/source/uibase/shells/olesh.cxx95
-rw-r--r--sw/source/uibase/shells/slotadd.cxx134
-rw-r--r--sw/source/uibase/shells/tabsh.cxx1682
-rw-r--r--sw/source/uibase/shells/textdrw.cxx126
-rw-r--r--sw/source/uibase/shells/textfld.cxx1805
-rw-r--r--sw/source/uibase/shells/textglos.cxx126
-rw-r--r--sw/source/uibase/shells/textidx.cxx324
-rw-r--r--sw/source/uibase/shells/textsh.cxx1107
-rw-r--r--sw/source/uibase/shells/textsh1.cxx2822
-rw-r--r--sw/source/uibase/shells/textsh2.cxx252
-rw-r--r--sw/source/uibase/shells/translatehelper.cxx216
-rw-r--r--sw/source/uibase/shells/txtattr.cxx849
-rw-r--r--sw/source/uibase/shells/txtcrsr.cxx464
-rw-r--r--sw/source/uibase/shells/txtnum.cxx330
30 files changed, 24115 insertions, 0 deletions
diff --git a/sw/source/uibase/shells/annotsh.cxx b/sw/source/uibase/shells/annotsh.cxx
new file mode 100644
index 0000000000..5c9ed82b41
--- /dev/null
+++ b/sw/source/uibase/shells/annotsh.cxx
@@ -0,0 +1,1855 @@
+/* -*- 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 <com/sun/star/i18n/TextConversionOption.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/linguistic2/XThesaurus.hpp>
+
+#include <i18nutil/transliteration.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/request.hxx>
+#include <editeng/editund2.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/flstitem.hxx>
+#include <editeng/spltitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/orphitem.hxx>
+#include <editeng/formatbreakitem.hxx>
+#include <editeng/widwitem.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/escapementitem.hxx>
+#include <editeng/lspcitem.hxx>
+#include <editeng/adjustitem.hxx>
+#include <editeng/hyphenzoneitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <svx/clipfmtitem.hxx>
+#include <svl/stritem.hxx>
+#include <svl/slstitm.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <svl/whiter.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/ctloptions.hxx>
+#include <unotools/useroptions.hxx>
+#include <editeng/flditem.hxx>
+#include <svx/hlnkitem.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <swundo.hxx>
+#include <doc.hxx>
+#include <viewopt.hxx>
+#include <wrtsh.hxx>
+#include <chrdlgmodes.hxx>
+#include <edtwin.hxx>
+#include <SwRewriter.hxx>
+
+#include <cmdid.h>
+#include <strings.hrc>
+#include <breakit.hxx>
+#include <annotsh.hxx>
+#include <view.hxx>
+#include <PostItMgr.hxx>
+#include <AnnotationWin.hxx>
+
+#include <swtypes.hxx>
+
+#include <svx/svxdlg.hxx>
+
+#include <vcl/EnumContext.hxx>
+#include <svl/itempool.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/editview.hxx>
+#include <osl/diagnose.h>
+
+#include <svl/languageoptions.hxx>
+
+#include <svl/undo.hxx>
+#include <swabstdlg.hxx>
+
+#include <comphelper/string.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <cppuhelper/bootstrap.hxx>
+
+#include <langhelper.hxx>
+
+#include <memory>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::i18n;
+
+#define ShellClass_SwAnnotationShell
+
+#include <sfx2/msg.hxx>
+#include <swslots.hxx>
+
+SFX_IMPL_INTERFACE(SwAnnotationShell, SfxShell)
+
+void SwAnnotationShell::InitInterface_Impl()
+{
+ GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Invisible, ToolbarId::Text_Toolbox_Sw);
+
+ GetStaticInterface()->RegisterPopupMenu("annotation");
+}
+
+
+SfxItemPool* SwAnnotationShell::GetAnnotationPool(SwView const & rV)
+{
+ SwWrtShell &rSh = rV.GetWrtShell();
+ return rSh.GetAttrPool().GetSecondaryPool();
+}
+
+SwAnnotationShell::SwAnnotationShell( SwView& r )
+ : m_rView(r)
+{
+ SetPool(SwAnnotationShell::GetAnnotationPool(m_rView));
+ SfxShell::SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::Annotation));
+}
+
+SwAnnotationShell::~SwAnnotationShell()
+{
+ if (m_rView.GetWrtShell().CanInsert())
+ m_rView.ShowCursor(true);
+}
+
+SfxUndoManager* SwAnnotationShell::GetUndoManager()
+{
+ SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr();
+ if ( !pPostItMgr ||
+ !pPostItMgr->HasActiveSidebarWin() )
+ {
+ OSL_ENSURE(pPostItMgr,"PostItMgr::Layout(): We are looping forever");
+ return nullptr;
+ }
+ return &pPostItMgr->GetActiveSidebarWin()->GetOutlinerView()->GetOutliner()->GetUndoManager();
+}
+
+void SwAnnotationShell::Exec( SfxRequest &rReq )
+{
+ //TODO: clean this up!!!!
+ SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr();
+ if ( !pPostItMgr || !pPostItMgr->HasActiveSidebarWin() )
+ return;
+
+ OutlinerView* pOLV = pPostItMgr->GetActiveSidebarWin()->GetOutlinerView();
+ SfxItemSet aEditAttr(pOLV->GetAttribs());
+ SfxItemSet aNewAttr(*aEditAttr.GetPool(), aEditAttr.GetRanges());
+
+ sal_uInt16 nSlot = rReq.GetSlot();
+ sal_uInt16 nWhich = GetPool().GetWhich(nSlot);
+ const SfxItemSet *pNewAttrs = rReq.GetArgs();
+ sal_uInt16 nEEWhich = 0;
+ switch (nSlot)
+ {
+ case SID_PARASPACE_INCREASE:
+ case SID_PARASPACE_DECREASE:
+ {
+ SvxULSpaceItem aULSpace( aEditAttr.Get( EE_PARA_ULSPACE ) );
+ sal_uInt16 nUpper = aULSpace.GetUpper();
+ sal_uInt16 nLower = aULSpace.GetLower();
+
+ if ( nSlot == SID_PARASPACE_INCREASE )
+ {
+ nUpper = std::min< sal_uInt16 >( nUpper + 57, 5670 );
+ nLower = std::min< sal_uInt16 >( nLower + 57, 5670 );
+ }
+ else
+ {
+ nUpper = std::max< sal_Int16 >( nUpper - 57, 0 );
+ nLower = std::max< sal_Int16 >( nLower - 57, 0 );
+ }
+
+ aULSpace.SetUpper( nUpper );
+ aULSpace.SetLower( nLower );
+ aNewAttr.Put( aULSpace );
+ rReq.Done();
+ }
+ break;
+ case SID_ATTR_PARA_LRSPACE:
+ {
+ SvxLRSpaceItem aParaMargin(static_cast<const SvxLRSpaceItem&>(rReq.
+ GetArgs()->Get(nSlot)));
+ aParaMargin.SetWhich( EE_PARA_LRSPACE );
+
+ aNewAttr.Put(aParaMargin);
+ rReq.Done();
+ break;
+ }
+ case SID_ATTR_PARA_LINESPACE:
+ {
+ SvxLineSpacingItem aParaMargin = static_cast<const SvxLineSpacingItem&>(pNewAttrs->Get(
+ GetPool().GetWhich(nSlot)));
+ aParaMargin.SetWhich( EE_PARA_SBL );
+
+ aNewAttr.Put(aParaMargin);
+ rReq.Done();
+ break;
+ }
+ case SID_ATTR_PARA_ULSPACE:
+ {
+ SvxULSpaceItem aULSpace = static_cast<const SvxULSpaceItem&>(pNewAttrs->Get(
+ GetPool().GetWhich(nSlot)));
+ aULSpace.SetWhich( EE_PARA_ULSPACE );
+ aNewAttr.Put( aULSpace );
+ rReq.Done();
+ }
+ break;
+ case FN_GROW_FONT_SIZE:
+ case FN_SHRINK_FONT_SIZE:
+ {
+ const SfxObjectShell* pObjSh = SfxObjectShell::Current();
+ const SvxFontListItem* pFontListItem = static_cast<const SvxFontListItem*>
+ (pObjSh ? pObjSh->GetItem(SID_ATTR_CHAR_FONTLIST) : nullptr);
+ const FontList* pFontList = pFontListItem ? pFontListItem->GetFontList() : nullptr;
+ pOLV->GetEditView().ChangeFontSize( nSlot == FN_GROW_FONT_SIZE, pFontList );
+ }
+ break;
+
+ case SID_ATTR_CHAR_FONT:
+ case SID_ATTR_CHAR_FONTHEIGHT:
+ case SID_ATTR_CHAR_WEIGHT:
+ case SID_ATTR_CHAR_POSTURE:
+ {
+ SfxItemPool* pSecondPool = aEditAttr.GetPool()->GetSecondaryPool();
+ if( !pSecondPool )
+ pSecondPool = aEditAttr.GetPool();
+ SvxScriptSetItem aSetItem( nSlot, *pSecondPool );
+ aSetItem.PutItemForScriptType( pOLV->GetSelectedScriptType(), pNewAttrs->Get( nWhich ));
+ aNewAttr.Put( aSetItem.GetItemSet() );
+ rReq.Done();
+ break;
+ }
+ case SID_ATTR_CHAR_COLOR: nEEWhich = EE_CHAR_COLOR; break;
+ case SID_ATTR_CHAR_BACK_COLOR: nEEWhich = EE_CHAR_BKGCOLOR; break;
+ case SID_ATTR_CHAR_UNDERLINE:
+ {
+ if( rReq.GetArgs() )
+ {
+ const SvxUnderlineItem* pItem = rReq.GetArg<SvxUnderlineItem>(SID_ATTR_CHAR_UNDERLINE);
+ if (pItem)
+ {
+ aNewAttr.Put(*pItem);
+ }
+ else
+ {
+ FontLineStyle eFU = aEditAttr.Get( EE_CHAR_UNDERLINE ).GetLineStyle();
+ aNewAttr.Put( SvxUnderlineItem( eFU != LINESTYLE_NONE ?LINESTYLE_NONE : LINESTYLE_SINGLE, EE_CHAR_UNDERLINE ) );
+ }
+ }
+ break;
+ }
+ case SID_ATTR_CHAR_OVERLINE:
+ {
+ FontLineStyle eFO = aEditAttr.Get(EE_CHAR_OVERLINE).GetLineStyle();
+ aNewAttr.Put(SvxOverlineItem(eFO == LINESTYLE_SINGLE ? LINESTYLE_NONE : LINESTYLE_SINGLE, EE_CHAR_OVERLINE));
+ break;
+ }
+ case SID_ATTR_CHAR_CONTOUR: nEEWhich = EE_CHAR_OUTLINE; break;
+ case SID_ATTR_CHAR_SHADOWED: nEEWhich = EE_CHAR_SHADOW; break;
+ case SID_ATTR_CHAR_STRIKEOUT: nEEWhich = EE_CHAR_STRIKEOUT; break;
+ case SID_ATTR_CHAR_WORDLINEMODE: nEEWhich = EE_CHAR_WLM; break;
+ case SID_ATTR_CHAR_RELIEF : nEEWhich = EE_CHAR_RELIEF; break;
+ case SID_ATTR_CHAR_LANGUAGE : nEEWhich = EE_CHAR_LANGUAGE;break;
+ case SID_ATTR_CHAR_KERNING : nEEWhich = EE_CHAR_KERNING; break;
+ case SID_ATTR_CHAR_SCALEWIDTH: nEEWhich = EE_CHAR_FONTWIDTH; break;
+ case SID_ATTR_CHAR_AUTOKERN : nEEWhich = EE_CHAR_PAIRKERNING; break;
+ case SID_ATTR_CHAR_ESCAPEMENT: nEEWhich = EE_CHAR_ESCAPEMENT; break;
+ case SID_ATTR_PARA_ADJUST_LEFT:
+ aNewAttr.Put(SvxAdjustItem(SvxAdjust::Left, EE_PARA_JUST));
+ break;
+ case SID_ATTR_PARA_ADJUST_CENTER:
+ aNewAttr.Put(SvxAdjustItem(SvxAdjust::Center, EE_PARA_JUST));
+ break;
+ case SID_ATTR_PARA_ADJUST_RIGHT:
+ aNewAttr.Put(SvxAdjustItem(SvxAdjust::Right, EE_PARA_JUST));
+ break;
+ case SID_ATTR_PARA_ADJUST_BLOCK:
+ aNewAttr.Put(SvxAdjustItem(SvxAdjust::Block, EE_PARA_JUST));
+ break;
+
+ case SID_ATTR_PARA_LINESPACE_10:
+ {
+ SvxLineSpacingItem aItem(LINE_SPACE_DEFAULT_HEIGHT, EE_PARA_SBL);
+ aItem.SetPropLineSpace(100);
+ aNewAttr.Put(aItem);
+ }
+ break;
+ case SID_ATTR_PARA_LINESPACE_115:
+ {
+ SvxLineSpacingItem aItem(LINE_SPACE_DEFAULT_HEIGHT, EE_PARA_SBL);
+ aItem.SetPropLineSpace(115);
+ aNewAttr.Put(aItem);
+ }
+ break;
+ case SID_ATTR_PARA_LINESPACE_15:
+ {
+ SvxLineSpacingItem aItem(LINE_SPACE_DEFAULT_HEIGHT, EE_PARA_SBL);
+ aItem.SetPropLineSpace(150);
+ aNewAttr.Put(aItem);
+ }
+ break;
+ case SID_ATTR_PARA_LINESPACE_20:
+ {
+ SvxLineSpacingItem aItem(LINE_SPACE_DEFAULT_HEIGHT, EE_PARA_SBL);
+ aItem.SetPropLineSpace(200);
+ aNewAttr.Put(aItem);
+ }
+ break;
+ case SID_SELECTALL:
+ {
+ Outliner * pOutliner = pOLV->GetOutliner();
+ if(pOutliner)
+ {
+ sal_Int32 nParaCount = pOutliner->GetParagraphCount();
+ if (nParaCount > 0)
+ pOLV->SelectRange(0, nParaCount );
+ }
+ break;
+ }
+ case FN_FORMAT_RESET:
+ {
+ pPostItMgr->GetActiveSidebarWin()->ResetAttributes();
+ rReq.Done();
+ break;
+ }
+ case FN_SET_SUPER_SCRIPT:
+ {
+ SvxEscapementItem aItem(EE_CHAR_ESCAPEMENT);
+ SvxEscapement eEsc = static_cast<SvxEscapement>(aEditAttr.Get( EE_CHAR_ESCAPEMENT ).GetEnumValue());
+
+ if( eEsc == SvxEscapement::Superscript )
+ aItem.SetEscapement( SvxEscapement::Off );
+ else
+ aItem.SetEscapement( SvxEscapement::Superscript );
+ aNewAttr.Put( aItem );
+ }
+ break;
+ case FN_SET_SUB_SCRIPT:
+ {
+ SvxEscapementItem aItem(EE_CHAR_ESCAPEMENT);
+ SvxEscapement eEsc = static_cast<SvxEscapement>(aEditAttr.Get( EE_CHAR_ESCAPEMENT ).GetEnumValue());
+
+ if( eEsc == SvxEscapement::Subscript )
+ aItem.SetEscapement( SvxEscapement::Off );
+ else
+ aItem.SetEscapement( SvxEscapement::Subscript );
+ aNewAttr.Put( aItem );
+ }
+ break;
+ case SID_HYPERLINK_SETLINK:
+ {
+ const SfxPoolItem* pItem = nullptr;
+ if(pNewAttrs)
+ pNewAttrs->GetItemState(nSlot, false, &pItem);
+
+ if(pItem)
+ {
+ const SvxHyperlinkItem& rHLinkItem = *static_cast<const SvxHyperlinkItem *>(pItem);
+ SvxURLField aField(rHLinkItem.GetURL(), rHLinkItem.GetName(), SvxURLFormat::AppDefault);
+ aField.SetTargetFrame(rHLinkItem.GetTargetFrame());
+
+ const SvxFieldItem* pFieldItem = pOLV->GetFieldAtSelection();
+
+ if (pFieldItem && dynamic_cast<const SvxURLField *>(pFieldItem->GetField()) != nullptr)
+ {
+ // Select the field so that it will be deleted during insert
+ ESelection aSel = pOLV->GetSelection();
+ aSel.nEndPos++;
+ pOLV->SetSelection(aSel);
+ }
+ if (pPostItMgr->GetActiveSidebarWin()->GetLayoutStatus()!=SwPostItHelper::DELETED)
+ pOLV->InsertField(SvxFieldItem(aField, EE_FEATURE_FIELD));
+ }
+ break;
+ }
+ case FN_INSERT_SOFT_HYPHEN:
+ case FN_INSERT_HARDHYPHEN:
+ case FN_INSERT_HARD_SPACE:
+ case FN_INSERT_NNBSP:
+ case SID_INSERT_RLM :
+ case SID_INSERT_LRM :
+ case SID_INSERT_WJ :
+ case SID_INSERT_ZWSP:
+ {
+ sal_Unicode cIns = 0;
+ switch(rReq.GetSlot())
+ {
+ case FN_INSERT_SOFT_HYPHEN: cIns = CHAR_SOFTHYPHEN; break;
+ case FN_INSERT_HARDHYPHEN: cIns = CHAR_HARDHYPHEN; break;
+ case FN_INSERT_HARD_SPACE: cIns = CHAR_HARDBLANK; break;
+ case FN_INSERT_NNBSP: cIns = CHAR_NNBSP; break;
+ case SID_INSERT_RLM : cIns = CHAR_RLM ; break;
+ case SID_INSERT_LRM : cIns = CHAR_LRM ; break;
+ case SID_INSERT_ZWSP : cIns = CHAR_ZWSP ; break;
+ case SID_INSERT_WJ: cIns = CHAR_WJ; break;
+ }
+ pOLV->InsertText( OUString(cIns));
+ rReq.Done();
+ break;
+ }
+ case SID_CHARMAP:
+ {
+ if (pPostItMgr->GetActiveSidebarWin()->GetLayoutStatus()!=SwPostItHelper::DELETED)
+ InsertSymbol(rReq);
+ break;
+ }
+ case FN_INSERT_STRING:
+ {
+ const SfxPoolItem* pItem = nullptr;
+ if (pNewAttrs)
+ pNewAttrs->GetItemState(nSlot, false, &pItem );
+ if (pItem && pPostItMgr->GetActiveSidebarWin()->GetLayoutStatus()!=SwPostItHelper::DELETED)
+ pOLV->InsertText(static_cast<const SfxStringItem *>(pItem)->GetValue());
+ break;
+ }
+ case FN_FORMAT_FOOTNOTE_DLG:
+ {
+ m_rView.ExecFormatFootnote();
+ break;
+ }
+ case FN_NUMBERING_OUTLINE_DLG:
+ {
+ m_rView.ExecNumberingOutline(GetPool());
+ rReq.Done();
+ }
+ break;
+ case SID_OPEN_XML_FILTERSETTINGS:
+ {
+ HandleOpenXmlFilterSettings(rReq);
+ }
+ break;
+ case FN_WORDCOUNT_DIALOG:
+ {
+ m_rView.UpdateWordCount(this, nSlot);
+ break;
+ }
+ case SID_CHAR_DLG_EFFECT:
+ case SID_CHAR_DLG_POSITION:
+ case SID_CHAR_DLG:
+ {
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ const SfxStringItem* pItem = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+
+ if( !pArgs || pItem )
+ {
+ /* mod
+ SwView* pView = &GetView();
+ FieldUnit eMetric = ::GetDfltMetric(dynamic_cast<SwWebView*>( pView) != nullptr );
+ SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, eMetric));
+ */
+ SfxItemSetFixed<XATTR_FILLSTYLE, XATTR_FILLCOLOR, EE_ITEMS_START, EE_ITEMS_END> aDlgAttr(GetPool());
+
+ // util::Language does not exist in the EditEngine! Therefore not included in the set.
+
+ aDlgAttr.Put( aEditAttr );
+ aDlgAttr.Put( SvxKerningItem(0, RES_CHRATR_KERNING) );
+
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateSwCharDlg(m_rView.GetFrameWeld(), m_rView, aDlgAttr, SwCharDlgMode::Ann));
+ if (nSlot == SID_CHAR_DLG_EFFECT)
+ {
+ pDlg->SetCurPageId("fonteffects");
+ }
+ if (nSlot == SID_CHAR_DLG_POSITION)
+ {
+ pDlg->SetCurPageId("position");
+ }
+ else if (pItem)
+ {
+ pDlg->SetCurPageId(pItem->GetValue());
+ }
+
+ sal_uInt16 nRet = pDlg->Execute();
+ if(RET_OK == nRet )
+ {
+ rReq.Done( *( pDlg->GetOutputItemSet() ) );
+ aNewAttr.Put(*pDlg->GetOutputItemSet());
+ }
+ if(RET_OK != nRet)
+ return ;
+ }
+ else
+ aNewAttr.Put(*pArgs);
+ break;
+ }
+ case SID_PARA_DLG:
+ {
+ const SfxItemSet* pArgs = rReq.GetArgs();
+
+ if (!pArgs)
+ {
+ /* mod todo ???
+ SwView* pView = &GetView();
+ FieldUnit eMetric = ::GetDfltMetric(dynamic_cast<SwWebView*>( pView) != nullptr );
+ SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, eMetric));
+ */
+ SfxItemSetFixed<
+ EE_ITEMS_START, EE_ITEMS_END,
+ SID_ATTR_PARA_HYPHENZONE, SID_ATTR_PARA_WIDOWS>
+ aDlgAttr( GetPool() );
+
+ aDlgAttr.Put(aEditAttr);
+
+ aDlgAttr.Put( SvxHyphenZoneItem( false, RES_PARATR_HYPHENZONE) );
+ aDlgAttr.Put( SvxFormatBreakItem( SvxBreak::NONE, RES_BREAK ) );
+ aDlgAttr.Put( SvxFormatSplitItem( true, RES_PARATR_SPLIT ) );
+ aDlgAttr.Put( SvxWidowsItem( 0, RES_PARATR_WIDOWS ) );
+ aDlgAttr.Put( SvxOrphansItem( 0, RES_PARATR_ORPHANS ) );
+
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateSwParaDlg(m_rView.GetFrameWeld(), m_rView, aDlgAttr, true));
+ sal_uInt16 nRet = pDlg->Execute();
+ if(RET_OK == nRet)
+ {
+ rReq.Done( *( pDlg->GetOutputItemSet() ) );
+ aNewAttr.Put(*pDlg->GetOutputItemSet());
+ }
+ if(RET_OK != nRet)
+ return;
+ }
+ else
+ aNewAttr.Put(*pArgs);
+ break;
+ }
+
+ case SID_AUTOSPELL_CHECK:
+ {
+ m_rView.ExecuteSlot(rReq);
+ break;
+ }
+ case SID_ATTR_PARA_LEFT_TO_RIGHT:
+ case SID_ATTR_PARA_RIGHT_TO_LEFT:
+ {
+ bool bLeftToRight = nSlot == SID_ATTR_PARA_LEFT_TO_RIGHT;
+
+ const SfxPoolItem* pPoolItem;
+ if( pNewAttrs && SfxItemState::SET == pNewAttrs->GetItemState( nSlot, true, &pPoolItem ) )
+ {
+ if( !static_cast<const SfxBoolItem*>(pPoolItem)->GetValue() )
+ bLeftToRight = !bLeftToRight;
+ }
+ SfxItemSetFixed<
+ EE_PARA_WRITINGDIR, EE_PARA_WRITINGDIR,
+ EE_PARA_JUST, EE_PARA_JUST>
+ aAttr( *aNewAttr.GetPool() );
+
+ SvxAdjust nAdjust = SvxAdjust::Left;
+ if( const SvxAdjustItem* pAdjustItem = aEditAttr.GetItemIfSet(EE_PARA_JUST ) )
+ nAdjust = pAdjustItem->GetAdjust();
+
+ if( bLeftToRight )
+ {
+ aAttr.Put( SvxFrameDirectionItem( SvxFrameDirection::Horizontal_LR_TB, EE_PARA_WRITINGDIR ) );
+ if( nAdjust == SvxAdjust::Right )
+ aAttr.Put( SvxAdjustItem( SvxAdjust::Left, EE_PARA_JUST ) );
+ }
+ else
+ {
+ aAttr.Put( SvxFrameDirectionItem( SvxFrameDirection::Horizontal_RL_TB, EE_PARA_WRITINGDIR ) );
+ if( nAdjust == SvxAdjust::Left )
+ aAttr.Put( SvxAdjustItem( SvxAdjust::Right, EE_PARA_JUST ) );
+ }
+ pOLV->SetAttribs(aAttr);
+ break;
+ }
+ }
+
+ if(nEEWhich && pNewAttrs)
+ {
+ aNewAttr.Put(pNewAttrs->Get(nWhich).CloneSetWhich(nEEWhich));
+ }
+ else if (nEEWhich == EE_CHAR_COLOR)
+ {
+ m_rView.GetViewFrame().GetDispatcher()->Execute(SID_CHAR_DLG_EFFECT);
+ }
+ else if (nEEWhich == EE_CHAR_KERNING)
+ {
+ m_rView.GetViewFrame().GetDispatcher()->Execute(SID_CHAR_DLG_POSITION);
+ }
+
+
+ tools::Rectangle aOutRect = pOLV->GetOutputArea();
+ if (tools::Rectangle() != aOutRect && aNewAttr.Count())
+ pOLV->SetAttribs(aNewAttr);
+
+ m_rView.GetViewFrame().GetBindings().InvalidateAll(false);
+ if ( pOLV->GetOutliner()->IsModified() )
+ m_rView.GetWrtShell().SetModified();
+
+}
+
+void SwAnnotationShell::GetState(SfxItemSet& rSet)
+{
+ //TODO: clean this up!!!
+ // FN_SET_SUPER_SCRIPT
+ //SID_ATTR_PARA_ADJUST
+ //SID_ATTR_PARA_ADJUST_BLOCK
+
+ SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr();
+ if ( !pPostItMgr || !pPostItMgr->HasActiveSidebarWin() )
+ return;
+
+ OutlinerView* pOLV = pPostItMgr->GetActiveSidebarWin()->GetOutlinerView();
+ SfxItemSet aEditAttr(pOLV->GetAttribs());
+
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while(nWhich)
+ {
+ sal_uInt16 nEEWhich = 0;
+ sal_uInt16 nSlotId = GetPool().GetSlotId( nWhich );
+ switch( nSlotId )
+ {
+ case SID_ATTR_PARA_LRSPACE:
+ case SID_ATTR_PARA_LEFTSPACE:
+ case SID_ATTR_PARA_RIGHTSPACE:
+ case SID_ATTR_PARA_FIRSTLINESPACE:
+ {
+ SfxItemState eState = aEditAttr.GetItemState( EE_PARA_LRSPACE );
+ if( eState >= SfxItemState::DEFAULT )
+ {
+ SvxLRSpaceItem aLR = aEditAttr.Get( EE_PARA_LRSPACE );
+ aLR.SetWhich(nSlotId);
+ rSet.Put(aLR);
+ }
+ else
+ rSet.InvalidateItem(nSlotId);
+ }
+ break;
+ case SID_ATTR_PARA_LINESPACE:
+ {
+ SfxItemState eState = aEditAttr.GetItemState( EE_PARA_SBL );
+ if( eState >= SfxItemState::DEFAULT )
+ {
+ const SvxLineSpacingItem& aLR = aEditAttr.Get( EE_PARA_SBL );
+ rSet.Put(aLR);
+ }
+ else
+ rSet.InvalidateItem(nSlotId);
+ }
+ break;
+ case SID_ATTR_PARA_ULSPACE:
+ case SID_ATTR_PARA_ABOVESPACE:
+ case SID_ATTR_PARA_BELOWSPACE:
+ case SID_PARASPACE_INCREASE:
+ case SID_PARASPACE_DECREASE:
+ {
+ SfxItemState eState = aEditAttr.GetItemState( EE_PARA_ULSPACE );
+ if( eState >= SfxItemState::DEFAULT )
+ {
+ SvxULSpaceItem aULSpace = aEditAttr.Get( EE_PARA_ULSPACE );
+ if ( !aULSpace.GetUpper() && !aULSpace.GetLower() )
+ rSet.DisableItem( SID_PARASPACE_DECREASE );
+ else if ( aULSpace.GetUpper() >= 5670 && aULSpace.GetLower() >= 5670 )
+ rSet.DisableItem( SID_PARASPACE_INCREASE );
+ if ( nSlotId == SID_ATTR_PARA_ULSPACE
+ || nSlotId == SID_ATTR_PARA_BELOWSPACE
+ || nSlotId == SID_ATTR_PARA_ABOVESPACE
+ )
+ {
+ aULSpace.SetWhich(nSlotId);
+ rSet.Put(aULSpace);
+ }
+ }
+ else
+ {
+ rSet.DisableItem( SID_PARASPACE_INCREASE );
+ rSet.DisableItem( SID_PARASPACE_DECREASE );
+ rSet.InvalidateItem( SID_ATTR_PARA_ULSPACE );
+ rSet.InvalidateItem( SID_ATTR_PARA_ABOVESPACE );
+ rSet.InvalidateItem( SID_ATTR_PARA_BELOWSPACE );
+ }
+ }
+ break;
+ case SID_ATTR_CHAR_FONT:
+ case SID_ATTR_CHAR_FONTHEIGHT:
+ case SID_ATTR_CHAR_WEIGHT:
+ case SID_ATTR_CHAR_POSTURE:
+ {
+ SvtScriptType nScriptType = pOLV->GetSelectedScriptType();
+ SfxItemPool* pSecondPool = aEditAttr.GetPool()->GetSecondaryPool();
+ if( !pSecondPool )
+ pSecondPool = aEditAttr.GetPool();
+ SvxScriptSetItem aSetItem( nSlotId, *pSecondPool );
+ aSetItem.GetItemSet().Put( aEditAttr, false );
+ const SfxPoolItem* pI = aSetItem.GetItemOfScript( nScriptType );
+ if( pI )
+ {
+ rSet.Put(pI->CloneSetWhich(nWhich));
+ }
+ else
+ rSet.InvalidateItem( nWhich );
+ }
+ break;
+ case SID_ATTR_CHAR_COLOR: nEEWhich = EE_CHAR_COLOR; break;
+ case SID_ATTR_CHAR_BACK_COLOR: nEEWhich = EE_CHAR_BKGCOLOR; break;
+ case SID_ATTR_CHAR_UNDERLINE: nEEWhich = EE_CHAR_UNDERLINE;break;
+ case SID_ATTR_CHAR_OVERLINE: nEEWhich = EE_CHAR_OVERLINE;break;
+ case SID_ATTR_CHAR_CONTOUR: nEEWhich = EE_CHAR_OUTLINE; break;
+ case SID_ATTR_CHAR_SHADOWED: nEEWhich = EE_CHAR_SHADOW;break;
+ case SID_ATTR_CHAR_STRIKEOUT: nEEWhich = EE_CHAR_STRIKEOUT;break;
+ case SID_ATTR_CHAR_LANGUAGE : nEEWhich = EE_CHAR_LANGUAGE;break;
+ case SID_ATTR_CHAR_ESCAPEMENT: nEEWhich = EE_CHAR_ESCAPEMENT;break;
+ case SID_ATTR_CHAR_KERNING: nEEWhich = EE_CHAR_KERNING;break;
+ case FN_SET_SUPER_SCRIPT:
+ case FN_SET_SUB_SCRIPT:
+ {
+ SvxEscapement nEsc;
+ if (nWhich==FN_SET_SUPER_SCRIPT)
+ nEsc = SvxEscapement::Superscript;
+ else
+ nEsc = SvxEscapement::Subscript;
+
+ const SfxPoolItem *pEscItem = &aEditAttr.Get( EE_CHAR_ESCAPEMENT );
+ if( nEsc == static_cast<const SvxEscapementItem*>(pEscItem)->GetEscapement() )
+ rSet.Put( SfxBoolItem( nWhich, true ));
+ else
+ rSet.InvalidateItem( nWhich );
+ break;
+ }
+ case SID_ATTR_PARA_ADJUST_LEFT:
+ case SID_ATTR_PARA_ADJUST_RIGHT:
+ case SID_ATTR_PARA_ADJUST_CENTER:
+ case SID_ATTR_PARA_ADJUST_BLOCK:
+ {
+ SvxAdjust eAdjust = SvxAdjust::Left;
+ if (nWhich==SID_ATTR_PARA_ADJUST_LEFT)
+ eAdjust = SvxAdjust::Left;
+ else if (nWhich==SID_ATTR_PARA_ADJUST_RIGHT)
+ eAdjust = SvxAdjust::Right;
+ else if (nWhich==SID_ATTR_PARA_ADJUST_CENTER)
+ eAdjust = SvxAdjust::Center;
+ else if (nWhich==SID_ATTR_PARA_ADJUST_BLOCK)
+ eAdjust = SvxAdjust::Block;
+
+ const SvxAdjustItem *pAdjust = aEditAttr.GetItemIfSet( EE_PARA_JUST, false );
+
+ if( !pAdjust || IsInvalidItem( pAdjust ))
+ {
+ rSet.InvalidateItem( nSlotId );
+ }
+ else
+ {
+ if ( eAdjust == pAdjust->GetAdjust())
+ rSet.Put( SfxBoolItem( nWhich, true ));
+ else
+ rSet.InvalidateItem( nWhich );
+ }
+ break;
+ }
+ case SID_ATTR_PARA_LINESPACE_10:
+ case SID_ATTR_PARA_LINESPACE_115:
+ case SID_ATTR_PARA_LINESPACE_15:
+ case SID_ATTR_PARA_LINESPACE_20:
+ {
+ int nLSpace = 0;
+ if (nWhich==SID_ATTR_PARA_LINESPACE_10)
+ nLSpace = 100;
+ else if (nWhich==SID_ATTR_PARA_LINESPACE_115)
+ nLSpace = 115;
+ else if (nWhich==SID_ATTR_PARA_LINESPACE_15)
+ nLSpace = 150;
+ else if (nWhich==SID_ATTR_PARA_LINESPACE_20)
+ nLSpace = 200;
+
+ const SvxLineSpacingItem *pLSpace = aEditAttr.GetItemIfSet( EE_PARA_SBL, false );
+
+ if( !pLSpace || IsInvalidItem( pLSpace ))
+ {
+ rSet.InvalidateItem( nSlotId );
+ }
+ else
+ {
+ if( nLSpace == pLSpace->GetPropLineSpace() )
+ rSet.Put( SfxBoolItem( nWhich, true ));
+ else
+ {
+ // tdf#114631 - disable non selected line spacing
+ rSet.Put(SfxBoolItem(nWhich, false));
+ }
+ }
+ break;
+ }
+ case SID_AUTOSPELL_CHECK:
+ {
+ const SfxPoolItemHolder aResult(m_rView.GetSlotState(nWhich));
+ if (nullptr != aResult.getItem())
+ rSet.Put(SfxBoolItem(nWhich, static_cast<const SfxBoolItem*>(aResult.getItem())->GetValue()));
+ else
+ rSet.DisableItem( nWhich );
+ break;
+ }
+ case SID_ATTR_PARA_LEFT_TO_RIGHT:
+ case SID_ATTR_PARA_RIGHT_TO_LEFT:
+ {
+ if ( !SvtCTLOptions::IsCTLFontEnabled() )
+ rSet.DisableItem( nWhich );
+ else
+ {
+ if(pOLV->GetOutliner() && pOLV->GetOutliner()->IsVertical())
+ rSet.DisableItem( nWhich );
+ else
+ {
+ bool bFlag = false;
+ switch( aEditAttr.Get( EE_PARA_WRITINGDIR ).GetValue() )
+ {
+ case SvxFrameDirection::Horizontal_LR_TB:
+ {
+ bFlag = nWhich == SID_ATTR_PARA_LEFT_TO_RIGHT;
+ rSet.Put( SfxBoolItem( nWhich, bFlag ));
+ break;
+ }
+ case SvxFrameDirection::Horizontal_RL_TB:
+ {
+ bFlag = nWhich != SID_ATTR_PARA_LEFT_TO_RIGHT;
+ rSet.Put( SfxBoolItem( nWhich, bFlag ));
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+ }
+ break;
+ case SID_INSERT_RLM :
+ case SID_INSERT_LRM :
+ {
+ bool bEnabled = SvtCTLOptions::IsCTLFontEnabled();
+ m_rView.GetViewFrame().GetBindings().SetVisibleState( nWhich, bEnabled );
+ if(!bEnabled)
+ rSet.DisableItem(nWhich);
+ }
+ break;
+ default:
+ rSet.InvalidateItem( nWhich );
+ break;
+ }
+
+ if(nEEWhich)
+ {
+ rSet.Put(aEditAttr.Get(nEEWhich).CloneSetWhich(nWhich));
+ if(nEEWhich == EE_CHAR_KERNING)
+ {
+ SfxItemState eState = aEditAttr.GetItemState( EE_CHAR_KERNING );
+ if ( eState == SfxItemState::DONTCARE )
+ {
+ rSet.InvalidateItem(EE_CHAR_KERNING);
+ }
+ }
+ }
+
+ if (pPostItMgr->GetActiveSidebarWin()->GetLayoutStatus()==SwPostItHelper::DELETED)
+ rSet.DisableItem( nWhich );
+
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void SwAnnotationShell::ExecSearch(SfxRequest& rReq)
+{
+ m_rView.ExecSearch(rReq);
+}
+
+void SwAnnotationShell::StateSearch(SfxItemSet &rSet)
+{
+ m_rView.StateSearch(rSet);
+}
+
+void SwAnnotationShell::ExecClpbrd(SfxRequest const &rReq)
+{
+ SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr();
+ if ( !pPostItMgr || !pPostItMgr->HasActiveSidebarWin() )
+ return;
+
+ OutlinerView* pOLV = pPostItMgr->GetActiveSidebarWin()->GetOutlinerView();
+
+ tools::Long aOldHeight = pPostItMgr->GetActiveSidebarWin()->GetPostItTextHeight();
+ sal_uInt16 nSlot = rReq.GetSlot();
+ switch (nSlot)
+ {
+ case SID_CUT:
+ if ( (pPostItMgr->GetActiveSidebarWin()->GetLayoutStatus()!=SwPostItHelper::DELETED) && pOLV->HasSelection() )
+ pOLV->Cut();
+ break;
+ case SID_COPY:
+ if( pOLV->HasSelection() )
+ pOLV->Copy();
+ break;
+ case SID_PASTE:
+ if (pPostItMgr->GetActiveSidebarWin()->GetLayoutStatus()!=SwPostItHelper::DELETED)
+ pOLV->PasteSpecial();
+ break;
+ case SID_PASTE_UNFORMATTED:
+ if (pPostItMgr->GetActiveSidebarWin()->GetLayoutStatus()!=SwPostItHelper::DELETED)
+ pOLV->Paste();
+ break;
+ case SID_PASTE_SPECIAL:
+ {
+ if (pPostItMgr->GetActiveSidebarWin()->GetLayoutStatus()!=SwPostItHelper::DELETED)
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<SfxAbstractPasteDialog> pDlg(pFact->CreatePasteDialog(m_rView.GetEditWin().GetFrameWeld()));
+
+ pDlg->Insert( SotClipboardFormatId::STRING, OUString() );
+ pDlg->Insert( SotClipboardFormatId::RTF, OUString() );
+ pDlg->Insert( SotClipboardFormatId::RICHTEXT, OUString() );
+
+ TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( &m_rView.GetEditWin() ) );
+
+ SotClipboardFormatId nFormat = pDlg->GetFormat( aDataHelper.GetTransferable() );
+
+ if (nFormat != SotClipboardFormatId::NONE)
+ {
+ if (nFormat == SotClipboardFormatId::STRING)
+ pOLV->Paste();
+ else
+ pOLV->PasteSpecial();
+ }
+ }
+ break;
+ }
+ case SID_CLIPBOARD_FORMAT_ITEMS:
+ {
+ SotClipboardFormatId nFormat = SotClipboardFormatId::NONE;
+ const SfxPoolItem* pItem;
+ if (rReq.GetArgs() && rReq.GetArgs()->GetItemState(nSlot, true, &pItem) == SfxItemState::SET)
+ {
+ if (const SfxUInt32Item* pUInt32Item = dynamic_cast<const SfxUInt32Item *>(pItem))
+ nFormat = static_cast<SotClipboardFormatId>(pUInt32Item->GetValue());
+ }
+
+ if ( nFormat != SotClipboardFormatId::NONE )
+ {
+ if (SotClipboardFormatId::STRING == nFormat)
+ pOLV->Paste();
+ else
+ pOLV->PasteSpecial();
+ }
+ break;
+ }
+ }
+ pPostItMgr->GetActiveSidebarWin()->ResizeIfNecessary(aOldHeight,pPostItMgr->GetActiveSidebarWin()->GetPostItTextHeight());
+}
+
+void SwAnnotationShell::StateClpbrd(SfxItemSet &rSet)
+{
+ SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr();
+ if ( !pPostItMgr || !pPostItMgr->HasActiveSidebarWin() )
+ return;
+ OutlinerView* pOLV = pPostItMgr->GetActiveSidebarWin()->GetOutlinerView();
+
+ TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( &m_rView.GetEditWin() ) );
+ bool bPastePossible = ( aDataHelper.HasFormat( SotClipboardFormatId::STRING ) || aDataHelper.HasFormat( SotClipboardFormatId::RTF )
+ || aDataHelper.HasFormat( SotClipboardFormatId::RICHTEXT ));
+ bPastePossible = bPastePossible && (pPostItMgr->GetActiveSidebarWin()->GetLayoutStatus()!=SwPostItHelper::DELETED);
+
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+
+ while(nWhich)
+ {
+ switch(nWhich)
+ {
+ case SID_CUT:
+ {
+ if (pPostItMgr->GetActiveSidebarWin()->GetLayoutStatus() == SwPostItHelper::DELETED)
+ rSet.DisableItem( nWhich );
+ [[fallthrough]];
+ }
+ case SID_COPY:
+ {
+ SfxObjectShell* pObjectShell = GetObjectShell();
+ if (!pOLV->HasSelection() || (pObjectShell && pObjectShell->isContentExtractionLocked()) )
+ rSet.DisableItem( nWhich );
+ break;
+ }
+ case SID_PASTE:
+ case SID_PASTE_UNFORMATTED:
+ case SID_PASTE_SPECIAL:
+ {
+ if( !bPastePossible )
+ rSet.DisableItem( nWhich );
+ break;
+ }
+ case SID_CLIPBOARD_FORMAT_ITEMS:
+ {
+ if ( bPastePossible )
+ {
+ SvxClipboardFormatItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS );
+ if ( aDataHelper.HasFormat( SotClipboardFormatId::RTF ) )
+ aFormats.AddClipbrdFormat( SotClipboardFormatId::RTF );
+ if ( aDataHelper.HasFormat( SotClipboardFormatId::RICHTEXT ) )
+ aFormats.AddClipbrdFormat( SotClipboardFormatId::RICHTEXT );
+ aFormats.AddClipbrdFormat( SotClipboardFormatId::STRING );
+ rSet.Put( aFormats );
+ }
+ else
+ rSet.DisableItem( nWhich );
+ break;
+ }
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void SwAnnotationShell::StateStatusLine(SfxItemSet &rSet)
+{
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+
+ while( nWhich )
+ {
+ switch( nWhich )
+ {
+ case FN_STAT_SELMODE:
+ {
+ rSet.Put(SfxUInt16Item(FN_STAT_SELMODE, 0));
+ rSet.DisableItem( nWhich );
+ break;
+ }
+ case FN_STAT_TEMPLATE:
+ {
+ rSet.DisableItem( nWhich );
+ break;
+ }
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void SwAnnotationShell::StateInsert(SfxItemSet &rSet)
+{
+ SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr();
+ if ( !pPostItMgr || !pPostItMgr->HasActiveSidebarWin() )
+ return;
+
+ OutlinerView* pOLV = pPostItMgr->GetActiveSidebarWin()->GetOutlinerView();
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+
+ while(nWhich)
+ {
+ switch(nWhich)
+ {
+ case SID_HYPERLINK_GETLINK:
+ {
+ SvxHyperlinkItem aHLinkItem;
+ aHLinkItem.SetInsertMode(HLINK_FIELD);
+
+ const SvxFieldItem* pFieldItem = pOLV->GetFieldAtSelection();
+
+ if (pFieldItem)
+ {
+ if (const SvxURLField* pURLField = dynamic_cast<const SvxURLField *>(pFieldItem->GetField()))
+ {
+ aHLinkItem.SetName(pURLField->GetRepresentation());
+ aHLinkItem.SetURL(pURLField->GetURL());
+ aHLinkItem.SetTargetFrame(pURLField->GetTargetFrame());
+ }
+ }
+ else
+ {
+ OUString sSel(pOLV->GetSelected());
+ sSel = sSel.copy(0, std::min<sal_Int32>(255, sSel.getLength()));
+ aHLinkItem.SetName(comphelper::string::stripEnd(sSel, ' '));
+ }
+
+ sal_uInt16 nHtmlMode = ::GetHtmlMode(m_rView.GetDocShell());
+ aHLinkItem.SetInsertMode(static_cast<SvxLinkInsertMode>(aHLinkItem.GetInsertMode() |
+ ((nHtmlMode & HTMLMODE_ON) != 0 ? HLINK_HTMLMODE : 0)));
+
+ rSet.Put(aHLinkItem);
+ }
+ break;
+ }
+
+ if (pPostItMgr->GetActiveSidebarWin()->GetLayoutStatus()==SwPostItHelper::DELETED)
+ rSet.DisableItem( nWhich );
+
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void SwAnnotationShell::NoteExec(SfxRequest const &rReq)
+{
+ SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr();
+ if ( !pPostItMgr )
+ return;
+
+ sal_uInt16 nSlot = rReq.GetSlot();
+ switch (nSlot)
+ {
+ case FN_REPLY:
+ case FN_POSTIT:
+ case FN_DELETE_COMMENT:
+ case FN_DELETE_COMMENT_THREAD:
+ case FN_RESOLVE_NOTE:
+ case FN_RESOLVE_NOTE_THREAD:
+ if ( pPostItMgr->HasActiveSidebarWin() )
+ pPostItMgr->GetActiveSidebarWin()->ExecuteCommand(nSlot);
+ break;
+ case FN_DELETE_ALL_NOTES:
+ pPostItMgr->Delete();
+ break;
+ case FN_FORMAT_ALL_NOTES:
+ pPostItMgr->ExecuteFormatAllDialog(m_rView);
+ break;
+ case FN_DELETE_NOTE_AUTHOR:
+ {
+ const SfxStringItem* pItem = rReq.GetArg<SfxStringItem>(nSlot);
+ if ( pItem )
+ pPostItMgr->Delete( pItem->GetValue() );
+ else if ( pPostItMgr->HasActiveSidebarWin() )
+ pPostItMgr->Delete( pPostItMgr->GetActiveSidebarWin()->GetAuthor() );
+ break;
+ }
+ case FN_HIDE_NOTE:
+ break;
+ case FN_HIDE_ALL_NOTES:
+ pPostItMgr->Hide();
+ break;
+ case FN_HIDE_NOTE_AUTHOR:
+ {
+ const SfxStringItem* pItem = rReq.GetArg<SfxStringItem>(nSlot);
+ if ( pItem )
+ pPostItMgr->Hide( pItem->GetValue() );
+ else if ( pPostItMgr->HasActiveSidebarWin() )
+ pPostItMgr->Hide( pPostItMgr->GetActiveSidebarWin()->GetAuthor() );
+ }
+ }
+}
+
+void SwAnnotationShell::GetNoteState(SfxItemSet &rSet)
+{
+ SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr();
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while(nWhich)
+ {
+ sal_uInt16 nSlotId = GetPool().GetSlotId( nWhich );
+ switch( nSlotId )
+ {
+ case FN_POSTIT:
+ case FN_DELETE_ALL_NOTES:
+ case FN_FORMAT_ALL_NOTES:
+ case FN_HIDE_NOTE:
+ case FN_HIDE_ALL_NOTES:
+ case FN_DELETE_COMMENT:
+ case FN_DELETE_COMMENT_THREAD:
+ {
+ if( !pPostItMgr
+ || !pPostItMgr->HasActiveAnnotationWin() )
+ {
+ rSet.DisableItem(nWhich);
+ }
+ break;
+ }
+ case FN_RESOLVE_NOTE:
+ {
+ if( !pPostItMgr
+ || !pPostItMgr->HasActiveAnnotationWin() )
+ {
+ rSet.DisableItem(nWhich);
+ }
+ else
+ {
+ SfxBoolItem aBool(nWhich, pPostItMgr->GetActiveSidebarWin()->IsResolved());
+ rSet.Put( aBool );
+ }
+ break;
+ }
+ case FN_RESOLVE_NOTE_THREAD:
+ {
+ if( !pPostItMgr
+ || !pPostItMgr->HasActiveAnnotationWin() )
+ {
+ rSet.DisableItem(nWhich);
+ }
+ else
+ {
+ SfxBoolItem aBool(nWhich, pPostItMgr->GetActiveSidebarWin()->IsThreadResolved());
+ rSet.Put( aBool );
+ }
+ break;
+ }
+ case FN_DELETE_NOTE_AUTHOR:
+ case FN_HIDE_NOTE_AUTHOR:
+ {
+ if( !pPostItMgr
+ || !pPostItMgr->HasActiveAnnotationWin() )
+ {
+ rSet.DisableItem(nWhich);
+ }
+ else
+ {
+ OUString aText( nSlotId == FN_DELETE_NOTE_AUTHOR ?
+ SwResId( STR_DELETE_NOTE_AUTHOR ) : SwResId( STR_HIDE_NOTE_AUTHOR ) );
+ SwRewriter aRewriter;
+ aRewriter.AddRule( UndoArg1, pPostItMgr->GetActiveSidebarWin()->GetAuthor() );
+ aText = aRewriter.Apply( aText );
+ SfxStringItem aItem( nSlotId, aText );
+ rSet.Put( aItem );
+ }
+ break;
+ }
+ case FN_REPLY:
+ {
+ if ( !pPostItMgr ||
+ !pPostItMgr->HasActiveAnnotationWin() )
+ {
+ rSet.DisableItem(nWhich);
+ }
+ else
+ {
+ SvtUserOptions aUserOpt;
+ OUString sAuthor;
+ if( (sAuthor = aUserOpt.GetFullName()).isEmpty() &&
+ (sAuthor = aUserOpt.GetID()).isEmpty() )
+ sAuthor = SwResId( STR_REDLINE_UNKNOWN_AUTHOR );
+ if (sAuthor == pPostItMgr->GetActiveSidebarWin()->GetAuthor())
+ rSet.DisableItem(nWhich);
+ }
+ break;
+ }
+ default:
+ rSet.InvalidateItem( nWhich );
+ break;
+ }
+
+ if (pPostItMgr && pPostItMgr->HasActiveSidebarWin())
+ {
+ if ( (pPostItMgr->GetActiveSidebarWin()->IsReadOnlyOrProtected()) &&
+ ( (nSlotId==FN_DELETE_COMMENT) || (nSlotId==FN_REPLY) ) )
+ rSet.DisableItem( nWhich );
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void SwAnnotationShell::ExecLingu(SfxRequest &rReq)
+{
+ SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr();
+ if ( !pPostItMgr || !pPostItMgr->HasActiveSidebarWin() )
+ return;
+
+ OutlinerView* pOLV = pPostItMgr->GetActiveSidebarWin()->GetOutlinerView();
+ sal_uInt16 nSlot = rReq.GetSlot();
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+ bool bRestoreSelection = false;
+ ESelection aOldSelection;
+
+ switch (nSlot)
+ {
+ case SID_LANGUAGE_STATUS:
+ {
+ aOldSelection = pOLV->GetSelection();
+ if (!pOLV->GetEditView().HasSelection())
+ {
+ pOLV->GetEditView().SelectCurrentWord();
+ }
+
+ bRestoreSelection = SwLangHelper::SetLanguageStatus(pOLV,rReq,m_rView,rSh);
+ break;
+ }
+ case SID_THES:
+ {
+ OUString aReplaceText;
+ const SfxStringItem* pItem2 = rReq.GetArg(FN_PARAM_THES_WORD_REPLACE);
+ if (pItem2)
+ aReplaceText = pItem2->GetValue();
+ if (!aReplaceText.isEmpty())
+ ReplaceTextWithSynonym( pOLV->GetEditView(), aReplaceText );
+ break;
+ }
+ case SID_THESAURUS:
+ {
+ pOLV->StartThesaurus(rReq.GetFrameWeld());
+ break;
+ }
+ case SID_HANGUL_HANJA_CONVERSION:
+ pOLV->StartTextConversion(rReq.GetFrameWeld(), LANGUAGE_KOREAN, LANGUAGE_KOREAN, nullptr,
+ i18n::TextConversionOption::CHARACTER_BY_CHARACTER, true, false);
+ break;
+
+ case SID_CHINESE_CONVERSION:
+ {
+ //open ChineseTranslationDialog
+ Reference< XComponentContext > xContext(
+ ::cppu::defaultBootstrap_InitialComponentContext() ); //@todo get context from calc if that has one
+ if(xContext.is())
+ {
+ Reference< lang::XMultiComponentFactory > xMCF( xContext->getServiceManager() );
+ if(xMCF.is())
+ {
+ Reference< ui::dialogs::XExecutableDialog > xDialog(
+ xMCF->createInstanceWithContext(
+ "com.sun.star.linguistic2.ChineseTranslationDialog", xContext),
+ UNO_QUERY);
+ Reference< lang::XInitialization > xInit( xDialog, UNO_QUERY );
+ if( xInit.is() )
+ {
+ // initialize dialog
+ uno::Sequence<uno::Any> aSeq(comphelper::InitAnyPropertySequence(
+ {
+ {"ParentWindow", uno::Any(Reference<awt::XWindow>())}
+ }));
+ xInit->initialize( aSeq );
+
+ //execute dialog
+ sal_Int16 nDialogRet = xDialog->execute();
+ if( RET_OK == nDialogRet )
+ {
+ //get some parameters from the dialog
+ bool bToSimplified = true;
+ bool bUseVariants = true;
+ bool bCommonTerms = true;
+ Reference< beans::XPropertySet > xProp( xDialog, UNO_QUERY );
+ if( xProp.is() )
+ {
+ try
+ {
+ xProp->getPropertyValue( "IsDirectionToSimplified" ) >>= bToSimplified;
+ xProp->getPropertyValue( "IsUseCharacterVariants" ) >>= bUseVariants;
+ xProp->getPropertyValue( "IsTranslateCommonTerms" ) >>= bCommonTerms;
+ }
+ catch (const Exception&)
+ {
+ }
+ }
+
+ //execute translation
+ LanguageType nSourceLang = bToSimplified ? LANGUAGE_CHINESE_TRADITIONAL : LANGUAGE_CHINESE_SIMPLIFIED;
+ LanguageType nTargetLang = bToSimplified ? LANGUAGE_CHINESE_SIMPLIFIED : LANGUAGE_CHINESE_TRADITIONAL;
+ sal_Int32 nOptions = bUseVariants ? i18n::TextConversionOption::USE_CHARACTER_VARIANTS : 0;
+ if( !bCommonTerms )
+ nOptions = nOptions | i18n::TextConversionOption::CHARACTER_BY_CHARACTER;
+
+ vcl::Font aTargetFont = OutputDevice::GetDefaultFont( DefaultFontType::CJK_TEXT,
+ nTargetLang, GetDefaultFontFlags::OnlyOne );
+
+ pOLV->StartTextConversion(rReq.GetFrameWeld(), nSourceLang, nTargetLang, &aTargetFont, nOptions, false, false);
+ }
+ }
+ Reference< lang::XComponent > xComponent( xDialog, UNO_QUERY );
+ if( xComponent.is() )
+ xComponent->dispose();
+ }
+ }
+ }
+ break;
+ }
+
+ if (bRestoreSelection)
+ {
+ // restore selection
+ pOLV->GetEditView().SetSelection( aOldSelection );
+ }
+}
+
+void SwAnnotationShell::GetLinguState(SfxItemSet &rSet)
+{
+ SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr();
+ if ( !pPostItMgr || !pPostItMgr->HasActiveSidebarWin() )
+ return;
+
+ OutlinerView* pOLV = pPostItMgr->GetActiveSidebarWin()->GetOutlinerView();
+
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while(nWhich)
+ {
+ switch (nWhich)
+ {
+ case SID_LANGUAGE_STATUS:
+ {
+ SwLangHelper::GetLanguageStatus(pOLV,rSet);
+ break;
+ }
+
+ case SID_THES:
+ {
+ OUString aStatusVal;
+ LanguageType nLang = LANGUAGE_NONE;
+ bool bIsLookUpWord = GetStatusValueForThesaurusFromContext( aStatusVal, nLang, pOLV->GetEditView() );
+ rSet.Put( SfxStringItem( SID_THES, aStatusVal ) );
+
+ // disable "Thesaurus" context menu entry if there is nothing to look up
+ uno::Reference< linguistic2::XThesaurus > xThes( ::GetThesaurus() );
+ if (!bIsLookUpWord ||
+ !xThes.is() || nLang == LANGUAGE_NONE || !xThes->hasLocale( LanguageTag::convertToLocale( nLang ) ))
+ rSet.DisableItem( SID_THES );
+ break;
+ }
+
+ // disable "Thesaurus" if the language is not supported
+ case SID_THESAURUS:
+ {
+ TypedWhichId<SvxLanguageItem> nLangWhich = GetWhichOfScript( RES_CHRATR_LANGUAGE,
+ SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() ) );
+ const SvxLanguageItem &rItem = m_rView.GetWrtShell().GetDoc()->GetDefault(nLangWhich);
+ LanguageType nLang = rItem.GetLanguage();
+ uno::Reference< linguistic2::XThesaurus > xThes( ::GetThesaurus() );
+ if (!xThes.is() || nLang == LANGUAGE_NONE ||
+ !xThes->hasLocale( LanguageTag::convertToLocale( nLang ) ))
+ rSet.DisableItem( SID_THESAURUS );
+ }
+ break;
+ case SID_HANGUL_HANJA_CONVERSION:
+ case SID_CHINESE_CONVERSION:
+ {
+ if (!SvtCJKOptions::IsAnyEnabled())
+ {
+ m_rView.GetViewFrame().GetBindings().SetVisibleState( nWhich, false );
+ rSet.DisableItem(nWhich);
+ }
+ else
+ m_rView.GetViewFrame().GetBindings().SetVisibleState( nWhich, true );
+ }
+ break;
+ }
+
+ if (pPostItMgr->GetActiveSidebarWin()->GetLayoutStatus()==SwPostItHelper::DELETED)
+ rSet.DisableItem( nWhich );
+
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void SwAnnotationShell::ExecTransliteration(SfxRequest const &rReq)
+{
+ SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr();
+ if (!pPostItMgr || !pPostItMgr->HasActiveSidebarWin())
+ return;
+
+ OutlinerView* pOLV = pPostItMgr->GetActiveSidebarWin()->GetOutlinerView();
+
+ if (!pOLV)
+ return;
+
+ TransliterationFlags nMode = TransliterationFlags::NONE;
+
+ switch( rReq.GetSlot() )
+ {
+ case SID_TRANSLITERATE_SENTENCE_CASE:
+ nMode = TransliterationFlags::SENTENCE_CASE;
+ break;
+ case SID_TRANSLITERATE_TITLE_CASE:
+ nMode = TransliterationFlags::TITLE_CASE;
+ break;
+ case SID_TRANSLITERATE_TOGGLE_CASE:
+ nMode = TransliterationFlags::TOGGLE_CASE;
+ break;
+ case SID_TRANSLITERATE_UPPER:
+ nMode = TransliterationFlags::LOWERCASE_UPPERCASE;
+ break;
+ case SID_TRANSLITERATE_LOWER:
+ nMode = TransliterationFlags::UPPERCASE_LOWERCASE;
+ break;
+ case SID_TRANSLITERATE_HALFWIDTH:
+ nMode = TransliterationFlags::FULLWIDTH_HALFWIDTH;
+ break;
+ case SID_TRANSLITERATE_FULLWIDTH:
+ nMode = TransliterationFlags::HALFWIDTH_FULLWIDTH;
+ break;
+ case SID_TRANSLITERATE_HIRAGANA:
+ nMode = TransliterationFlags::KATAKANA_HIRAGANA;
+ break;
+ case SID_TRANSLITERATE_KATAKANA:
+ nMode = TransliterationFlags::HIRAGANA_KATAKANA;
+ break;
+
+ default:
+ OSL_ENSURE(false, "wrong dispatcher");
+ }
+
+ if( nMode != TransliterationFlags::NONE )
+ pOLV->TransliterateText( nMode );
+}
+
+void SwAnnotationShell::ExecRotateTransliteration( SfxRequest const & rReq )
+{
+ if( rReq.GetSlot() != SID_TRANSLITERATE_ROTATE_CASE )
+ return;
+
+ SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr();
+ if (!pPostItMgr || !pPostItMgr->HasActiveSidebarWin())
+ return;
+
+ OutlinerView* pOLV = pPostItMgr->GetActiveSidebarWin()->GetOutlinerView();
+
+ if (!pOLV)
+ return;
+
+ pOLV->TransliterateText(m_aRotateCase.getNextMode());
+}
+
+void SwAnnotationShell::ExecUndo(SfxRequest &rReq)
+{
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ SfxUndoManager* pUndoManager = GetUndoManager();
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+ SwUndoId nUndoId(SwUndoId::EMPTY);
+
+ // tdf#147928 get these before "undo" which may delete this SwAnnotationShell
+ SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr();
+ SfxBindings& rBindings = m_rView.GetViewFrame().GetBindings();
+
+ tools::Long aOldHeight = pPostItMgr->HasActiveSidebarWin()
+ ? pPostItMgr->GetActiveSidebarWin()->GetPostItTextHeight()
+ : 0;
+
+ sal_uInt16 nId = rReq.GetSlot();
+ sal_uInt16 nCnt = 1;
+ const SfxPoolItem* pItem=nullptr;
+ if( pArgs && SfxItemState::SET == pArgs->GetItemState( nId, false, &pItem ) )
+ nCnt = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
+ switch( nId )
+ {
+ case SID_UNDO:
+ {
+ rSh.GetLastUndoInfo(nullptr, &nUndoId);
+ if (nUndoId == SwUndoId::CONFLICT)
+ {
+ rReq.SetReturnValue( SfxUInt32Item(nId, static_cast<sal_uInt32>(SID_REPAIRPACKAGE)) );
+ break;
+ }
+
+ if ( pUndoManager )
+ {
+ sal_uInt16 nCount = pUndoManager->GetUndoActionCount();
+ sal_uInt16 nSteps = nCnt;
+ if ( nCount < nCnt )
+ {
+ nCnt = nCnt - nCount;
+ nSteps = nCount;
+ }
+ else
+ nCnt = 0;
+
+ while( nSteps-- )
+ pUndoManager->Undo();
+ }
+
+ if ( nCnt )
+ rSh.Do( SwWrtShell::UNDO, nCnt );
+
+ break;
+ }
+
+ case SID_REDO:
+ {
+ (void)rSh.GetFirstRedoInfo(nullptr, &nUndoId);
+ if (nUndoId == SwUndoId::CONFLICT)
+ {
+ rReq.SetReturnValue( SfxUInt32Item(nId, static_cast<sal_uInt32>(SID_REPAIRPACKAGE)) );
+ break;
+ }
+
+ if ( pUndoManager )
+ {
+ sal_uInt16 nCount = pUndoManager->GetRedoActionCount();
+ sal_uInt16 nSteps = nCnt;
+ if ( nCount < nCnt )
+ {
+ nCnt = nCnt - nCount;
+ nSteps = nCount;
+ }
+ else
+ nCnt = 0;
+
+ while( nSteps-- )
+ pUndoManager->Redo();
+ }
+
+ if ( nCnt )
+ rSh.Do( SwWrtShell::REDO, nCnt );
+
+ break;
+ }
+ }
+
+ rBindings.InvalidateAll(false);
+
+ if (pPostItMgr->HasActiveSidebarWin())
+ pPostItMgr->GetActiveSidebarWin()->ResizeIfNecessary(aOldHeight, pPostItMgr->GetActiveSidebarWin()->GetPostItTextHeight());
+}
+
+void SwAnnotationShell::StateUndo(SfxItemSet &rSet)
+{
+ SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr();
+ if ( !pPostItMgr || !pPostItMgr->HasActiveSidebarWin() )
+ return;
+
+ SfxWhichIter aIter(rSet);
+ SwUndoId nUndoId(SwUndoId::EMPTY);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ SfxUndoManager* pUndoManager = GetUndoManager();
+ SfxViewFrame& rSfxViewFrame = m_rView.GetViewFrame();
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+
+ while( nWhich )
+ {
+ switch ( nWhich )
+ {
+ case SID_UNDO:
+ {
+ sal_uInt16 nCount = pUndoManager ? pUndoManager->GetUndoActionCount() : 0;
+ if ( nCount )
+ rSfxViewFrame.GetSlotState( nWhich, rSfxViewFrame.GetInterface(), &rSet );
+ else if (rSh.GetLastUndoInfo(nullptr, &nUndoId))
+ {
+ rSet.Put( SfxStringItem( nWhich, rSh.GetDoString(SwWrtShell::UNDO)) );
+ }
+ else if (nUndoId == SwUndoId::CONFLICT)
+ {
+ rSet.Put( SfxUInt32Item(nWhich, static_cast<sal_uInt32>(SID_REPAIRPACKAGE)) );
+ }
+ else
+ rSet.DisableItem(nWhich);
+ break;
+ }
+ case SID_REDO:
+ {
+ sal_uInt16 nCount = pUndoManager ? pUndoManager->GetRedoActionCount() : 0;
+ if ( nCount )
+ rSfxViewFrame.GetSlotState( nWhich, rSfxViewFrame.GetInterface(), &rSet );
+ else if (rSh.GetFirstRedoInfo(nullptr, &nUndoId))
+ {
+ rSet.Put(SfxStringItem( nWhich, rSh.GetDoString(SwWrtShell::REDO)) );
+ }
+ else if (nUndoId == SwUndoId::CONFLICT)
+ {
+ rSet.Put( SfxUInt32Item(nWhich, static_cast<sal_uInt32>(SID_REPAIRPACKAGE)) );
+ }
+ else
+ rSet.DisableItem(nWhich);
+ break;
+ }
+ case SID_GETUNDOSTRINGS:
+ case SID_GETREDOSTRINGS:
+ {
+ if( pUndoManager )
+ {
+ OUString (SfxUndoManager::*fnGetComment)( size_t, bool const ) const;
+
+ sal_uInt16 nCount;
+ if( SID_GETUNDOSTRINGS == nWhich )
+ {
+ nCount = pUndoManager->GetUndoActionCount();
+ fnGetComment = &SfxUndoManager::GetUndoActionComment;
+ }
+ else
+ {
+ nCount = pUndoManager->GetRedoActionCount();
+ fnGetComment = &SfxUndoManager::GetRedoActionComment;
+ }
+
+ OUStringBuffer sList;
+ if( nCount )
+ {
+ for( sal_uInt16 n = 0; n < nCount; ++n )
+ sList.append( (pUndoManager->*fnGetComment)( n, SfxUndoManager::TopLevel ) + "\n");
+ }
+
+ SfxStringListItem aItem( nWhich );
+ if ((nWhich == SID_GETUNDOSTRINGS) &&
+ rSh.GetLastUndoInfo(nullptr, nullptr))
+ {
+ rSh.GetDoStrings( SwWrtShell::UNDO, aItem );
+ }
+ else if ((nWhich == SID_GETREDOSTRINGS) &&
+ (rSh.GetFirstRedoInfo(nullptr, nullptr)))
+ {
+ rSh.GetDoStrings( SwWrtShell::REDO, aItem );
+ }
+
+ sList.append(aItem.GetString());
+ aItem.SetString( sList.makeStringAndClear() );
+ rSet.Put( aItem );
+ }
+ else
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ default:
+ {
+ rSfxViewFrame.GetSlotState( nWhich, rSfxViewFrame.GetInterface(), &rSet );
+ break;
+ }
+
+ }
+
+ if (pPostItMgr->GetActiveSidebarWin()->GetLayoutStatus()==SwPostItHelper::DELETED)
+ rSet.DisableItem( nWhich );
+
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void SwAnnotationShell::StateDisableItems( SfxItemSet &rSet )
+{
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while (nWhich)
+ {
+ rSet.DisableItem( nWhich );
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void SwAnnotationShell::InsertSymbol(SfxRequest& rReq)
+{
+ SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr();
+ if ( !pPostItMgr || !pPostItMgr->HasActiveSidebarWin() )
+ return;
+
+ OutlinerView* pOLV = pPostItMgr->GetActiveSidebarWin()->GetOutlinerView();
+
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ const SfxStringItem* pCharMapItem = nullptr;
+ if( pArgs )
+ pCharMapItem = pArgs->GetItemIfSet(SID_CHARMAP, false);
+
+ OUString sSym;
+ OUString sFontName;
+ if ( pCharMapItem )
+ {
+ sSym = pCharMapItem->GetValue();
+ const SfxStringItem* pFontItem = pArgs->GetItemIfSet( SID_ATTR_SPECIALCHAR, false);
+ if (pFontItem)
+ sFontName = pFontItem->GetValue();
+ }
+
+ SfxItemSet aSet(pOLV->GetAttribs());
+ SvtScriptType nScript = pOLV->GetSelectedScriptType();
+ std::shared_ptr<SvxFontItem> aSetDlgFont(std::make_shared<SvxFontItem>(RES_CHRATR_FONT));
+ {
+ SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT, *aSet.GetPool() );
+ aSetItem.GetItemSet().Put( aSet, false );
+ const SfxPoolItem* pI = aSetItem.GetItemOfScript( nScript );
+ if( pI )
+ {
+ aSetDlgFont.reset(static_cast<SvxFontItem*>(pI->Clone()));
+ }
+ else
+ {
+ TypedWhichId<SvxFontItem> nFontWhich =
+ GetWhichOfScript(
+ SID_ATTR_CHAR_FONT,
+ SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() ) );
+ aSetDlgFont.reset(aSet.Get(nFontWhich).Clone());
+ }
+
+ if (sFontName.isEmpty())
+ sFontName = aSetDlgFont->GetFamilyName();
+ }
+
+ vcl::Font aFont(sFontName, Size(1,1));
+ if( sSym.isEmpty() )
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+
+ SfxAllItemSet aAllSet( GetPool() );
+ aAllSet.Put( SfxBoolItem( FN_PARAM_1, false ) );
+
+ SwViewOption aOpt(*m_rView.GetWrtShell().GetViewOptions());
+ const OUString& sSymbolFont = aOpt.GetSymbolFont();
+ if( !sSymbolFont.isEmpty() )
+ aAllSet.Put( SfxStringItem( SID_FONT_NAME, sSymbolFont ) );
+ else
+ aAllSet.Put( SfxStringItem( SID_FONT_NAME, aSetDlgFont->GetFamilyName() ) );
+
+ // If character is selected then it can be shown.
+ auto xFrame = m_rView.GetViewFrame().GetFrame().GetFrameInterface();
+ ScopedVclPtr<SfxAbstractDialog> pDlg(pFact->CreateCharMapDialog(m_rView.GetFrameWeld(), aAllSet, xFrame));
+ pDlg->Execute();
+ return;
+ }
+
+ // do not flicker
+ pOLV->HideCursor();
+ Outliner * pOutliner = pOLV->GetOutliner();
+ pOutliner->SetUpdateLayout(false);
+
+ SfxItemSet aOldSet( pOLV->GetAttribs() );
+ SfxItemSetFixed<
+ EE_CHAR_FONTINFO, EE_CHAR_FONTINFO,
+ EE_CHAR_FONTINFO_CJK, EE_CHAR_FONTINFO_CTL>
+ aFontSet( *aOldSet.GetPool() );
+ aFontSet.Set( aOldSet );
+
+ // Insert string
+ pOLV->InsertText( sSym);
+
+ // Attributing (set font)
+ SfxItemSet aSetFont( *aFontSet.GetPool(), aFontSet.GetRanges() );
+ SvxFontItem aFontItem (aFont.GetFamilyType(), aFont.GetFamilyName(),
+ aFont.GetStyleName(), aFont.GetPitch(),
+ aFont.GetCharSet(),
+ EE_CHAR_FONTINFO );
+ SvtScriptType nScriptBreak = g_pBreakIt->GetAllScriptsOfText( sSym );
+ if( SvtScriptType::LATIN & nScriptBreak )
+ aSetFont.Put( aFontItem );
+ if( SvtScriptType::ASIAN & nScriptBreak )
+ {
+ aFontItem.SetWhich(EE_CHAR_FONTINFO_CJK);
+ aSetFont.Put( aFontItem );
+ }
+ if( SvtScriptType::COMPLEX & nScriptBreak )
+ {
+ aFontItem.SetWhich(EE_CHAR_FONTINFO_CTL);
+ aSetFont.Put( aFontItem );
+ }
+ pOLV->SetAttribs(aSetFont);
+
+ // Erase selection
+ ESelection aSel(pOLV->GetSelection());
+ aSel.nStartPara = aSel.nEndPara;
+ aSel.nStartPos = aSel.nEndPos;
+ pOLV->SetSelection(aSel);
+
+ // Restore old font
+ pOLV->SetAttribs( aFontSet );
+
+ // From now on show it again
+ pOutliner->SetUpdateLayout(true);
+ pOLV->ShowCursor();
+
+ rReq.AppendItem( SfxStringItem( SID_CHARMAP, sSym ) );
+ if(!aFont.GetFamilyName().isEmpty())
+ rReq.AppendItem( SfxStringItem( SID_ATTR_SPECIALCHAR, aFont.GetFamilyName() ) );
+ rReq.Done();
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/basesh.cxx b/sw/source/uibase/shells/basesh.cxx
new file mode 100644
index 0000000000..57e7c82995
--- /dev/null
+++ b/sw/source/uibase/shells/basesh.cxx
@@ -0,0 +1,3372 @@
+/* -*- 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 <sal/config.h>
+
+#include <hintids.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <svl/languageoptions.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <svx/imapdlg.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/request.hxx>
+#include <svl/whiter.hxx>
+#include <svl/visitem.hxx>
+#include <editeng/langitem.hxx>
+#include <svx/clipfmtitem.hxx>
+#include <svx/contdlg.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/inputctx.hxx>
+#include <svl/slstitm.hxx>
+#include <svl/ptitem.hxx>
+#include <svl/stritem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/shaditem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/brushitem.hxx>
+#include <editeng/opaqitem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <svx/flagsdef.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <sfx2/objface.hxx>
+#include <fmturl.hxx>
+#include <fmthdft.hxx>
+#include <fmtclds.hxx>
+#include <docsh.hxx>
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <swmodule.hxx>
+#include <swundo.hxx>
+#include <fldbas.hxx>
+#include <uitool.hxx>
+#include <basesh.hxx>
+#include <viewopt.hxx>
+#include <fontcfg.hxx>
+#include <fmtsrnd.hxx>
+#include <fldmgr.hxx>
+#include <frmmgr.hxx>
+#include <tablemgr.hxx>
+#include <mdiexp.hxx>
+#include <swdtflvr.hxx>
+#include <pagedesc.hxx>
+#include <fmtcol.hxx>
+#include <edtwin.hxx>
+#include <tblafmt.hxx>
+#include <swwait.hxx>
+#include <cmdid.h>
+#include <strings.hrc>
+#include <unotxdoc.hxx>
+#include <doc.hxx>
+#include <drawdoc.hxx>
+#include <IDocumentSettingAccess.hxx>
+#include <IDocumentDrawModelAccess.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <ThemeColorChanger.hxx>
+#include <swabstdlg.hxx>
+#include <modcfg.hxx>
+#include <svx/fmshell.hxx>
+#include <SwRewriter.hxx>
+#include <GraphicSizeCheck.hxx>
+#include <svx/galleryitem.hxx>
+#include <svx/theme/ThemeColorPaletteManager.hxx>
+#include <sfx2/devtools/DevelopmentToolChildWindow.hxx>
+#include <com/sun/star/gallery/GalleryItemType.hpp>
+#include <com/sun/star/beans/PropertyValues.hpp>
+#include <memory>
+
+
+#include <svx/unobrushitemhelper.hxx>
+#include <svx/dialog/ThemeDialog.hxx>
+#include <comphelper/scopeguard.hxx>
+#include <comphelper/lok.hxx>
+#include <sfx2/lokhelper.hxx>
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
+#include <osl/diagnose.h>
+
+#include <svx/svxdlg.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+
+#include <shellres.hxx>
+#include <UndoTable.hxx>
+
+#include <ndtxt.hxx>
+#include <UndoManager.hxx>
+#include <fmtrfmrk.hxx>
+#include <txtrfmrk.hxx>
+#include <translatehelper.hxx>
+
+FlyMode SwBaseShell::s_eFrameMode = FLY_DRAG_END;
+
+// These variables keep the state of Gallery (slot SID_GALLERY_BG_BRUSH)
+// detected by GetGalleryState() for the subsequent ExecuteGallery() call.
+
+static sal_uInt8 nParagraphPos;
+static sal_uInt8 nGraphicPos;
+static sal_uInt8 nOlePos;
+static sal_uInt8 nFramePos;
+static sal_uInt8 nTablePos;
+static sal_uInt8 nTableRowPos;
+static sal_uInt8 nTableCellPos;
+static sal_uInt8 nPagePos;
+static sal_uInt8 nHeaderPos;
+static sal_uInt8 nFooterPos;
+
+#define ShellClass_SwBaseShell
+#include <sfx2/msg.hxx>
+#include <swslots.hxx>
+
+#include <AccessibilityCheck.hxx>
+
+namespace
+{
+ SvxContourDlg* GetContourDlg(SwView const &rView)
+ {
+ SfxChildWindow *pWnd = rView.GetViewFrame().GetChildWindow(SvxContourDlgChildWindow::GetChildWindowId());
+ return pWnd ? static_cast<SvxContourDlg*>(pWnd->GetController().get()) : nullptr;
+ }
+
+ SvxIMapDlg* GetIMapDlg(SwView const &rView)
+ {
+ SfxChildWindow* pWnd = rView.GetViewFrame().GetChildWindow(SvxIMapDlgChildWindow::GetChildWindowId());
+ return pWnd ? static_cast<SvxIMapDlg*>(pWnd->GetController().get()) : nullptr;
+ }
+}
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
+
+SFX_IMPL_SUPERCLASS_INTERFACE(SwBaseShell, SfxShell)
+
+void SwBaseShell::InitInterface_Impl()
+{
+ GetStaticInterface()->RegisterChildWindow(SvxIMapDlgChildWindow::GetChildWindowId());
+ GetStaticInterface()->RegisterChildWindow(SvxContourDlgChildWindow::GetChildWindowId());
+ GetStaticInterface()->RegisterChildWindow(DevelopmentToolChildWindow::GetChildWindowId());
+}
+
+static void lcl_UpdateIMapDlg( SwWrtShell& rSh )
+{
+ Graphic aGrf( rSh.GetIMapGraphic() );
+ GraphicType nGrfType = aGrf.GetType();
+ void* pEditObj = GraphicType::NONE != nGrfType && GraphicType::Default != nGrfType
+ ? rSh.GetIMapInventor() : nullptr;
+ TargetList aList;
+ SfxFrame::GetDefaultTargetList(aList);
+
+ SfxItemSetFixed<RES_URL, RES_URL> aSet( rSh.GetAttrPool() );
+ rSh.GetFlyFrameAttr( aSet );
+ const SwFormatURL &rURL = aSet.Get( RES_URL );
+ SvxIMapDlgChildWindow::UpdateIMapDlg(
+ aGrf, rURL.GetMap(), &aList, pEditObj );
+}
+
+static bool lcl_UpdateContourDlg( SwWrtShell &rSh, SelectionType nSel )
+{
+ Graphic aGraf( rSh.GetIMapGraphic() );
+ GraphicType nGrfType = aGraf.GetType();
+ bool bRet = GraphicType::NONE != nGrfType && GraphicType::Default != nGrfType;
+ if( bRet )
+ {
+ OUString aGrfName;
+ if ( nSel & SelectionType::Graphic )
+ rSh.GetGrfNms( &aGrfName, nullptr );
+
+ SvxContourDlg *pDlg = GetContourDlg(rSh.GetView());
+ if (pDlg)
+ {
+ pDlg->Update(aGraf, !aGrfName.isEmpty(),
+ rSh.GetGraphicPolygon(), rSh.GetIMapInventor());
+ }
+ }
+ return bRet;
+}
+
+void SwBaseShell::ExecDelete(SfxRequest &rReq)
+{
+ SwWrtShell &rSh = GetShell();
+ SwEditWin& rTmpEditWin = GetView().GetEditWin();
+ switch(rReq.GetSlot())
+ {
+ case SID_DELETE:
+ if (rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton())
+ {
+ // Disallow if the cursor is at the end of a paragraph and the document model
+ // node at this position is an outline node with folded content or the next node
+ // is an outline node with folded content.
+ if (rSh.IsEndPara())
+ {
+ SwNodeIndex aIdx(rSh.GetCursor()->GetPointNode());
+ if (aIdx.GetNode().IsTextNode())
+ {
+ bool bVisible = true;
+ aIdx.GetNode().GetTextNode()->GetAttrOutlineContentVisible(bVisible);
+ if (!bVisible)
+ break;
+ ++aIdx;
+ if (aIdx.GetNode().IsTextNode())
+ {
+ bVisible = true;
+ aIdx.GetNode().GetTextNode()->GetAttrOutlineContentVisible(bVisible);
+ if (!bVisible)
+ break;
+ }
+ }
+ }
+ }
+ rSh.DelRight();
+ break;
+
+ case FN_BACKSPACE:
+ if (rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton())
+ {
+ // Disallow if the cursor is at the start of a paragraph and the document model
+ // node at this position is an outline node with folded content or the previous
+ // node is a content node without a layout frame.
+ if (rSh.IsSttPara())
+ {
+ SwNodeIndex aIdx(rSh.GetCursor()->GetPointNode());
+ if (aIdx.GetNode().IsTextNode())
+ {
+ bool bVisible = true;
+ aIdx.GetNode().GetTextNode()->GetAttrOutlineContentVisible(bVisible);
+ if (!bVisible)
+ break;
+ --aIdx;
+ if (aIdx.GetNode().IsContentNode() &&
+ !aIdx.GetNode().GetContentNode()->getLayoutFrame(rSh.GetLayout()))
+ break;
+ }
+ }
+ }
+ if( rSh.IsNoNum() )
+ {
+ rSh.SttCursorMove();
+ bool bLeft = rSh.Left( SwCursorSkipMode::Chars, true, 1, false );
+ if( bLeft )
+ {
+ rSh.DelLeft();
+ }
+ else
+ // JP 15.07.96: If it no longer goes forward, cancel
+ // the numbering. For example at the beginning
+ // of a doc, frame, table or an area.
+ rSh.DelNumRules();
+
+ rSh.EndCursorMove();
+ break;
+ }
+
+ [[fallthrough]]; // otherwise call DelLeft
+ case FN_SHIFT_BACKSPACE:
+ rSh.DelLeft();
+ break;
+ default:
+ OSL_FAIL("wrong Dispatcher");
+ return;
+ }
+ rReq.Done();
+
+ //#i42732# - notify the edit window that from now on we do not use the input language
+ rTmpEditWin.SetUseInputLanguage( false );
+}
+
+void SwBaseShell::ExecClpbrd(SfxRequest &rReq)
+{
+ // Attention: At risk of suicide!
+ // After paste, paste special the shell can be destroy.
+
+ SwWrtShell &rSh = GetShell();
+ sal_uInt16 nId = rReq.GetSlot();
+ bool bIgnore = false;
+ PasteTableType ePasteTable = PasteTableType::PASTE_DEFAULT;
+
+ switch( nId )
+ {
+ case SID_CUT:
+ case SID_COPY:
+ m_rView.GetEditWin().FlushInBuffer();
+ if ( rSh.HasSelection() )
+ {
+ rtl::Reference<SwTransferable> pTransfer = new SwTransferable( rSh );
+
+ if ( nId == SID_CUT && FlyProtectFlags::NONE == rSh.IsSelObjProtected(FlyProtectFlags::Content|FlyProtectFlags::Parent) )
+ pTransfer->Cut();
+ else
+ {
+ const bool bLockedView = rSh.IsViewLocked();
+ rSh.LockView( true ); //lock visible section
+ pTransfer->Copy();
+ rSh.LockView( bLockedView );
+ }
+ break;
+ }
+ return;
+
+ case FN_PASTE_NESTED_TABLE:
+ case FN_TABLE_PASTE_ROW_BEFORE:
+ case FN_TABLE_PASTE_COL_BEFORE:
+ switch ( nId )
+ {
+ case FN_PASTE_NESTED_TABLE:
+ ePasteTable = PasteTableType::PASTE_TABLE;
+ break;
+ case FN_TABLE_PASTE_ROW_BEFORE:
+ ePasteTable = PasteTableType::PASTE_ROW;
+ break;
+ case FN_TABLE_PASTE_COL_BEFORE:
+ ePasteTable = PasteTableType::PASTE_COLUMN;
+ break;
+ default:
+ ;
+ }
+ [[fallthrough]];
+ case SID_PASTE:
+ {
+ TransferableDataHelper aDataHelper(
+ TransferableDataHelper::CreateFromSystemClipboard( &rSh.GetView().GetEditWin() ) );
+ if( aDataHelper.GetXTransferable().is()
+ && SwTransferable::IsPaste( rSh, aDataHelper ) )
+ {
+ // Temporary variables, because the shell could already be
+ // destroyed after the paste.
+ SwView* pView = &m_rView;
+
+ RndStdIds nAnchorType = RndStdIds::FLY_AT_PARA;
+ const SfxUInt16Item* pAnchorType = rReq.GetArg<SfxUInt16Item>(FN_PARAM_1);
+ if (pAnchorType)
+ nAnchorType = static_cast<RndStdIds>(pAnchorType->GetValue());
+ bool bIgnoreComments = false;
+ const SfxBoolItem* pIgnoreComments = rReq.GetArg<SfxBoolItem>(FN_PARAM_2);
+ if (pIgnoreComments)
+ bIgnoreComments = pIgnoreComments->GetValue();
+ SwTransferable::Paste(rSh, aDataHelper, nAnchorType, bIgnoreComments, ePasteTable);
+
+ if( rSh.IsFrameSelected() || rSh.IsObjSelected() )
+ rSh.EnterSelFrameMode();
+ pView->AttrChangedNotify(nullptr);
+
+ // Fold pasted outlines that have outline content visible attribute false
+ MakeAllOutlineContentTemporarilyVisible a(rSh.GetDoc());
+ }
+ else
+ return;
+ }
+ break;
+
+ case SID_CLIPBOARD_FORMAT_ITEMS:
+ {
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ const SfxPoolItem* pFormat;
+ if( pArgs && SfxItemState::SET == pArgs->GetItemState( nId, false, &pFormat ) )
+ {
+ TransferableDataHelper aDataHelper(
+ TransferableDataHelper::CreateFromSystemClipboard(
+ &rSh.GetView().GetEditWin()) );
+ if( aDataHelper.GetXTransferable().is()
+ /*&& SwTransferable::IsPaste( rSh, aDataHelper )*/ )
+ {
+ // Temporary variables, because the shell could already be
+ // destroyed after the paste.
+ SwView* pView = &m_rView;
+
+ SwTransferable::PasteFormat( rSh, aDataHelper,
+ static_cast<SotClipboardFormatId>(static_cast<const SfxUInt32Item*>(pFormat)->GetValue()) );
+
+ //Done() has to be called before the shell has been removed
+ rReq.Done();
+ bIgnore = true;
+ if( rSh.IsFrameSelected() || rSh.IsObjSelected())
+ rSh.EnterSelFrameMode();
+ pView->AttrChangedNotify(nullptr);
+
+ // Fold pasted outlines that have outline content visible attribute false
+ MakeAllOutlineContentTemporarilyVisible a(rSh.GetDoc());
+ }
+ }
+ }
+ break;
+
+ case SID_PASTE_UNFORMATTED:
+ {
+ TransferableDataHelper aDataHelper(
+ TransferableDataHelper::CreateFromSystemClipboard( &rSh.GetView().GetEditWin()) );
+ if( aDataHelper.GetXTransferable().is()
+ && SwTransferable::IsPaste( rSh, aDataHelper ) )
+ {
+ // Temporary variables, because the shell could already be
+ // destroyed after the paste.
+ SwView* pView = &m_rView;
+ rReq.Ignore();
+ bIgnore = true;
+ if(SwTransferable::PasteUnformatted( rSh, aDataHelper ))
+ {
+ SfxViewFrame& rViewFrame = pView->GetViewFrame();
+ uno::Reference< frame::XDispatchRecorder > xRecorder =
+ rViewFrame.GetBindings().GetRecorder();
+ if(xRecorder.is()) {
+ SfxRequest aReq(rViewFrame, SID_CLIPBOARD_FORMAT_ITEMS);
+ aReq.AppendItem( SfxUInt32Item( SID_CLIPBOARD_FORMAT_ITEMS, static_cast<sal_uInt32>(SotClipboardFormatId::STRING) ) );
+ aReq.Done();
+ }
+ }
+
+ if (rSh.IsFrameSelected() || rSh.IsObjSelected())
+ rSh.EnterSelFrameMode();
+ pView->AttrChangedNotify(nullptr);
+
+ // Fold pasted outlines that have outline content visible attribute false
+ MakeAllOutlineContentTemporarilyVisible a(rSh.GetDoc());
+ }
+ else
+ return;
+ }
+ break;
+
+ case SID_PASTE_SPECIAL:
+ {
+ std::shared_ptr<TransferableDataHelper> aDataHelper =
+ std::make_shared<TransferableDataHelper>(TransferableDataHelper::CreateFromSystemClipboard( &rSh.GetView().GetEditWin()));
+
+ if( aDataHelper->GetXTransferable().is()
+ && SwTransferable::IsPaste( rSh, *aDataHelper )
+ && !rSh.CursorInsideInputField() )
+ {
+ rReq.Ignore();
+ bIgnore = true;
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ VclPtr<SfxAbstractPasteDialog> pDlg(pFact->CreatePasteDialog( rReq.GetFrameWeld() ));
+
+ // Prepare the dialog
+ SwTransferable::PrePasteSpecial(rSh, *aDataHelper, pDlg);
+ pDlg->PreGetFormat(*aDataHelper);
+
+
+ pDlg->StartExecuteAsync([aDataHelper, pDlg, &rSh, this](sal_Int32 nResult){
+ if (nResult == RET_OK)
+ {
+ // Temporary variables, because the shell could already be
+ // destroyed after the paste.
+ SwView* pView = &m_rView;
+ bool bRet = false;
+ SotClipboardFormatId nFormatId = pDlg->GetFormatOnly();
+
+ if( nFormatId != SotClipboardFormatId::NONE )
+ bRet = SwTransferable::PasteFormat( rSh, *aDataHelper, nFormatId );
+
+ if (bRet)
+ {
+ SfxViewFrame& rViewFrame = pView->GetViewFrame();
+ uno::Reference< frame::XDispatchRecorder > xRecorder =
+ rViewFrame.GetBindings().GetRecorder();
+ if(xRecorder.is()) {
+ SfxRequest aReq(rViewFrame, SID_CLIPBOARD_FORMAT_ITEMS);
+ aReq.AppendItem( SfxUInt32Item( SID_CLIPBOARD_FORMAT_ITEMS, static_cast<sal_uInt32>(nFormatId) ) );
+ aReq.Done();
+ }
+ }
+
+ if (rSh.IsFrameSelected() || rSh.IsObjSelected())
+ rSh.EnterSelFrameMode();
+ pView->AttrChangedNotify(nullptr);
+
+ // Fold pasted outlines that have outline content visible attribute false
+ MakeAllOutlineContentTemporarilyVisible a(rSh.GetDoc());
+ }
+
+ pDlg->disposeOnce();
+
+ });
+ }
+ else
+ return;
+ }
+ break;
+
+ default:
+ OSL_FAIL("wrong Dispatcher");
+ return;
+ }
+ if(!bIgnore)
+ rReq.Done();
+}
+
+// ClipBoard state
+
+void SwBaseShell::StateClpbrd(SfxItemSet &rSet)
+{
+ SwWrtShell &rSh = GetShell();
+ SfxWhichIter aIter(rSet);
+
+ const bool bCopy = rSh.HasSelection();
+
+ sal_uInt16 nWhich = aIter.FirstWhich();
+
+ while(nWhich)
+ {
+ switch(nWhich)
+ {
+ case SID_CUT:
+ if( FlyProtectFlags::NONE != rSh.IsSelObjProtected(FlyProtectFlags::Content|FlyProtectFlags::Parent ) )
+ {
+ rSet.DisableItem( nWhich );
+ break;
+ }
+ [[fallthrough]];
+ case SID_COPY:
+ if( !bCopy || GetObjectShell()->isContentExtractionLocked())
+ rSet.DisableItem( nWhich );
+ break;
+
+ case FN_PASTE_NESTED_TABLE:
+ case FN_TABLE_PASTE_ROW_BEFORE:
+ case FN_TABLE_PASTE_COL_BEFORE:
+ if( !rSh.IsCursorInTable()
+ || !GetView().IsPasteSpecialAllowed()
+ || rSh.CursorInsideInputField()
+ // disable if not a native Writer table and not a spreadsheet format
+ || !GetView().IsPasteSpreadsheet(rSh.GetTableCopied()) )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_PASTE:
+ if( !GetView().IsPasteAllowed() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_PASTE_SPECIAL:
+ if( !GetView().IsPasteSpecialAllowed()
+ || rSh.CursorInsideInputField() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_PASTE_UNFORMATTED:
+ if( !GetView().IsPasteSpecialAllowed() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_CLIPBOARD_FORMAT_ITEMS:
+ {
+ TransferableDataHelper aDataHelper(
+ TransferableDataHelper::CreateFromSystemClipboard(
+ &rSh.GetView().GetEditWin()) );
+
+ SvxClipboardFormatItem aFormatItem( SID_CLIPBOARD_FORMAT_ITEMS );
+ SwTransferable::FillClipFormatItem( rSh, aDataHelper, aFormatItem );
+ rSet.Put( aFormatItem );
+ }
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+// Perform undo
+
+void SwBaseShell::ExecUndo(SfxRequest &rReq)
+{
+ MakeAllOutlineContentTemporarilyVisible a(GetShell().GetDoc(), true);
+
+ SwWrtShell &rWrtShell = GetShell();
+
+ SwUndoId nUndoId(SwUndoId::EMPTY);
+ sal_uInt16 nId = rReq.GetSlot(), nCnt = 1;
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ const SfxPoolItem* pItem;
+ if( pArgs && SfxItemState::SET == pArgs->GetItemState( nId, false, &pItem ))
+ nCnt = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
+
+ // Repair mode: allow undo/redo of all undo actions, even if access would
+ // be limited based on the view shell ID.
+ bool bRepair = false;
+ const SfxBoolItem* pRepairItem;
+ if (pArgs && (pRepairItem = pArgs->GetItemIfSet(SID_REPAIRPACKAGE, false)))
+ bRepair = pRepairItem->GetValue();
+
+ // #i106349#: save pointer: undo/redo may delete the shell, i.e., this!
+ SfxViewFrame& rViewFrame( GetView().GetViewFrame() );
+
+ IDocumentUndoRedo& rUndoRedo = rWrtShell.GetIDocumentUndoRedo();
+ bool bWasRepair = rUndoRedo.DoesRepair();
+ rUndoRedo.DoRepair(bRepair);
+ comphelper::ScopeGuard aGuard([&rUndoRedo, bWasRepair]()
+ {
+ rUndoRedo.DoRepair(bWasRepair);
+ });
+
+ switch( nId )
+ {
+ case SID_UNDO:
+ if (rUndoRedo.GetLastUndoInfo(nullptr, &nUndoId, &rWrtShell.GetView()))
+ {
+ for (SwViewShell& rShell : rWrtShell.GetRingContainer())
+ rShell.LockPaint(LockPaintReason::Undo);
+
+ sal_uInt16 nUndoOffset = 0;
+ if (comphelper::LibreOfficeKit::isActive() && !bRepair && nCnt == 1)
+ {
+ sw::UndoManager& rManager = rWrtShell.GetDoc()->GetUndoManager();
+ const SfxUndoAction* pAction = rManager.GetUndoAction();
+ SwView& rView = rWrtShell.GetView();
+ ViewShellId nViewShellId = rView.GetViewShellId();
+ sal_uInt16 nOffset = 0;
+ if (pAction->GetViewShellId() != nViewShellId
+ && rManager.IsViewUndoActionIndependent(&rView, nOffset))
+ {
+ // Execute the undo with an offset: don't undo the top action, but an
+ // earlier one, since it's independent and that belongs to our view.
+ nUndoOffset += nOffset;
+ }
+ }
+
+ rWrtShell.Do(SwWrtShell::UNDO, nCnt, nUndoOffset);
+
+ for (SwViewShell& rShell : rWrtShell.GetRingContainer())
+ rShell.UnlockPaint();
+
+ // tdf#141613 FIXME: Disable redoing header/footer changes for now.
+ // The proper solution would be to write a SwUndoHeaderFooter class
+ // to represent the addition of a header or footer to the current page.
+ if (nUndoId == SwUndoId::HEADER_FOOTER)
+ rUndoRedo.ClearRedo();
+ }
+ break;
+
+ case SID_REDO:
+ if (rUndoRedo.GetFirstRedoInfo(nullptr, &nUndoId, &rWrtShell.GetView()))
+ {
+ for (SwViewShell& rShell : rWrtShell.GetRingContainer())
+ rShell.LockPaint(LockPaintReason::Redo);
+ rWrtShell.Do( SwWrtShell::REDO, nCnt );
+ for (SwViewShell& rShell : rWrtShell.GetRingContainer())
+ rShell.UnlockPaint();
+ }
+ break;
+
+ case SID_REPEAT:
+ rWrtShell.Do( SwWrtShell::REPEAT );
+ break;
+ default:
+ OSL_FAIL("wrong Dispatcher");
+ }
+
+ if (nUndoId == SwUndoId::CONFLICT)
+ {
+ rReq.SetReturnValue( SfxUInt32Item(nId, static_cast<sal_uInt32>(SID_REPAIRPACKAGE)) );
+ }
+
+ rViewFrame.GetBindings().InvalidateAll(false);
+}
+
+// State of undo
+
+void SwBaseShell::StateUndo(SfxItemSet &rSet)
+{
+ SwUndoId nUndoId(SwUndoId::EMPTY);
+ SwWrtShell &rSh = GetShell();
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while(nWhich)
+ {
+ switch(nWhich)
+ {
+ case SID_UNDO:
+ {
+ if (rSh.GetLastUndoInfo(nullptr, &nUndoId, &rSh.GetView()))
+ {
+ rSet.Put( SfxStringItem(nWhich,
+ rSh.GetDoString(SwWrtShell::UNDO)));
+ }
+ else if (nUndoId == SwUndoId::CONFLICT)
+ {
+ rSet.Put( SfxUInt32Item(nWhich, static_cast<sal_uInt32>(SID_REPAIRPACKAGE)) );
+ }
+ else
+ rSet.DisableItem(nWhich);
+
+ break;
+ }
+ case SID_REDO:
+ {
+ if (rSh.GetFirstRedoInfo(nullptr, &nUndoId, &rSh.GetView()))
+ {
+ rSet.Put(SfxStringItem(nWhich,
+ rSh.GetDoString(SwWrtShell::REDO)));
+ }
+ else if (nUndoId == SwUndoId::CONFLICT)
+ {
+ rSet.Put( SfxInt32Item(nWhich, static_cast<sal_uInt32>(SID_REPAIRPACKAGE)) );
+ }
+ else
+ rSet.DisableItem(nWhich);
+ break;
+ }
+ case SID_REPEAT:
+ { // Repeat is only possible if no REDO is possible - UI-Restriction
+ if ((!rSh.GetFirstRedoInfo(nullptr, nullptr)) &&
+ !rSh.IsSelFrameMode() &&
+ (SwUndoId::EMPTY != rSh.GetRepeatInfo(nullptr)))
+ {
+ rSet.Put(SfxStringItem(nWhich, rSh.GetRepeatString()));
+ }
+ else
+ rSet.DisableItem(nWhich);
+ break;
+ }
+
+ case SID_GETUNDOSTRINGS:
+ if (rSh.GetLastUndoInfo(nullptr, nullptr))
+ {
+ SfxStringListItem aStrLst( nWhich );
+ rSh.GetDoStrings( SwWrtShell::UNDO, aStrLst );
+ rSet.Put( aStrLst );
+ }
+ else
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_GETREDOSTRINGS:
+ if (rSh.GetFirstRedoInfo(nullptr, nullptr))
+ {
+ SfxStringListItem aStrLst( nWhich );
+ rSh.GetDoStrings( SwWrtShell::REDO, aStrLst );
+ rSet.Put( aStrLst );
+ }
+ else
+ rSet.DisableItem( nWhich );
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+namespace
+{
+/// Searches for the specified field type and field name prefix and update the matching fields to
+/// have the provided new name and content.
+bool UpdateFieldContents(SfxRequest& rReq, SwWrtShell& rWrtSh)
+{
+ const SfxStringItem* pTypeName = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ if (!pTypeName || pTypeName->GetValue() != "SetRef")
+ {
+ // This is implemented so far only for reference marks.
+ return false;
+ }
+
+ const SfxStringItem* pNamePrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_2);
+ if (!pNamePrefix)
+ {
+ return false;
+ }
+ const OUString& rNamePrefix = pNamePrefix->GetValue();
+
+ const SfxUnoAnyItem* pFields = rReq.GetArg<SfxUnoAnyItem>(FN_PARAM_3);
+ if (!pFields)
+ {
+ return false;
+ }
+ uno::Sequence<beans::PropertyValues> aFields;
+ pFields->GetValue() >>= aFields;
+
+ SwDoc* pDoc = rWrtSh.GetDoc();
+ pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::UPDATE_FIELDS, nullptr);
+ rWrtSh.StartAction();
+
+ std::vector<const SwFormatRefMark*> aRefMarks;
+
+ for (sal_uInt16 i = 0; i < pDoc->GetRefMarks(); ++i)
+ {
+ aRefMarks.push_back(pDoc->GetRefMark(i));
+ }
+
+ std::sort(aRefMarks.begin(), aRefMarks.end(),
+ [](const SwFormatRefMark* pMark1, const SwFormatRefMark* pMark2) -> bool {
+ const SwTextRefMark* pTextRefMark1 = pMark1->GetTextRefMark();
+ const SwTextRefMark* pTextRefMark2 = pMark2->GetTextRefMark();
+ SwPosition aPos1(pTextRefMark1->GetTextNode(), pTextRefMark1->GetStart());
+ SwPosition aPos2(pTextRefMark2->GetTextNode(), pTextRefMark2->GetStart());
+ return aPos1 < aPos2;
+ });
+
+ sal_uInt16 nFieldIndex = 0;
+ for (auto& pIntermediateRefMark : aRefMarks)
+ {
+ auto pRefMark = const_cast<SwFormatRefMark*>(pIntermediateRefMark);
+ if (!pRefMark->GetRefName().startsWith(rNamePrefix))
+ {
+ continue;
+ }
+
+ if (nFieldIndex >= aFields.getLength())
+ {
+ break;
+ }
+ comphelper::SequenceAsHashMap aMap(aFields[nFieldIndex++]);
+ auto aName = aMap["Name"].get<OUString>();
+ pRefMark->GetRefName() = aName;
+
+ OUString aContent = aMap["Content"].get<OUString>();
+ auto pTextRefMark = const_cast<SwTextRefMark*>(pRefMark->GetTextRefMark());
+ pTextRefMark->UpdateFieldContent(pDoc, rWrtSh, aContent);
+ }
+
+ rWrtSh.EndAction();
+ pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::UPDATE_FIELDS, nullptr);
+ return true;
+}
+
+/// Searches for the specified field type and field name prefix under cursor and update the matching
+/// field to have the provided new name and content.
+void UpdateFieldContent(SfxRequest& rReq, SwWrtShell& rWrtSh)
+{
+ const SfxStringItem* pTypeName = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ if (!pTypeName || pTypeName->GetValue() != "SetRef")
+ {
+ // This is implemented so far only for reference marks.
+ return;
+ }
+
+ const SfxStringItem* pNamePrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_2);
+ if (!pNamePrefix)
+ {
+ return;
+ }
+ const OUString& rNamePrefix = pNamePrefix->GetValue();
+
+ const SfxUnoAnyItem* pField = rReq.GetArg<SfxUnoAnyItem>(FN_PARAM_3);
+ if (!pField)
+ {
+ return;
+ }
+ uno::Sequence<beans::PropertyValue> aField;
+ pField->GetValue() >>= aField;
+
+ SwPosition& rCursor = *rWrtSh.GetCursor()->GetPoint();
+ SwTextNode* pTextNode = rCursor.GetNode().GetTextNode();
+ std::vector<SwTextAttr*> aAttrs
+ = pTextNode->GetTextAttrsAt(rCursor.GetContentIndex(), RES_TXTATR_REFMARK);
+ if (aAttrs.empty())
+ {
+ return;
+ }
+
+ auto& rRefmark = const_cast<SwFormatRefMark&>(aAttrs[0]->GetRefMark());
+ if (!rRefmark.GetRefName().startsWith(rNamePrefix))
+ {
+ return;
+ }
+
+ SwDoc* pDoc = rWrtSh.GetDoc();
+ SwRewriter aRewriter;
+ aRewriter.AddRule(UndoArg1, rRefmark.GetRefName());
+ pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::UPDATE_FIELD, &aRewriter);
+ rWrtSh.StartAction();
+ comphelper::ScopeGuard g(
+ [&rWrtSh, &aRewriter]
+ {
+ rWrtSh.EndAction();
+ rWrtSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::UPDATE_FIELD, &aRewriter);
+ });
+
+ comphelper::SequenceAsHashMap aMap(aField);
+ auto aName = aMap["Name"].get<OUString>();
+ rRefmark.GetRefName() = aName;
+
+ OUString aContent = aMap["Content"].get<OUString>();
+ auto pTextRefMark = const_cast<SwTextRefMark*>(rRefmark.GetTextRefMark());
+ pTextRefMark->UpdateFieldContent(pDoc, rWrtSh, aContent);
+}
+}
+
+// Evaluate respectively dispatching the slot Id
+
+void SwBaseShell::Execute(SfxRequest &rReq)
+{
+ const SfxPoolItem *pItem;
+ SwWrtShell &rSh = GetShell();
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ bool bMore = false;
+
+ sal_uInt16 nSlot = rReq.GetSlot();
+ switch(nSlot)
+ {
+ case FN_REPAGINATE:
+ {
+ Reference < XModel > xModel = GetView().GetDocShell()->GetModel();
+ auto pDoc = comphelper::getFromUnoTunnel<SwXTextDocument>(xModel);
+ pDoc->NotifyRefreshListeners();
+ rSh.CalcLayout();
+ }
+ break;
+ case FN_UPDATE_FIELDS:
+ {
+ if (UpdateFieldContents(rReq, rSh))
+ {
+ // Parameters indicated that the name / content of fields has to be updated to
+ // the provided values, don't do an actual fields update.
+ break;
+ }
+
+ rSh.UpdateDocStat();
+ rSh.EndAllTableBoxEdit();
+ rSh.SwViewShell::UpdateFields(true);
+
+ if( rSh.IsCursorInTable() )
+ {
+ if( !rSh.IsTableComplexForChart() )
+ SwTableFUNC( &rSh ).UpdateChart();
+ rSh.ClearTableBoxContent();
+ rSh.SaveTableBoxContent();
+ }
+ }
+ break;
+ case FN_UPDATE_FIELD:
+ {
+ UpdateFieldContent(rReq, rSh);
+ }
+ break;
+ case FN_UPDATE_CHARTS:
+ {
+ SwWait aWait( *m_rView.GetDocShell(), true );
+ rSh.UpdateAllCharts();
+ }
+ break;
+
+ case FN_UPDATE_ALL:
+ {
+ comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer
+ = GetObjectShell()->getEmbeddedObjectContainer();
+ rEmbeddedObjectContainer.setUserAllowsLinkUpdate(true);
+
+ SwView& rTempView = GetView();
+ rSh.EnterStdMode();
+ if( !rSh.GetLinkManager().GetLinks().empty() )
+ {
+ rSh.StartAllAction();
+ rSh.GetLinkManager().UpdateAllLinks( false, true, nullptr );
+ rSh.EndAllAction();
+ }
+ SfxDispatcher &rDis = *rTempView.GetViewFrame().GetDispatcher();
+ rDis.Execute( FN_UPDATE_FIELDS );
+ rDis.Execute( FN_UPDATE_TOX );
+ rDis.Execute( FN_UPDATE_CHARTS );
+ rSh.Reformat();
+ rSh.UpdateOleObjectPreviews();
+ }
+ break;
+
+ case FN_UPDATE_INPUTFIELDS:
+ rSh.UpdateInputFields();
+ break;
+
+ case FN_PREV_BOOKMARK:
+ rReq.SetReturnValue(SfxBoolItem( nSlot, rSh.GoPrevBookmark()));
+ break;
+ case FN_NEXT_BOOKMARK:
+ rReq.SetReturnValue(SfxBoolItem( nSlot, rSh.GoNextBookmark()));
+ break;
+
+ case FN_GOTO_NEXT_MARK:
+ case FN_GOTO_PREV_MARK:
+ {
+ SwFieldMgr aFieldMgr;
+ SwFieldType* pFieldType = aFieldMgr.GetFieldType(SwFieldIds::JumpEdit);
+
+ if (pFieldType)
+ {
+ if (rSh.IsSelFrameMode())
+ {
+ rSh.UnSelectFrame();
+ rSh.LeaveSelFrameMode();
+ }
+
+ if (rSh.HasMark())
+ {
+ SwMvContext aMvContext(&rSh);
+ if (rSh.IsCursorPtAtEnd())
+ rSh.SwapPam();
+ rSh.ClearMark();
+ rSh.EndSelect();
+ }
+ bool bRet = rSh.MoveFieldType( pFieldType, nSlot == FN_GOTO_NEXT_MARK );
+ SwField* pCurField = bRet ? rSh.GetCurField() : nullptr;
+ if (pCurField)
+ rSh.ClickToField(*pCurField, /*bExecHyperlinks=*/false);
+ rReq.SetReturnValue(SfxBoolItem( nSlot, bRet));
+ }
+ }
+ break;
+
+ case FN_START_DOC_DIRECT:
+ case FN_END_DOC_DIRECT:
+ {
+ if (rSh.IsSelFrameMode())
+ {
+ rSh.UnSelectFrame();
+ rSh.LeaveSelFrameMode();
+ }
+ rSh.EnterStdMode();
+ nSlot == FN_START_DOC_DIRECT ?
+ rSh.SttEndDoc(true) :
+ rSh.SttEndDoc(false);
+ }
+ break;
+ case FN_GOTO_PREV_OBJ:
+ case FN_GOTO_NEXT_OBJ:
+ {
+ bool bSuccess = rSh.GotoObj( nSlot == FN_GOTO_NEXT_OBJ );
+ rReq.SetReturnValue(SfxBoolItem(nSlot, bSuccess));
+ if (bSuccess && !rSh.IsSelFrameMode())
+ {
+ rSh.HideCursor();
+ rSh.EnterSelFrameMode();
+ GetView().AttrChangedNotify(nullptr);
+ }
+ }
+ break;
+ case SID_GALLERY_FORMATS:
+ {
+ const SvxGalleryItem* pGalleryItem = SfxItemSet::GetItem<SvxGalleryItem>(pArgs, SID_GALLERY_FORMATS, false);
+ if ( !pGalleryItem )
+ break;
+
+ const SelectionType nSelType = rSh.GetSelectionType();
+ sal_Int8 nGalleryItemType( pGalleryItem->GetType() );
+
+ if ( (!rSh.IsSelFrameMode() || nSelType & SelectionType::Graphic) &&
+ nGalleryItemType == css::gallery::GalleryItemType::GRAPHIC )
+ {
+ SwWait aWait( *m_rView.GetDocShell(), true );
+
+ OUString aGrfName, aFltName;
+ const Graphic aGrf( pGalleryItem->GetGraphic() );
+
+ if ( nSelType & SelectionType::Graphic )
+ rSh.ReRead( aGrfName, aFltName, &aGrf );
+ else
+ rSh.InsertGraphic( aGrfName, aFltName, aGrf );
+
+ GetView().GetEditWin().GrabFocus();
+ }
+ else if(!rSh.IsSelFrameMode() &&
+ nGalleryItemType == css::gallery::GalleryItemType::MEDIA )
+ {
+ const SfxStringItem aMediaURLItem( SID_INSERT_AVMEDIA, pGalleryItem->GetURL() );
+ GetView().GetViewFrame().GetDispatcher()->ExecuteList(
+ SID_INSERT_AVMEDIA, SfxCallMode::SYNCHRON,
+ { &aMediaURLItem });
+ }
+ }
+ break;
+ case FN_PAGE_STYLE_SET_COLS:
+ {
+ if (pArgs)
+ {
+ // Determine the current PageDescriptor and fill the set with that.
+ const size_t nCurIdx = rSh.GetCurPageDesc();
+ SwPageDesc aPageDesc(rSh.GetPageDesc(nCurIdx));
+
+ SwFrameFormat &rFormat = aPageDesc.GetMaster();
+
+ SwFormatCol aFormatCol = rFormat.GetCol();
+
+ sal_uInt16 nCount;
+ if(SfxItemState::SET == pArgs->GetItemState(nSlot))
+ nCount = static_cast<const SfxUInt16Item &>(pArgs->Get(nSlot)).GetValue();
+ else
+ nCount = pArgs->Get(SID_ATTR_COLUMNS).GetValue();
+ sal_uInt16 nGutterWidth = DEF_GUTTER_WIDTH;
+
+ aFormatCol.Init(nCount ? nCount : 1, nGutterWidth, USHRT_MAX);
+ aFormatCol.SetWishWidth(USHRT_MAX);
+ aFormatCol.SetGutterWidth(nGutterWidth, USHRT_MAX);
+
+ rFormat.SetFormatAttr(aFormatCol);
+
+ rSh.ChgPageDesc(nCurIdx, aPageDesc);
+ }
+ else
+ GetView().GetViewFrame().GetDispatcher()->Execute(FN_FORMAT_PAGE_COLUMN_DLG);
+ }
+ break;
+ case FN_CONVERT_TABLE_TO_TEXT:
+ case FN_CONVERT_TEXT_TO_TABLE:
+ case FN_CONVERT_TEXT_TABLE:
+ {
+ sal_Unicode cDelim = 0;
+ bool bToTable = false;
+ if( nSlot == FN_CONVERT_TEXT_TO_TABLE ||
+ ( nSlot == FN_CONVERT_TEXT_TABLE && nullptr == rSh.GetTableFormat() ))
+ bToTable = true;
+ SwInsertTableOptions aInsTableOpts( SwInsertTableFlags::All, 1 );
+ SwTableAutoFormat const* pTAFormat = nullptr;
+ std::unique_ptr<SwTableAutoFormatTable> pAutoFormatTable;
+ bool bDeleteFormat = true;
+ if(pArgs && SfxItemState::SET == pArgs->GetItemState( FN_PARAM_1, true, &pItem))
+ {
+ aInsTableOpts.mnInsMode = SwInsertTableFlags::NONE;
+ // Delimiter
+ OUString sDelim = static_cast< const SfxStringItem* >(pItem)->GetValue();
+ if(!sDelim.isEmpty())
+ cDelim = sDelim[0];
+ // AutoFormat
+ if(SfxItemState::SET == pArgs->GetItemState( FN_PARAM_2, true, &pItem))
+ {
+ OUString sAutoFormat = static_cast< const SfxStringItem* >(pItem)->GetValue();
+
+ pAutoFormatTable.reset(new SwTableAutoFormatTable);
+ pAutoFormatTable->Load();
+
+ for( sal_uInt16 i = 0, nCount = pAutoFormatTable->size(); i < nCount; i++ )
+ {
+ SwTableAutoFormat const*const pFormat = &(*pAutoFormatTable)[ i ];
+ if( pFormat->GetName() == sAutoFormat )
+ {
+ pTAFormat = pFormat;
+ bDeleteFormat = false;
+ break;
+ }
+ }
+ }
+ //WithHeader
+ if(SfxItemState::SET == pArgs->GetItemState( FN_PARAM_3, true, &pItem) &&
+ static_cast< const SfxBoolItem* >(pItem)->GetValue())
+ aInsTableOpts.mnInsMode |= SwInsertTableFlags::Headline;
+ // RepeatHeaderLines
+ if(SfxItemState::SET == pArgs->GetItemState( FN_PARAM_4, true, &pItem))
+ aInsTableOpts.mnRowsToRepeat =
+ o3tl::narrowing<sal_uInt16>(static_cast< const SfxInt16Item* >(pItem)->GetValue());
+ //WithBorder
+ if(SfxItemState::SET == pArgs->GetItemState( FN_PARAM_5, true, &pItem) &&
+ static_cast< const SfxBoolItem* >(pItem)->GetValue())
+ aInsTableOpts.mnInsMode |= SwInsertTableFlags::DefaultBorder;
+ //DontSplitTable
+ if(SfxItemState::SET == pArgs->GetItemState( FN_PARAM_6, true, &pItem) &&
+ !static_cast< const SfxBoolItem* >(pItem)->GetValue() )
+ aInsTableOpts.mnInsMode |= SwInsertTableFlags::SplitLayout;
+ }
+ else
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSwConvertTableDlg> pDlg(pFact->CreateSwConvertTableDlg(GetView(), bToTable));
+ if( RET_OK == pDlg->Execute() )
+ {
+ pDlg->GetValues( cDelim, aInsTableOpts, pTAFormat );
+
+ }
+ }
+
+ if( cDelim )
+ {
+ //Shell change!
+ SwView& rSaveView = m_rView;
+ bool bInserted = false;
+ //recording:
+ SfxViewFrame& rViewFrame = GetView().GetViewFrame();
+ if (SfxRequest::HasMacroRecorder(rViewFrame))
+ {
+ SfxRequest aReq(rViewFrame, nSlot);
+ aReq.AppendItem( SfxStringItem( FN_PARAM_1, OUString(cDelim) ));
+ if(bToTable)
+ {
+ if(pTAFormat)
+ aReq.AppendItem( SfxStringItem( FN_PARAM_2, pTAFormat->GetName()));
+ aReq.AppendItem( SfxBoolItem ( FN_PARAM_3, bool(aInsTableOpts.mnInsMode & SwInsertTableFlags::Headline)));
+ aReq.AppendItem( SfxInt16Item( FN_PARAM_4, static_cast<short>(aInsTableOpts.mnRowsToRepeat) ));
+ aReq.AppendItem( SfxBoolItem ( FN_PARAM_5, bool(aInsTableOpts.mnInsMode & SwInsertTableFlags::DefaultBorder) ));
+ aReq.AppendItem( SfxBoolItem ( FN_PARAM_6, !(aInsTableOpts.mnInsMode & SwInsertTableFlags::SplitLayout)));
+ }
+ aReq.Done();
+ }
+
+ if( !bToTable )
+ rSh.TableToText( cDelim );
+ else
+ {
+ bInserted = rSh.TextToTable( aInsTableOpts, cDelim, pTAFormat );
+ }
+ rSh.EnterStdMode();
+
+ if( bInserted )
+ rSaveView.AutoCaption( TABLE_CAP );
+ }
+ if(bDeleteFormat)
+ delete pTAFormat;
+ }
+ break;
+ case SID_STYLE_WATERCAN:
+ case SID_STYLE_UPDATE_BY_EXAMPLE:
+ case SID_STYLE_NEW_BY_EXAMPLE:
+ case SID_STYLE_APPLY:
+ {
+ ShellMode eMode = GetView().GetShellMode();
+ if ( ShellMode::Draw != eMode &&
+ ShellMode::DrawForm != eMode &&
+ ShellMode::DrawText != eMode &&
+ ShellMode::Bezier != eMode )
+ {
+ // oj #107754#
+ if ( SID_STYLE_WATERCAN == nSlot )
+ {
+ const bool bLockedView = rSh.IsViewLocked();
+ rSh.LockView( true ); //lock visible section
+
+ GetView().GetDocShell()->ExecStyleSheet(rReq);
+
+ rSh.LockView( bLockedView );
+ }
+ else
+ // Will be recorded from the DocShell
+ GetView().GetDocShell()->ExecStyleSheet(rReq);
+ }
+ }
+ break;
+ case SID_CLASSIFICATION_APPLY:
+ {
+ GetView().GetDocShell()->Execute(rReq);
+ }
+ break;
+ case SID_CLASSIFICATION_DIALOG:
+ {
+ GetView().GetDocShell()->Execute(rReq);
+ }
+ break;
+ case SID_PARAGRAPH_SIGN_CLASSIFY_DLG:
+ {
+ GetView().GetDocShell()->Execute(rReq);
+ }
+ break;
+ case SID_WATERMARK:
+ {
+ GetView().GetDocShell()->Execute(rReq);
+ }
+ break;
+ case FN_ESCAPE:
+ GetView().ExecuteSlot(rReq);
+ break;
+ case SID_IMAP:
+ {
+ sal_uInt16 nId = SvxIMapDlgChildWindow::GetChildWindowId();
+
+ SfxViewFrame& rVFrame = GetView().GetViewFrame();
+ rVFrame.ToggleChildWindow( nId );
+ rVFrame.GetBindings().Invalidate( SID_IMAP );
+
+ if ( rVFrame.HasChildWindow( nId ) && rSh.IsFrameSelected() )
+ lcl_UpdateIMapDlg( rSh );
+ }
+ break;
+ case SID_IMAP_EXEC:
+ {
+ SvxIMapDlg* pDlg = GetIMapDlg(GetView());
+
+ // Check, if the allocation is useful or allowed at all.
+ if ( rSh.IsFrameSelected() &&
+ pDlg->GetEditingObject() == rSh.GetIMapInventor() )
+ {
+ SfxItemSetFixed<RES_URL, RES_URL> aSet( rSh.GetAttrPool() );
+ rSh.GetFlyFrameAttr( aSet );
+ SwFormatURL aURL( aSet.Get( RES_URL ) );
+ aURL.SetMap( &pDlg->GetImageMap() );
+ aSet.Put( aURL );
+ rSh.SetFlyFrameAttr( aSet );
+ }
+ }
+ break;
+ case FN_SET_TRACKED_CHANGES_IN_TEXT:
+ case FN_SET_TRACKED_DELETIONS_IN_MARGIN:
+ case FN_SET_TRACKED_INSERTIONS_IN_MARGIN:
+ {
+ SwViewOption aViewOption = *rSh.GetViewOptions();
+ bool bAllInText = FN_SET_TRACKED_CHANGES_IN_TEXT == nSlot;
+ aViewOption.SetShowChangesInMargin( !bAllInText );
+ if ( !bAllInText )
+ aViewOption.SetShowChangesInMargin2( FN_SET_TRACKED_INSERTIONS_IN_MARGIN == nSlot );
+ rSh.ApplyViewOptions( aViewOption );
+
+ // tdf#140982 restore annotation ranges stored in temporary bookmarks
+ // (only remove temporary bookmarks during file saving to avoid possible
+ // conflict with lazy deletion of the bookmarks of the moved tracked deletions)
+ if ( bAllInText || FN_SET_TRACKED_INSERTIONS_IN_MARGIN == nSlot )
+ rSh.GetDoc()->getIDocumentMarkAccess()->restoreAnnotationMarks(false);
+ }
+ break;
+ case SID_CONTOUR_DLG:
+ {
+ sal_uInt16 nId = SvxContourDlgChildWindow::GetChildWindowId();
+
+ SfxViewFrame& rVFrame = GetView().GetViewFrame();
+ rVFrame.ToggleChildWindow( nId );
+ rVFrame.GetBindings().Invalidate( SID_CONTOUR_DLG );
+
+ SelectionType nSel = rSh.GetSelectionType();
+ if ( rVFrame.HasChildWindow( nId ) &&
+ (nSel & (SelectionType::Graphic|SelectionType::Ole)) )
+ {
+ lcl_UpdateContourDlg( rSh, nSel );
+ }
+ }
+ break;
+ case SID_CONTOUR_EXEC:
+ {
+ SvxContourDlg *pDlg = GetContourDlg(GetView());
+ // Check, if the allocation is useful or allowed at all.
+ SelectionType nSel = rSh.GetSelectionType();
+ if ( nSel & (SelectionType::Graphic|SelectionType::Ole) )
+ {
+ if (pDlg && pDlg->GetEditingObject() == rSh.GetIMapInventor())
+ {
+ rSh.StartAction();
+ SfxItemSetFixed<RES_SURROUND, RES_SURROUND> aSet( rSh.GetAttrPool() );
+ rSh.GetFlyFrameAttr( aSet );
+ SwFormatSurround aSur( aSet.Get( RES_SURROUND ) );
+ if ( !aSur.IsContour() )
+ {
+ aSur.SetContour( true );
+ if ( aSur.GetSurround() == css::text::WrapTextMode_NONE )
+ aSur.SetSurround( css::text::WrapTextMode_PARALLEL );
+ aSet.Put( aSur );
+ rSh.SetFlyFrameAttr( aSet );
+ }
+ const tools::PolyPolygon aPoly( pDlg->GetPolyPolygon() );
+ rSh.SetGraphicPolygon( &aPoly );
+ if ( pDlg->IsGraphicChanged() )
+ rSh.ReRead( OUString(), OUString(), &pDlg->GetGraphic());
+ rSh.EndAction();
+ }
+ }
+ }
+ break;
+ case FN_FRAME_TO_ANCHOR:
+ {
+ rSh.GotoFlyAnchor();
+ rSh.EnterStdMode();
+ rSh.CallChgLnk();
+ }
+ break;
+ case FN_TOOL_ANCHOR_PAGE:
+ case FN_TOOL_ANCHOR_PARAGRAPH:
+ case FN_TOOL_ANCHOR_CHAR:
+ case FN_TOOL_ANCHOR_AT_CHAR:
+ case FN_TOOL_ANCHOR_FRAME:
+ {
+ RndStdIds eSet = nSlot == FN_TOOL_ANCHOR_PAGE
+ ? RndStdIds::FLY_AT_PAGE
+ : nSlot == FN_TOOL_ANCHOR_PARAGRAPH
+ ? RndStdIds::FLY_AT_PARA
+ : nSlot == FN_TOOL_ANCHOR_FRAME
+ ? RndStdIds::FLY_AT_FLY
+ : nSlot == FN_TOOL_ANCHOR_CHAR
+ ? RndStdIds::FLY_AS_CHAR
+ : RndStdIds::FLY_AT_CHAR;
+ rSh.StartUndo();
+ if (rSh.IsObjSelected())
+ rSh.ChgAnchor(eSet);
+ else if (rSh.IsFrameSelected())
+ {
+ SwFormatAnchor aAnc(eSet, eSet == RndStdIds::FLY_AT_PAGE ? rSh.GetPhyPageNum() : 0);
+ SfxItemSet aSet(SwFEShell::makeItemSetFromFormatAnchor(GetPool(), aAnc));
+ rSh.SetFlyFrameAttr(aSet);
+ }
+ // if new anchor is 'as char' and it is a Math object and the usual
+ // pre-conditions are met then align the formula to the baseline of the text
+ const uno::Reference < embed::XEmbeddedObject > xObj( rSh.GetOleRef() );
+ const bool bDoMathBaselineAlignment = xObj.is() && SotExchange::IsMath( xObj->getClassID() )
+ && RndStdIds::FLY_AS_CHAR == eSet && rSh.GetDoc()->getIDocumentSettingAccess().get( DocumentSettingId::MATH_BASELINE_ALIGNMENT );
+ if (bDoMathBaselineAlignment)
+ rSh.AlignFormulaToBaseline( xObj );
+
+ sal_uInt16 nHtmlMode = ::GetHtmlMode(GetView().GetDocShell());
+ if( nHtmlMode )
+ {
+ SfxItemSetFixed<RES_SURROUND, RES_HORI_ORIENT> aSet(GetPool());
+ rSh.GetFlyFrameAttr(aSet);
+
+ const SwFormatSurround& rSurround = aSet.Get(RES_SURROUND);
+ const SwFormatVertOrient& rVert = aSet.Get(RES_VERT_ORIENT);
+ const SwFormatHoriOrient& rHori = aSet.Get(RES_HORI_ORIENT);
+ sal_Int16 eVOrient = rVert.GetVertOrient();
+ sal_Int16 eHOrient = rHori.GetHoriOrient();
+ css::text::WrapTextMode eSurround = rSurround.GetSurround();
+
+ switch( eSet )
+ {
+ case RndStdIds::FLY_AT_FLY:
+ case RndStdIds::FLY_AT_PAGE:
+ //Wrap through, left or from left, top, from top
+ if(eSurround != css::text::WrapTextMode_THROUGH)
+ aSet.Put(SwFormatSurround(css::text::WrapTextMode_THROUGH));
+
+ if( eVOrient != text::VertOrientation::TOP && eVOrient != text::VertOrientation::NONE)
+ aSet.Put(SwFormatVertOrient(0, text::VertOrientation::TOP));
+
+ if (eHOrient != text::HoriOrientation::NONE && eHOrient != text::HoriOrientation::LEFT)
+ aSet.Put(SwFormatHoriOrient(0, text::HoriOrientation::LEFT));
+ break;
+
+ case RndStdIds::FLY_AT_PARA:
+ // left, from left, right, top, no wrap, wrap left and right
+ if (eSurround != css::text::WrapTextMode_LEFT && eSurround != css::text::WrapTextMode_RIGHT)
+ aSet.Put(SwFormatSurround(css::text::WrapTextMode_LEFT));
+
+ if( eVOrient != text::VertOrientation::TOP)
+ aSet.Put(SwFormatVertOrient(0, text::VertOrientation::TOP));
+
+ if (eHOrient != text::HoriOrientation::NONE && eHOrient != text::HoriOrientation::LEFT && eHOrient != text::HoriOrientation::RIGHT)
+ aSet.Put(SwFormatHoriOrient(0, text::HoriOrientation::LEFT));
+ break;
+
+ case RndStdIds::FLY_AT_CHAR:
+ // left, from left, right, top, wrap through
+ if(eSurround != css::text::WrapTextMode_THROUGH)
+ aSet.Put(SwFormatSurround(css::text::WrapTextMode_THROUGH));
+
+ if( eVOrient != text::VertOrientation::TOP)
+ aSet.Put(SwFormatVertOrient(0, text::VertOrientation::TOP));
+
+ if (eHOrient != text::HoriOrientation::NONE && eHOrient != text::HoriOrientation::LEFT && eHOrient != text::HoriOrientation::RIGHT)
+ aSet.Put(SwFormatHoriOrient(0, text::HoriOrientation::LEFT));
+ break;
+
+ default:
+ ;
+ }
+
+ if( aSet.Count() )
+ rSh.SetFlyFrameAttr( aSet );
+ }
+ rSh.EndUndo();
+
+ GetView().GetViewFrame().GetBindings().Invalidate( SID_ANCHOR_MENU );
+ }
+ break;
+
+ case FN_FRAME_NOWRAP:
+ case FN_FRAME_WRAP:
+ case FN_FRAME_WRAP_IDEAL:
+ case FN_FRAME_WRAPTHRU:
+ case FN_FRAME_WRAPTHRU_TRANSP:
+ case FN_FRAME_WRAPTHRU_TOGGLE:
+ case FN_FRAME_WRAP_CONTOUR:
+ case FN_WRAP_ANCHOR_ONLY:
+ case FN_FRAME_WRAP_LEFT:
+ case FN_FRAME_WRAP_RIGHT:
+ SetWrapMode( nSlot );
+ break;
+
+ case FN_UPDATE_ALL_LINKS:
+ {
+ if( !rSh.GetLinkManager().GetLinks().empty() )
+ {
+ rSh.EnterStdMode();
+ rSh.StartAllAction();
+ rSh.GetLinkManager().UpdateAllLinks( false, false, nullptr );
+ rSh.EndAllAction();
+ }
+ }
+ break;
+
+ case FN_XFORMS_DESIGN_MODE:
+ if (pArgs && pArgs->GetItemState(nSlot, true, &pItem) == SfxItemState::SET)
+ {
+ if (const SfxBoolItem* pBoolItem = dynamic_cast<const SfxBoolItem*>(pItem))
+ {
+ bool bDesignMode = pBoolItem->GetValue();
+
+ // set from design mode
+ OSL_ENSURE( GetView().GetFormShell() != nullptr, "form shell?" );
+ SfxRequest aReq(GetView().GetViewFrame(), SID_FM_DESIGN_MODE);
+ aReq.AppendItem( SfxBoolItem( SID_FM_DESIGN_MODE, bDesignMode ) );
+ GetView().GetFormShell()->Execute( aReq );
+ aReq.Done();
+
+ // also set suitable view options
+ SwViewOption aViewOption = *rSh.GetViewOptions();
+ aViewOption.SetFormView( ! bDesignMode );
+ rSh.ApplyViewOptions( aViewOption );
+ }
+ }
+ break;
+
+ default:
+ bMore = true;
+ }
+
+
+ if(!bMore || !pArgs)
+ return;
+
+ pItem = nullptr;
+ pArgs->GetItemState(GetPool().GetWhich(nSlot), false, &pItem);
+ if(!pItem)
+ return;
+
+ switch(nSlot)
+ {
+ case SID_ATTR_BRUSH:
+ case SID_ATTR_BORDER_SHADOW:
+ case RES_SHADOW:
+ {
+ rSh.StartAllAction();
+ // Table cell(s) selected?
+ if ( rSh.IsTableMode() )
+ {
+ SwFrameFormat *pFormat = rSh.GetTableFormat();
+ pFormat->SetFormatAttr( *pItem );
+ }
+ else if ( rSh.IsFrameSelected() )
+ {
+ // Set border attributes via Frame-Manager.
+ SwFlyFrameAttrMgr aMgr( false, &rSh, Frmmgr_Type::NONE, nullptr );
+ aMgr.SetAttrSet( *pArgs );
+ aMgr.UpdateFlyFrame();
+ }
+ else
+ {
+ rSh.SetAttrSet( *pArgs );
+ }
+ rSh.EndAllAction();
+ }
+ break;
+ case FN_PAGE_STYLE_SET_LR_MARGIN:
+ case FN_PAGE_STYLE_SET_UL_MARGIN:
+ case FN_PAGE_STYLE_SET_NUMBER_FORMAT:
+ case FN_PAGE_STYLE_SET_PAPER_SIZE:
+ case FN_PAGE_STYLE_SET_PAPER_BIN:
+ {
+ OSL_FAIL("not implemented");
+ }
+ break;
+
+ case SID_ATTR_BORDER_OUTER:
+ {
+ // Table cell(s) selected?
+ if ( rSh.IsTableMode() )
+ {
+ // Set border attributes Get/SetTabBorders()
+ rSh.SetTabBorders(*pArgs);
+ }
+ else if ( rSh.IsFrameSelected() )
+ {
+ // Set border attributes via Frame-Manager.
+ SwFlyFrameAttrMgr aMgr( false, &rSh, Frmmgr_Type::NONE, nullptr );
+ aMgr.SetAttrSet(*pArgs);
+ aMgr.UpdateFlyFrame();
+ }
+ else
+ {
+ // Set border attributes via shell quite normally.
+ rSh.SetAttrItem( *pItem );
+ }
+ }
+ break;
+ default:
+ OSL_FAIL("wrong Dispatcher");
+ }
+}
+
+// Here the state for SID_IMAP / SID_CONTOUR will be handled
+// until the swapping of the graphic is finished.
+
+IMPL_LINK_NOARG(SwBaseShell, GraphicArrivedHdl, SwCursorShell&, void)
+{
+ SwWrtShell &rSh = GetShell();
+ if (CNT_GRF != rSh.SwEditShell::GetCntType())
+ return;
+ GraphicType const nGrfType(rSh.GetGraphicType());
+ if (GraphicType::NONE == nGrfType || m_aGrfUpdateSlots.empty())
+ return;
+
+ bool bProtect = FlyProtectFlags::NONE != rSh.IsSelObjProtected(FlyProtectFlags::Content|FlyProtectFlags::Parent);
+ SfxViewFrame& rVFrame = GetView().GetViewFrame();
+ for( const auto nSlot : m_aGrfUpdateSlots )
+ {
+ bool bSetState = false;
+ bool bState = false;
+ switch( nSlot )
+ {
+ case SID_IMAP:
+ case SID_IMAP_EXEC:
+ {
+ sal_uInt16 nId = SvxIMapDlgChildWindow::GetChildWindowId();
+ SfxChildWindow *pChildWindow = rVFrame.HasChildWindow(nId) ?
+ rVFrame.GetChildWindow(nId) : nullptr;
+ SvxIMapDlg *pDlg = pChildWindow ?
+ static_cast<SvxIMapDlg*>(pChildWindow->GetController().get()) : nullptr;
+
+ if( pDlg && ( SID_IMAP_EXEC == nSlot ||
+ ( SID_IMAP == nSlot && !bProtect)) &&
+ pDlg->GetEditingObject() != rSh.GetIMapInventor())
+ lcl_UpdateIMapDlg( rSh );
+
+ if( !bProtect && SID_IMAP == nSlot )
+ {
+ bSetState = true;
+ bState = nullptr != pDlg;
+ }
+ }
+ break;
+
+ case SID_CONTOUR_DLG:
+ if( !bProtect )
+ {
+ sal_uInt16 nId = SvxContourDlgChildWindow::GetChildWindowId();
+ SfxChildWindow *pChildWindow = rVFrame.HasChildWindow(nId) ?
+ rVFrame.GetChildWindow(nId) : nullptr;
+ SvxIMapDlg *pDlg = pChildWindow ?
+ static_cast<SvxIMapDlg*>(pChildWindow->GetController().get()) : nullptr;
+ if( pDlg && pDlg->GetEditingObject() !=
+ rSh.GetIMapInventor() )
+ lcl_UpdateContourDlg( rSh, SelectionType::Graphic );
+
+ bSetState = true;
+ bState = nullptr != pDlg;
+ }
+ break;
+
+ case FN_FRAME_WRAP_CONTOUR:
+ if( !bProtect )
+ {
+ SfxItemSetFixed<RES_SURROUND, RES_SURROUND> aSet(GetPool());
+ rSh.GetFlyFrameAttr(aSet);
+ const SwFormatSurround& rWrap = aSet.Get(RES_SURROUND);
+ bSetState = true;
+ bState = rWrap.IsContour();
+ }
+ break;
+
+ case SID_GRFFILTER:
+ case SID_GRFFILTER_INVERT:
+ case SID_GRFFILTER_SMOOTH:
+ case SID_GRFFILTER_SHARPEN:
+ case SID_GRFFILTER_REMOVENOISE:
+ case SID_GRFFILTER_SOBEL:
+ case SID_GRFFILTER_MOSAIC:
+ case SID_GRFFILTER_EMBOSS:
+ case SID_GRFFILTER_POSTER:
+ case SID_GRFFILTER_POPART:
+ case SID_GRFFILTER_SEPIA:
+ case SID_GRFFILTER_SOLARIZE:
+ bSetState = bState = GraphicType::Bitmap == nGrfType;
+ break;
+ }
+
+ if( bSetState )
+ {
+ SfxBoolItem aBool( nSlot, bState );
+ if( m_pGetStateSet )
+ m_pGetStateSet->Put( aBool );
+ else
+ rVFrame.GetBindings().SetState( aBool );
+ }
+ }
+ m_aGrfUpdateSlots.clear();
+}
+
+void SwBaseShell::GetState( SfxItemSet &rSet )
+{
+ SwWrtShell &rSh = GetShell();
+ SfxViewFrame& rVFrame = GetView().GetViewFrame();
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ m_pGetStateSet = &rSet;
+ while ( nWhich )
+ {
+ switch ( nWhich )
+ {
+ case SID_GALLERY_FORMATS:
+ if ( rSh.IsObjSelected() ||
+ (rSh.IsSelFrameMode() &&
+ !(rSh.GetSelectionType() & SelectionType::Graphic)) )
+ rSet.DisableItem( nWhich );
+ break;
+ case SID_GALLERY_ENABLE_ADDCOPY:
+ // #108230# allow copy from gallery in Writer AND Writer/Web!
+ rSet.Put( SfxBoolItem( SID_GALLERY_ENABLE_ADDCOPY, true ) );
+ break;
+ case FN_EDIT_REGION:
+ if( !rSh.IsAnySectionInDoc() )
+ rSet.DisableItem(nWhich);
+ break;
+
+ case FN_EDIT_CURRENT_REGION:
+ //tdf#112808 if cursor is in an index, don't show the edit section.
+ if( !rSh.GetCurrSection() ||
+ (rSh.GetCurrSection()->GetType() != SectionType::Content &&
+ rSh.GetCurrSection()->GetType() != SectionType::FileLink ))
+ {
+ rSet.DisableItem(nWhich);
+ }
+ break;
+
+ case FN_INSERT_REGION:
+ if( rSh.CursorInsideInputField()
+ || rSh.IsSelFrameMode()
+ || !rSh.IsInsRegionAvailable() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case FN_CONVERT_TABLE_TO_TEXT:
+ {
+ FrameTypeFlags eFrameType = rSh.GetFrameType(nullptr,true);
+ if( (eFrameType & FrameTypeFlags::FOOTNOTE) ||
+ !rSh.GetTableFormat() )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+ case FN_CONVERT_TEXT_TO_TABLE:
+ {
+ FrameTypeFlags eFrameType = rSh.GetFrameType(nullptr,true);
+ if( (eFrameType & FrameTypeFlags::FOOTNOTE) ||
+ !rSh.IsTextToTableAvailable() )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+ case FN_CONVERT_TEXT_TABLE:
+ {
+ FrameTypeFlags eFrameType = rSh.GetFrameType(nullptr,true);
+ if( (eFrameType & FrameTypeFlags::FOOTNOTE) ||
+ (!rSh.GetTableFormat() && !rSh.IsTextToTableAvailable() ) )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+ case RES_SHADOW:
+ {
+ SfxItemSetFixed<RES_SHADOW, RES_SHADOW> aSet( rSh.GetAttrPool());
+
+ // Table cell(s) selected?
+ if ( rSh.IsTableMode() )
+ {
+ SwFrameFormat *pFormat = rSh.GetTableFormat();
+ aSet.Put(pFormat->GetFormatAttr( nWhich ));
+ }
+ else if( rSh.IsFrameSelected() )
+ {
+ SwFlyFrameAttrMgr aMgr( false, &rSh, Frmmgr_Type::NONE, nullptr );
+ aSet.Put( aMgr.GetAttrSet() );
+ }
+ else
+ rSh.GetCurAttr( aSet );
+
+ const SvxShadowItem& rShItem = static_cast<const SvxShadowItem&>(aSet.Get(nWhich));
+ rSet.Put(rShItem);
+ }
+ break;
+ case SID_IMAP:
+ {
+ // #i59688#
+ // Improve efficiency:
+ // If selected object is protected, item has to disabled.
+ const bool bProtect = FlyProtectFlags::NONE != rSh.IsSelObjProtected(FlyProtectFlags::Content|FlyProtectFlags::Parent);
+ if ( bProtect )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ else
+ {
+ const sal_uInt16 nId = SvxIMapDlgChildWindow::GetChildWindowId();
+ const bool bHas = rVFrame.HasChildWindow( nId );
+ const bool bFrameSel = rSh.IsFrameSelected();
+ const bool bIsGraphicSelection =
+ rSh.GetSelectionType() == SelectionType::Graphic;
+
+ // #i59688#
+ // Avoid unnecessary loading of selected graphic.
+ // The graphic is only needed, if the dialog is open.
+ // If the swapping of the graphic is finished, the status
+ // must be determined asynchronously, until this the slot
+ // will be disabled.
+ if ( bHas && bIsGraphicSelection && rSh.IsLinkedGrfSwapOut() )
+ {
+ if( AddGrfUpdateSlot( nWhich ))
+ rSh.GetGraphic(false); // start the loading
+ }
+ else
+ {
+ if ( !bHas &&
+ ( !bFrameSel ||
+ ( bIsGraphicSelection &&
+ rSh.GetGraphicType() == GraphicType::NONE ) ) )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ else
+ {
+ SfxBoolItem aBool(nWhich, bHas);
+ if ( bHas && bFrameSel )
+ lcl_UpdateIMapDlg( rSh );
+ rSet.Put(aBool);
+ }
+ }
+ }
+ }
+ break;
+ case SID_IMAP_EXEC:
+ {
+ bool bDisable = false;
+ if( !rSh.IsFrameSelected())
+ bDisable = true;
+ sal_uInt16 nId = SvxIMapDlgChildWindow::GetChildWindowId();
+ if(!bDisable && rVFrame.HasChildWindow( nId ))
+ {
+ if(rSh.GetSelectionType() == SelectionType::Graphic
+ && rSh.IsLinkedGrfSwapOut())
+ {
+ if( AddGrfUpdateSlot( nWhich ))
+ rSh.GetGraphic(false); // start the loading
+ }
+ else
+ {
+ SvxIMapDlg *pDlg = GetIMapDlg(GetView());
+ if (pDlg && pDlg->GetEditingObject() != rSh.GetIMapInventor())
+ lcl_UpdateIMapDlg( rSh );
+ }
+ }
+ rSet.Put(SfxBoolItem(nWhich, bDisable));
+ }
+ break;
+
+ case FN_BACKSPACE:
+ case SID_DELETE:
+ if ( ( rSh.HasReadonlySel() && !rSh.CursorInsideInputField() )
+ || rSh.IsSelObjProtected( FlyProtectFlags::Content|FlyProtectFlags::Parent ) != FlyProtectFlags::NONE )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_CONTOUR_DLG:
+ {
+ bool bParentCntProt = FlyProtectFlags::NONE != rSh.IsSelObjProtected(FlyProtectFlags::Content|FlyProtectFlags::Parent );
+
+ if( bParentCntProt || 0 != (HTMLMODE_ON & ::GetHtmlMode(
+ GetView().GetDocShell() )) )
+ rSet.DisableItem( nWhich );
+ else
+ {
+ sal_uInt16 nId = SvxContourDlgChildWindow::GetChildWindowId();
+ bool bHas = GetView().GetViewFrame().HasChildWindow( nId );
+ SelectionType nSel = rSh.GetSelectionType();
+ bool bOk(nSel & (SelectionType::Graphic|SelectionType::Ole));
+
+ bool bDisable = false;
+ if( !bHas && !bOk )
+ bDisable = true;
+ // #i59688#
+ // Avoid unnecessary loading of selected graphic.
+ // The graphic is only needed, if the dialog is open.
+ // If the swapping of the graphic is finished, the status
+ // must be determined asynchronously, until this the slot
+ // will be disabled.
+ else if ( bHas && (nSel & SelectionType::Graphic) &&
+ rSh.IsLinkedGrfSwapOut() )
+ {
+ if( AddGrfUpdateSlot( nWhich ))
+ rSh.GetGraphic(false); // start the loading
+ // #i75481#
+ bDisable = true;
+ }
+ else if( bHas && bOk )
+ bDisable = !lcl_UpdateContourDlg( rSh, nSel );
+ else if( bOk )
+ {
+ // #i75481#
+ // apply fix #i59688# only for selected graphics
+ if ( nSel & SelectionType::Graphic )
+ bDisable = GraphicType::NONE == rSh.GetGraphicType();
+ else
+ bDisable = GraphicType::NONE == rSh.GetIMapGraphic().GetType();
+ }
+
+ if( bDisable )
+ rSet.DisableItem( nWhich );
+ else
+ rSet.Put( SfxBoolItem(nWhich, bHas) );
+ }
+ }
+ break;
+ case SID_CONTOUR_EXEC:
+ {
+ bool bDisable = false;
+ SelectionType nSel = rSh.GetSelectionType();
+ if( !(nSel & (SelectionType::Graphic|SelectionType::Ole)) )
+ bDisable = true;
+ sal_uInt16 nId = SvxContourDlgChildWindow::GetChildWindowId();
+ if( !bDisable && GetView().GetViewFrame().HasChildWindow( nId ))
+ {
+ SvxContourDlg *pDlg = GetContourDlg(GetView());
+ if (pDlg && pDlg->GetEditingObject() != rSh.GetIMapInventor())
+ bDisable = true;
+ }
+ rSet.Put(SfxBoolItem(nWhich, bDisable));
+ }
+ break;
+
+ case SID_ANCHOR_MENU:
+ case FN_TOOL_ANCHOR_PAGE:
+ case FN_TOOL_ANCHOR_PARAGRAPH:
+ case FN_TOOL_ANCHOR_CHAR:
+ case FN_TOOL_ANCHOR_AT_CHAR:
+ case FN_TOOL_ANCHOR_FRAME:
+ {
+ bool bObj = 0 != rSh.IsObjSelected();
+ bool bParentCntProt = rSh.IsSelObjProtected( FlyProtectFlags::Content|FlyProtectFlags::Parent ) != FlyProtectFlags::NONE;
+
+ if( !bParentCntProt && (bObj || rSh.IsFrameSelected()))
+ {
+ SfxItemSetFixed<RES_ANCHOR, RES_ANCHOR> aSet(GetPool());
+ if(bObj)
+ rSh.GetObjAttr(aSet);
+ else
+ rSh.GetFlyFrameAttr(aSet);
+ RndStdIds eSet = aSet.Get(RES_ANCHOR).GetAnchorId();
+ const bool bSet =
+ ((nWhich == FN_TOOL_ANCHOR_PAGE) &&
+ (eSet == RndStdIds::FLY_AT_PAGE))
+ || ((nWhich == FN_TOOL_ANCHOR_PARAGRAPH) &&
+ (eSet == RndStdIds::FLY_AT_PARA))
+ || ((nWhich == FN_TOOL_ANCHOR_FRAME) &&
+ (eSet == RndStdIds::FLY_AT_FLY))
+ || ((nWhich == FN_TOOL_ANCHOR_AT_CHAR) &&
+ (eSet == RndStdIds::FLY_AT_CHAR))
+ || ((nWhich == FN_TOOL_ANCHOR_CHAR) &&
+ (eSet == RndStdIds::FLY_AS_CHAR));
+
+ if( nWhich == FN_TOOL_ANCHOR_FRAME && !rSh.IsFlyInFly() )
+ rSet.DisableItem(nWhich);
+ else if(nWhich != SID_ANCHOR_MENU)
+ rSet.Put(SfxBoolItem(nWhich, bSet));
+
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ if (nWhich == FN_TOOL_ANCHOR_PAGE || nWhich == FN_TOOL_ANCHOR_FRAME)
+ {
+ rSet.DisableItem(nWhich);
+ }
+ }
+ }
+ else
+ rSet.DisableItem( nWhich );
+ }
+ break;
+ case FN_FRAME_NOWRAP:
+ case FN_FRAME_WRAP:
+ case FN_FRAME_WRAP_IDEAL:
+ case FN_FRAME_WRAPTHRU:
+ case FN_FRAME_WRAPTHRU_TRANSP:
+ case FN_FRAME_WRAPTHRU_TOGGLE:
+ case FN_FRAME_WRAP_CONTOUR:
+ case FN_WRAP_ANCHOR_ONLY:
+ case FN_FRAME_WRAP_LEFT:
+ case FN_FRAME_WRAP_RIGHT:
+ {
+ bool bObj = 0 != rSh.IsObjSelected();
+ bool bParentCntProt = rSh.IsSelObjProtected( FlyProtectFlags::Content|FlyProtectFlags::Parent ) != FlyProtectFlags::NONE;
+
+ if( !bParentCntProt && (bObj || rSh.IsFrameSelected()))
+ {
+ SfxItemSetFixed<RES_OPAQUE, RES_ANCHOR> aSet(GetPool());
+ RndStdIds nAnchorType;
+ if(bObj)
+ {
+ rSh.GetObjAttr(aSet);
+ nAnchorType = rSh.GetAnchorId();
+ }
+ else
+ {
+ rSh.GetFlyFrameAttr(aSet);
+ nAnchorType = aSet.Get(RES_ANCHOR).GetAnchorId();
+ }
+ const SwFormatSurround& rWrap = aSet.Get(RES_SURROUND);
+
+ const SvxOpaqueItem& rOpaque = aSet.Get(RES_OPAQUE);
+ bool bOpaque = rOpaque.GetValue();
+ css::text::WrapTextMode nSurround = rWrap.GetSurround();
+ bool bSet = false;
+
+ bool bDisable =
+ (nAnchorType == RndStdIds::UNKNOWN) || (nAnchorType == RndStdIds::FLY_AS_CHAR);
+ const bool bHtmlMode =
+ 0 != ::GetHtmlMode(GetView().GetDocShell());
+
+ switch( nWhich )
+ {
+ case FN_FRAME_NOWRAP:
+ bDisable |=
+ ( (nAnchorType != RndStdIds::FLY_AT_PARA)
+ && (nAnchorType != RndStdIds::FLY_AT_CHAR)
+ && (nAnchorType != RndStdIds::FLY_AT_PAGE));
+ bSet = nSurround == css::text::WrapTextMode_NONE;
+ break;
+ case FN_FRAME_WRAP:
+ bDisable |= bHtmlMode;
+ bSet = nSurround == css::text::WrapTextMode_PARALLEL;
+ break;
+ case FN_FRAME_WRAP_IDEAL:
+ bDisable |= bHtmlMode;
+ bSet = nSurround == css::text::WrapTextMode_DYNAMIC;
+ break;
+ case FN_FRAME_WRAPTHRU:
+ bDisable |= (bHtmlMode ||
+ ( (nAnchorType != RndStdIds::FLY_AT_PARA)
+ && (nAnchorType != RndStdIds::FLY_AT_CHAR)
+ && (nAnchorType != RndStdIds::FLY_AT_PAGE)));
+ if(bObj)
+ bSet = nSurround == css::text::WrapTextMode_THROUGH && rSh.GetLayerId();
+ else
+ bSet = nSurround == css::text::WrapTextMode_THROUGH && bOpaque;
+ break;
+ case FN_FRAME_WRAPTHRU_TRANSP:
+ case FN_FRAME_WRAPTHRU_TOGGLE:
+ bDisable |= bHtmlMode;
+ if(bObj)
+ bSet = nSurround == css::text::WrapTextMode_THROUGH && !rSh.GetLayerId();
+ else
+ bSet = nSurround == css::text::WrapTextMode_THROUGH && !bOpaque;
+ break;
+ case FN_FRAME_WRAP_CONTOUR:
+ bDisable |= bHtmlMode;
+ //no contour available when no wrap or wrap through is set
+ bDisable |= (nSurround == css::text::WrapTextMode_NONE || nSurround == css::text::WrapTextMode_THROUGH);
+ if( !bDisable )
+ {
+ SelectionType nSel = rSh.GetSelectionType();
+ if( (nSel & SelectionType::Graphic) &&
+ rSh.IsLinkedGrfSwapOut())
+ {
+ if( AddGrfUpdateSlot( nWhich ))
+ rSh.GetGraphic(false); // start the loading
+ }
+ else if( rSh.IsFrameSelected() )
+ {
+ // #i102253# applied patch from OD (see task)
+ bDisable =
+ nSel & SelectionType::Frame ||
+ GraphicType::NONE == rSh.GetIMapGraphic().GetType();
+ }
+ }
+ bSet = !bDisable && rWrap.IsContour();
+
+ break;
+ case FN_WRAP_ANCHOR_ONLY:
+ bDisable |= (bHtmlMode ||
+ (nAnchorType != RndStdIds::FLY_AT_PARA));
+ bSet = rWrap.IsAnchorOnly();
+ break;
+ case FN_FRAME_WRAP_LEFT:
+ bSet = nSurround == css::text::WrapTextMode_LEFT;
+ break;
+ case FN_FRAME_WRAP_RIGHT:
+ bSet = nSurround == css::text::WrapTextMode_RIGHT;
+ break;
+ }
+
+ if(bDisable)
+ rSet.DisableItem(nWhich);
+ else
+ rSet.Put(SfxBoolItem(nWhich, bSet));
+ }
+ else
+ rSet.DisableItem(nWhich);
+ }
+ break;
+ case FN_UPDATE_CHARTS:
+ if( !rSh.HasCharts() )
+ rSet.DisableItem( nWhich );
+ break;
+ case FN_UPDATE_ALL_LINKS:
+ if ( rSh.GetLinkManager().GetLinks().empty() )
+ rSet.DisableItem(nWhich);
+ break;
+ case FN_XFORMS_DESIGN_MODE:
+ // enable if in XForms document
+ if( rSh.GetDoc()->isXForms() )
+ {
+ // determine current state from view options
+ bool bValue = ! rSh.GetViewOptions()->IsFormView();
+ rSet.Put( SfxBoolItem( nWhich, bValue ) );
+ }
+ else
+ rSet.Put( SfxVisibilityItem( nWhich, false ) );
+ break;
+ case SID_GRAPHIC_SIZE_CHECK:
+ {
+ sal_Int32 nDPI = rSh.GetDoc()->getIDocumentSettingAccess().getImagePreferredDPI();
+ if (nDPI <= 0)
+ rSet.DisableItem(nWhich);
+ }
+ break;
+ case SID_THEME_DIALOG:
+ {
+ bool bDisable = true;
+ auto* pDocument = rSh.GetDoc();
+ auto* pDocumentShell = pDocument->GetDocShell();
+ if (pDocumentShell)
+ {
+ SdrModel* pModel = pDocument->getIDocumentDrawModelAccess().GetDrawModel();
+ if (pModel)
+ {
+ auto const& pTheme = pModel->getTheme();
+ if (pTheme)
+ bDisable = false;
+ }
+ }
+ if (bDisable)
+ rSet.DisableItem(nWhich);
+ }
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+ m_pGetStateSet = nullptr;
+}
+
+// Disable the slots with this status method
+
+void SwBaseShell::StateDisableItems( SfxItemSet &rSet )
+{
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+
+ while (nWhich)
+ {
+ rSet.DisableItem( nWhich );
+ nWhich = aIter.NextWhich();
+ }
+}
+
+// Disable the slots with this status method
+
+void SwBaseShell::StateStyle( SfxItemSet &rSet )
+{
+ bool bParentCntProt = GetShell().IsSelObjProtected( FlyProtectFlags::Content|FlyProtectFlags::Parent ) != FlyProtectFlags::NONE;
+ ShellMode eMode = GetView().GetShellMode();
+
+ if ( bParentCntProt ||
+ ShellMode::Draw == eMode ||
+ ShellMode::DrawForm == eMode ||
+ ShellMode::DrawText == eMode ||
+ ShellMode::Bezier == eMode )
+ {
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ rSet.DisableItem( nWhich );
+ nWhich = aIter.NextWhich();
+ }
+ }
+ else
+ GetView().GetDocShell()->StateStyleSheet(rSet, &GetShell());
+}
+
+void SwBaseShell::SetWrapMode( sal_uInt16 nSlot )
+{
+ SwWrtShell &rSh = GetShell();
+ bool bObj = 0 != rSh.IsObjSelected();
+ if( !bObj && !rSh.IsFrameSelected())
+ return;
+
+ SfxItemSetFixed<RES_OPAQUE, RES_SURROUND> aSet(GetPool());
+ if(bObj)
+ rSh.GetObjAttr(aSet);
+ else
+ rSh.GetFlyFrameAttr(aSet);
+ SwFormatSurround aWrap( aSet.Get(RES_SURROUND) );
+ css::text::WrapTextMode nOldSurround(aWrap.GetSurround());
+ css::text::WrapTextMode nSurround = css::text::WrapTextMode_PARALLEL;
+
+ switch (nSlot)
+ {
+ case FN_FRAME_NOWRAP:
+ nSurround = css::text::WrapTextMode_NONE;
+ if (aWrap.IsContour())
+ aWrap.SetContour(false);
+ break;
+ case FN_FRAME_WRAP_IDEAL:
+ nSurround = css::text::WrapTextMode_DYNAMIC;
+ break;
+ case FN_WRAP_ANCHOR_ONLY:
+ aWrap.SetAnchorOnly(!aWrap.IsAnchorOnly());
+
+ // keep previous wrapping
+
+ // switch to wrap css::text::WrapTextMode_PARALLEL, if previous wrap is css::text::WrapTextMode_NONE
+ if ( nOldSurround != css::text::WrapTextMode_NONE )
+ {
+ nSurround = nOldSurround;
+ }
+ break;
+ case FN_FRAME_WRAP_CONTOUR:
+ aWrap.SetContour(!aWrap.IsContour());
+ // Contour is meaningless in no-wrap or wrap-through context. Otherwise keep existing wrap.
+ if ( !aWrap.IsContour() ||
+ ( nOldSurround != css::text::WrapTextMode_NONE &&
+ nOldSurround != css::text::WrapTextMode_THROUGH ) )
+ {
+ nSurround = nOldSurround;
+ }
+ break;
+ case FN_FRAME_WRAPTHRU_TRANSP:
+ case FN_FRAME_WRAPTHRU_TOGGLE:
+ if (aWrap.IsContour())
+ aWrap.SetContour(false);
+ [[fallthrough]];
+ case FN_FRAME_WRAPTHRU:
+ nSurround = css::text::WrapTextMode_THROUGH;
+ break;
+
+ case FN_FRAME_WRAP_LEFT:
+ nSurround = css::text::WrapTextMode_LEFT;
+ break;
+
+ case FN_FRAME_WRAP_RIGHT:
+ nSurround = css::text::WrapTextMode_RIGHT;
+ break;
+
+ default:
+ break;
+ }
+ aWrap.SetSurround(nSurround);
+
+ if (nSlot != FN_FRAME_WRAP_CONTOUR)
+ {
+ // Defaulting the contour wrap on draw objects.
+ if (bObj && nOldSurround != nSurround &&
+ (nOldSurround == css::text::WrapTextMode_NONE || nOldSurround == css::text::WrapTextMode_THROUGH))
+ {
+ aWrap.SetContour(true);
+ }
+ }
+
+ aSet.Put( aWrap );
+
+ bool bOpaque = nSlot != FN_FRAME_WRAPTHRU_TRANSP && nSlot != FN_FRAME_WRAPTHRU_TOGGLE;
+ if( nSlot == FN_FRAME_WRAPTHRU_TOGGLE )
+ {
+ if( bObj )
+ bOpaque = !rSh.GetLayerId();
+ else
+ {
+ const SvxOpaqueItem& aOpaque( aSet.Get(RES_OPAQUE) );
+ bOpaque = !aOpaque.GetValue();
+ }
+ }
+ aSet.Put(SvxOpaqueItem(RES_OPAQUE, bOpaque ));
+
+ if(bObj)
+ {
+ rSh.SetObjAttr(aSet);
+ if ( bOpaque )
+ rSh.SelectionToHeaven();
+ else
+ rSh.SelectionToHell();
+ }
+ else
+ rSh.SetFlyFrameAttr(aSet);
+
+}
+
+//Force update of the status line
+
+void SwBaseShell::SetFrameMode(FlyMode eMode, SwWrtShell *pSh )
+{
+ s_eFrameMode = eMode;
+ SfxBindings &rBnd = pSh->GetView().GetViewFrame().GetBindings();
+
+ if( eMode == FLY_DRAG || pSh->IsFrameSelected() || pSh->IsObjSelected() )
+ {
+ const SfxPointItem aTmp1( SID_ATTR_POSITION, pSh->GetAnchorObjDiff());
+ const SvxSizeItem aTmp2( SID_ATTR_SIZE, pSh->GetObjSize());
+ rBnd.SetState( aTmp1 );
+ rBnd.SetState( aTmp2 );
+ }
+ else if( eMode == FLY_DRAG_END )
+ {
+ static sal_uInt16 aInval[] =
+ {
+ SID_ATTR_POSITION, SID_ATTR_SIZE, 0
+ };
+ rBnd.Invalidate(aInval);
+ }
+}
+
+SwBaseShell::SwBaseShell(SwView& rVw) :
+ SfxShell( &rVw ),
+ m_rView(rVw),
+ m_pGetStateSet(nullptr)
+{
+ SwWrtShell& rWrtSh = m_rView.GetWrtShell();
+
+ SetPool(&rWrtSh.GetAttrPool());
+ SetName("Base");
+ rWrtSh.SetGrfArrivedLnk( LINK( this, SwBaseShell, GraphicArrivedHdl));
+}
+
+SwBaseShell::~SwBaseShell()
+{
+ if( m_rView.GetCurShell() == this )
+ m_rView.ResetSubShell();
+
+ Link<SwCursorShell&,void> aTmp( LINK( this, SwBaseShell, GraphicArrivedHdl));
+ if( aTmp == m_rView.GetWrtShell().GetGrfArrivedLnk() )
+ m_rView.GetWrtShell().SetGrfArrivedLnk( Link<SwCursorShell&,void>() );
+}
+
+void SwBaseShell::ExecTextCtrl( SfxRequest& rReq )
+{
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ const sal_uInt16 nSlot = rReq.GetSlot();
+
+ if( pArgs)
+ {
+ SwWrtShell &rSh = GetShell();
+ std::unique_ptr<SvxScriptSetItem> pSSetItem;
+ SfxItemPool& rPool = rSh.GetAttrPool();
+ sal_uInt16 nWhich = rPool.GetWhich( nSlot );
+ SvtScriptType nScripts = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX;
+ SfxItemSetFixed<RES_CHRATR_FONTSIZE, RES_CHRATR_FONTSIZE,
+ RES_CHRATR_CJK_FONTSIZE, RES_CHRATR_CJK_FONTSIZE,
+ RES_CHRATR_CTL_FONTSIZE, RES_CHRATR_CTL_FONTSIZE>
+ aHeightSet( GetPool() );
+
+ switch( nSlot )
+ {
+ case SID_ATTR_CHAR_FONT:
+ {
+ nScripts = rSh.GetScriptType();
+ // #i42732# input language should be preferred over
+ // current cursor position to detect script type
+ if(!rSh.HasSelection())
+ {
+ LanguageType nInputLang = GetView().GetEditWin().GetInputLanguage();
+ if(nInputLang != LANGUAGE_DONTKNOW && nInputLang != LANGUAGE_SYSTEM)
+ nScripts = SvtLanguageOptions::GetScriptTypeOfLanguage( nInputLang );
+ }
+ [[fallthrough]];
+ }
+ case SID_ATTR_CHAR_POSTURE:
+ case SID_ATTR_CHAR_WEIGHT:
+ {
+ pSSetItem.reset(new SvxScriptSetItem( nSlot, rPool ));
+ pSSetItem->PutItemForScriptType( nScripts, pArgs->Get( nWhich ));
+ pArgs = &pSSetItem->GetItemSet();
+ }
+ break;
+ case SID_ATTR_CHAR_FONTHEIGHT:
+ {
+ if(rSh.HasSelection())
+ {
+ pSSetItem.reset(new SvxScriptSetItem( nSlot, rPool ));
+ pSSetItem->PutItemForScriptType( nScripts, pArgs->Get( nWhich ));
+ pArgs = &pSSetItem->GetItemSet();
+ }
+ else
+ {
+ nScripts = rSh.GetScriptType();
+ LanguageType nInputLang = GetView().GetEditWin().GetInputLanguage();
+ if(nInputLang != LANGUAGE_DONTKNOW && nInputLang != LANGUAGE_SYSTEM)
+ nScripts = SvtLanguageOptions::GetScriptTypeOfLanguage( nInputLang );
+ sal_uInt32 nHeight = static_cast< const SvxFontHeightItem& >(pArgs->Get( nWhich )).GetHeight();
+ SwStdFontConfig* pStdFont = SW_MOD()->GetStdFontConfig();
+
+ SfxItemSetFixed<RES_CHRATR_LANGUAGE, RES_CHRATR_LANGUAGE,
+ RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CJK_LANGUAGE,
+ RES_CHRATR_CTL_LANGUAGE, RES_CHRATR_CTL_LANGUAGE>
+ aLangSet( GetPool() );
+ rSh.GetCurAttr( aLangSet );
+
+ sal_Int32 nWesternSize =
+ pStdFont->GetFontHeight(FONT_STANDARD, FONT_GROUP_DEFAULT,
+ aLangSet.Get( RES_CHRATR_LANGUAGE).GetLanguage());
+ sal_Int32 nCJKSize =
+ pStdFont->GetFontHeight(FONT_STANDARD, FONT_GROUP_CJK,
+ aLangSet.Get( RES_CHRATR_CJK_LANGUAGE).GetLanguage());
+ sal_Int32 nCTLSize =
+ pStdFont->GetFontHeight(FONT_STANDARD, FONT_GROUP_CTL,
+ aLangSet.Get( RES_CHRATR_CTL_LANGUAGE).GetLanguage());
+
+ switch(nScripts)
+ {
+ case SvtScriptType::LATIN:
+ nCJKSize = nHeight * nCJKSize / nWesternSize;
+ nCTLSize = nHeight * nCTLSize / nWesternSize;
+ nWesternSize = static_cast<sal_Int32>(nHeight);
+ break;
+ case SvtScriptType::ASIAN:
+ nCTLSize = nHeight* nCTLSize / nCJKSize;
+ nWesternSize = nHeight * nWesternSize / nCJKSize;
+ nCJKSize = static_cast<sal_Int32>(nHeight);
+ break;
+ case SvtScriptType::COMPLEX:
+ nCJKSize = nHeight * nCJKSize / nCTLSize;
+ nWesternSize = nHeight * nWesternSize / nCTLSize;
+ nCTLSize = static_cast<sal_Int32>(nHeight);
+ break;
+ default: break;
+ }
+ aHeightSet.Put( SvxFontHeightItem( static_cast<sal_uInt32>(nWesternSize), 100, RES_CHRATR_FONTSIZE ));
+ aHeightSet.Put( SvxFontHeightItem( static_cast<sal_uInt32>(nCJKSize), 100, RES_CHRATR_CJK_FONTSIZE ));
+ aHeightSet.Put( SvxFontHeightItem( static_cast<sal_uInt32>(nCTLSize), 100, RES_CHRATR_CTL_FONTSIZE ));
+ pArgs = &aHeightSet;
+ }
+ }
+ break;
+ }
+
+ if( pArgs )
+ {
+ bool bAuto = false;
+ if ( !isCHRATR(nWhich) ||
+ ( rSh.HasSelection() && rSh.IsSelFullPara() ) )
+ {
+ SwTextFormatColl * pColl = rSh.GetCurTextFormatColl();
+ if ( pColl && pColl->IsAutoUpdateOnDirectFormat() )
+ {
+ rSh.AutoUpdatePara( pColl, *pArgs );
+ bAuto = true;
+ }
+ }
+
+ if (!bAuto)
+ {
+ rSh.SetAttrSet( *pArgs );
+ }
+ }
+ }
+ else
+ {
+ if (nSlot == SID_ATTR_CHAR_KERNING)
+ GetView().GetViewFrame().GetDispatcher()->Execute(SID_CHAR_DLG_POSITION);
+ else if (nSlot == SID_ATTR_CHAR_COLOR)
+ GetView().GetViewFrame().GetDispatcher()->Execute(SID_CHAR_DLG_EFFECT);
+ else
+ GetView().GetViewFrame().GetDispatcher()->Execute(SID_CHAR_DLG);
+ }
+ rReq.Done();
+}
+
+void SwBaseShell::GetTextCtrlState( SfxItemSet& rSet )
+{
+ SwWrtShell &rSh = GetShell();
+ rSh.GetCurAttr( rSet );
+}
+
+void SwBaseShell::GetTextFontCtrlState( SfxItemSet& rSet )
+{
+ SwWrtShell &rSh = GetShell();
+ bool bFirst = true;
+ std::optional<SfxItemSet> pFntCoreSet;
+ SvtScriptType nScriptType = SvtScriptType::LATIN;
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while( nWhich )
+ {
+ switch( nWhich )
+ {
+ case RES_CHRATR_FONT:
+ case RES_CHRATR_FONTSIZE:
+ case RES_CHRATR_WEIGHT:
+ case RES_CHRATR_POSTURE:
+ {
+ if( !pFntCoreSet )
+ {
+ pFntCoreSet.emplace( *rSet.GetPool(),
+ svl::Items<RES_CHRATR_BEGIN, RES_CHRATR_END-1> );
+ rSh.GetCurAttr( *pFntCoreSet );
+ nScriptType = rSh.GetScriptType();
+ // #i42732# input language should be preferred over
+ // current cursor position to detect script type
+ SwEditWin& rEditWin = GetView().GetEditWin();
+ if( rEditWin.IsUseInputLanguage() )
+ {
+ if(!rSh.HasSelection() && (
+ nWhich == RES_CHRATR_FONT ||
+ nWhich == RES_CHRATR_FONTSIZE ))
+ {
+ LanguageType nInputLang = rEditWin.GetInputLanguage();
+ if(nInputLang != LANGUAGE_DONTKNOW && nInputLang != LANGUAGE_SYSTEM)
+ nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( nInputLang );
+ }
+ }
+ }
+ SfxItemPool& rPool = *rSet.GetPool();
+ SvxScriptSetItem aSetItem( rPool.GetSlotId( nWhich ), rPool );
+ aSetItem.GetItemSet().Put( *pFntCoreSet, false );
+ const SfxPoolItem* pI = aSetItem.GetItemOfScript( nScriptType );
+ if( pI )
+ {
+ rSet.Put( pI->CloneSetWhich(nWhich) );
+ }
+ else
+ rSet.InvalidateItem( nWhich );
+ // Set input context of the SwEditWin according to the selected font and script type
+ if(RES_CHRATR_FONT == nWhich)
+ {
+ vcl::Font aFont;
+ if (const SvxFontItem* pFontItem = dynamic_cast<const SvxFontItem*>(pI))
+ {
+ aFont.SetFamilyName(pFontItem->GetFamilyName());
+ aFont.SetStyleName(pFontItem->GetStyleName());
+ aFont.SetFamily(pFontItem->GetFamily());
+ aFont.SetPitch(pFontItem->GetPitch());
+ aFont.SetCharSet(pFontItem->GetCharSet());
+ }
+
+ bool bVertical = rSh.IsInVerticalText();
+ aFont.SetOrientation(Degree10(bVertical ? 2700 : 0));
+ aFont.SetVertical(bVertical);
+ GetView().GetEditWin().SetInputContext( InputContext( aFont, InputContextFlags::Text |
+ InputContextFlags::ExtText ) );
+ }
+ }
+ break;
+
+ default:
+ if( bFirst )
+ {
+ rSh.GetCurAttr( rSet );
+ bFirst = false;
+ }
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void SwBaseShell::GetBckColState(SfxItemSet &rSet)
+{
+ SwWrtShell &rSh = GetShell();
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich(aIter.FirstWhich());
+ SelectionType nSelType(rSh.GetSelectionType());
+ std::unique_ptr<SvxBrushItem> aBrushItem(std::make_unique<SvxBrushItem>(RES_BACKGROUND));
+
+ if( nWhich == SID_TABLE_CELL_BACKGROUND_COLOR )
+ {
+ rSh.GetBoxBackground( aBrushItem );
+ }
+ else
+ {
+ // Adapt to new DrawingLayer FillStyle; use a parent which has XFILL_NONE set
+ SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aCoreSet(GetPool());
+
+ aCoreSet.SetParent(&GetView().GetDocShell()->GetDoc()->GetDfltFrameFormat()->GetAttrSet());
+
+ if(nSelType & SelectionType::Graphic || SelectionType::Frame & nSelType)
+ {
+ rSh.GetFlyFrameAttr(aCoreSet);
+ }
+ else
+ {
+ rSh.GetCurAttr(aCoreSet);
+ }
+
+ aBrushItem = getSvxBrushItemFromSourceSet(aCoreSet, RES_BACKGROUND);
+ }
+
+ while(nWhich)
+ {
+ switch(nWhich)
+ {
+ case SID_BACKGROUND_COLOR:
+ case SID_TABLE_CELL_BACKGROUND_COLOR:
+ {
+ SvxColorItem aColorItem(aBrushItem->GetColor(), aBrushItem->getComplexColor(), nWhich);
+ rSet.Put(aColorItem);
+ break;
+ }
+ case SID_ATTR_BRUSH:
+ case RES_BACKGROUND:
+ {
+ // if this was intended to have a independent copy of the Item to be set
+ // this is not needed due to the ItemSet/Pool cloning Items which get set anyways.
+ // Keeping code as reference - it may have had other reasons I do notz see (?!?)
+ // std::unique_ptr<SfxPoolItem> pNewItem(aBrushItem.CloneSetWhich(GetPool().GetWhich(nWhich)));
+ rSet.Put(*aBrushItem);
+ break;
+ }
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void SwBaseShell::ExecBckCol(SfxRequest& rReq)
+{
+ SwWrtShell &rSh = GetShell();
+ SelectionType nSelType(rSh.GetSelectionType());
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ sal_uInt16 nSlot(rReq.GetSlot());
+
+ if (!pArgs && nSlot != SID_BACKGROUND_COLOR && nSlot != SID_TABLE_CELL_BACKGROUND_COLOR)
+ {
+ return;
+ }
+
+ std::unique_ptr<SvxBrushItem> aBrushItem(std::make_unique<SvxBrushItem>(RES_BACKGROUND));
+
+ if ( nSlot == SID_TABLE_CELL_BACKGROUND_COLOR )
+ {
+ rSh.GetBoxBackground( aBrushItem );
+ }
+ else
+ {
+ // Adapt to new DrawingLayer FillStyle; use a parent which has XFILL_NONE set
+ SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aCoreSet(GetPool());
+
+ aCoreSet.SetParent(&GetView().GetDocShell()->GetDoc()->GetDfltFrameFormat()->GetAttrSet());
+
+ if((SelectionType::Frame & nSelType) || (SelectionType::Graphic & nSelType))
+ {
+ rSh.GetFlyFrameAttr(aCoreSet);
+ }
+ else
+ {
+ rSh.GetCurAttr(aCoreSet);
+ }
+
+ aBrushItem = getSvxBrushItemFromSourceSet(aCoreSet, RES_BACKGROUND);
+ }
+
+ switch(nSlot)
+ {
+ case SID_BACKGROUND_COLOR:
+ case SID_TABLE_CELL_BACKGROUND_COLOR:
+ {
+ bool bIsTransparent = false;
+
+ aBrushItem->SetGraphicPos(GPOS_NONE);
+
+ sal_uInt16 nSlotId = (nSlot == SID_BACKGROUND_COLOR) ? SID_BACKGROUND_COLOR : SID_TABLE_CELL_BACKGROUND_COLOR;
+ if (pArgs)
+ {
+ const SvxColorItem& rNewColorItem = static_cast<const SvxColorItem&>(pArgs->Get(nSlotId));
+ aBrushItem->SetColor(rNewColorItem.GetValue());
+ aBrushItem->setComplexColor(rNewColorItem.getComplexColor());
+ GetView().GetViewFrame().GetBindings().SetState(rNewColorItem);
+ }
+ else
+ {
+ bIsTransparent = true;
+ }
+
+ if (bIsTransparent)
+ {
+ aBrushItem->SetColor(COL_TRANSPARENT);
+ rReq.AppendItem(SvxColorItem(COL_TRANSPARENT,nSlot));
+ }
+ break;
+ }
+
+ case SID_ATTR_BRUSH:
+ case RES_BACKGROUND:
+ {
+ assert(pArgs && "only SID_BACKGROUND_COLOR can have !pArgs, checked at entry");
+ aBrushItem.reset(static_cast<SvxBrushItem*>(pArgs->Get(GetPool().GetWhich(nSlot)).Clone()));
+ break;
+ }
+ default:
+ {
+ rReq.Ignore();
+ OSL_FAIL("unknown message in ExecuteAttr!" );
+ return;
+ }
+ }
+
+ if ( nSlot == SID_TABLE_CELL_BACKGROUND_COLOR )
+ {
+ rSh.SetBoxBackground( *aBrushItem );
+ }
+ else
+ {
+ // Adapt to new DrawingLayer FillStyle; use a parent which has XFILL_NONE set
+ SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aCoreSet(GetPool());
+
+ aCoreSet.SetParent(&GetView().GetDocShell()->GetDoc()->GetDfltFrameFormat()->GetAttrSet());
+ setSvxBrushItemAsFillAttributesToTargetSet(*aBrushItem, aCoreSet);
+
+ if((SelectionType::Frame & nSelType) || (SelectionType::Graphic & nSelType))
+ {
+ // Template autoupdate
+ SwFrameFormat* pFormat = rSh.GetSelectedFrameFormat();
+
+ if(pFormat && pFormat->IsAutoUpdateOnDirectFormat())
+ {
+ rSh.AutoUpdateFrame(pFormat, aCoreSet);
+ }
+ else
+ {
+ rSh.SetFlyFrameAttr(aCoreSet);
+ }
+ }
+ else
+ {
+ SwTextFormatColl* pColl = rSh.GetCurTextFormatColl();
+
+ if(pColl && pColl->IsAutoUpdateOnDirectFormat())
+ {
+ rSh.AutoUpdatePara(pColl, aCoreSet);
+ }
+ else
+ {
+ rSh.SetAttrSet(aCoreSet);
+ }
+ }
+ }
+
+ rReq.Done();
+}
+
+void SwBaseShell::GetBorderState(SfxItemSet &rSet)
+{
+ SwWrtShell &rSh = GetShell();
+ // Table cell(s) selected?
+ bool bPrepare = true;
+ bool bTableMode = rSh.IsTableMode();
+ if ( bTableMode )
+ {
+ SfxItemSetFixed<RES_BOX, RES_BOX,
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER> aCoreSet( GetPool() );
+ SvxBoxInfoItem aBoxInfo( SID_ATTR_BORDER_INNER );
+ aCoreSet.Put( aBoxInfo );
+ rSh.GetTabBorders( aCoreSet );
+ rSet.Put( aCoreSet );
+ }
+ else if ( rSh.IsFrameSelected() )
+ {
+ SwFlyFrameAttrMgr aMgr( false, &rSh, Frmmgr_Type::NONE, nullptr );
+ rSet.Put( aMgr.GetAttrSet() );
+ bPrepare = false;
+ }
+ else
+ // Get border attributes via shell quite normal
+ rSh.GetCurAttr( rSet );
+ if ( bPrepare )
+ ::PrepareBoxInfo( rSet, rSh );
+ // Switch the border toolbox controller mode
+ rSet.Put( SfxBoolItem( SID_BORDER_REDUCED_MODE, !bTableMode ));
+}
+
+void SwBaseShell::ExecDlg(SfxRequest &rReq)
+{
+ SwWrtShell &rSh = GetShell();
+ weld::Window* pMDI = GetView().GetFrameWeld();
+ // So that from the basic no dialogues for the background views are called:
+ bool bBackground = (&GetView() != GetActiveView());
+ const SfxPoolItem* pItem = nullptr;
+ const SfxItemSet* pArgs = rReq.GetArgs();
+
+ sal_uInt16 nSlot = rReq.GetSlot();
+ const SfxItemSet* pOutSet = nullptr;
+ bool bDone = false;
+ if(pArgs)
+ pArgs->GetItemState( GetPool().GetWhich(nSlot), false, &pItem );
+
+ switch ( nSlot )
+ {
+ case FN_FORMAT_TITLEPAGE_DLG:
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateTitlePageDlg(pMDI));
+ VclAbstractDialog::AsyncContext aContext;
+ aContext.maEndDialogFn = [](sal_Int32){};
+ pDlg->StartExecuteAsync(aContext);
+ }
+ break;
+ case FN_FORMAT_PAGE_DLG:
+ case FN_FORMAT_PAGE_COLUMN_DLG:
+ case FN_FORMAT_PAGE_SETTING_DLG:
+ case FN_FORMAT_PAGE_AREA_DLG:
+ {
+ if( !bBackground )
+ {
+ const size_t nCurIdx = rSh.GetCurPageDesc();
+ const SwPageDesc& rPageDesc = rSh.GetPageDesc( nCurIdx );
+ // Temporary view, because the shell does not need to be valid after the dialog
+ // for example disable header
+ SwView& rTempView = GetView();
+
+ OUString sPageId;
+ switch (nSlot)
+ {
+ case FN_FORMAT_PAGE_COLUMN_DLG:
+ sPageId = "columns";
+ break;
+ case FN_FORMAT_PAGE_SETTING_DLG:
+ sPageId = "page";
+ break;
+ case FN_FORMAT_PAGE_AREA_DLG:
+ sPageId = "area";
+ break;
+ case FN_FORMAT_PAGE_DLG:
+ if (pItem)
+ sPageId = static_cast<const SfxStringItem*>(pItem)->GetValue();
+ break;
+ }
+ rTempView.GetDocShell()->FormatPage(rReq.GetFrameWeld(), rPageDesc.GetName(), sPageId, rSh, &rReq);
+ rTempView.InvalidateRulerPos();
+
+ bDone = true; // FormatPage() takes care of calling Done()
+ }
+ }
+ break;
+ case FN_FORMAT_BORDER_DLG:
+ {
+ SfxItemSetFixed<RES_BOX , RES_SHADOW,
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER> aSet( rSh.GetAttrPool() );
+ ScopedVclPtr<SfxAbstractDialog> pDlg;
+ // Table cell(s) selected?
+ if ( rSh.IsTableMode() )
+ {
+ // Set border attributes Get/SetTabBorders()
+ ::PrepareBoxInfo( aSet, rSh );
+ rSh.GetTabBorders( aSet );
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ pDlg.disposeAndReset(pFact->CreateSwBorderDlg(pMDI, aSet, SwBorderModes::TABLE));
+ if ( pDlg->Execute() == RET_OK )
+ {
+ rSh.SetTabBorders( *pDlg->GetOutputItemSet() );
+ pOutSet = pDlg->GetOutputItemSet();
+ }
+ }
+ else if ( rSh.IsFrameSelected() )
+ {
+ // Set border attributes via Frame-Manager
+ SwFlyFrameAttrMgr aMgr( false, &rSh, Frmmgr_Type::NONE, nullptr );
+ aSet.Put( aMgr.GetAttrSet() );
+
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ pDlg.disposeAndReset(pFact->CreateSwBorderDlg(pMDI, aSet, SwBorderModes::FRAME));
+ if ( pDlg->Execute() == RET_OK )
+ {
+ aMgr.SetAttrSet( *pDlg->GetOutputItemSet() );
+ aMgr.UpdateFlyFrame();
+ pOutSet = pDlg->GetOutputItemSet();
+ }
+ }
+ else
+ {
+ // Set border attributes via Shell quite normal
+ rSh.GetCurAttr( aSet );
+ ::PrepareBoxInfo( aSet, rSh );
+
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ pDlg.disposeAndReset(pFact->CreateSwBorderDlg(pMDI, aSet, SwBorderModes::PARA));
+ if ( pDlg->Execute() == RET_OK )
+ {
+ rSh.SetAttrSet( *pDlg->GetOutputItemSet() );
+ pOutSet = pDlg->GetOutputItemSet();
+ }
+ }
+ if(pOutSet)
+ {
+ rReq.Done(*pOutSet);
+ bDone = true;
+ }
+ }
+ break;
+ case FN_FORMAT_BACKGROUND_DLG:
+ {
+ SfxItemSetFixed<RES_BACKGROUND, RES_BACKGROUND,
+ XATTR_FILL_FIRST, XATTR_FILL_LAST> aSet( rSh.GetAttrPool() );
+
+ ScopedVclPtr<SfxAbstractDialog> pDlg;
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+
+ // Table cell(s) selected?
+ if ( rSh.IsTableMode() )
+ {
+ // Get background attributes of the table and put it in the set
+ // tdf#144843 calling GetBoxBackground *requires* an incarnation to be handed over
+ std::unique_ptr<SvxBrushItem> aBrush(std::make_unique<SvxBrushItem>(RES_BACKGROUND));
+ rSh.GetBoxBackground( aBrush );
+ pDlg.disposeAndReset(pFact->CreateSwBackgroundDialog(pMDI, aSet));
+ aSet.Put( std::move(aBrush) );
+ if ( pDlg->Execute() == RET_OK )
+ {
+
+ rSh.SetBoxBackground( pDlg->GetOutputItemSet()->Get( RES_BACKGROUND ) );
+ pOutSet = pDlg->GetOutputItemSet();
+ }
+ }
+ else if ( rSh.IsFrameSelected() )
+ {
+
+ rSh.GetFlyFrameAttr( aSet );
+
+ pDlg.disposeAndReset(pFact->CreateSwBackgroundDialog(pMDI, aSet));
+ if ( pDlg->Execute() == RET_OK )
+ {
+ rSh.SetFlyFrameAttr(const_cast<SfxItemSet &>(*pDlg->GetOutputItemSet()) );
+ pOutSet = pDlg->GetOutputItemSet();
+ }
+ }
+ else
+ {
+ // Set border attributes Umrandungsattribute with the shell quite normal.
+ rSh.GetCurAttr( aSet );
+
+ pDlg.disposeAndReset(pFact->CreateSwBackgroundDialog(pMDI, aSet));
+ if ( pDlg->Execute() == RET_OK )
+ {
+ rSh.SetAttrSet( *pDlg->GetOutputItemSet() );
+ pOutSet = pDlg->GetOutputItemSet();
+ }
+ }
+ if(pOutSet)
+ {
+ rReq.Done(*pOutSet);
+ bDone = true;
+ }
+ }
+ break;
+
+ case SID_GRAPHIC_SIZE_CHECK:
+ {
+ sw::GraphicSizeCheckGUIResult aResult(rSh.GetDoc());
+ svx::GenericCheckDialog aDialog(pMDI, aResult);
+ aDialog.run();
+ }
+ break;
+
+ case SID_THEME_DIALOG:
+ {
+ auto* pDocument = rSh.GetDoc();
+ auto* pDocumentShell = pDocument->GetDocShell();
+ if (pDocumentShell)
+ {
+ SdrModel* pModel = pDocument->getIDocumentDrawModelAccess().GetDrawModel();
+ auto const& pTheme = pModel->getTheme();
+ if (pTheme)
+ {
+ std::shared_ptr<svx::IThemeColorChanger> pChanger(new sw::ThemeColorChanger(pDocumentShell));
+ auto pDialog = std::make_shared<svx::ThemeDialog>(pMDI, pTheme.get());
+ weld::DialogController::runAsync(pDialog, [pDialog, pChanger](sal_uInt32 nResult) {
+ if (RET_OK != nResult)
+ return;
+
+ auto pColorSet = pDialog->getCurrentColorSet();
+ if (pColorSet)
+ {
+ pChanger->apply(pColorSet);
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ svx::ThemeColorPaletteManager aManager(pColorSet);
+ SfxLokHelper::notifyAllViews(LOK_CALLBACK_COLOR_PALETTES, aManager.generateJSON());
+ }
+ }
+ });
+ }
+ }
+ }
+ break;
+
+ default:OSL_FAIL("wrong Dispatcher (basesh.cxx)");
+ }
+ if(!bDone)
+ rReq.Done();
+}
+
+SwWrtShell& SwBaseShell::GetShell()
+{
+ return m_rView.GetWrtShell();
+}
+
+SwWrtShell* SwBaseShell::GetShellPtr()
+{
+ return m_rView.GetWrtShellPtr();
+}
+
+static void EndUndo(SwWrtShell& rSh)
+{
+ SwRewriter aRewriter;
+
+ if (rSh.GetTableFormat())
+ {
+ aRewriter.AddRule(UndoArg1, SwResId(STR_START_QUOTE));
+ aRewriter.AddRule(UndoArg2, rSh.GetTableFormat()->GetName());
+ aRewriter.AddRule(UndoArg3, SwResId(STR_END_QUOTE));
+
+ }
+ rSh.EndUndo(SwUndoId::INSTABLE, &aRewriter); // If possible change the Shell
+}
+
+static void InsertTableImpl(SwWrtShell& rSh,
+ SwView &rTempView,
+ const OUString& aTableName,
+ sal_uInt16 nRows,
+ sal_uInt16 nCols,
+ SwInsertTableOptions aInsTableOpts,
+ const OUString& aAutoName,
+ const std::unique_ptr<SwTableAutoFormat>& pTAFormat)
+{
+ rSh.StartUndo(SwUndoId::INSTABLE);
+
+ rSh.StartAllAction();
+ if( rSh.HasSelection() )
+ rSh.DelRight();
+
+ rSh.InsertTable( aInsTableOpts, nRows, nCols, pTAFormat.get() );
+ rSh.MoveTable( GotoPrevTable, fnTableStart );
+
+ if( !aTableName.isEmpty() && !rSh.GetTableStyle( aTableName ) )
+ rSh.GetTableFormat()->SetFormatName( aTableName );
+
+ if( pTAFormat != nullptr && !aAutoName.isEmpty()
+ && aAutoName != SwViewShell::GetShellRes()->aStrNone )
+ {
+ SwTableNode* pTableNode = const_cast<SwTableNode*>( rSh.IsCursorInTable() );
+ if ( pTableNode )
+ {
+ pTableNode->GetTable().SetTableStyleName( aAutoName );
+ SwUndoTableAutoFormat* pUndo = new SwUndoTableAutoFormat( *pTableNode, *pTAFormat );
+ if ( pUndo )
+ rSh.GetIDocumentUndoRedo().AppendUndo( std::unique_ptr<SwUndo>(pUndo) );
+ }
+ }
+
+ rSh.EndAllAction();
+ rTempView.AutoCaption(TABLE_CAP);
+}
+
+void SwBaseShell::InsertTable( SfxRequest& _rRequest )
+{
+ const SfxItemSet* pArgs = _rRequest.GetArgs();
+ SwWrtShell& rSh = GetShell();
+
+ if ( rSh.GetFrameType( nullptr, true ) & FrameTypeFlags::FOOTNOTE )
+ return;
+
+ SwView &rTempView = GetView(); // Because GetView() does not work after the shell exchange
+ bool bHTMLMode = 0 != (::GetHtmlMode(rTempView.GetDocShell())&HTMLMODE_ON);
+ bool bCallEndUndo = false;
+
+ if( !pArgs && rSh.IsSelection() && !rSh.IsInClickToEdit() &&
+ !rSh.IsTableMode() )
+ {
+ const SwModuleOptions* pModOpt = SW_MOD()->GetModuleConfig();
+ SwInsertTableOptions aInsTableOpts = pModOpt->GetInsTableFlags(bHTMLMode);
+
+ rSh.StartUndo(SwUndoId::INSTABLE);
+ bCallEndUndo = true;
+
+ bool bInserted = rSh.TextToTable( aInsTableOpts, '\t' );
+ rSh.EnterStdMode();
+ if (bInserted)
+ rTempView.AutoCaption(TABLE_CAP);
+ _rRequest.Done();
+ }
+ else
+ {
+ sal_uInt16 nColsIn = 0;
+ sal_uInt16 nRowsIn = 0;
+ SwInsertTableOptions aInsTableOptsIn( SwInsertTableFlags::All, 1 );
+ OUString aTableNameIn;
+ OUString aAutoNameIn;
+ std::unique_ptr<SwTableAutoFormat> pTAFormatIn;
+
+ if( pArgs && pArgs->Count() >= 2 )
+ {
+ const SfxStringItem* pName = _rRequest.GetArg<SfxStringItem>(FN_INSERT_TABLE);
+ const SfxUInt16Item* pCols = _rRequest.GetArg<SfxUInt16Item>(SID_ATTR_TABLE_COLUMN);
+ const SfxUInt16Item* pRows = _rRequest.GetArg<SfxUInt16Item>(SID_ATTR_TABLE_ROW);
+ const SfxInt32Item* pFlags = _rRequest.GetArg<SfxInt32Item>(FN_PARAM_1);
+ const SfxStringItem* pAuto = _rRequest.GetArg<SfxStringItem>(FN_PARAM_2);
+
+ if ( pName )
+ aTableNameIn = pName->GetValue();
+ if ( pCols )
+ nColsIn = pCols->GetValue();
+ if ( pRows )
+ nRowsIn = pRows->GetValue();
+ if ( pAuto )
+ {
+ aAutoNameIn = pAuto->GetValue();
+ if ( !aAutoNameIn.isEmpty() )
+ {
+ SwTableAutoFormatTable aTableTable;
+ aTableTable.Load();
+ for ( size_t n=0; n<aTableTable.size(); n++ )
+ {
+ if ( aTableTable[n].GetName() == aAutoNameIn )
+ {
+ pTAFormatIn.reset(new SwTableAutoFormat( aTableTable[n] ));
+ break;
+ }
+ }
+ }
+ }
+
+ if ( pFlags )
+ aInsTableOptsIn.mnInsMode = static_cast<SwInsertTableFlags>(pFlags->GetValue());
+ else
+ {
+ const SwModuleOptions* pModOpt = SW_MOD()->GetModuleConfig();
+ aInsTableOptsIn = pModOpt->GetInsTableFlags(bHTMLMode);
+ }
+ }
+
+ if( !nColsIn || !nRowsIn )
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ std::shared_ptr<AbstractInsTableDlg> pAbstractDialog(pFact->CreateInsTableDlg(rTempView));
+ std::shared_ptr<weld::DialogController> pDialogController(pAbstractDialog->getDialogController());
+
+ weld::DialogController::runAsync(pDialogController,
+ [pAbstractDialog, &rSh, &rTempView, aTableNameIn, nRowsIn, nColsIn, aInsTableOptsIn, aAutoNameIn] (sal_Int32 nResult) {
+ if( RET_OK == nResult )
+ {
+ sal_uInt16 nCols = nColsIn;
+ sal_uInt16 nRows = nRowsIn;
+ SwInsertTableOptions aInsTableOpts = aInsTableOptsIn;
+ OUString aTableName = aTableNameIn;
+ OUString aAutoName = aAutoNameIn;
+ std::unique_ptr<SwTableAutoFormat> pTAFormat;
+
+ pAbstractDialog->GetValues( aTableName, nRows, nCols, aInsTableOpts, aAutoName, pTAFormat );
+
+ if( nCols && nRows )
+ {
+ InsertTableImpl( rSh, rTempView, aTableName, nRows, nCols, aInsTableOpts, aAutoName, pTAFormat );
+ EndUndo(rSh);
+ }
+ }
+ }
+ );
+ }
+ else
+ {
+ // record before shell change
+ _rRequest.AppendItem( SfxStringItem( FN_INSERT_TABLE, aTableNameIn ) );
+ if ( !aAutoNameIn.isEmpty() )
+ _rRequest.AppendItem( SfxStringItem( FN_PARAM_2, aAutoNameIn ) );
+ _rRequest.AppendItem( SfxUInt16Item( SID_ATTR_TABLE_COLUMN, nColsIn ) );
+ _rRequest.AppendItem( SfxUInt16Item( SID_ATTR_TABLE_ROW, nRowsIn ) );
+ _rRequest.AppendItem( SfxInt32Item( FN_PARAM_1, static_cast<sal_Int32>(aInsTableOptsIn.mnInsMode) ) );
+ _rRequest.Done();
+
+ InsertTableImpl( rSh, rTempView, aTableNameIn, nRowsIn, nColsIn, aInsTableOptsIn, aAutoNameIn, pTAFormatIn );
+
+ bCallEndUndo = true;
+ }
+ }
+
+ if( bCallEndUndo )
+ EndUndo(rSh);
+}
+
+void SwBaseShell::GetGalleryState( SfxItemSet &rSet )
+{
+ SwWrtShell &rSh = GetShell();
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ switch ( nWhich )
+ {
+ case SID_GALLERY_BG_BRUSH:
+ {
+ SelectionType nSel = rSh.GetSelectionType();
+ SfxStringListItem aLst( nWhich );
+ std::vector<OUString> &rLst = aLst.GetList();
+ nParagraphPos = nGraphicPos = nOlePos = nFramePos = nTablePos =
+ nTableRowPos = nTableCellPos = nPagePos =
+ nHeaderPos = nFooterPos = 0;
+ sal_uInt8 nPos = 1;
+ rLst.push_back( SwResId( STR_SWBG_PAGE ) );
+ nPagePos = nPos++;
+ sal_uInt16 nHtmlMode = ::GetHtmlMode(GetView().GetDocShell());
+ bool bHtmlMode = 0 != (nHtmlMode & HTMLMODE_ON);
+
+ if ( (!bHtmlMode || (nHtmlMode & HTMLMODE_FULL_STYLES)) &&
+ (nSel & SelectionType::Text) )
+ {
+ rLst.push_back( SwResId( STR_SWBG_PARAGRAPH ) );
+ nParagraphPos = nPos++;
+ }
+ if ( (!bHtmlMode || (nHtmlMode & HTMLMODE_SOME_STYLES)) &&
+ nSel & (SelectionType::Table|SelectionType::TableCell) )
+ {
+ rLst.push_back( SwResId( STR_SWBG_TABLE ) );
+ nTablePos = nPos++;
+
+ if(!bHtmlMode)
+ {
+ rLst.push_back( SwResId( STR_SWBG_TABLE_ROW ) );
+ nTableRowPos = nPos++;
+ }
+
+ rLst.push_back( SwResId( STR_SWBG_TABLE_CELL) );
+ nTableCellPos = nPos++;
+ }
+ if(!bHtmlMode)
+ {
+ if ( nSel & SelectionType::Frame )
+ {
+ rLst.push_back( SwResId( STR_SWBG_FRAME ) );
+ nFramePos = nPos++;
+ }
+ if ( nSel & SelectionType::Graphic )
+ {
+ rLst.push_back( SwResId( STR_SWBG_GRAPHIC ) );
+ nGraphicPos = nPos++;
+ }
+ if ( nSel & SelectionType::Ole )
+ {
+ rLst.push_back( SwResId( STR_SWBG_OLE ) );
+ nOlePos = nPos++;
+ }
+ const FrameTypeFlags nType = rSh.GetFrameType(nullptr,true);
+ if ( nType & FrameTypeFlags::HEADER )
+ {
+ rLst.push_back( SwResId( STR_SWBG_HEADER ) );
+ nHeaderPos = nPos++;
+ }
+ if ( nType & FrameTypeFlags::FOOTER )
+ {
+ rLst.push_back( SwResId( STR_SWBG_FOOTER ) );
+ nFooterPos = nPos;
+ }
+ }
+ if ( rLst.empty() )
+ rSet.DisableItem( nWhich );
+ else
+ rSet.Put( aLst );
+ break;
+ }
+ }
+}
+
+void SwBaseShell::ExecuteGallery(SfxRequest &rReq)
+{
+ SwWrtShell &rSh = GetShell();
+ rSh.StartAction();
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ sal_uInt16 nSlot = rReq.GetSlot();
+ switch(nSlot)
+ {
+ case SID_GALLERY_BG_BRUSH:
+ {
+ if ( !pArgs )
+ break;
+
+ SelectionType nSel = rSh.GetSelectionType();
+ if ( nSel & SelectionType::DrawObjectEditMode )
+ break;
+
+ const SfxUInt16Item* pPos = rReq.GetArg<SfxUInt16Item>(SID_GALLERY_BG_POS);
+ const SvxBrushItem* pBrush = rReq.GetArg<SvxBrushItem>(SID_GALLERY_BG_BRUSH);
+ if ( !pPos || !pBrush )
+ break;
+
+ sal_uInt8 nPos = pPos->GetValue();
+ ++nPos;
+
+ SvxBrushItem aBrush( *pBrush );
+ aBrush.SetWhich( RES_BACKGROUND );
+ if ( nPos == nParagraphPos )
+ rSh.SetAttrItem( aBrush );
+ else if ( nPos == nTablePos )
+ rSh.SetTabBackground( aBrush );
+ else if ( nPos == nTableRowPos )
+ rSh.SetRowBackground( aBrush );
+ else if ( nPos == nTableCellPos )
+ rSh.SetBoxBackground( aBrush );
+ else if ( nPos == nFramePos || nPos == nGraphicPos || nPos == nOlePos )
+ {
+ SfxItemSetFixed<RES_BACKGROUND, RES_BACKGROUND> aCoreSet(GetPool());
+ aCoreSet.Put( aBrush );
+ rSh.SetFlyFrameAttr( aCoreSet );
+ }
+ else if ( nPos == nPagePos || nPos == nHeaderPos || nPos == nFooterPos )
+ {
+ sal_uInt16 nDesc = rSh.GetCurPageDesc();
+ SwPageDesc aDesc( rSh.GetPageDesc( nDesc ) );
+ if ( nPos == nPagePos )
+ aDesc.GetMaster().SetFormatAttr( aBrush );
+ else if ( nPos == nHeaderPos )
+ {
+ SwFormatHeader aHead( aDesc.GetMaster().GetHeader() );
+ aHead.GetHeaderFormat()->SetFormatAttr( aBrush );
+ aDesc.GetMaster().SetFormatAttr( aHead );
+ }
+ else if ( nPos == nFooterPos )
+ {
+ SwFormatFooter aFoot( aDesc.GetMaster().GetFooter() );
+ aFoot.GetFooterFormat()->SetFormatAttr( aBrush );
+ aDesc.GetMaster().SetFormatAttr( aFoot );
+ }
+ rSh.ChgPageDesc( nDesc, aDesc );
+ }
+ break;
+ }
+ }
+ rSh.EndAction();
+ rReq.Done();
+}
+
+void SwBaseShell::ExecField( SfxRequest const & rReq )
+{
+ sal_uInt16 nSlot = rReq.GetSlot();
+ switch( nSlot )
+ {
+#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
+ case FN_CHANGE_DBFIELD:
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSwChangeDBDlg(GetView()));
+ pDlg->Execute();
+ }
+ break;
+#endif
+ default:
+ OSL_FAIL("wrong dispatcher");
+ }
+}
+
+std::shared_ptr<std::vector<std::unique_ptr<SwPaM>>> SwBaseShell::CopyPaMRing(SwPaM& rOrig)
+{
+ auto vCursors = std::make_shared<std::vector<std::unique_ptr<SwPaM>>>();
+ vCursors->emplace_back(std::make_unique<SwPaM>(rOrig, nullptr));
+ for (auto& rCursor : rOrig.GetRingContainer())
+ {
+ if (&rCursor != &rOrig)
+ vCursors->emplace_back(std::make_unique<SwPaM>(rCursor, vCursors->front().get()));
+ }
+ return vCursors;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/beziersh.cxx b/sw/source/uibase/shells/beziersh.cxx
new file mode 100644
index 0000000000..2c4510fd7a
--- /dev/null
+++ b/sw/source/uibase/shells/beziersh.cxx
@@ -0,0 +1,325 @@
+/* -*- 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 <cmdid.h>
+#include <svx/svdview.hxx>
+#include <svl/eitem.hxx>
+#include <svl/whiter.hxx>
+#include <svx/svdopath.hxx>
+#include <vcl/EnumContext.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/viewfrm.hxx>
+
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <edtwin.hxx>
+#include <drawbase.hxx>
+#include <beziersh.hxx>
+#define ShellClass_SwBezierShell
+#include <sfx2/msg.hxx>
+#include <swslots.hxx>
+
+SFX_IMPL_INTERFACE(SwBezierShell, SwBaseShell)
+
+void SwBezierShell::InitInterface_Impl()
+{
+ GetStaticInterface()->RegisterPopupMenu("draw");
+
+ GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Invisible, ToolbarId::Bezier_Toolbox_Sw);
+}
+
+
+SwBezierShell::SwBezierShell(SwView &_rView):
+ SwBaseShell( _rView )
+{
+ SetName("Bezier");
+
+ SwWrtShell *pSh = &GetShell();
+ SdrView* pSdrView = pSh->GetDrawView();
+ pSdrView->SetEliminatePolyPointLimitAngle(1500_deg100);
+
+ SfxShell::SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::Draw));
+}
+
+void SwBezierShell::Execute(SfxRequest const &rReq)
+{
+ SwWrtShell *pSh = &GetShell();
+ SdrView* pSdrView = pSh->GetDrawView();
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ sal_uInt16 nSlotId = rReq.GetSlot();
+ bool bChanged = pSdrView->GetModel().IsChanged();
+ pSdrView->GetModel().SetChanged(false);
+ const SfxPoolItem* pItem;
+ if(pArgs)
+ pArgs->GetItemState(nSlotId, false, &pItem);
+
+ switch (nSlotId)
+ {
+ case SID_DELETE:
+ case FN_BACKSPACE:
+ if (pSh->IsObjSelected())
+ {
+ if (pSdrView->HasMarkedPoints())
+ pSh->GetView().GetViewFrame().GetDispatcher()->Execute(SID_BEZIER_DELETE);
+ else
+ {
+ pSh->DelSelectedObj();
+ if (pSh->IsSelFrameMode())
+ {
+ pSh->LeaveSelFrameMode();
+ pSh->NoEdit();
+ }
+ GetView().AttrChangedNotify(nullptr); // Shell change if applicable...
+ }
+ }
+ break;
+
+ case FN_ESCAPE:
+ if (pSdrView->HasMarkedPoints())
+ pSdrView->UnmarkAllPoints();
+ else
+ {
+ if ( pSh->IsDrawCreate() )
+ {
+ GetView().GetDrawFuncPtr()->BreakCreate();
+ GetView().AttrChangedNotify(nullptr); // Shell change if applicable...
+ }
+ else if ( pSh->HasSelection() || GetView().IsDrawMode() )
+ {
+ GetView().LeaveDrawCreate();
+ pSh->EnterStdMode();
+ GetView().AttrChangedNotify(nullptr); // Shell change if applicable...
+ }
+ }
+ break;
+
+ case SID_BEZIER_MOVE:
+ case SID_BEZIER_INSERT:
+ {
+ GetView().GetEditWin().SetBezierMode(nSlotId);
+ static sal_uInt16 aInva[] =
+ {
+ SID_BEZIER_INSERT,
+ SID_BEZIER_MOVE,
+ 0
+ };
+ GetView().GetViewFrame().GetBindings().Invalidate(aInva);
+ }
+ break;
+
+ case SID_BEZIER_DELETE:
+ case SID_BEZIER_CUTLINE:
+ case SID_BEZIER_CONVERT:
+ case SID_BEZIER_EDGE:
+ case SID_BEZIER_SMOOTH:
+ case SID_BEZIER_SYMMTR:
+ case SID_BEZIER_CLOSE:
+ case SID_BEZIER_ELIMINATE_POINTS:
+ {
+ const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
+
+ if (rMarkList.GetMark(0) && !pSdrView->IsAction())
+ {
+ switch (nSlotId)
+ {
+ case SID_BEZIER_DELETE:
+ pSdrView->DeleteMarkedPoints();
+ break;
+
+ case SID_BEZIER_CUTLINE:
+ {
+ pSdrView->RipUpAtMarkedPoints();
+ pSh->CheckUnboundObjects();
+ }
+ break;
+
+ case SID_BEZIER_CONVERT:
+ {
+ pSdrView->SetMarkedSegmentsKind(SdrPathSegmentKind::Toggle);
+ break;
+ }
+
+ case SID_BEZIER_EDGE:
+ case SID_BEZIER_SMOOTH:
+ case SID_BEZIER_SYMMTR:
+ {
+ SdrPathSmoothKind eKind = SdrPathSmoothKind::Asymmetric;
+
+ switch (nSlotId)
+ {
+ case SID_BEZIER_EDGE: eKind = SdrPathSmoothKind::Angular; break;
+ case SID_BEZIER_SMOOTH: eKind = SdrPathSmoothKind::Asymmetric; break;
+ case SID_BEZIER_SYMMTR: eKind = SdrPathSmoothKind::Symmetric; break;
+ }
+
+ SdrPathSmoothKind eSmooth = pSdrView->GetMarkedPointsSmooth();
+ if (eKind != eSmooth)
+ {
+ pSdrView->SetMarkedPointsSmooth(eKind);
+
+ static sal_uInt16 aInva[] =
+ {
+ SID_BEZIER_SMOOTH,
+ SID_BEZIER_EDGE,
+ SID_BEZIER_SYMMTR,
+ 0
+ };
+ GetView().GetViewFrame().GetBindings().Invalidate(aInva);
+ }
+ break;
+ }
+
+ case SID_BEZIER_CLOSE:
+ {
+ SdrPathObj* pPathObj = static_cast<SdrPathObj*>( rMarkList.GetMark(0)->GetMarkedSdrObj() );
+ pSdrView->UnmarkAllPoints();
+ // Size aDist(GetView().GetEditWin().PixelToLogic(Size(8,8)));
+ pPathObj->ToggleClosed(); // aDist.Width());
+ break;
+ }
+
+ case SID_BEZIER_ELIMINATE_POINTS:
+ pSdrView->SetEliminatePolyPoints(!pSdrView->IsEliminatePolyPoints());
+ break;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (pSdrView->GetModel().IsChanged())
+ GetShell().SetModified();
+ else if (bChanged)
+ pSdrView->GetModel().SetChanged();
+}
+
+void SwBezierShell::GetState(SfxItemSet &rSet)
+{
+ SdrView* pSdrView = GetShell().GetDrawView();
+
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+
+ while( nWhich )
+ {
+ switch( nWhich )
+ {
+ case SID_BEZIER_MOVE:
+ case SID_BEZIER_INSERT:
+ {
+ sal_uInt16 nEditMode = GetView().GetEditWin().GetBezierMode();
+
+ rSet.Put(SfxBoolItem(nWhich, nEditMode == nWhich));
+ }
+ break;
+
+ case SID_BEZIER_CUTLINE:
+ if (!pSdrView->IsRipUpAtMarkedPointsPossible())
+ {
+ rSet.DisableItem(SID_BEZIER_CUTLINE);
+ }
+ break;
+
+ case SID_BEZIER_DELETE:
+ if (!pSdrView->IsDeleteMarkedPointsPossible())
+ {
+ rSet.DisableItem(SID_BEZIER_DELETE);
+ }
+ break;
+
+ case SID_BEZIER_CONVERT:
+ if (!pSdrView->IsSetMarkedSegmentsKindPossible())
+ {
+ rSet.DisableItem(SID_BEZIER_CONVERT);
+ }
+ else
+ {
+ SdrPathSegmentKind eSegm = pSdrView->GetMarkedSegmentsKind();
+ switch (eSegm)
+ {
+ case SdrPathSegmentKind::DontCare: rSet.InvalidateItem(SID_BEZIER_CONVERT); break;
+ case SdrPathSegmentKind::Line : rSet.Put(SfxBoolItem(SID_BEZIER_CONVERT,false)); break; // Button pressed = curve
+ case SdrPathSegmentKind::Curve : rSet.Put(SfxBoolItem(SID_BEZIER_CONVERT,true)); break;
+ default:; //prevent warning
+ }
+ }
+ break;
+
+ case SID_BEZIER_EDGE:
+ case SID_BEZIER_SMOOTH:
+ case SID_BEZIER_SYMMTR:
+ if (!pSdrView->IsSetMarkedPointsSmoothPossible())
+ rSet.DisableItem(nWhich);
+ else
+ {
+ SdrPathSmoothKind eSmooth = pSdrView->GetMarkedPointsSmooth();
+ bool bEnable = false;
+ switch (eSmooth)
+ {
+ case SdrPathSmoothKind::DontCare :
+ break;
+ case SdrPathSmoothKind::Angular :
+ bEnable = nWhich == SID_BEZIER_EDGE;
+ break;
+ case SdrPathSmoothKind::Asymmetric:
+ bEnable = nWhich == SID_BEZIER_SMOOTH;
+ break;
+ case SdrPathSmoothKind::Symmetric :
+ bEnable = nWhich == SID_BEZIER_SYMMTR;
+ break;
+ }
+ rSet.Put(SfxBoolItem(nWhich, bEnable));
+ }
+ break;
+
+ case SID_BEZIER_CLOSE:
+ if (!pSdrView->IsOpenCloseMarkedObjectsPossible())
+ {
+ rSet.DisableItem(SID_BEZIER_CLOSE);
+ }
+ else
+ {
+ SdrObjClosedKind eClose = pSdrView->GetMarkedObjectsClosedState();
+ switch (eClose)
+ {
+ case SdrObjClosedKind::DontCare: rSet.InvalidateItem(SID_BEZIER_CLOSE); break;
+ case SdrObjClosedKind::Open : rSet.Put(SfxBoolItem(SID_BEZIER_CLOSE,false)); break;
+ case SdrObjClosedKind::Closed : rSet.Put(SfxBoolItem(SID_BEZIER_CLOSE,true)); break;
+ default:; //prevent warning
+ }
+ }
+ break;
+
+ case SID_BEZIER_ELIMINATE_POINTS:
+ rSet.Put(SfxBoolItem(SID_BEZIER_ELIMINATE_POINTS, pSdrView->IsEliminatePolyPoints()));
+ break;
+
+ default:
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/drawdlg.cxx b/sw/source/uibase/shells/drawdlg.cxx
new file mode 100644
index 0000000000..ec93f35029
--- /dev/null
+++ b/sw/source/uibase/shells/drawdlg.cxx
@@ -0,0 +1,368 @@
+/* -*- 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 <sfx2/request.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svx/svdview.hxx>
+
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <cmdid.h>
+
+#include <drawsh.hxx>
+#include <svx/svxdlg.hxx>
+#include <svx/dialogs.hrc>
+#include <memory>
+#include <svl/stritem.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/chrtitem.hxx>
+#include <svx/xlnwtit.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/xflftrit.hxx>
+#include <svx/xfltrit.hxx>
+#include <comphelper/lok.hxx>
+#include <textboxhelper.hxx>
+
+using namespace com::sun::star::drawing;
+
+void SwDrawShell::ExecDrawDlg(SfxRequest& rReq)
+{
+ SwWrtShell* pSh = &GetShell();
+ SdrView* pView = pSh->GetDrawView();
+ SdrModel& rModel = pView->GetModel();
+ bool bChanged = rModel.IsChanged();
+ rModel.SetChanged(false);
+
+ SfxItemSet aNewAttr(rModel.GetItemPool());
+ pView->GetAttributes( aNewAttr );
+
+ GetView().NoRotate();
+
+ switch (rReq.GetSlot())
+ {
+ case FN_DRAWTEXT_ATTR_DLG:
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateTextTabDialog(rReq.GetFrameWeld(), &aNewAttr, pView));
+ sal_uInt16 nResult = pDlg->Execute();
+
+ if (nResult == RET_OK)
+ {
+ if (pView->AreObjectsMarked())
+ {
+ pSh->StartAction();
+ pView->SetAttributes(*pDlg->GetOutputItemSet());
+ auto vMarkedObjs = pView->GetMarkedObjects();
+ for (auto pObj : vMarkedObjs)
+ {
+ // If the shape has textframe, set its params as well.
+ if (SwTextBoxHelper::hasTextFrame(pObj))
+ SwTextBoxHelper::updateTextBoxMargin(pObj);
+ }
+ rReq.Done(*(pDlg->GetOutputItemSet()));
+ pSh->EndAction();
+ }
+ }
+ }
+ break;
+
+ case SID_MEASURE_DLG:
+ {
+ bool bHasMarked = pView->AreObjectsMarked();
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<SfxAbstractDialog> pDlg(pFact->CreateSfxDialog(rReq.GetFrameWeld(),
+ aNewAttr, pView, RID_SVXPAGE_MEASURE));
+ if (pDlg->Execute() == RET_OK)
+ {
+ pSh->StartAction();
+ if (bHasMarked)
+ pView->SetAttrToMarked(*pDlg->GetOutputItemSet(), false);
+ else
+ pView->SetDefaultAttr(*pDlg->GetOutputItemSet(), false);
+ pSh->EndAction();
+ }
+ }
+ break;
+
+ case SID_ATTRIBUTES_AREA:
+ {
+ bool bHasMarked = pView->AreObjectsMarked();
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ VclPtr<AbstractSvxAreaTabDialog> pDlg(pFact->CreateSvxAreaTabDialog(rReq.GetFrameWeld(),
+ &aNewAttr,
+ &rModel,
+ true,
+ false));
+
+ pDlg->StartExecuteAsync([bChanged, bHasMarked, &rModel, pDlg, pSh, pView, this](
+ sal_Int32 nResult){
+ rModel.SetChanged(false);
+
+ if (nResult == RET_OK)
+ {
+ pSh->StartAction();
+ if (bHasMarked)
+ pView->SetAttributes(*pDlg->GetOutputItemSet());
+ else
+ pView->SetDefaultAttr(*pDlg->GetOutputItemSet(), false);
+ pSh->EndAction();
+
+ static sal_uInt16 aInval[] =
+ {
+ SID_ATTR_FILL_STYLE,
+ SID_ATTR_FILL_COLOR,
+ SID_ATTR_FILL_TRANSPARENCE,
+ SID_ATTR_FILL_FLOATTRANSPARENCE,
+ 0
+ };
+ SfxBindings &rBnd = GetView().GetViewFrame().GetBindings();
+ rBnd.Invalidate(aInval);
+ rBnd.Update(SID_ATTR_FILL_STYLE);
+ rBnd.Update(SID_ATTR_FILL_COLOR);
+ rBnd.Update(SID_ATTR_FILL_TRANSPARENCE);
+ rBnd.Update(SID_ATTR_FILL_FLOATTRANSPARENCE);
+ }
+
+ if (rModel.IsChanged())
+ GetShell().SetModified();
+ else if (bChanged)
+ rModel.SetChanged();
+
+ pDlg->disposeOnce();
+ });
+ }
+ break;
+
+ case SID_ATTRIBUTES_LINE:
+ {
+ bool bHasMarked = pView->AreObjectsMarked();
+
+ const SdrObject* pObj = nullptr;
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ if( rMarkList.GetMarkCount() == 1 )
+ pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ VclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateSvxLineTabDialog(rReq.GetFrameWeld(),
+ &aNewAttr,
+ &rModel,
+ pObj,
+ bHasMarked));
+
+ pDlg->StartExecuteAsync([bChanged, bHasMarked, &rModel, pDlg, pSh, pView, this](
+ sal_Int32 nResult){
+ rModel.SetChanged(false);
+
+ if (nResult == RET_OK)
+ {
+ pSh->StartAction();
+ if(bHasMarked)
+ pView->SetAttrToMarked(*pDlg->GetOutputItemSet(), false);
+ else
+ pView->SetDefaultAttr(*pDlg->GetOutputItemSet(), false);
+ pSh->EndAction();
+
+ static sal_uInt16 aInval[] =
+ {
+ SID_ATTR_LINE_STYLE, // ( SID_SVX_START + 169 )
+ SID_ATTR_LINE_DASH, // ( SID_SVX_START + 170 )
+ SID_ATTR_LINE_WIDTH, // ( SID_SVX_START + 171 )
+ SID_ATTR_LINE_COLOR, // ( SID_SVX_START + 172 )
+ SID_ATTR_LINE_START, // ( SID_SVX_START + 173 )
+ SID_ATTR_LINE_END, // ( SID_SVX_START + 174 )
+ SID_ATTR_LINE_TRANSPARENCE, // (SID_SVX_START+1107)
+ SID_ATTR_LINE_JOINT, // (SID_SVX_START+1110)
+ SID_ATTR_LINE_CAP, // (SID_SVX_START+1111)
+ 0
+ };
+
+ GetView().GetViewFrame().GetBindings().Invalidate(aInval);
+ }
+
+ if (rModel.IsChanged())
+ GetShell().SetModified();
+ else if (bChanged)
+ rModel.SetChanged();
+
+ pDlg->disposeOnce();
+ });
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (rModel.IsChanged())
+ GetShell().SetModified();
+ else if (bChanged)
+ rModel.SetChanged();
+}
+
+namespace
+{
+ void lcl_convertStringArguments(const std::unique_ptr<SfxItemSet>& pArgs)
+ {
+ if (const SvxDoubleItem* pWidthItem = pArgs->GetItemIfSet(SID_ATTR_LINE_WIDTH_ARG, false))
+ {
+ double fValue = pWidthItem->GetValue();
+ // FIXME: different units...
+ int nPow = 100;
+ int nValue = fValue * nPow;
+
+ XLineWidthItem aItem(nValue);
+ pArgs->Put(aItem);
+ }
+ if (const SfxStringItem* pJSON = pArgs->GetItemIfSet(SID_FILL_GRADIENT_JSON, false))
+ {
+ basegfx::BGradient aGradient = basegfx::BGradient::fromJSON(pJSON->GetValue());
+ XFillGradientItem aItem(aGradient);
+ pArgs->Put(aItem);
+ }
+ }
+}
+
+void SwDrawShell::ExecDrawAttrArgs(SfxRequest const & rReq)
+{
+ SwWrtShell* pSh = &GetShell();
+ SdrView* pView = pSh->GetDrawView();
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ bool bChanged = pView->GetModel().IsChanged();
+ pView->GetModel().SetChanged(false);
+
+ GetView().NoRotate();
+
+ if (pArgs)
+ {
+ if(pView->AreObjectsMarked())
+ {
+ std::unique_ptr<SfxItemSet> pNewArgs = pArgs->Clone();
+ lcl_convertStringArguments(pNewArgs);
+ pView->SetAttrToMarked(*pNewArgs, false);
+ }
+ else
+ pView->SetDefaultAttr(*rReq.GetArgs(), false);
+ }
+ else
+ {
+ SfxDispatcher* pDis = pSh->GetView().GetViewFrame().GetDispatcher();
+ switch (rReq.GetSlot())
+ {
+ case SID_ATTR_FILL_STYLE:
+ case SID_ATTR_FILL_COLOR:
+ case SID_ATTR_FILL_GRADIENT:
+ case SID_ATTR_FILL_HATCH:
+ case SID_ATTR_FILL_BITMAP:
+ case SID_ATTR_FILL_TRANSPARENCE:
+ case SID_ATTR_FILL_FLOATTRANSPARENCE:
+ pDis->Execute(SID_ATTRIBUTES_AREA);
+ break;
+ case SID_ATTR_LINE_STYLE:
+ case SID_ATTR_LINE_DASH:
+ case SID_ATTR_LINE_WIDTH:
+ case SID_ATTR_LINE_COLOR:
+ case SID_ATTR_LINE_TRANSPARENCE:
+ case SID_ATTR_LINE_JOINT:
+ case SID_ATTR_LINE_CAP:
+ pDis->Execute(SID_ATTRIBUTES_LINE);
+ break;
+ }
+ }
+ if (pView->GetModel().IsChanged())
+ GetShell().SetModified();
+ else
+ if (bChanged)
+ pView->GetModel().SetChanged();
+}
+
+static void lcl_unifyFillTransparencyItems(const SfxItemSet& rSet)
+{
+ // Transparent fill options are None, Solid, Linear, Axial, Radial, Elliptical, Square, Rectangular.
+ // But this is represented across two items namely XFillTransparenceItem (for None and Solid)
+ // and XFillFloatTransparenceItem (for the rest). To simplify the representation in LOKit case let's
+ // use XFillFloatTransparenceItem to carry the information of XFillTransparenceItem when gradients
+ // are disabled. When gradient transparency is disabled, all fields of XFillFloatTransparenceItem are invalid
+ // and not used. So convert XFillTransparenceItem's constant transparency percentage as an intensity
+ // and assign this to the XFillFloatTransparenceItem's start-intensity and end-intensity fields.
+ // Now the LOK clients need only listen to statechange messages of XFillFloatTransparenceItem
+ // to get fill-transparency settings instead of listening to two separate items.
+
+ XFillFloatTransparenceItem* pFillFloatTranspItem =
+ const_cast<XFillFloatTransparenceItem*>
+ (rSet.GetItem<XFillFloatTransparenceItem>(XATTR_FILLFLOATTRANSPARENCE));
+ if (!pFillFloatTranspItem || pFillFloatTranspItem->IsEnabled())
+ return;
+
+ const XFillTransparenceItem* pFillTranspItem =
+ rSet.GetItem<XFillTransparenceItem>(XATTR_FILLTRANSPARENCE);
+
+ if (!pFillTranspItem)
+ return;
+
+ basegfx::BGradient aTmpGradient = pFillFloatTranspItem->GetGradientValue();
+ sal_uInt16 nTranspPercent = pFillTranspItem->GetValue();
+ // Encode transparency percentage as intensity
+ sal_uInt16 nIntensity = 100 - std::min<sal_uInt16>
+ (std::max<sal_uInt16>(nTranspPercent, 0), 100);
+ aTmpGradient.SetStartIntens(nIntensity);
+ aTmpGradient.SetEndIntens(nIntensity);
+ pFillFloatTranspItem->SetGradientValue(aTmpGradient);
+}
+
+void SwDrawShell::GetDrawAttrState(SfxItemSet& rSet)
+{
+ SdrView* pSdrView = GetShell().GetDrawView();
+
+ if (pSdrView->AreObjectsMarked())
+ {
+ bool bDisable = Disable( rSet );
+
+ if( !bDisable )
+ {
+ SfxItemSet aSet(rSet);
+ aSet.MergeRange(SDRATTR_TEXTCOLUMNS_NUMBER, SDRATTR_TEXTCOLUMNS_SPACING);
+ pSdrView->GetAttributes(aSet);
+ if (const SfxPoolItem* pItem = nullptr;
+ aSet.GetItemState(SDRATTR_TEXTCOLUMNS_NUMBER, false, &pItem)
+ >= SfxItemState::DEFAULT
+ && pItem)
+ {
+ aSet.Put(pItem->CloneSetWhich(SID_ATTR_TEXTCOLUMNS_NUMBER));
+ }
+ if (const SfxPoolItem* pItem = nullptr;
+ aSet.GetItemState(SDRATTR_TEXTCOLUMNS_SPACING, false, &pItem)
+ >= SfxItemState::DEFAULT
+ && pItem)
+ {
+ aSet.Put(pItem->CloneSetWhich(SID_ATTR_TEXTCOLUMNS_SPACING));
+ }
+ rSet.Put(aSet, false);
+ if (comphelper::LibreOfficeKit::isActive())
+ lcl_unifyFillTransparencyItems(rSet);
+ }
+ }
+ else
+ rSet.Put(pSdrView->GetDefaultAttr());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/drawsh.cxx b/sw/source/uibase/shells/drawsh.cxx
new file mode 100644
index 0000000000..23c4dd6187
--- /dev/null
+++ b/sw/source/uibase/shells/drawsh.cxx
@@ -0,0 +1,629 @@
+/* -*- 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/svdview.hxx>
+#include <svx/svdotext.hxx>
+#include <svl/whiter.hxx>
+#include <svx/fontwork.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svx/extrusionbar.hxx>
+#include <svx/fontworkbar.hxx>
+#include <uitool.hxx>
+#include <dcontact.hxx>
+#include <textboxhelper.hxx>
+#include <wview.hxx>
+#include <swmodule.hxx>
+
+#include <svx/svdoashp.hxx>
+#include <svx/xfillit0.hxx>
+#include <vcl/EnumContext.hxx>
+#include <svx/svdoole2.hxx>
+#include <sfx2/opengrf.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/sdasitm.hxx>
+#include <osl/diagnose.h>
+
+#include <swundo.hxx>
+#include <wrtsh.hxx>
+#include <cmdid.h>
+#include <strings.hrc>
+#include <drwbassh.hxx>
+#include <drawsh.hxx>
+
+#define ShellClass_SwDrawShell
+#include <sfx2/msg.hxx>
+#include <swslots.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+SFX_IMPL_INTERFACE(SwDrawShell, SwDrawBaseShell)
+
+void SwDrawShell::InitInterface_Impl()
+{
+ GetStaticInterface()->RegisterPopupMenu("draw");
+
+ GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Invisible, ToolbarId::Draw_Toolbox_Sw);
+
+ GetStaticInterface()->RegisterChildWindow(SvxFontWorkChildWindow::GetChildWindowId());
+}
+
+
+// #i123922# check as the name implies
+SdrObject* SwDrawShell::IsSingleFillableNonOLESelected()
+{
+ SwWrtShell &rSh = GetShell();
+ SdrView* pSdrView = rSh.GetDrawView();
+
+ if(!pSdrView)
+ {
+ return nullptr;
+ }
+
+ if(1 != pSdrView->GetMarkedObjectCount())
+ {
+ return nullptr;
+ }
+
+ SdrObject* pPickObj = pSdrView->GetMarkedObjectByIndex(0);
+
+ if(!pPickObj)
+ {
+ return nullptr;
+ }
+
+ if(!pPickObj->IsClosedObj())
+ {
+ return nullptr;
+ }
+
+ if(dynamic_cast< SdrOle2Obj* >(pPickObj))
+ {
+ return nullptr;
+ }
+
+ return pPickObj;
+}
+
+// #i123922# insert given graphic data dependent of the object type in focus
+void SwDrawShell::InsertPictureFromFile(SdrObject& rObject)
+{
+ SwWrtShell &rSh = GetShell();
+ SdrView* pSdrView = rSh.GetDrawView();
+
+ if(!pSdrView)
+ return;
+
+ SvxOpenGraphicDialog aDlg(SwResId(STR_INSERT_GRAPHIC), GetView().GetFrameWeld());
+
+ if (ERRCODE_NONE != aDlg.Execute())
+ return;
+
+ Graphic aGraphic;
+ ErrCode nError = aDlg.GetGraphic(aGraphic);
+
+ if(ERRCODE_NONE != nError)
+ return;
+
+ const bool bAsLink(aDlg.IsAsLink());
+ SdrObject* pResult = &rObject;
+
+ rSh.StartUndo(SwUndoId::PASTE_CLIPBOARD);
+
+ if (SdrGrafObj* pSdrGrafObj = dynamic_cast<SdrGrafObj*>(&rObject))
+ {
+ rtl::Reference<SdrGrafObj> pNewGrafObj = SdrObject::Clone(*pSdrGrafObj, pSdrGrafObj->getSdrModelFromSdrObject());
+
+ pNewGrafObj->SetGraphic(aGraphic);
+
+ // #i123922# for handling MasterObject and virtual ones correctly, SW
+ // wants us to call ReplaceObject at the page, but that also
+ // triggers the same assertion (I tried it), so stay at the view method
+ pSdrView->ReplaceObjectAtView(&rObject, *pSdrView->GetSdrPageView(), pNewGrafObj.get());
+
+ // set in all cases - the Clone() will have copied an existing link (!)
+ pNewGrafObj->SetGraphicLink(
+ bAsLink ? aDlg.GetPath() : OUString());
+
+ pResult = pNewGrafObj.get();
+ }
+ else // if(rObject.IsClosedObj() && !dynamic_cast< SdrOle2Obj* >(&rObject))
+ {
+ pSdrView->AddUndo(std::make_unique<SdrUndoAttrObj>(rObject));
+
+ SfxItemSetFixed<XATTR_FILLSTYLE, XATTR_FILLBITMAP> aSet(pSdrView->GetModel().GetItemPool());
+
+ aSet.Put(XFillStyleItem(drawing::FillStyle_BITMAP));
+ aSet.Put(XFillBitmapItem(OUString(), std::move(aGraphic)));
+ rObject.SetMergedItemSetAndBroadcast(aSet);
+ }
+
+ rSh.EndUndo( SwUndoId::END );
+
+ if(pResult)
+ {
+ // we are done; mark the modified/new object
+ pSdrView->MarkObj(pResult, pSdrView->GetSdrPageView());
+ }
+}
+
+void SwDrawShell::Execute(SfxRequest &rReq)
+{
+ SwWrtShell &rSh = GetShell();
+ SdrView *pSdrView = rSh.GetDrawView();
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ SfxBindings &rBnd = GetView().GetViewFrame().GetBindings();
+ sal_uInt16 nSlotId = rReq.GetSlot();
+ bool bChanged = pSdrView->GetModel().IsChanged();
+
+ pSdrView->GetModel().SetChanged(false);
+
+ const SfxPoolItem* pItem;
+ if(pArgs)
+ pArgs->GetItemState(nSlotId, false, &pItem);
+
+ bool bMirror = true;
+
+ switch (nSlotId)
+ {
+ case SID_OBJECT_ROTATE:
+ if (rSh.IsObjSelected() && pSdrView->IsRotateAllowed())
+ {
+ if (GetView().IsDrawRotate())
+ rSh.SetDragMode(SdrDragMode::Move);
+ else
+ rSh.SetDragMode(SdrDragMode::Rotate);
+
+ GetView().FlipDrawRotate();
+ }
+ break;
+ case SID_MOVE_SHAPE_HANDLE:
+ {
+ if (pArgs && pArgs->Count() >= 3)
+ {
+ const SfxUInt32Item* handleNumItem = rReq.GetArg<SfxUInt32Item>(FN_PARAM_1);
+ const SfxUInt32Item* newPosXTwips = rReq.GetArg<SfxUInt32Item>(FN_PARAM_2);
+ const SfxUInt32Item* newPosYTwips = rReq.GetArg<SfxUInt32Item>(FN_PARAM_3);
+ const SfxInt32Item* OrdNum = rReq.GetArg<SfxInt32Item>(FN_PARAM_4);
+
+ const sal_uLong handleNum = handleNumItem->GetValue();
+ const sal_uLong newPosX = newPosXTwips->GetValue();
+ const sal_uLong newPosY = newPosYTwips->GetValue();
+ const Point mPoint(newPosX, newPosY);
+ const SdrHdl* handle = pSdrView->GetHdlList().GetHdl(handleNum);
+ if (!handle)
+ {
+ break;
+ }
+
+ if (handle->GetKind() == SdrHdlKind::Anchor || handle->GetKind() == SdrHdlKind::Anchor_TR)
+ {
+ rSh.FindAnchorPos(mPoint, /*bMoveIt=*/true);
+ pSdrView->ModelHasChanged();
+ }
+ else
+ pSdrView->MoveShapeHandle(handleNum, mPoint, OrdNum ? OrdNum->GetValue() : -1);
+ }
+ }
+ break;
+ case SID_BEZIER_EDIT:
+ if (GetView().IsDrawRotate())
+ {
+ rSh.SetDragMode(SdrDragMode::Move);
+ GetView().FlipDrawRotate();
+ }
+ GetView().FlipDrawSelMode();
+ pSdrView->SetFrameDragSingles(GetView().IsDrawSelMode());
+ GetView().AttrChangedNotify(nullptr); // Shell switch
+ break;
+
+ case SID_OBJECT_HELL:
+ if (rSh.IsObjSelected())
+ {
+ rSh.StartUndo( SwUndoId::START );
+ SetWrapMode(FN_FRAME_WRAPTHRU_TRANSP);
+ rSh.SelectionToHell();
+ rSh.EndUndo( SwUndoId::END );
+ rBnd.Invalidate(SID_OBJECT_HEAVEN);
+ }
+ break;
+
+ case SID_OBJECT_HEAVEN:
+ if (rSh.IsObjSelected())
+ {
+ rSh.StartUndo( SwUndoId::START );
+ SetWrapMode(FN_FRAME_WRAPTHRU);
+ rSh.SelectionToHeaven();
+ rSh.EndUndo( SwUndoId::END );
+ rBnd.Invalidate(SID_OBJECT_HELL);
+ }
+ break;
+
+ case FN_TOOL_HIERARCHIE:
+ if (rSh.IsObjSelected())
+ {
+ rSh.StartUndo( SwUndoId::START );
+ if (rSh.GetLayerId() == SdrLayerID(0))
+ {
+ SetWrapMode(FN_FRAME_WRAPTHRU);
+ rSh.SelectionToHeaven();
+ }
+ else
+ {
+ SetWrapMode(FN_FRAME_WRAPTHRU_TRANSP);
+ rSh.SelectionToHell();
+ }
+ rSh.EndUndo( SwUndoId::END );
+ rBnd.Invalidate( SID_OBJECT_HELL );
+ rBnd.Invalidate( SID_OBJECT_HEAVEN );
+ }
+ break;
+
+ case SID_FLIP_VERTICAL:
+ bMirror = false;
+ [[fallthrough]];
+ case SID_FLIP_HORIZONTAL:
+ rSh.MirrorSelection( bMirror );
+ break;
+
+ case SID_FONTWORK:
+ {
+ FieldUnit eMetric = ::GetDfltMetric( dynamic_cast<SwWebView*>( &rSh.GetView()) != nullptr );
+ SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)) );
+ SfxViewFrame& rVFrame = GetView().GetViewFrame();
+ if (pArgs)
+ {
+ rVFrame.SetChildWindow(SvxFontWorkChildWindow::GetChildWindowId(),
+ static_cast<const SfxBoolItem&>((pArgs->Get(SID_FONTWORK))).GetValue());
+ }
+ else
+ rVFrame.ToggleChildWindow( SvxFontWorkChildWindow::GetChildWindowId() );
+ rVFrame.GetBindings().Invalidate(SID_FONTWORK);
+ }
+ break;
+ case FN_FORMAT_FOOTNOTE_DLG:
+ {
+ GetView().ExecFormatFootnote();
+ break;
+ }
+ case FN_NUMBERING_OUTLINE_DLG:
+ {
+ GetView().ExecNumberingOutline(GetPool());
+ rReq.Done();
+ }
+ break;
+ case SID_OPEN_XML_FILTERSETTINGS:
+ {
+ HandleOpenXmlFilterSettings(rReq);
+ }
+ break;
+ case FN_WORDCOUNT_DIALOG:
+ {
+ GetView().UpdateWordCount(this, nSlotId);
+ }
+ break;
+ case SID_EXTRUSION_TOGGLE:
+ case SID_EXTRUSION_TILT_DOWN:
+ case SID_EXTRUSION_TILT_UP:
+ case SID_EXTRUSION_TILT_LEFT:
+ case SID_EXTRUSION_TILT_RIGHT:
+ case SID_EXTRUSION_3D_COLOR:
+ case SID_EXTRUSION_DEPTH:
+ case SID_EXTRUSION_DIRECTION:
+ case SID_EXTRUSION_PROJECTION:
+ case SID_EXTRUSION_LIGHTING_DIRECTION:
+ case SID_EXTRUSION_LIGHTING_INTENSITY:
+ case SID_EXTRUSION_SURFACE:
+ case SID_EXTRUSION_DEPTH_FLOATER:
+ case SID_EXTRUSION_DIRECTION_FLOATER:
+ case SID_EXTRUSION_LIGHTING_FLOATER:
+ case SID_EXTRUSION_SURFACE_FLOATER:
+ case SID_EXTRUSION_DEPTH_DIALOG:
+ svx::ExtrusionBar::execute( pSdrView, rReq, rBnd );
+ rReq.Ignore ();
+ break;
+
+ case SID_FONTWORK_SHAPE:
+ case SID_FONTWORK_SHAPE_TYPE:
+ case SID_FONTWORK_ALIGNMENT:
+ case SID_FONTWORK_SAME_LETTER_HEIGHTS:
+ case SID_FONTWORK_CHARACTER_SPACING:
+ case SID_FONTWORK_KERN_CHARACTER_PAIRS:
+ case SID_FONTWORK_CHARACTER_SPACING_FLOATER:
+ case SID_FONTWORK_ALIGNMENT_FLOATER:
+ case SID_FONTWORK_CHARACTER_SPACING_DIALOG:
+ svx::FontworkBar::execute(*pSdrView, rReq, rBnd);
+ rReq.Ignore ();
+ break;
+
+ case SID_INSERT_GRAPHIC:
+ {
+ // #i123922# check if we can do something
+ SdrObject* pObj = IsSingleFillableNonOLESelected();
+
+ if(pObj)
+ {
+ // ...and if yes, do something
+ InsertPictureFromFile(*pObj);
+ }
+
+ break;
+ }
+
+ case FN_ADD_TEXT_BOX:
+ {
+ if (SdrObject* pObj = IsSingleFillableNonOLESelected())
+ {
+ SwFrameFormat* pFrameFormat = ::FindFrameFormat(pObj);
+ if (pFrameFormat)
+ SwTextBoxHelper::create(pFrameFormat, pObj, pObj->HasText());
+ }
+ break;
+ }
+ case FN_REMOVE_TEXT_BOX:
+ {
+ if (SdrObject* pObj = IsSingleFillableNonOLESelected())
+ {
+ SwFrameFormat* pFrameFormat = ::FindFrameFormat(pObj);
+ if (pFrameFormat)
+ SwTextBoxHelper::destroy(pFrameFormat, pObj);
+ }
+ break;
+ }
+ default:
+ OSL_ENSURE(false, "wrong dispatcher");
+ return;
+ }
+ if (pSdrView->GetModel().IsChanged())
+ rSh.SetModified();
+ else if (bChanged)
+ pSdrView->GetModel().SetChanged();
+}
+
+void SwDrawShell::GetState(SfxItemSet& rSet)
+{
+ SwWrtShell &rSh = GetShell();
+ SdrView* pSdrView = rSh.GetDrawViewWithValidMarkList();
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ bool bProtected = rSh.IsSelObjProtected(FlyProtectFlags::Content) != FlyProtectFlags::NONE;
+
+ if (!bProtected) // Check the parent
+ bProtected |= rSh.IsSelObjProtected( FlyProtectFlags::Content|FlyProtectFlags::Parent ) != FlyProtectFlags::NONE;
+
+ while( nWhich )
+ {
+ switch( nWhich )
+ {
+ case SID_OBJECT_HELL:
+ if ( !rSh.IsObjSelected() || rSh.GetLayerId() == SdrLayerID(0) || bProtected )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_OBJECT_HEAVEN:
+ if ( !rSh.IsObjSelected() || rSh.GetLayerId() == SdrLayerID(1) || bProtected )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case FN_TOOL_HIERARCHIE:
+ if ( !rSh.IsObjSelected() || bProtected )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_OBJECT_ROTATE:
+ {
+ const bool bIsRotate = GetView().IsDrawRotate();
+ if ( (!bIsRotate && !pSdrView->IsRotateAllowed()) || bProtected )
+ rSet.DisableItem( nWhich );
+ else
+ rSet.Put( SfxBoolItem( nWhich, bIsRotate ) );
+ }
+ break;
+
+ case SID_BEZIER_EDIT:
+ if (!Disable(rSet, nWhich))
+ rSet.Put( SfxBoolItem( nWhich, !GetView().IsDrawSelMode()));
+ break;
+
+ case SID_FLIP_VERTICAL:
+ if ( !pSdrView->IsMirrorAllowed() || bProtected )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ else
+ {
+ // TTTT - needs to be adapted in aw080:
+ // state is not kept for drawing objects --> provide not flipped state
+ rSet.Put( SfxBoolItem( nWhich, false ) );
+ }
+ break;
+
+ case SID_FLIP_HORIZONTAL:
+ if ( !pSdrView->IsMirrorAllowed() || bProtected )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ else
+ {
+ // TTTT - needs to be adapted in aw080:
+ // state is not kept for drawing objects --> provide not flipped state
+ rSet.Put( SfxBoolItem( nWhich, false ) );
+ }
+ break;
+
+ case SID_FONTWORK:
+ {
+ if (bProtected)
+ rSet.DisableItem( nWhich );
+ else
+ {
+ const sal_uInt16 nId = SvxFontWorkChildWindow::GetChildWindowId();
+ rSet.Put(SfxBoolItem( nWhich , GetView().GetViewFrame().HasChildWindow(nId)));
+ }
+ }
+ break;
+
+ case SID_INSERT_GRAPHIC:
+ {
+ // #i123922# check if we can do something
+ SdrObject* pObj = IsSingleFillableNonOLESelected();
+
+ if(!pObj)
+ {
+ rSet.DisableItem(nWhich);
+ }
+
+ break;
+ }
+ case FN_ADD_TEXT_BOX:
+ {
+ bool bDisable = true;
+ if (SdrObject* pObj = IsSingleFillableNonOLESelected())
+ {
+ SwFrameFormat* pFrameFormat = ::FindFrameFormat(pObj);
+ // Allow creating a TextBox only in case this is a draw format without a TextBox so far.
+ if (pFrameFormat && pFrameFormat->Which() == RES_DRAWFRMFMT && !SwTextBoxHelper::isTextBox(pFrameFormat, RES_DRAWFRMFMT, pObj))
+ {
+ if (SdrObjCustomShape* pCustomShape = dynamic_cast<SdrObjCustomShape*>( pObj) )
+ {
+ const SdrCustomShapeGeometryItem& rGeometryItem = pCustomShape->GetMergedItem(SDRATTR_CUSTOMSHAPE_GEOMETRY);
+ if (const uno::Any* pAny = rGeometryItem.GetPropertyValueByName("Type"))
+ // But still disallow fontwork shapes.
+ bDisable = pAny->get<OUString>().startsWith("fontwork-");
+ }
+ }
+ }
+
+ if (bDisable)
+ rSet.DisableItem(nWhich);
+ break;
+ }
+ case FN_REMOVE_TEXT_BOX:
+ {
+ bool bDisable = true;
+ if (SdrObject* pObj = IsSingleFillableNonOLESelected())
+ {
+ SwFrameFormat* pFrameFormat = ::FindFrameFormat(pObj);
+ // Allow removing a TextBox only in case it has one.
+ if (pFrameFormat && SwTextBoxHelper::isTextBox(pFrameFormat, RES_DRAWFRMFMT, pObj))
+ bDisable = false;
+ }
+
+ if (bDisable)
+ rSet.DisableItem(nWhich);
+ break;
+ }
+ }
+ nWhich = aIter.NextWhich();
+ }
+ svx::ExtrusionBar::getState( pSdrView, rSet );
+ svx::FontworkBar::getState( pSdrView, rSet );
+}
+
+SwDrawShell::SwDrawShell(SwView &_rView) :
+ SwDrawBaseShell(_rView)
+{
+ SetName("Draw");
+
+ vcl::EnumContext::Context eContext = vcl::EnumContext::Context::Draw;
+
+ SwWrtShell &rSh = GetShell();
+ SdrView* pDrView = rSh.GetDrawView();
+
+ if (pDrView && svx::checkForSelectedFontWork(pDrView))
+ eContext = vcl::EnumContext::Context::DrawFontwork;
+
+ SfxShell::SetContextName(vcl::EnumContext::GetContextName(eContext));
+}
+
+// Edit SfxRequests for FontWork
+
+void SwDrawShell::ExecFormText(SfxRequest const & rReq)
+{
+ SwWrtShell &rSh = GetShell();
+ SdrView* pDrView = rSh.GetDrawView();
+ bool bChanged = pDrView->GetModel().IsChanged();
+ pDrView->GetModel().SetChanged(false);
+
+ const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
+
+ if ( rMarkList.GetMarkCount() == 1 && rReq.GetArgs() )
+ {
+ const SfxItemSet& rSet = *rReq.GetArgs();
+
+ if ( pDrView->IsTextEdit() )
+ {
+ pDrView->SdrEndTextEdit( true );
+ GetView().AttrChangedNotify(nullptr);
+ }
+
+ pDrView->SetAttributes(rSet);
+ }
+ if (pDrView->GetModel().IsChanged())
+ rSh.SetModified();
+ else
+ if (bChanged)
+ pDrView->GetModel().SetChanged();
+}
+
+//Return status values for FontWork
+
+void SwDrawShell::GetFormTextState(SfxItemSet& rSet)
+{
+ SwWrtShell &rSh = GetShell();
+ SdrView* pDrView = rSh.GetDrawView();
+ const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
+ const SdrObject* pObj = nullptr;
+
+ if ( rMarkList.GetMarkCount() == 1 )
+ pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+
+ const SdrTextObj* pTextObj = DynCastSdrTextObj(pObj);
+ const bool bDeactivate(
+ !pObj ||
+ !pTextObj ||
+ !pTextObj->HasText() ||
+ dynamic_cast< const SdrObjCustomShape* >(pObj)); // #121538# no FontWork for CustomShapes
+
+ if(bDeactivate)
+ {
+ rSet.DisableItem(XATTR_FORMTXTSTYLE);
+ rSet.DisableItem(XATTR_FORMTXTADJUST);
+ rSet.DisableItem(XATTR_FORMTXTDISTANCE);
+ rSet.DisableItem(XATTR_FORMTXTSTART);
+ rSet.DisableItem(XATTR_FORMTXTMIRROR);
+ rSet.DisableItem(XATTR_FORMTXTHIDEFORM);
+ rSet.DisableItem(XATTR_FORMTXTOUTLINE);
+ rSet.DisableItem(XATTR_FORMTXTSHADOW);
+ rSet.DisableItem(XATTR_FORMTXTSHDWCOLOR);
+ rSet.DisableItem(XATTR_FORMTXTSHDWXVAL);
+ rSet.DisableItem(XATTR_FORMTXTSHDWYVAL);
+ }
+ else
+ {
+ pDrView->GetAttributes( rSet );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/drformsh.cxx b/sw/source/uibase/shells/drformsh.cxx
new file mode 100644
index 0000000000..fcf2eab803
--- /dev/null
+++ b/sw/source/uibase/shells/drformsh.cxx
@@ -0,0 +1,251 @@
+/* -*- 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/hlnkitem.hxx>
+#include <svx/svdview.hxx>
+#include <svl/whiter.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/dispatch.hxx>
+#include <vcl/EnumContext.hxx>
+#include <svx/svdouno.hxx>
+#include <com/sun/star/form/FormButtonType.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <sfx2/htmlmode.hxx>
+#include <tools/urlobj.hxx>
+#include <osl/diagnose.h>
+
+#include <viewopt.hxx>
+#include <wrtsh.hxx>
+#include <cmdid.h>
+#include <drwbassh.hxx>
+#include <drformsh.hxx>
+#include <svl/urihelper.hxx>
+#include <view.hxx>
+#include <sfx2/docfile.hxx>
+#include <docsh.hxx>
+
+#define ShellClass_SwDrawFormShell
+#include <sfx2/msg.hxx>
+#include <swslots.hxx>
+
+using namespace ::com::sun::star;
+
+SFX_IMPL_INTERFACE(SwDrawFormShell, SwDrawBaseShell)
+
+void SwDrawFormShell::InitInterface_Impl()
+{
+ GetStaticInterface()->RegisterPopupMenu("form");
+
+ GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Invisible, ToolbarId::Text_Toolbox_Sw);
+}
+
+
+void SwDrawFormShell::Execute(SfxRequest const &rReq)
+{
+ SwWrtShell &rSh = GetShell();
+ const SfxPoolItem* pItem = nullptr;
+ const SfxItemSet *pArgs = rReq.GetArgs();
+
+ switch ( rReq.GetSlot() )
+ {
+ case SID_HYPERLINK_SETLINK:
+ {
+ if(pArgs)
+ pArgs->GetItemState(SID_HYPERLINK_SETLINK, false, &pItem);
+ if(pItem)
+ {
+ SdrView *pSdrView = rSh.GetDrawView();
+ const SvxHyperlinkItem& rHLinkItem = *static_cast<const SvxHyperlinkItem *>(pItem);
+ bool bConvertToText = rHLinkItem.GetInsertMode() == HLINK_DEFAULT ||
+ rHLinkItem.GetInsertMode() == HLINK_FIELD;
+ const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
+ if (rMarkList.GetMark(0))
+ {
+ SdrUnoObj* pUnoCtrl = dynamic_cast<SdrUnoObj*>( rMarkList.GetMark(0)->GetMarkedSdrObj() );
+ if (pUnoCtrl && SdrInventor::FmForm == pUnoCtrl->GetObjInventor())
+ {
+ if(bConvertToText)
+ {
+ //remove object -> results in destruction of this!
+ SwView& rTempView = GetView();
+ rTempView.GetViewFrame().GetDispatcher()->Execute(SID_DELETE, SfxCallMode::SYNCHRON );
+ rTempView.StopShellTimer();
+ //issue a new command to insert the link
+ rTempView.GetViewFrame().GetDispatcher()->ExecuteList(
+ SID_HYPERLINK_SETLINK, SfxCallMode::ASYNCHRON,
+ { &rHLinkItem });
+ }
+ else
+ {
+ const uno::Reference< awt::XControlModel >& xControlModel = pUnoCtrl->GetUnoControlModel();
+
+ OSL_ENSURE( xControlModel.is(), "UNO-Control without Model" );
+ if( !xControlModel.is() )
+ return;
+
+ uno::Reference< beans::XPropertySet > xPropSet(xControlModel, uno::UNO_QUERY);
+
+ // Can we set a URL to the object?
+ OUString sTargetURL( "TargetURL" );
+ uno::Reference< beans::XPropertySetInfo > xPropInfoSet = xPropSet->getPropertySetInfo();
+ if( xPropInfoSet->hasPropertyByName( sTargetURL ))
+ {
+ beans::Property aProp = xPropInfoSet->getPropertyByName( sTargetURL );
+ if( !aProp.Name.isEmpty() )
+ {
+ uno::Any aTmp;
+ // Yes!
+ OUString sLabel("Label");
+ if( xPropInfoSet->hasPropertyByName(sLabel) )
+ {
+ aTmp <<= rHLinkItem.GetName();
+ xPropSet->setPropertyValue(sLabel, aTmp );
+ }
+
+ SfxMedium* pMedium = GetView().GetDocShell()->GetMedium();
+ INetURLObject aAbs;
+ if( pMedium )
+ aAbs = pMedium->GetURLObject();
+ aTmp <<= URIHelper::SmartRel2Abs(aAbs, rHLinkItem.GetURL());
+ xPropSet->setPropertyValue( sTargetURL, aTmp );
+
+ if( !rHLinkItem.GetTargetFrame().isEmpty() )
+ {
+ aTmp <<= rHLinkItem.GetTargetFrame();
+ xPropSet->setPropertyValue( "TargetFrame", aTmp );
+ }
+
+ aTmp <<= form::FormButtonType_URL;
+ xPropSet->setPropertyValue( "ButtonType", aTmp );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ default:
+ OSL_ENSURE(false, "wrong dispatcher");
+ return;
+ }
+}
+
+void SwDrawFormShell::GetState(SfxItemSet& rSet)
+{
+ SwWrtShell &rSh = GetShell();
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+
+ while( nWhich )
+ {
+ switch( nWhich )
+ {
+ case SID_HYPERLINK_GETLINK:
+ {
+ SdrView* pSdrView = rSh.GetDrawViewWithValidMarkList();
+ const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
+ SvxHyperlinkItem aHLinkItem;
+ if (rMarkList.GetMark(0))
+ {
+ SdrUnoObj* pUnoCtrl = dynamic_cast<SdrUnoObj*>( rMarkList.GetMark(0)->GetMarkedSdrObj() );
+ if (pUnoCtrl && SdrInventor::FmForm == pUnoCtrl->GetObjInventor())
+ {
+ const uno::Reference< awt::XControlModel >& xControlModel = pUnoCtrl->GetUnoControlModel();
+
+ OSL_ENSURE( xControlModel.is(), "UNO-Control without Model" );
+ if( !xControlModel.is() )
+ return;
+
+ uno::Reference< beans::XPropertySet > xPropSet(xControlModel, uno::UNO_QUERY);
+
+ uno::Any aTmp;
+ uno::Reference< beans::XPropertySetInfo > xInfo = xPropSet->getPropertySetInfo();
+ if(xInfo->hasPropertyByName( "ButtonType" ))
+ {
+ form::FormButtonType eButtonType = form::FormButtonType_URL;
+ aTmp = xPropSet->getPropertyValue( "ButtonType" );
+ if( aTmp >>= eButtonType )
+ {
+ // Label
+ if(xInfo->hasPropertyByName( "Label" ))
+ {
+ aTmp = xPropSet->getPropertyValue( "Label" );
+ OUString sTmp;
+ if( (aTmp >>= sTmp) && !sTmp.isEmpty())
+ {
+ aHLinkItem.SetName(sTmp);
+ }
+ }
+
+ // URL
+ if(xInfo->hasPropertyByName( "TargetURL" ))
+ {
+ aTmp = xPropSet->getPropertyValue( "TargetURL" );
+ OUString sTmp;
+ if( (aTmp >>= sTmp) && !sTmp.isEmpty())
+ {
+ aHLinkItem.SetURL(sTmp);
+ }
+ }
+
+ // Target
+ if(xInfo->hasPropertyByName( "TargetFrame" ))
+ {
+ aTmp = xPropSet->getPropertyValue( "TargetFrame" );
+ OUString sTmp;
+ if( (aTmp >>= sTmp) && !sTmp.isEmpty())
+ {
+ aHLinkItem.SetTargetFrame(sTmp);
+ }
+ }
+ aHLinkItem.SetInsertMode(HLINK_BUTTON);
+ }
+ }
+ }
+ }
+ sal_uInt16 nHtmlMode = ::GetHtmlMode(GetView().GetDocShell());
+ aHLinkItem.SetInsertMode(static_cast<SvxLinkInsertMode>(aHLinkItem.GetInsertMode() |
+ ((nHtmlMode & HTMLMODE_ON) != 0 ? HLINK_HTMLMODE : 0)));
+
+ rSet.Put(aHLinkItem);
+ }
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+SwDrawFormShell::SwDrawFormShell(SwView &_rView) :
+ SwDrawBaseShell(_rView)
+{
+ GetShell().NoEdit();
+ SetName("DrawForm");
+ SfxShell::SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::Form));
+}
+
+SwDrawFormShell::~SwDrawFormShell()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/drwbassh.cxx b/sw/source/uibase/shells/drwbassh.cxx
new file mode 100644
index 0000000000..a5a63a6634
--- /dev/null
+++ b/sw/source/uibase/shells/drwbassh.cxx
@@ -0,0 +1,1245 @@
+/* -*- 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 <swtypes.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svx/svdview.hxx>
+#include <svl/whiter.hxx>
+#include <svx/swframevalidation.hxx>
+#include <svx/anchorid.hxx>
+#include <svx/hlnkitem.hxx>
+#include <osl/diagnose.h>
+#include <drawdoc.hxx>
+#include <uitool.hxx>
+#include <fmtornt.hxx>
+#include <cmdid.h>
+#include <swmodule.hxx>
+#include <wrtsh.hxx>
+#include <wview.hxx>
+#include <edtwin.hxx>
+#include <viewopt.hxx>
+#include <dcontact.hxx>
+#include <frmfmt.hxx>
+#include <drawbase.hxx>
+#include <drwbassh.hxx>
+#include <swdtflvr.hxx>
+#include <svx/svditer.hxx>
+#define ShellClass_SwDrawBaseShell
+#include <sfx2/msg.hxx>
+#include <swslots.hxx>
+#include <svx/svxdlg.hxx>
+#include <svx/svdogrp.hxx>
+#include <vcl/unohelp2.hxx>
+#include <swabstdlg.hxx>
+#include <swundo.hxx>
+#include <com/sun/star/text/HoriOrientation.hpp>
+#include <com/sun/star/text/VertOrientation.hpp>
+#include <com/sun/star/text/RelOrientation.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <IDocumentDrawModelAccess.hxx>
+#include <fmtfollowtextflow.hxx>
+#include <textboxhelper.hxx>
+#include <svx/diagram/IDiagramHelper.hxx>
+
+using namespace ::com::sun::star;
+using namespace css::beans;
+using namespace css::drawing;
+using namespace css::uno;
+
+SFX_IMPL_SUPERCLASS_INTERFACE(SwDrawBaseShell, SwBaseShell)
+
+void SwDrawBaseShell::InitInterface_Impl()
+{
+}
+
+
+SwDrawBaseShell::SwDrawBaseShell(SwView &_rView)
+ : SwBaseShell(_rView)
+{
+ GetShell().NoEdit();
+
+ SwEditWin& rWin = GetView().GetEditWin();
+
+ rWin.SetBezierMode(SID_BEZIER_MOVE);
+
+ if ( !_rView.GetDrawFuncPtr() )
+ _rView.GetEditWin().StdDrawMode( SdrObjKind::NONE, true );
+
+ SwTransferable::CreateSelection( GetShell() );
+}
+
+SwDrawBaseShell::~SwDrawBaseShell()
+{
+ GetView().ExitDraw();
+ GetShell().Edit();
+ SwTransferable::ClearSelection( GetShell() );
+}
+
+void SwDrawBaseShell::Execute(SfxRequest const &rReq)
+{
+ SwWrtShell *pSh = &GetShell();
+ SdrView* pSdrView = pSh->GetDrawView();
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ sal_uInt16 nSlotId = rReq.GetSlot();
+ bool bChanged = pSdrView->GetModel().IsChanged();
+ pSdrView->GetModel().SetChanged(false);
+ const SfxPoolItem* pItem = nullptr;
+ if(pArgs)
+ pArgs->GetItemState(nSlotId, false, &pItem);
+
+ bool bAlignPossible = pSh->IsAlignPossible();
+
+ bool bTopParam = true, bBottomParam = true;
+ bool bDone = false;
+ SfxBindings& rBind = GetView().GetViewFrame().GetBindings();
+
+ switch (nSlotId)
+ {
+ case FN_DRAW_WRAP_DLG:
+ {
+ if(pSdrView->AreObjectsMarked())
+ {
+ if(!pArgs)
+ {
+ const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
+ if( rMarkList.GetMark(0) != nullptr )
+ {
+ SfxItemSetFixed<
+ RES_LR_SPACE, RES_UL_SPACE,
+ RES_SURROUND, RES_SURROUND,
+ RES_ANCHOR, RES_ANCHOR,
+ RES_WRAP_INFLUENCE_ON_OBJPOS, RES_WRAP_INFLUENCE_ON_OBJPOS,
+ SID_HTML_MODE, SID_HTML_MODE,
+ FN_DRAW_WRAP_DLG, FN_DRAW_WRAP_DLG>
+ aSet( GetPool() );
+
+ aSet.Put(SfxBoolItem(SID_HTML_MODE,
+ 0 != ::GetHtmlMode(pSh->GetView().GetDocShell())));
+
+ aSet.Put(SfxInt16Item(FN_DRAW_WRAP_DLG, pSh->GetLayerId().get()));
+
+ pSh->GetObjAttr(aSet);
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<SfxAbstractDialog> pDlg(pFact->CreateSwWrapDlg(GetView().GetFrameWeld(), aSet, pSh));
+
+ if (pDlg->Execute() == RET_OK)
+ {
+ const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
+ if(const SfxInt16Item* pWrapItem = pOutSet->GetItemIfSet(FN_DRAW_WRAP_DLG, false))
+ {
+ short nLayer = pWrapItem->GetValue();
+ if (nLayer == 1)
+ pSh->SelectionToHeaven();
+ else
+ pSh->SelectionToHell();
+ }
+
+ pSh->SetObjAttr(*pOutSet);
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case SID_ATTR_TRANSFORM:
+ {
+ if(pSdrView->AreObjectsMarked())
+ {
+ if(!pArgs)
+ {
+ const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
+ if( rMarkList.GetMark(0) != nullptr )
+ {
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ VclPtr<SfxAbstractTabDialog> pDlg;
+ bool bCaption = false;
+
+ // Allowed anchorages:
+ RndStdIds nAnchor = pSh->GetAnchorId();
+ SvxAnchorIds nAllowedAnchors = SvxAnchorIds::Paragraph | SvxAnchorIds::Character | SvxAnchorIds::Page;
+ sal_uInt16 nHtmlMode = ::GetHtmlMode(pSh->GetView().GetDocShell());
+
+ if ( pSh->IsFlyInFly() )
+ nAllowedAnchors |= SvxAnchorIds::Fly;
+
+ if (pObj->GetObjIdentifier() == SdrObjKind::Caption )
+ bCaption = true;
+
+ if (bCaption)
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ VclPtr<AbstractSvxCaptionDialog> pCaptionDlg =
+ pFact->CreateCaptionDialog( rReq.GetFrameWeld(), pSdrView, nAllowedAnchors );
+ pDlg.reset(pCaptionDlg);
+ pCaptionDlg->SetValidateFramePosLink( LINK(this, SwDrawBaseShell, ValidatePosition) );
+ }
+ else
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ VclPtr<AbstractSvxTransformTabDialog> pTransform =
+ pFact->CreateSvxTransformTabDialog(rReq.GetFrameWeld(), nullptr, pSdrView, nAllowedAnchors);
+ pDlg.reset(pTransform);
+ pTransform->SetValidateFramePosLink( LINK(this, SwDrawBaseShell, ValidatePosition) );
+ }
+ SfxItemSet aNewAttr(pSdrView->GetGeoAttrFromMarked());
+
+ const WhichRangesContainer& pRange = pDlg->GetInputRanges( *aNewAttr.GetPool() );
+ SfxItemSet aSet( *aNewAttr.GetPool(), pRange );
+ FieldUnit eMetric = ::GetDfltMetric( dynamic_cast<SwWebView*>(&GetView()) != nullptr );
+ SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)) );
+
+ aSet.Put( aNewAttr, false );
+
+ if (bCaption)
+ pSdrView->GetAttributes( aSet );
+
+ aSet.Put(SfxInt16Item(SID_ATTR_TRANSFORM_ANCHOR, static_cast<sal_Int16>(nAnchor)));
+ bool bRTL;
+ bool bVertL2R;
+ aSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_IN_VERTICAL_TEXT, pSh->IsFrameVertical(true, bRTL, bVertL2R)));
+ aSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_IN_RTL_TEXT, bRTL));
+
+ SwFrameFormat* pFrameFormat = FindFrameFormat( pObj );
+
+ aSet.Put( pFrameFormat->GetFormatAttr(RES_FOLLOW_TEXT_FLOW) );
+
+ SwFormatVertOrient aVOrient(pFrameFormat->GetFormatAttr(RES_VERT_ORIENT));
+ aSet.Put(SfxInt16Item(SID_ATTR_TRANSFORM_VERT_ORIENT, aVOrient.GetVertOrient()));
+ aSet.Put(SfxInt16Item(SID_ATTR_TRANSFORM_VERT_RELATION, aVOrient.GetRelationOrient() ));
+ aSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_VERT_POSITION, aVOrient.GetPos()));
+
+ SwFormatHoriOrient aHOrient(pFrameFormat->GetFormatAttr(RES_HORI_ORIENT));
+ aSet.Put(SfxInt16Item(SID_ATTR_TRANSFORM_HORI_ORIENT, aHOrient.GetHoriOrient()));
+ aSet.Put(SfxInt16Item(SID_ATTR_TRANSFORM_HORI_RELATION, aHOrient.GetRelationOrient() ));
+ aSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_HORI_MIRROR, aHOrient.IsPosToggle()));
+ aSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_HORI_POSITION, aHOrient.GetPos()));
+
+ aSet.Put(SfxUInt16Item(SID_HTML_MODE, nHtmlMode));
+
+ pDlg->SetInputSet( &aSet );
+
+ pDlg->StartExecuteAsync([bCaption, bChanged, pDlg, pFrameFormat, pSdrView,
+ pSh, &rMarkList, this](
+ sal_Int32 nResult){
+ pSdrView->GetModel().SetChanged(false);
+
+ if (nResult == RET_OK)
+ {
+ SwFormatVertOrient aVOrientFinal(pFrameFormat->GetFormatAttr(RES_VERT_ORIENT));
+ SwFormatHoriOrient aHOrientFinal(pFrameFormat->GetFormatAttr(RES_HORI_ORIENT));
+
+ const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
+ pSh->StartAllAction();
+
+ // #i30451#
+ pSh->StartUndo(SwUndoId::INSFMTATTR);
+
+ pSdrView->SetGeoAttrToMarked(*pOutSet);
+
+ if (bCaption)
+ pSdrView->SetAttributes(*pOutSet);
+
+ bool bPosCorr =
+ SfxItemState::SET != pOutSet->GetItemState(
+ SID_ATTR_TRANSFORM_POS_X, false ) &&
+ SfxItemState::SET != pOutSet->GetItemState(
+ SID_ATTR_TRANSFORM_POS_Y, false );
+
+ SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END - 1> aFrameAttrSet(GetPool());
+
+ bool bSingleSelection = rMarkList.GetMarkCount() == 1;
+
+ if(const SfxInt16Item* pAnchorItem = pOutSet->GetItemIfSet(
+ SID_ATTR_TRANSFORM_ANCHOR, false))
+ {
+ if(!bSingleSelection)
+ pSh->ChgAnchor(static_cast<RndStdIds>(pAnchorItem
+ ->GetValue()), false, bPosCorr );
+ else
+ {
+ SwFormatAnchor aAnchor(pFrameFormat->GetAnchor());
+ aAnchor.SetType(static_cast<RndStdIds>(pAnchorItem->GetValue()));
+ aFrameAttrSet.Put( aAnchor );
+ }
+ }
+ const SfxInt16Item* pHoriOrient =
+ pOutSet->GetItemIfSet(SID_ATTR_TRANSFORM_HORI_ORIENT, false);
+ const SfxInt16Item* pHoriRelation =
+ pOutSet->GetItemIfSet(SID_ATTR_TRANSFORM_HORI_RELATION, false);
+ const SfxInt32Item* pHoriPosition =
+ pOutSet->GetItemIfSet(SID_ATTR_TRANSFORM_HORI_POSITION, false);
+ const SfxBoolItem* pHoriMirror =
+ pOutSet->GetItemIfSet(SID_ATTR_TRANSFORM_HORI_MIRROR, false);
+ if(pHoriOrient || pHoriRelation || pHoriPosition || pHoriMirror)
+ {
+ if(pHoriOrient)
+ aHOrientFinal.SetHoriOrient(pHoriOrient->GetValue());
+ if(pHoriRelation)
+ aHOrientFinal.SetRelationOrient(pHoriRelation->GetValue());
+ if(pHoriPosition)
+ aHOrientFinal.SetPos( pHoriPosition->GetValue());
+ if(pHoriMirror)
+ aHOrientFinal.SetPosToggle( pHoriMirror->GetValue());
+ aFrameAttrSet.Put(aHOrientFinal);
+ }
+
+ const SfxInt16Item* pVertOrient =
+ pOutSet->GetItemIfSet(SID_ATTR_TRANSFORM_VERT_ORIENT, false);
+ const SfxInt16Item* pVertRelation =
+ pOutSet->GetItemIfSet(SID_ATTR_TRANSFORM_VERT_RELATION, false);
+ const SfxInt32Item* pVertPosition =
+ pOutSet->GetItemIfSet(SID_ATTR_TRANSFORM_VERT_POSITION, false);
+ if(pVertOrient || pVertRelation || pVertPosition )
+ {
+ if(pVertOrient)
+ aVOrientFinal.SetVertOrient(pVertOrient->GetValue());
+ if(pVertRelation)
+ aVOrientFinal.SetRelationOrient(pVertRelation->GetValue());
+ if(pVertPosition)
+ aVOrientFinal.SetPos( pVertPosition->GetValue());
+ aFrameAttrSet.Put( aVOrientFinal );
+ }
+ const SwFormatFollowTextFlow* pFollowItem =
+ pOutSet->GetItemIfSet(RES_FOLLOW_TEXT_FLOW, false);
+ if(pFollowItem)
+ aFrameAttrSet.Put(*pFollowItem);
+
+ if(aFrameAttrSet.Count())
+ pSh->SetDrawingAttr(aFrameAttrSet);
+
+ GetView().GetViewFrame().GetBindings().InvalidateAll(false);
+
+ // #i30451#
+ pSh->EndUndo( SwUndoId::INSFMTATTR );
+
+ pSh->EndAllAction();
+ }
+
+ if (pSdrView->GetModel().IsChanged())
+ pSh->SetModified();
+ else if (bChanged)
+ pSdrView->GetModel().SetChanged();
+
+ pDlg->disposeOnce();
+ });
+ }
+ }
+ else
+ {
+ pSh->StartAllAction();
+ pSdrView->SetGeoAttrToMarked( *pArgs );
+ const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ if (pObj)
+ {
+ SwFrameFormat* pFrameFormat = FindFrameFormat(pObj);
+ if (pFrameFormat)
+ {
+ const SwFormatAnchor& rAnchor = pFrameFormat->GetAnchor();
+ // Don't change shape position / size, just update the anchor doc model
+ // position.
+ pSh->ChgAnchor(rAnchor.GetAnchorId(), /*bSameOnly=*/true);
+ }
+ }
+ pSh->EndAllAction();
+ }
+ }
+ }
+ break;
+
+ case SID_DELETE:
+ case FN_BACKSPACE:
+ if (pSh->IsObjSelected() && !pSdrView->IsTextEdit())
+ {
+ bDone = true;
+
+ const Point aPt = pSh->GetObjRect().TopLeft(); // tdf#150589
+
+ if( GetView().IsDrawRotate() )
+ {
+ pSh->SetDragMode( SdrDragMode::Move );
+ GetView().FlipDrawRotate();
+ }
+
+ pSh->SetModified();
+ pSh->DelSelectedObj();
+
+ if (rReq.IsAPI() ||
+ GetView().GetEditWin().IsObjectSelect() )
+ {
+ // If basic call, then back to the text shell, because the
+ // Basic otherwise has no possibility to return.
+ if (GetView().GetDrawFuncPtr())
+ {
+ GetView().GetDrawFuncPtr()->Deactivate();
+ GetView().SetDrawFuncPtr(nullptr);
+ }
+ GetView().LeaveDrawCreate(); // Switch to selection mode
+ }
+
+ if (pSh->IsSelFrameMode())
+ {
+ pSh->LeaveSelFrameMode();
+ // #105852# FME <- perhaps fixed by tdf#150589
+ static_cast<SwEditShell*>(pSh)->SetCursor(aPt);
+ }
+
+ }
+ break;
+
+ case SID_GROUP:
+ if (pSh->IsObjSelected() > 1 && pSh->IsGroupAllowed())
+ {
+ pSh->GroupSelection();
+ rBind.Invalidate(SID_UNGROUP);
+ }
+ break;
+
+ case SID_UNGROUP:
+ if (pSh->IsGroupSelected(true) && pSh->IsUnGroupAllowed())
+ {
+ pSh->UnGroupSelection();
+ rBind.Invalidate(SID_GROUP);
+ }
+ break;
+
+ case SID_ENTER_GROUP:
+ if (pSh->IsGroupSelected(false))
+ {
+ pSdrView->EnterMarkedGroup();
+ rBind.InvalidateAll(false);
+ }
+ break;
+
+ case SID_LEAVE_GROUP:
+ if (pSdrView->IsGroupEntered())
+ {
+ pSdrView->LeaveOneGroup();
+ rBind.Invalidate(SID_ENTER_GROUP);
+ rBind.Invalidate(SID_UNGROUP);
+ }
+ break;
+
+ case SID_REGENERATE_DIAGRAM:
+ case SID_EDIT_DIAGRAM:
+ {
+ const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
+
+ if (1 == rMarkList.GetMarkCount())
+ {
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+
+ // Support advanced DiagramHelper
+ if(nullptr != pObj && pObj->isDiagram())
+ {
+ if(SID_REGENERATE_DIAGRAM == nSlotId)
+ {
+ pSdrView->UnmarkAll();
+ pObj->getDiagramHelper()->reLayout(*static_cast<SdrObjGroup*>(pObj));
+ pSdrView->MarkObj(pObj, pSdrView->GetSdrPageView());
+ }
+ else // SID_EDIT_DIAGRAM
+ {
+ VclAbstractDialogFactory* pFact = VclAbstractDialogFactory::Create();
+ ScopedVclPtr<VclAbstractDialog> pDlg = pFact->CreateDiagramDialog(
+ GetView().GetFrameWeld(),
+ *static_cast<SdrObjGroup*>(pObj));
+ pDlg->Execute();
+ }
+ }
+ }
+ }
+ break;
+
+ case SID_OBJECT_ALIGN_LEFT:
+ case SID_OBJECT_ALIGN_CENTER:
+ case SID_OBJECT_ALIGN_RIGHT:
+ case SID_OBJECT_ALIGN_UP:
+ case SID_OBJECT_ALIGN_MIDDLE:
+ case SID_OBJECT_ALIGN_DOWN:
+ {
+ if ( bAlignPossible )
+ {
+ const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
+ if (rMarkList.GetMarkCount() == 1
+ && !SwTextBoxHelper::hasTextFrame(rMarkList.GetMark(0)->GetMarkedSdrObj()))
+ {
+ sal_Int16 nHorizOrient = -1, nVertOrient = -1;
+
+ switch (nSlotId)
+ {
+ case SID_OBJECT_ALIGN_LEFT:
+ nHorizOrient = text::HoriOrientation::LEFT;
+ break;
+ case SID_OBJECT_ALIGN_CENTER:
+ nHorizOrient = text::HoriOrientation::CENTER;
+ break;
+ case SID_OBJECT_ALIGN_RIGHT:
+ nHorizOrient = text::HoriOrientation::RIGHT;
+ break;
+ case SID_OBJECT_ALIGN_UP:
+ nVertOrient = text::VertOrientation::TOP;
+ break;
+ case SID_OBJECT_ALIGN_MIDDLE:
+ nVertOrient = text::VertOrientation::CENTER;
+ break;
+ case SID_OBJECT_ALIGN_DOWN:
+ nVertOrient = text::VertOrientation::BOTTOM;
+ break;
+ default:
+ break;
+ }
+
+ if (nHorizOrient != -1)
+ {
+ pSh->StartAction();
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ SwFrameFormat* pFrameFormat = FindFrameFormat( pObj );
+ SwFormatHoriOrient aHOrient(pFrameFormat->GetFormatAttr(RES_HORI_ORIENT));
+ aHOrient.SetHoriOrient( nHorizOrient );
+ pFrameFormat->SetFormatAttr(aHOrient);
+ pSh->EndAction();
+ }
+
+ if (nVertOrient != -1)
+ {
+ pSh->StartAction();
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ SwFrameFormat* pFrameFormat = FindFrameFormat( pObj );
+ SwFormatVertOrient aVOrient(pFrameFormat->GetFormatAttr(RES_VERT_ORIENT));
+ aVOrient.SetVertOrient( nVertOrient );
+ pFrameFormat->SetFormatAttr(aVOrient);
+ pSh->EndAction();
+ }
+
+ break;
+ }
+
+ pSh->StartAction();
+ switch (nSlotId)
+ {
+ case SID_OBJECT_ALIGN_LEFT:
+ pSdrView->AlignMarkedObjects(SdrHorAlign::Left, SdrVertAlign::NONE);
+ break;
+ case SID_OBJECT_ALIGN_CENTER:
+ pSdrView->AlignMarkedObjects(SdrHorAlign::Center, SdrVertAlign::NONE);
+ break;
+ case SID_OBJECT_ALIGN_RIGHT:
+ pSdrView->AlignMarkedObjects(SdrHorAlign::Right, SdrVertAlign::NONE);
+ break;
+ case SID_OBJECT_ALIGN_UP:
+ pSdrView->AlignMarkedObjects(SdrHorAlign::NONE, SdrVertAlign::Top);
+ break;
+ case SID_OBJECT_ALIGN_MIDDLE:
+ pSdrView->AlignMarkedObjects(SdrHorAlign::NONE, SdrVertAlign::Center);
+ break;
+ case SID_OBJECT_ALIGN_DOWN:
+ pSdrView->AlignMarkedObjects(SdrHorAlign::NONE, SdrVertAlign::Bottom);
+ break;
+ }
+ pSh->EndAction();
+ }
+ }
+ break;
+
+ case FN_FRAME_UP:
+ bTopParam = false;
+ [[fallthrough]];
+ case SID_FRAME_TO_TOP:
+ pSh->SelectionToTop( bTopParam );
+ break;
+
+ case FN_FRAME_DOWN:
+ bBottomParam = false;
+ [[fallthrough]];
+ case SID_FRAME_TO_BOTTOM:
+ pSh->SelectionToBottom( bBottomParam );
+ break;
+
+ case FN_NAME_SHAPE:
+ {
+ bDone = true;
+
+ if(1 == pSdrView->GetMarkedObjectCount())
+ {
+ // #i68101#
+ SdrObject* pSelected = pSdrView->GetMarkedObjectByIndex(0);
+ OSL_ENSURE(pSelected, "DrawViewShell::FuTemp03: nMarkCount, but no object (!)");
+ OUString aName(pSelected->GetName());
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxObjectNameDialog> pDlg(pFact->CreateSvxObjectNameDialog(GetView().GetFrameWeld(), aName));
+
+ pDlg->SetCheckNameHdl(LINK(this, SwDrawBaseShell, CheckGroupShapeNameHdl));
+
+ if(RET_OK == pDlg->Execute())
+ {
+ const OUString aOrigName = aName;
+ pDlg->GetName(aName);
+ pSelected->SetName(aName);
+ pSh->SetModified();
+
+ // update accessibility sidebar object name if we modify the object name on the navigator bar
+ if (!aName.isEmpty() && aOrigName != aName)
+ {
+ if (SwNode* pSwNode = FindFrameFormat(pSelected)->GetAnchor().GetAnchorNode())
+ pSwNode->resetAndQueueAccessibilityCheck(true);
+ }
+ }
+ }
+
+ break;
+ }
+
+ // #i68101#
+ case FN_TITLE_DESCRIPTION_SHAPE:
+ {
+ bDone = true;
+
+ if(1 == pSdrView->GetMarkedObjectCount())
+ {
+ SdrObject* pSelected = pSdrView->GetMarkedObjectByIndex(0);
+ OSL_ENSURE(pSelected, "DrawViewShell::FuTemp03: nMarkCount, but no object (!)");
+ OUString aTitle(pSelected->GetTitle());
+ OUString aDescription(pSelected->GetDescription());
+ bool isDecorative(pSelected->IsDecorative());
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxObjectTitleDescDialog> pDlg(pFact->CreateSvxObjectTitleDescDialog(GetView().GetFrameWeld(),
+ aTitle, aDescription, isDecorative));
+
+ if(RET_OK == pDlg->Execute())
+ {
+ pDlg->GetTitle(aTitle);
+ pDlg->GetDescription(aDescription);
+ pDlg->IsDecorative(isDecorative);
+
+ pSelected->SetTitle(aTitle);
+ pSelected->SetDescription(aDescription);
+ pSelected->SetDecorative(isDecorative);
+
+ pSh->SetModified();
+ }
+ }
+
+ break;
+ }
+
+ case SID_OPEN_HYPERLINK:
+ {
+ const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ LoadURL(GetShell(), pObj->getHyperlink(), LoadUrlFlags::NewView,
+ /*rTargetFrameName=*/OUString());
+ break;
+ }
+
+ case SID_EDIT_HYPERLINK:
+ case SID_HYPERLINK_DIALOG:
+ {
+ GetView().GetViewFrame().SetChildWindow(SID_HYPERLINK_DIALOG, true);
+ break;
+ }
+
+ case SID_HYPERLINK_SETLINK:
+ {
+ if(pItem)
+ {
+ const SvxHyperlinkItem& rHLinkItem = *static_cast<const SvxHyperlinkItem *>(pItem);
+ const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ pObj->setHyperlink(rHLinkItem.GetURL());
+ }
+ break;
+ }
+
+ case SID_REMOVE_HYPERLINK:
+ {
+ const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ pObj->setHyperlink(OUString());
+ break;
+ }
+
+ case SID_COPY_HYPERLINK_LOCATION:
+ {
+ const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ uno::Reference<datatransfer::clipboard::XClipboard> xClipboard
+ = GetView().GetEditWin().GetClipboard();
+ vcl::unohelper::TextDataObject::CopyStringTo(pObj->getHyperlink(), xClipboard);
+ break;
+ }
+
+ default:
+ OSL_ENSURE(false, "wrong Dispatcher");
+ return;
+ }
+ if(!bDone)
+ {
+ if(nSlotId >= SID_OBJECT_ALIGN_LEFT && nSlotId <= SID_OBJECT_ALIGN_DOWN)
+ rBind.Invalidate(SID_ATTR_LONG_LRSPACE);
+ if (pSdrView->GetModel().IsChanged())
+ pSh->SetModified();
+ else if (bChanged)
+ pSdrView->GetModel().SetChanged();
+ }
+}
+
+// Checks whether a given name is allowed for a group shape
+
+IMPL_LINK( SwDrawBaseShell, CheckGroupShapeNameHdl, AbstractSvxObjectNameDialog&, rNameDialog, bool )
+{
+ SwWrtShell &rSh = GetShell();
+ SdrView *pSdrView = rSh.GetDrawView();
+ const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
+ OSL_ENSURE(rMarkList.GetMarkCount() == 1, "wrong draw selection");
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ const OUString sCurrentName = pObj->GetName();
+ OUString sNewName;
+ rNameDialog.GetName(sNewName);
+ bool bRet = false;
+ if (sNewName.isEmpty() || sCurrentName == sNewName)
+ bRet = true;
+ else
+ {
+ bRet = true;
+ SwDrawModel* pModel = rSh.getIDocumentDrawModelAccess().GetDrawModel();
+ SdrObjListIter aIter( pModel->GetPage(0), SdrIterMode::DeepWithGroups );
+ while( aIter.IsMore() )
+ {
+ SdrObject* pTempObj = aIter.Next();
+ if ( pObj != pTempObj && pTempObj->GetName() == sNewName )
+ {
+ bRet = false;
+ break;
+ }
+ }
+ }
+ return bRet;
+}
+
+void SwDrawBaseShell::GetState(SfxItemSet& rSet)
+{
+ SwWrtShell &rSh = GetShell();
+ SdrView* pSdrView = rSh.GetDrawViewWithValidMarkList();
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ bool bProtected = rSh.IsSelObjProtected(FlyProtectFlags::Content) != FlyProtectFlags::NONE;
+
+ if (!bProtected) // Look in the parent
+ bProtected |= rSh.IsSelObjProtected( FlyProtectFlags::Content|FlyProtectFlags::Parent ) != FlyProtectFlags::NONE;
+
+ while( nWhich )
+ {
+ switch( nWhich )
+ {
+ case FN_DRAW_WRAP_DLG:
+ case SID_ATTR_TRANSFORM:
+ case SID_FRAME_TO_TOP:
+ case SID_FRAME_TO_BOTTOM:
+ case FN_FRAME_UP:
+ case FN_FRAME_DOWN:
+ case SID_DELETE:
+ case FN_BACKSPACE:
+ if( bProtected || !rSh.IsObjSelected() )
+ rSet.DisableItem( nWhich );
+ break;
+ case SID_GROUP:
+ if ( rSh.IsObjSelected() < 2 || bProtected || !rSh.IsGroupAllowed() )
+ rSet.DisableItem( nWhich );
+ break;
+ case SID_UNGROUP:
+ if ( !rSh.IsGroupSelected(true) || bProtected || !rSh.IsUnGroupAllowed() )
+ rSet.DisableItem( nWhich );
+ break;
+ case SID_ENTER_GROUP:
+ if ( !rSh.IsGroupSelected(false) )
+ rSet.DisableItem( nWhich );
+ break;
+ case SID_LEAVE_GROUP:
+ if ( !pSdrView->IsGroupEntered() )
+ rSet.DisableItem( nWhich );
+ break;
+ case SID_OBJECT_ALIGN_LEFT:
+ case SID_OBJECT_ALIGN_CENTER:
+ case SID_OBJECT_ALIGN_RIGHT:
+ case SID_OBJECT_ALIGN_UP:
+ case SID_OBJECT_ALIGN_MIDDLE:
+ case SID_OBJECT_ALIGN_DOWN:
+ case SID_OBJECT_ALIGN:
+ {
+ bool bDisableThis = false;
+ bool bDisableHoriz = false;
+ bool bHoriz = (nWhich == SID_OBJECT_ALIGN_LEFT || nWhich == SID_OBJECT_ALIGN_CENTER ||
+ nWhich == SID_OBJECT_ALIGN_RIGHT);
+ bool bVert = (nWhich == SID_OBJECT_ALIGN_UP || nWhich == SID_OBJECT_ALIGN_MIDDLE ||
+ nWhich == SID_OBJECT_ALIGN_DOWN);
+ const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
+ if ( !rSh.IsAlignPossible() || bProtected )
+ {
+ bDisableThis = true;
+ rSet.DisableItem( nWhich );
+ }
+ else if ( rSh.GetAnchorId() == RndStdIds::FLY_AS_CHAR )
+ {
+ //if only one object is selected it can only be vertically
+ // aligned because it is character bound
+ if( rMarkList.GetMarkCount() == 1 )
+ {
+ bDisableHoriz = true;
+ rSet.DisableItem(SID_OBJECT_ALIGN_LEFT);
+ rSet.DisableItem(SID_OBJECT_ALIGN_CENTER);
+ rSet.DisableItem(SID_OBJECT_ALIGN_RIGHT);
+ }
+ }
+
+ if (bHoriz && !bDisableThis && !bDisableHoriz &&
+ rMarkList.GetMarkCount() == 1)
+ {
+ sal_Int16 nHoriOrient = -1;
+ switch(nWhich)
+ {
+ case SID_OBJECT_ALIGN_LEFT:
+ nHoriOrient = text::HoriOrientation::LEFT;
+ break;
+ case SID_OBJECT_ALIGN_CENTER:
+ nHoriOrient = text::HoriOrientation::CENTER;
+ break;
+ case SID_OBJECT_ALIGN_RIGHT:
+ nHoriOrient = text::HoriOrientation::RIGHT;
+ break;
+ default:
+ break;
+ }
+
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ SwFrameFormat* pFrameFormat = FindFrameFormat(pObj);
+ SwFormatHoriOrient aHOrient(pFrameFormat->GetFormatAttr(RES_HORI_ORIENT));
+ rSet.Put(SfxBoolItem(nWhich, aHOrient.GetHoriOrient() == nHoriOrient));
+ }
+
+ if (bVert && !bDisableThis && rMarkList.GetMarkCount() == 1)
+ {
+ sal_Int16 nVertOrient = -1;
+ switch(nWhich)
+ {
+ case SID_OBJECT_ALIGN_UP:
+ nVertOrient = text::VertOrientation::TOP;
+ break;
+ case SID_OBJECT_ALIGN_MIDDLE:
+ nVertOrient = text::VertOrientation::CENTER;
+ break;
+ case SID_OBJECT_ALIGN_DOWN:
+ nVertOrient = text::VertOrientation::BOTTOM;
+ break;
+ default:
+ break;
+ }
+
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ SwFrameFormat* pFrameFormat = FindFrameFormat(pObj);
+ SwFormatVertOrient aVOrient(pFrameFormat->GetFormatAttr(RES_VERT_ORIENT));
+ rSet.Put(SfxBoolItem(nWhich, aVOrient.GetVertOrient() == nVertOrient));
+ }
+ }
+ break;
+
+ case FN_NAME_SHAPE :
+ {
+ if(1 != pSdrView->GetMarkedObjectCount())
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ // #i68101#
+ case FN_TITLE_DESCRIPTION_SHAPE:
+ {
+ const bool bIsWebView(nullptr != dynamic_cast<SwWebView*>(&GetView()));
+
+ if(!bIsWebView && 1 != pSdrView->GetMarkedObjectCount())
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case SID_OPEN_HYPERLINK:
+ case SID_EDIT_HYPERLINK:
+ case SID_HYPERLINK_DIALOG:
+ case SID_REMOVE_HYPERLINK:
+ case SID_COPY_HYPERLINK_LOCATION:
+ {
+ if (pSdrView->GetMarkedObjectCount() != 1)
+ {
+ rSet.DisableItem(nWhich);
+ break;
+ }
+
+ const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ SdrObjKind nObjType = pObj->GetObjIdentifier();
+
+ // Only enable hyperlink for the following types
+ switch (nObjType)
+ {
+ case SdrObjKind::PathFill:
+ case SdrObjKind::CircleSection:
+ case SdrObjKind::Line:
+ case SdrObjKind::CustomShape:
+ case SdrObjKind::Text:
+ case SdrObjKind::Rectangle:
+ case SdrObjKind::Caption:
+ case SdrObjKind::Polygon:
+ case SdrObjKind::PolyLine:
+ case SdrObjKind::E3D_Scene:
+ case SdrObjKind::Measure:
+ case SdrObjKind::Edge:
+ break;
+ default:
+ rSet.DisableItem(nWhich);
+ break;
+ }
+
+ if (nWhich == SID_OPEN_HYPERLINK || nWhich == SID_REMOVE_HYPERLINK
+ || nWhich == SID_EDIT_HYPERLINK || nWhich == SID_COPY_HYPERLINK_LOCATION)
+ {
+ if (pObj->getHyperlink().isEmpty())
+ rSet.DisableItem(nWhich);
+ }
+ }
+ break;
+
+ case SID_HYPERLINK_GETLINK:
+ {
+ const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
+ if (rMarkList.GetMark(0) != nullptr)
+ {
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ OUString sHyperLink = pObj->getHyperlink();
+ SvxHyperlinkItem aHLinkItem;
+ aHLinkItem.SetURL(sHyperLink);
+ rSet.Put(aHLinkItem);
+ }
+ }
+ break;
+
+ case SID_REGENERATE_DIAGRAM:
+ case SID_EDIT_DIAGRAM:
+ {
+ bool bDisable(true);
+ const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
+ if (nullptr != rMarkList.GetMark(0))
+ {
+ SdrObject* pObj(rMarkList.GetMark(0)->GetMarkedSdrObj());
+
+ if(nullptr != pObj && pObj->isDiagram())
+ {
+ bDisable = false;
+ }
+ }
+
+ if(bDisable)
+ {
+ rSet.DisableItem(nWhich);
+ }
+ }
+ break;
+
+
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void SwDrawBaseShell::GetDrawAttrStateForIFBX( SfxItemSet& rSet )
+{
+ SwWrtShell *pSh = &GetShell();
+ SdrView* pSdrView = pSh->GetDrawView();
+ const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
+ if( rMarkList.GetMark(0) != nullptr )
+ {
+ SfxItemSet aNewAttr(pSdrView->GetGeoAttrFromMarked());
+ rSet.Put(aNewAttr,false);
+ }
+}
+
+bool SwDrawBaseShell::Disable(SfxItemSet& rSet, sal_uInt16 nWhich)
+{
+ bool bDisable = GetShell().IsSelObjProtected(FlyProtectFlags::Content) != FlyProtectFlags::NONE;
+
+ if (bDisable)
+ {
+ if (nWhich)
+ rSet.DisableItem( nWhich );
+ else
+ {
+ SfxWhichIter aIter( rSet );
+ nWhich = aIter.FirstWhich();
+ while (nWhich)
+ {
+ rSet.DisableItem( nWhich );
+ nWhich = aIter.NextWhich();
+ }
+ }
+ }
+
+ return bDisable;
+}
+
+void SwDrawBaseShell::DisableState( SfxItemSet& rSet )
+{
+ SwWrtShell *pSh = &GetShell();
+ SdrView* pSdrView = pSh->GetDrawView();
+ const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
+ const size_t nMarkCount = rMarkList.GetMarkCount();
+ bool bShowArea = true, bShowMeasure = true;
+
+ for (size_t i = 0; i < nMarkCount && i < 50; ++i)
+ {
+ SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
+ SdrObjKind nObjType = pObj->GetObjIdentifier();
+
+ if ( nObjType != SdrObjKind::Measure )
+ bShowMeasure = false;
+
+ // If marked object is 2D, disable format area command.
+ if ( nObjType == SdrObjKind::PolyLine ||
+ nObjType == SdrObjKind::Line ||
+ nObjType == SdrObjKind::PathLine ||
+ nObjType == SdrObjKind::FreehandLine ||
+ nObjType == SdrObjKind::Edge ||
+ nObjType == SdrObjKind::CircleArc ||
+ bShowMeasure )
+ bShowArea = false;
+
+ if (!bShowArea && !bShowMeasure)
+ break;
+ }
+
+ if (!bShowArea)
+ rSet.DisableItem(SID_ATTRIBUTES_AREA);
+
+ if (!bShowMeasure)
+ rSet.DisableItem(SID_MEASURE_DLG);
+
+ Disable(rSet);
+
+}
+
+// Validate of drawing positions
+
+IMPL_LINK(SwDrawBaseShell, ValidatePosition, SvxSwFrameValidation&, rValidation, void )
+{
+ SwWrtShell *pSh = &GetShell();
+ rValidation.nMinHeight = MINFLY;
+ rValidation.nMinWidth = MINFLY;
+
+ SwRect aBoundRect;
+
+ // OD 18.09.2003 #i18732# - adjustment for allowing vertical position
+ // aligned to page for fly frame anchored to paragraph or to character.
+ const RndStdIds eAnchorType = rValidation.nAnchorType;
+ const SwFormatAnchor* pAnchor = nullptr;
+ SdrView* pSdrView = pSh->GetDrawView();
+ const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
+ if( rMarkList.GetMarkCount() == 1 )
+ {
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ SwFrameFormat* pFrameFormat = FindFrameFormat( pObj );
+ pAnchor = &pFrameFormat->GetAnchor();
+ }
+
+ pSh->CalcBoundRect( aBoundRect, eAnchorType,
+ rValidation.nHRelOrient,
+ rValidation.nVRelOrient,
+ pAnchor,
+ rValidation.bFollowTextFlow,
+ rValidation.bMirror, nullptr, &rValidation.aPercentSize);
+
+ bool bIsInVertical( false );
+ {
+ bool bRTL;
+ bool bVertL2R;
+ bIsInVertical = pSh->IsFrameVertical(true, bRTL, bVertL2R);
+ }
+ if(bIsInVertical)
+ {
+ Point aPos(aBoundRect.Pos());
+ tools::Long nTmp = aPos.X();
+ aPos.setX( aPos.Y() );
+ aPos.setY( nTmp );
+ Size aSize(aBoundRect.SSize());
+ nTmp = aSize.Width();
+ aSize.setWidth( aSize.Height() );
+ aSize.setHeight( nTmp );
+ aBoundRect.Chg( aPos, aSize );
+ //exchange width/height to enable correct values
+ nTmp = rValidation.nWidth;
+ rValidation.nWidth = rValidation.nHeight;
+ rValidation.nHeight = nTmp;
+ }
+ if ((eAnchorType == RndStdIds::FLY_AT_PAGE) || (eAnchorType == RndStdIds::FLY_AT_FLY))
+ {
+ // MinimalPosition
+ rValidation.nMinHPos = aBoundRect.Left();
+ rValidation.nMinVPos = aBoundRect.Top();
+ SwTwips nH = rValidation.nHPos;
+ SwTwips nV = rValidation.nVPos;
+
+ if (rValidation.nHPos + rValidation.nWidth > aBoundRect.Right())
+ {
+ if (rValidation.nHoriOrient == text::HoriOrientation::NONE)
+ {
+ rValidation.nHPos -= ((rValidation.nHPos + rValidation.nWidth) - aBoundRect.Right());
+ nH = rValidation.nHPos;
+ }
+ else
+ rValidation.nWidth = aBoundRect.Right() - rValidation.nHPos;
+ }
+
+ if (rValidation.nHPos + rValidation.nWidth > aBoundRect.Right())
+ rValidation.nWidth = aBoundRect.Right() - rValidation.nHPos;
+
+ if (rValidation.nVPos + rValidation.nHeight > aBoundRect.Bottom())
+ {
+ if (rValidation.nVertOrient == text::VertOrientation::NONE)
+ {
+ rValidation.nVPos -= ((rValidation.nVPos + rValidation.nHeight) - aBoundRect.Bottom());
+ nV = rValidation.nVPos;
+ }
+ else
+ rValidation.nHeight = aBoundRect.Bottom() - rValidation.nVPos;
+ }
+
+ if (rValidation.nVPos + rValidation.nHeight > aBoundRect.Bottom())
+ rValidation.nHeight = aBoundRect.Bottom() - rValidation.nVPos;
+
+ if ( rValidation.nVertOrient != text::VertOrientation::NONE )
+ nV = aBoundRect.Top();
+
+ if ( rValidation.nHoriOrient != text::HoriOrientation::NONE )
+ nH = aBoundRect.Left();
+
+ rValidation.nMaxHPos = aBoundRect.Right() - rValidation.nWidth;
+ rValidation.nMaxHeight = aBoundRect.Bottom() - nV;
+
+ rValidation.nMaxVPos = aBoundRect.Bottom() - rValidation.nHeight;
+ rValidation.nMaxWidth = aBoundRect.Right() - nH;
+ }
+ else if ((eAnchorType == RndStdIds::FLY_AT_PARA) || (eAnchorType == RndStdIds::FLY_AT_CHAR))
+ {
+ if (rValidation.nHPos + rValidation.nWidth > aBoundRect.Right())
+ {
+ if (rValidation.nHoriOrient == text::HoriOrientation::NONE)
+ {
+ rValidation.nHPos -= ((rValidation.nHPos + rValidation.nWidth) - aBoundRect.Right());
+ }
+ else
+ rValidation.nWidth = aBoundRect.Right() - rValidation.nHPos;
+ }
+
+ // OD 29.09.2003 #i17567#, #i18732# - consider following the text flow
+ // and alignment at page areas.
+ const bool bMaxVPosAtBottom = !rValidation.bFollowTextFlow ||
+ rValidation.nVRelOrient == text::RelOrientation::PAGE_FRAME ||
+ rValidation.nVRelOrient == text::RelOrientation::PAGE_PRINT_AREA ||
+ rValidation.nVRelOrient == text::RelOrientation::PAGE_PRINT_AREA_BOTTOM;
+ {
+ SwTwips nTmpMaxVPos = ( bMaxVPosAtBottom
+ ? aBoundRect.Bottom()
+ : aBoundRect.Height() ) -
+ rValidation.nHeight;
+ if ( rValidation.nVPos > nTmpMaxVPos )
+ {
+ if (rValidation.nVertOrient == text::VertOrientation::NONE)
+ {
+ rValidation.nVPos = nTmpMaxVPos;
+ }
+ else
+ {
+ rValidation.nHeight = ( bMaxVPosAtBottom
+ ? aBoundRect.Bottom()
+ : aBoundRect.Height() ) - rValidation.nVPos;
+ }
+ }
+ }
+
+ rValidation.nMinHPos = aBoundRect.Left();
+ rValidation.nMaxHPos = aBoundRect.Right() - rValidation.nWidth;
+
+ rValidation.nMinVPos = aBoundRect.Top();
+ // OD 26.09.2003 #i17567#, #i18732# - determine maximum vertical position
+ if ( bMaxVPosAtBottom )
+ {
+ rValidation.nMaxVPos = aBoundRect.Bottom() - rValidation.nHeight;
+ }
+ else
+ {
+ rValidation.nMaxVPos = aBoundRect.Height() - rValidation.nHeight;
+ }
+
+ // Maximum width height
+ const SwTwips nH = ( rValidation.nHoriOrient != text::HoriOrientation::NONE )
+ ? aBoundRect.Left()
+ : rValidation.nHPos;
+ const SwTwips nV = ( rValidation.nVertOrient != text::VertOrientation::NONE )
+ ? aBoundRect.Top()
+ : rValidation.nVPos;
+ rValidation.nMaxHeight = rValidation.nMaxVPos + rValidation.nHeight - nV;
+ rValidation.nMaxWidth = rValidation.nMaxHPos + rValidation.nWidth - nH;
+ }
+ else if (eAnchorType == RndStdIds::FLY_AS_CHAR)
+ {
+ rValidation.nMinHPos = 0;
+ rValidation.nMaxHPos = 0;
+
+ rValidation.nMaxHeight = aBoundRect.Height();
+ rValidation.nMaxWidth = aBoundRect.Width();
+
+ rValidation.nMaxVPos = aBoundRect.Height();
+ rValidation.nMinVPos = -aBoundRect.Height() + rValidation.nHeight;
+ if (rValidation.nMaxVPos < rValidation.nMinVPos)
+ {
+ rValidation.nMinVPos = rValidation.nMaxVPos;
+ rValidation.nMaxVPos = -aBoundRect.Height();
+ }
+ }
+ if(bIsInVertical)
+ {
+ //restore width/height exchange
+ tools::Long nTmp = rValidation.nWidth;
+ rValidation.nWidth = rValidation.nHeight;
+ rValidation.nHeight = nTmp;
+ }
+
+ if (rValidation.nMaxWidth < rValidation.nWidth)
+ rValidation.nWidth = rValidation.nMaxWidth;
+ if (rValidation.nMaxHeight < rValidation.nHeight)
+ rValidation.nHeight = rValidation.nMaxHeight;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/drwtxtex.cxx b/sw/source/uibase/shells/drwtxtex.cxx
new file mode 100644
index 0000000000..4d8dd6304e
--- /dev/null
+++ b/sw/source/uibase/shells/drwtxtex.cxx
@@ -0,0 +1,1241 @@
+/* -*- 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 <com/sun/star/linguistic2/XThesaurus.hpp>
+
+#include <comphelper/string.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/request.hxx>
+#include <svx/svdview.hxx>
+#include <editeng/spltitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/orphitem.hxx>
+#include <editeng/formatbreakitem.hxx>
+#include <editeng/widwitem.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/escapementitem.hxx>
+#include <editeng/lspcitem.hxx>
+#include <editeng/flstitem.hxx>
+#include <editeng/adjustitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/urlfieldhelper.hxx>
+#include <svx/svdoutl.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svl/stritem.hxx>
+#include <svl/whiter.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/ctloptions.hxx>
+#include <svl/languageoptions.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/editstat.hxx>
+#include <svx/clipfmtitem.hxx>
+#include <svx/hlnkitem.hxx>
+#include <svx/svxdlg.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <editeng/writingmodeitem.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/editview.hxx>
+#include <vcl/unohelp2.hxx>
+#include <editeng/hyphenzoneitem.hxx>
+#include <osl/diagnose.h>
+
+#include <cmdid.h>
+#include <doc.hxx>
+#include <drwtxtsh.hxx>
+#include <edtwin.hxx>
+#include <hintids.hxx>
+#include <langhelper.hxx>
+#include <chrdlgmodes.hxx>
+#include <swmodule.hxx>
+#include <uitool.hxx>
+#include <viewopt.hxx>
+#include <wrtsh.hxx>
+#include <wview.hxx>
+
+#include <swabstdlg.hxx>
+
+using namespace ::com::sun::star;
+
+void SwDrawTextShell::Execute( SfxRequest &rReq )
+{
+ SwWrtShell &rSh = GetShell();
+ OutlinerView* pOLV = m_pSdrView->GetTextEditOutlinerView();
+ SfxItemSet aEditAttr(pOLV->GetAttribs());
+ SfxItemSet aNewAttr(*aEditAttr.GetPool(), aEditAttr.GetRanges());
+
+ const sal_uInt16 nSlot = rReq.GetSlot();
+
+ const sal_uInt16 nWhich = GetPool().GetWhich(nSlot);
+ std::unique_ptr<SfxItemSet> pNewAttrs(rReq.GetArgs() ? rReq.GetArgs()->Clone() : nullptr);
+
+ bool bRestoreSelection = false;
+ ESelection aOldSelection;
+
+ sal_uInt16 nEEWhich = 0;
+ switch (nSlot)
+ {
+ case SID_LANGUAGE_STATUS:
+ {
+ aOldSelection = pOLV->GetSelection();
+ if (!pOLV->GetEditView().HasSelection())
+ {
+ pOLV->GetEditView().SelectCurrentWord();
+ }
+
+ bRestoreSelection = SwLangHelper::SetLanguageStatus(pOLV,rReq,GetView(),rSh);
+ break;
+ }
+
+ case SID_THES:
+ {
+ OUString aReplaceText;
+ const SfxStringItem* pItem2 = rReq.GetArg(FN_PARAM_THES_WORD_REPLACE);
+ if (pItem2)
+ aReplaceText = pItem2->GetValue();
+ if (!aReplaceText.isEmpty())
+ ReplaceTextWithSynonym( pOLV->GetEditView(), aReplaceText );
+ break;
+ }
+
+ case SID_ATTR_CHAR_FONT:
+ case SID_ATTR_CHAR_FONTHEIGHT:
+ case SID_ATTR_CHAR_WEIGHT:
+ case SID_ATTR_CHAR_POSTURE:
+ {
+ SfxItemPool* pPool2 = aEditAttr.GetPool()->GetSecondaryPool();
+ if( !pPool2 )
+ pPool2 = aEditAttr.GetPool();
+ SvxScriptSetItem aSetItem( nSlot, *pPool2 );
+
+ // #i78017 establish the same behaviour as in Writer
+ SvtScriptType nScriptTypes = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX;
+ if (nSlot == SID_ATTR_CHAR_FONT)
+ nScriptTypes = pOLV->GetSelectedScriptType();
+
+ if (pNewAttrs)
+ {
+ aSetItem.PutItemForScriptType( nScriptTypes, pNewAttrs->Get( nWhich ) );
+ aNewAttr.Put( aSetItem.GetItemSet() );
+ }
+ }
+ break;
+
+ case SID_ATTR_CHAR_COLOR: nEEWhich = EE_CHAR_COLOR; break;
+ case SID_ATTR_CHAR_BACK_COLOR: nEEWhich = EE_CHAR_BKGCOLOR; break;
+
+ case SID_ATTR_CHAR_UNDERLINE:
+ {
+ if ( pNewAttrs )
+ {
+ const SvxTextLineItem& rTextLineItem = static_cast< const SvxTextLineItem& >( pNewAttrs->Get( pNewAttrs->GetPool()->GetWhich(nSlot) ) );
+ aNewAttr.Put( SvxUnderlineItem( rTextLineItem.GetLineStyle(), EE_CHAR_UNDERLINE ) );
+ }
+ else
+ {
+ FontLineStyle eFU = aEditAttr.Get(EE_CHAR_UNDERLINE).GetLineStyle();
+ aNewAttr.Put( SvxUnderlineItem(eFU == LINESTYLE_SINGLE ? LINESTYLE_NONE : LINESTYLE_SINGLE, EE_CHAR_UNDERLINE) );
+ }
+ }
+ break;
+
+ case SID_ATTR_CHAR_OVERLINE:
+ {
+ FontLineStyle eFO = aEditAttr.Get(EE_CHAR_OVERLINE).GetLineStyle();
+ aNewAttr.Put(SvxOverlineItem(eFO == LINESTYLE_SINGLE ? LINESTYLE_NONE : LINESTYLE_SINGLE, EE_CHAR_OVERLINE));
+ }
+ break;
+
+ case SID_ATTR_CHAR_CONTOUR: nEEWhich = EE_CHAR_OUTLINE; break;
+ case SID_ATTR_CHAR_SHADOWED: nEEWhich = EE_CHAR_SHADOW; break;
+ case SID_ATTR_CHAR_STRIKEOUT: nEEWhich = EE_CHAR_STRIKEOUT; break;
+ case SID_ATTR_CHAR_WORDLINEMODE: nEEWhich = EE_CHAR_WLM; break;
+ case SID_ATTR_CHAR_RELIEF : nEEWhich = EE_CHAR_RELIEF; break;
+ case SID_ATTR_CHAR_LANGUAGE : nEEWhich = EE_CHAR_LANGUAGE;break;
+ case SID_ATTR_CHAR_KERNING : nEEWhich = EE_CHAR_KERNING; break;
+ case SID_ATTR_CHAR_SCALEWIDTH: nEEWhich = EE_CHAR_FONTWIDTH; break;
+ case SID_ATTR_CHAR_AUTOKERN : nEEWhich = EE_CHAR_PAIRKERNING; break;
+ case SID_ATTR_CHAR_ESCAPEMENT: nEEWhich = EE_CHAR_ESCAPEMENT; break;
+ case SID_ATTR_PARA_ADJUST_LEFT:
+ aNewAttr.Put(SvxAdjustItem(SvxAdjust::Left, EE_PARA_JUST));
+ break;
+ case SID_ATTR_PARA_ADJUST_CENTER:
+ aNewAttr.Put(SvxAdjustItem(SvxAdjust::Center, EE_PARA_JUST));
+ break;
+ case SID_ATTR_PARA_ADJUST_RIGHT:
+ aNewAttr.Put(SvxAdjustItem(SvxAdjust::Right, EE_PARA_JUST));
+ break;
+ case SID_ATTR_PARA_ADJUST_BLOCK:
+ aNewAttr.Put(SvxAdjustItem(SvxAdjust::Block, EE_PARA_JUST));
+ break;
+ case SID_ATTR_PARA_LRSPACE:
+ {
+ SvxLRSpaceItem aParaMargin(static_cast<const SvxLRSpaceItem&>(rReq.
+ GetArgs()->Get(nSlot)));
+ aParaMargin.SetWhich( EE_PARA_LRSPACE );
+ aNewAttr.Put(aParaMargin);
+ rReq.Done();
+ }
+ break;
+ case SID_HANGING_INDENT:
+ {
+ SfxItemState eState = aEditAttr.GetItemState( EE_PARA_LRSPACE );
+ if( eState >= SfxItemState::DEFAULT )
+ {
+ SvxLRSpaceItem aParaMargin = aEditAttr.Get( EE_PARA_LRSPACE );
+ aParaMargin.SetWhich( EE_PARA_LRSPACE );
+ short int nFirstLineOffset = aParaMargin.GetTextFirstLineOffset();
+ aParaMargin.SetTextLeft( aParaMargin.GetTextLeft() + nFirstLineOffset );
+ aParaMargin.SetRight( aParaMargin.GetRight() );
+ aParaMargin.SetTextFirstLineOffset( nFirstLineOffset * -1 );
+ aNewAttr.Put(aParaMargin);
+ rReq.Done();
+ }
+ }
+ break;
+ case SID_ATTR_PARA_LINESPACE:
+ if (pNewAttrs)
+ {
+ SvxLineSpacingItem aLineSpace = static_cast<const SvxLineSpacingItem&>(pNewAttrs->Get(
+ GetPool().GetWhich(nSlot)));
+ aLineSpace.SetWhich( EE_PARA_SBL );
+ aNewAttr.Put( aLineSpace );
+ rReq.Done();
+ }
+ break;
+ case SID_ATTR_PARA_ULSPACE:
+ if (pNewAttrs)
+ {
+ SvxULSpaceItem aULSpace = static_cast<const SvxULSpaceItem&>(pNewAttrs->Get(
+ GetPool().GetWhich(nSlot)));
+ aULSpace.SetWhich( EE_PARA_ULSPACE );
+ aNewAttr.Put( aULSpace );
+ rReq.Done();
+ }
+ break;
+ case SID_PARASPACE_INCREASE:
+ case SID_PARASPACE_DECREASE:
+ {
+ SvxULSpaceItem aULSpace( aEditAttr.Get( EE_PARA_ULSPACE ) );
+ sal_uInt16 nUpper = aULSpace.GetUpper();
+ sal_uInt16 nLower = aULSpace.GetLower();
+
+ if ( nSlot == SID_PARASPACE_INCREASE )
+ {
+ nUpper = std::min< sal_uInt16 >( nUpper + 57, 5670 );
+ nLower = std::min< sal_uInt16 >( nLower + 57, 5670 );
+ }
+ else
+ {
+ nUpper = std::max< sal_Int16 >( nUpper - 57, 0 );
+ nLower = std::max< sal_Int16 >( nLower - 57, 0 );
+ }
+
+ aULSpace.SetUpper( nUpper );
+ aULSpace.SetLower( nLower );
+ aNewAttr.Put( aULSpace );
+ rReq.Done();
+ }
+ break;
+ case SID_ATTR_PARA_LINESPACE_10:
+ {
+ SvxLineSpacingItem aItem(LINE_SPACE_DEFAULT_HEIGHT, EE_PARA_SBL);
+ aItem.SetPropLineSpace(100);
+ aNewAttr.Put(aItem);
+ }
+ break;
+ case SID_ATTR_PARA_LINESPACE_115:
+ {
+ SvxLineSpacingItem aItem(LINE_SPACE_DEFAULT_HEIGHT, EE_PARA_SBL);
+ aItem.SetPropLineSpace(115);
+ aNewAttr.Put(aItem);
+ }
+ break;
+ case SID_ATTR_PARA_LINESPACE_15:
+ {
+ SvxLineSpacingItem aItem(LINE_SPACE_DEFAULT_HEIGHT, EE_PARA_SBL);
+ aItem.SetPropLineSpace(150);
+ aNewAttr.Put(aItem);
+ }
+ break;
+ case SID_ATTR_PARA_LINESPACE_20:
+ {
+ SvxLineSpacingItem aItem(LINE_SPACE_DEFAULT_HEIGHT, EE_PARA_SBL);
+ aItem.SetPropLineSpace(200);
+ aNewAttr.Put(aItem);
+ }
+ break;
+
+ case FN_SET_SUPER_SCRIPT:
+ {
+ SvxEscapementItem aItem(EE_CHAR_ESCAPEMENT);
+ SvxEscapement eEsc = static_cast<SvxEscapement>(aEditAttr.Get( EE_CHAR_ESCAPEMENT ).GetEnumValue());
+
+ if( eEsc == SvxEscapement::Superscript )
+ aItem.SetEscapement( SvxEscapement::Off );
+ else
+ aItem.SetEscapement( SvxEscapement::Superscript );
+ aNewAttr.Put( aItem );
+ }
+ break;
+ case FN_SET_SUB_SCRIPT:
+ {
+ SvxEscapementItem aItem(EE_CHAR_ESCAPEMENT);
+ SvxEscapement eEsc = static_cast<SvxEscapement>(aEditAttr.Get( EE_CHAR_ESCAPEMENT ).GetEnumValue());
+
+ if( eEsc == SvxEscapement::Subscript )
+ aItem.SetEscapement( SvxEscapement::Off );
+ else
+ aItem.SetEscapement( SvxEscapement::Subscript );
+ aNewAttr.Put( aItem );
+ }
+ break;
+
+ case SID_CHAR_DLG_EFFECT:
+ case SID_CHAR_DLG_POSITION:
+ case SID_CHAR_DLG:
+ case SID_CHAR_DLG_FOR_PARAGRAPH:
+ {
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ const SfxStringItem* pItem = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+
+ if( !pArgs || pItem )
+ {
+ aOldSelection = pOLV->GetSelection();
+ if (nSlot == SID_CHAR_DLG_FOR_PARAGRAPH)
+ {
+ // select current paragraph (and restore selection later on...)
+ EditView & rEditView = pOLV->GetEditView();
+ SwLangHelper::SelectPara( rEditView, rEditView.GetSelection() );
+ bRestoreSelection = true;
+ }
+
+ SwView* pView = &GetView();
+ FieldUnit eMetric = ::GetDfltMetric(dynamic_cast<SwWebView*>( pView) != nullptr );
+ SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)) );
+ SfxItemSetFixed<XATTR_FILLSTYLE, XATTR_FILLCOLOR, EE_ITEMS_START, EE_ITEMS_END> aDlgAttr(GetPool());
+
+ // util::Language does not exists in the EditEngine! That is why not in set.
+
+ aDlgAttr.Put( aEditAttr );
+ aDlgAttr.Put( SvxKerningItem(0, RES_CHRATR_KERNING) );
+
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateSwCharDlg(pView->GetFrameWeld(), *pView, aDlgAttr, SwCharDlgMode::Draw));
+ if (nSlot == SID_CHAR_DLG_EFFECT)
+ {
+ pDlg->SetCurPageId("fonteffects");
+ }
+ else if (nSlot == SID_CHAR_DLG_POSITION)
+ {
+ pDlg->SetCurPageId("position");
+ }
+ else if (nSlot == SID_CHAR_DLG_FOR_PARAGRAPH)
+ {
+ pDlg->SetCurPageId("font");
+ }
+ else if (pItem)
+ {
+ pDlg->SetCurPageId(pItem->GetValue());
+ }
+
+ sal_uInt16 nRet = pDlg->Execute();
+ if(RET_OK == nRet )
+ {
+ rReq.Done( *( pDlg->GetOutputItemSet() ) );
+ aNewAttr.Put(*pDlg->GetOutputItemSet());
+ }
+ if(RET_OK != nRet)
+ return ;
+ }
+ else
+ aNewAttr.Put(*pArgs);
+ }
+ break;
+ case FN_FORMAT_FOOTNOTE_DLG:
+ {
+ GetView().ExecFormatFootnote();
+ break;
+ }
+ case FN_NUMBERING_OUTLINE_DLG:
+ {
+ GetView().ExecNumberingOutline(GetPool());
+ rReq.Done();
+ }
+ break;
+ case SID_OPEN_XML_FILTERSETTINGS:
+ {
+ HandleOpenXmlFilterSettings(rReq);
+ }
+ break;
+ case FN_WORDCOUNT_DIALOG:
+ {
+ GetView().UpdateWordCount(this, nSlot);
+ }
+ break;
+ case SID_PARA_DLG:
+ {
+ const SfxItemSet* pArgs = rReq.GetArgs();
+
+ if (!pArgs)
+ {
+ SwView* pView = &GetView();
+ FieldUnit eMetric = ::GetDfltMetric(dynamic_cast<SwWebView*>( pView) != nullptr );
+ SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)) );
+ SfxItemSetFixed<
+ EE_ITEMS_START, EE_ITEMS_END,
+ SID_ATTR_PARA_HYPHENZONE, SID_ATTR_PARA_WIDOWS> aDlgAttr( GetPool() );
+
+ aDlgAttr.Put(aEditAttr);
+
+ aDlgAttr.Put( SvxHyphenZoneItem( false, RES_PARATR_HYPHENZONE) );
+ aDlgAttr.Put( SvxFormatBreakItem( SvxBreak::NONE, RES_BREAK ) );
+ aDlgAttr.Put( SvxFormatSplitItem( true, RES_PARATR_SPLIT ) );
+ aDlgAttr.Put( SvxWidowsItem( 0, RES_PARATR_WIDOWS ) );
+ aDlgAttr.Put( SvxOrphansItem( 0, RES_PARATR_ORPHANS ) );
+
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateSwParaDlg(GetView().GetFrameWeld(), GetView(), aDlgAttr, true));
+ sal_uInt16 nRet = pDlg->Execute();
+ if(RET_OK == nRet)
+ {
+ rReq.Done( *( pDlg->GetOutputItemSet() ) );
+ aNewAttr.Put(*pDlg->GetOutputItemSet());
+ }
+ if(RET_OK != nRet)
+ return;
+ }
+ else
+ aNewAttr.Put(*pArgs);
+ }
+ break;
+ case SID_AUTOSPELL_CHECK:
+ {
+//!! JP 16.03.2001: why?? pSdrView = rSh.GetDrawView();
+//!! JP 16.03.2001: why?? pOutliner = pSdrView->GetTextEditOutliner();
+ SdrOutliner * pOutliner = m_pSdrView->GetTextEditOutliner();
+ EEControlBits nCtrl = pOutliner->GetControlWord();
+
+ bool bSet = static_cast<const SfxBoolItem&>(rReq.GetArgs()->Get(
+ nSlot)).GetValue();
+ if(bSet)
+ nCtrl |= EEControlBits::ONLINESPELLING|EEControlBits::ALLOWBIGOBJS;
+ else
+ nCtrl &= ~EEControlBits::ONLINESPELLING;
+ pOutliner->SetControlWord(nCtrl);
+
+ m_rView.ExecuteSlot(rReq);
+ }
+ break;
+ case SID_HYPERLINK_SETLINK:
+ {
+ const SfxPoolItem* pItem = nullptr;
+ if(pNewAttrs)
+ pNewAttrs->GetItemState(nSlot, false, &pItem);
+
+ if(pItem)
+ {
+ const SvxHyperlinkItem& rHLinkItem = *static_cast<const SvxHyperlinkItem *>(pItem);
+ SvxURLField aField(rHLinkItem.GetURL(), rHLinkItem.GetName(), SvxURLFormat::AppDefault);
+ aField.SetTargetFrame(rHLinkItem.GetTargetFrame());
+
+ const SvxFieldItem* pFieldItem = pOLV->GetFieldAtSelection();
+
+ if (pFieldItem && dynamic_cast< const SvxURLField *>( pFieldItem->GetField() ) != nullptr )
+ {
+ // Select field so that it will be deleted during insert
+ ESelection aSel = pOLV->GetSelection();
+ aSel.nEndPos++;
+ pOLV->SetSelection(aSel);
+ }
+ pOLV->InsertField(SvxFieldItem(aField, EE_FEATURE_FIELD));
+ }
+ }
+ break;
+
+ case SID_EDIT_HYPERLINK:
+ {
+ // Ensure the field is selected first
+ pOLV->SelectFieldAtCursor();
+ GetView().GetViewFrame().GetDispatcher()->Execute(SID_HYPERLINK_DIALOG);
+ }
+ break;
+
+ case SID_REMOVE_HYPERLINK:
+ {
+ URLFieldHelper::RemoveURLField(pOLV->GetEditView());
+ }
+ break;
+
+ case SID_OPEN_HYPERLINK:
+ {
+ const SvxFieldItem* pFieldItem
+ = pOLV->GetFieldAtSelection(/*AlsoCheckBeforeCursor=*/true);
+ const SvxFieldData* pField = pFieldItem ? pFieldItem->GetField() : nullptr;
+ if (const SvxURLField* pURLField = dynamic_cast<const SvxURLField*>(pField))
+ {
+ ::LoadURL(GetShell(), pURLField->GetURL(), LoadUrlFlags::NONE,
+ pURLField->GetTargetFrame());
+ }
+ }
+ break;
+
+ case SID_COPY_HYPERLINK_LOCATION:
+ {
+ const SvxFieldItem* pFieldItem
+ = pOLV->GetFieldAtSelection(/*AlsoCheckBeforeCursor=*/true);
+ const SvxFieldData* pField = pFieldItem ? pFieldItem->GetField() : nullptr;
+ if (const SvxURLField* pURLField = dynamic_cast<const SvxURLField*>(pField))
+ {
+ uno::Reference<datatransfer::clipboard::XClipboard> xClipboard
+ = GetView().GetEditWin().GetClipboard();
+ vcl::unohelper::TextDataObject::CopyStringTo(pURLField->GetURL(), xClipboard);
+ }
+ }
+ break;
+
+ case SID_TEXTDIRECTION_LEFT_TO_RIGHT:
+ case SID_TEXTDIRECTION_TOP_TO_BOTTOM:
+ // Shell switch!
+ {
+ SdrObject* pTmpObj = m_pSdrView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
+ SdrPageView* pTmpPV = m_pSdrView->GetSdrPageView();
+ SdrView* pTmpView = m_pSdrView;
+
+ m_pSdrView->SdrEndTextEdit(true);
+
+ SfxItemSetFixed<SDRATTR_TEXTDIRECTION,
+ SDRATTR_TEXTDIRECTION> aAttr( *aNewAttr.GetPool() );
+
+ aAttr.Put( SvxWritingModeItem(
+ nSlot == SID_TEXTDIRECTION_LEFT_TO_RIGHT ?
+ text::WritingMode_LR_TB
+ : text::WritingMode_TB_RL, SDRATTR_TEXTDIRECTION ) );
+ pTmpView->SetAttributes( aAttr );
+
+ rSh.GetView().BeginTextEdit( pTmpObj, pTmpPV, &rSh.GetView().GetEditWin());
+ rSh.GetView().AttrChangedNotify(nullptr);
+ }
+ return;
+
+ case SID_ATTR_PARA_LEFT_TO_RIGHT:
+ case SID_ATTR_PARA_RIGHT_TO_LEFT:
+ {
+ SdrObject* pTmpObj = m_pSdrView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
+ SdrPageView* pTmpPV = m_pSdrView->GetSdrPageView();
+ SdrView* pTmpView = m_pSdrView;
+
+ m_pSdrView->SdrEndTextEdit(true);
+ bool bLeftToRight = nSlot == SID_ATTR_PARA_LEFT_TO_RIGHT;
+
+ const SfxPoolItem* pPoolItem;
+ if( pNewAttrs && SfxItemState::SET == pNewAttrs->GetItemState( nSlot, true, &pPoolItem ) )
+ {
+ if( !static_cast<const SfxBoolItem*>(pPoolItem)->GetValue() )
+ bLeftToRight = !bLeftToRight;
+ }
+ SfxItemSetFixed<
+ EE_PARA_WRITINGDIR, EE_PARA_WRITINGDIR,
+ EE_PARA_JUST, EE_PARA_JUST> aAttr( *aNewAttr.GetPool() );
+
+ SvxAdjust nAdjust = SvxAdjust::Left;
+ if( const SvxAdjustItem* pAdjustItem = aEditAttr.GetItemIfSet(EE_PARA_JUST) )
+ nAdjust = pAdjustItem->GetAdjust();
+
+ if( bLeftToRight )
+ {
+ aAttr.Put( SvxFrameDirectionItem( SvxFrameDirection::Horizontal_LR_TB, EE_PARA_WRITINGDIR ) );
+ if( nAdjust == SvxAdjust::Right )
+ aAttr.Put( SvxAdjustItem( SvxAdjust::Left, EE_PARA_JUST ) );
+ }
+ else
+ {
+ aAttr.Put( SvxFrameDirectionItem( SvxFrameDirection::Horizontal_RL_TB, EE_PARA_WRITINGDIR ) );
+ if( nAdjust == SvxAdjust::Left )
+ aAttr.Put( SvxAdjustItem( SvxAdjust::Right, EE_PARA_JUST ) );
+ }
+ pTmpView->SetAttributes( aAttr );
+ rSh.GetView().BeginTextEdit( pTmpObj, pTmpPV, &rSh.GetView().GetEditWin() );
+ rSh.GetView().AttrChangedNotify(nullptr);
+ }
+ return;
+
+ case FN_GROW_FONT_SIZE:
+ case FN_SHRINK_FONT_SIZE:
+ {
+ const SfxObjectShell* pObjSh = SfxObjectShell::Current();
+ const SvxFontListItem* pFontListItem = static_cast< const SvxFontListItem* >
+ (pObjSh ? pObjSh->GetItem(SID_ATTR_CHAR_FONTLIST) : nullptr);
+ const FontList* pFontList = pFontListItem ? pFontListItem->GetFontList() : nullptr;
+ pOLV->GetEditView().ChangeFontSize( nSlot == FN_GROW_FONT_SIZE, pFontList );
+ }
+ break;
+
+ default:
+ assert(false && "wrong dispatcher");
+ return;
+ }
+ if (nEEWhich && pNewAttrs)
+ {
+ aNewAttr.Put(pNewAttrs->Get(nWhich).CloneSetWhich(nEEWhich));
+ }
+ else if (nEEWhich == EE_CHAR_COLOR)
+ {
+ GetView().GetViewFrame().GetDispatcher()->Execute(SID_CHAR_DLG_EFFECT);
+ }
+ else if (nEEWhich == EE_CHAR_KERNING)
+ {
+ GetView().GetViewFrame().GetDispatcher()->Execute(SID_CHAR_DLG_POSITION);
+ }
+
+
+ SetAttrToMarked(aNewAttr);
+
+ GetView().GetViewFrame().GetBindings().InvalidateAll(false);
+
+ if (IsTextEdit() && pOLV->GetOutliner()->IsModified())
+ rSh.SetModified();
+
+ if (bRestoreSelection)
+ {
+ // restore selection
+ pOLV->GetEditView().SetSelection( aOldSelection );
+ }
+}
+
+void SwDrawTextShell::GetState(SfxItemSet& rSet)
+{
+ if (!IsTextEdit()) // Otherwise sometimes crash!
+ return;
+
+ OutlinerView* pOLV = m_pSdrView->GetTextEditOutlinerView();
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+
+ SfxItemSet aEditAttr(pOLV->GetAttribs());
+ const SvxAdjustItem *pAdjust = nullptr;
+ const SvxLineSpacingItem *pLSpace = nullptr;
+ const SfxPoolItem *pEscItem = nullptr;
+ SvxAdjust eAdjust;
+ int nLSpace;
+ SvxEscapement nEsc;
+
+ while (nWhich)
+ {
+ sal_uInt16 nSlotId = GetPool().GetSlotId(nWhich);
+ bool bFlag = false;
+ switch (nSlotId)
+ {
+ case SID_LANGUAGE_STATUS: //20412:
+ {
+ SwLangHelper::GetLanguageStatus(pOLV, rSet);
+ nSlotId = 0;
+ break;
+ }
+
+ case SID_THES:
+ {
+ OUString aStatusVal;
+ LanguageType nLang = LANGUAGE_NONE;
+ bool bIsLookUpWord
+ = GetStatusValueForThesaurusFromContext(aStatusVal, nLang, pOLV->GetEditView());
+ rSet.Put(SfxStringItem(SID_THES, aStatusVal));
+
+ // disable "Thesaurus" context menu entry if there is nothing to look up
+ uno::Reference<linguistic2::XThesaurus> xThes(::GetThesaurus());
+ if (!bIsLookUpWord || !xThes.is() || nLang == LANGUAGE_NONE
+ || !xThes->hasLocale(LanguageTag::convertToLocale(nLang)))
+ rSet.DisableItem(SID_THES);
+
+ //! avoid putting the same item as SfxBoolItem at the end of this function
+ nSlotId = 0;
+ break;
+ }
+
+ case SID_ATTR_PARA_ADJUST_LEFT:
+ eAdjust = SvxAdjust::Left;
+ goto ASK_ADJUST;
+ case SID_ATTR_PARA_ADJUST_RIGHT:
+ eAdjust = SvxAdjust::Right;
+ goto ASK_ADJUST;
+ case SID_ATTR_PARA_ADJUST_CENTER:
+ eAdjust = SvxAdjust::Center;
+ goto ASK_ADJUST;
+ case SID_ATTR_PARA_ADJUST_BLOCK:
+ eAdjust = SvxAdjust::Block;
+ goto ASK_ADJUST;
+ ASK_ADJUST:
+ {
+ if (!pAdjust)
+ pAdjust = aEditAttr.GetItemIfSet(EE_PARA_JUST, false);
+
+ if (!pAdjust || IsInvalidItem(pAdjust))
+ {
+ rSet.InvalidateItem(nSlotId);
+ nSlotId = 0;
+ }
+ else
+ bFlag = eAdjust == pAdjust->GetAdjust();
+ }
+ break;
+
+ case SID_ATTR_PARA_LRSPACE:
+ case SID_ATTR_PARA_LEFTSPACE:
+ case SID_ATTR_PARA_RIGHTSPACE:
+ case SID_ATTR_PARA_FIRSTLINESPACE:
+ {
+ SfxItemState eState = aEditAttr.GetItemState(EE_PARA_LRSPACE);
+ if (eState >= SfxItemState::DEFAULT)
+ {
+ SvxLRSpaceItem aLR = aEditAttr.Get(EE_PARA_LRSPACE);
+ aLR.SetWhich(SID_ATTR_PARA_LRSPACE);
+ rSet.Put(aLR);
+ }
+ else
+ rSet.InvalidateItem(nSlotId);
+ nSlotId = 0;
+ }
+ break;
+ case SID_ATTR_PARA_LINESPACE:
+ {
+ SfxItemState eState = aEditAttr.GetItemState(EE_PARA_SBL);
+ if (eState >= SfxItemState::DEFAULT)
+ {
+ const SvxLineSpacingItem& aLR = aEditAttr.Get(EE_PARA_SBL);
+ rSet.Put(aLR);
+ }
+ else
+ rSet.InvalidateItem(nSlotId);
+ nSlotId = 0;
+ }
+ break;
+ case SID_ATTR_PARA_ULSPACE:
+ case SID_ATTR_PARA_BELOWSPACE:
+ case SID_ATTR_PARA_ABOVESPACE:
+ case SID_PARASPACE_INCREASE:
+ case SID_PARASPACE_DECREASE:
+ {
+ SfxItemState eState = aEditAttr.GetItemState(EE_PARA_ULSPACE);
+ if (eState >= SfxItemState::DEFAULT)
+ {
+ SvxULSpaceItem aULSpace = aEditAttr.Get(EE_PARA_ULSPACE);
+ if (!aULSpace.GetUpper() && !aULSpace.GetLower())
+ rSet.DisableItem(SID_PARASPACE_DECREASE);
+ else if (aULSpace.GetUpper() >= 5670 && aULSpace.GetLower() >= 5670)
+ rSet.DisableItem(SID_PARASPACE_INCREASE);
+ if (nSlotId == SID_ATTR_PARA_ULSPACE || nSlotId == SID_ATTR_PARA_ABOVESPACE
+ || nSlotId == SID_ATTR_PARA_BELOWSPACE)
+ {
+ aULSpace.SetWhich(nSlotId);
+ rSet.Put(aULSpace);
+ }
+ }
+ else
+ {
+ rSet.DisableItem(SID_PARASPACE_INCREASE);
+ rSet.DisableItem(SID_PARASPACE_DECREASE);
+ rSet.InvalidateItem(SID_ATTR_PARA_ULSPACE);
+ rSet.InvalidateItem(SID_ATTR_PARA_ABOVESPACE);
+ rSet.InvalidateItem(SID_ATTR_PARA_BELOWSPACE);
+ }
+ nSlotId = 0;
+ }
+ break;
+
+ case SID_ATTR_PARA_LINESPACE_10:
+ nLSpace = 100;
+ goto ASK_LINESPACE;
+ case SID_ATTR_PARA_LINESPACE_115:
+ nLSpace = 115;
+ goto ASK_LINESPACE;
+ case SID_ATTR_PARA_LINESPACE_15:
+ nLSpace = 150;
+ goto ASK_LINESPACE;
+ case SID_ATTR_PARA_LINESPACE_20:
+ nLSpace = 200;
+ goto ASK_LINESPACE;
+ ASK_LINESPACE:
+ {
+ if (!pLSpace)
+ pLSpace = aEditAttr.GetItemIfSet(EE_PARA_SBL, false);
+
+ if (!pLSpace || IsInvalidItem(pLSpace))
+ {
+ rSet.InvalidateItem(nSlotId);
+ nSlotId = 0;
+ }
+ else if (nLSpace
+ == pLSpace->GetPropLineSpace())
+ bFlag = true;
+ else
+ {
+ // tdf#114631 - disable non selected line spacing
+ rSet.Put(SfxBoolItem(nWhich, false));
+ nSlotId = 0;
+ }
+ }
+ break;
+
+ case FN_SET_SUPER_SCRIPT:
+ nEsc = SvxEscapement::Superscript;
+ goto ASK_ESCAPE;
+ case FN_SET_SUB_SCRIPT:
+ nEsc = SvxEscapement::Subscript;
+ goto ASK_ESCAPE;
+ ASK_ESCAPE:
+ {
+ if (!pEscItem)
+ pEscItem = &aEditAttr.Get(EE_CHAR_ESCAPEMENT);
+
+ if (nEsc == static_cast<const SvxEscapementItem*>(pEscItem)->GetEscapement())
+ bFlag = true;
+ else
+ nSlotId = 0;
+ }
+ break;
+
+ case SID_THESAURUS:
+ {
+ // disable "Thesaurus" if the language is not supported
+ TypedWhichId<SvxLanguageItem> nLangWhich = GetWhichOfScript(
+ RES_CHRATR_LANGUAGE,
+ SvtLanguageOptions::GetI18NScriptTypeOfLanguage(GetAppLanguage()));
+ const SvxLanguageItem& rItem = GetShell().GetDoc()->GetDefault(nLangWhich);
+ LanguageType nLang = rItem.GetLanguage();
+
+ uno::Reference<linguistic2::XThesaurus> xThes(::GetThesaurus());
+ if (!xThes.is() || nLang == LANGUAGE_NONE
+ || !xThes->hasLocale(LanguageTag::convertToLocale(nLang)))
+ rSet.DisableItem(SID_THESAURUS);
+ nSlotId = 0;
+ }
+ break;
+ case SID_HANGUL_HANJA_CONVERSION:
+ case SID_CHINESE_CONVERSION:
+ {
+ if (!SvtCJKOptions::IsAnyEnabled())
+ {
+ GetView().GetViewFrame().GetBindings().SetVisibleState(nWhich, false);
+ rSet.DisableItem(nWhich);
+ }
+ else
+ GetView().GetViewFrame().GetBindings().SetVisibleState(nWhich, true);
+ }
+ break;
+
+ case SID_TEXTDIRECTION_LEFT_TO_RIGHT:
+ case SID_TEXTDIRECTION_TOP_TO_BOTTOM:
+ if (!SvtCJKOptions::IsVerticalTextEnabled())
+ {
+ rSet.DisableItem(nSlotId);
+ nSlotId = 0;
+ }
+ else
+ {
+ SdrOutliner* pOutliner = m_pSdrView->GetTextEditOutliner();
+ if (pOutliner)
+ bFlag = pOutliner->IsVertical()
+ == (SID_TEXTDIRECTION_TOP_TO_BOTTOM == nSlotId);
+ else
+ {
+ text::WritingMode eMode = aEditAttr.Get(SDRATTR_TEXTDIRECTION).GetValue();
+
+ if (nSlotId == SID_TEXTDIRECTION_LEFT_TO_RIGHT)
+ {
+ bFlag = eMode == text::WritingMode_LR_TB;
+ }
+ else
+ {
+ bFlag = eMode != text::WritingMode_TB_RL;
+ }
+ }
+ }
+ break;
+ case SID_ATTR_PARA_LEFT_TO_RIGHT:
+ case SID_ATTR_PARA_RIGHT_TO_LEFT:
+ {
+ if (!SvtCTLOptions::IsCTLFontEnabled())
+ {
+ rSet.DisableItem(nWhich);
+ nSlotId = 0;
+ }
+ else
+ {
+ SdrOutliner* pOutliner = m_pSdrView->GetTextEditOutliner();
+ if (pOutliner && pOutliner->IsVertical())
+ {
+ rSet.DisableItem(nWhich);
+ nSlotId = 0;
+ }
+ else
+ {
+ switch (aEditAttr.Get(EE_PARA_WRITINGDIR).GetValue())
+ {
+ case SvxFrameDirection::Horizontal_LR_TB:
+ bFlag = nWhich == SID_ATTR_PARA_LEFT_TO_RIGHT;
+ break;
+
+ case SvxFrameDirection::Horizontal_RL_TB:
+ bFlag = nWhich != SID_ATTR_PARA_LEFT_TO_RIGHT;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ break;
+ case SID_TRANSLITERATE_HALFWIDTH:
+ case SID_TRANSLITERATE_FULLWIDTH:
+ case SID_TRANSLITERATE_HIRAGANA:
+ case SID_TRANSLITERATE_KATAKANA:
+ {
+ if (!SvtCJKOptions::IsChangeCaseMapEnabled())
+ {
+ rSet.DisableItem(nWhich);
+ GetView().GetViewFrame().GetBindings().SetVisibleState(nWhich, false);
+ }
+ else
+ GetView().GetViewFrame().GetBindings().SetVisibleState(nWhich, true);
+ }
+ break;
+ case SID_INSERT_RLM:
+ case SID_INSERT_LRM:
+ {
+ bool bEnabled = SvtCTLOptions::IsCTLFontEnabled();
+ GetView().GetViewFrame().GetBindings().SetVisibleState(nWhich, bEnabled);
+ if (!bEnabled)
+ rSet.DisableItem(nWhich);
+ }
+ break;
+ case SID_REMOVE_HYPERLINK:
+ case SID_EDIT_HYPERLINK:
+ case SID_OPEN_HYPERLINK:
+ case SID_COPY_HYPERLINK_LOCATION:
+ {
+ if (!URLFieldHelper::IsCursorAtURLField(pOLV, /*AlsoCheckBeforeCursor=*/true))
+ rSet.DisableItem(nWhich);
+ nSlotId = 0;
+ }
+ break;
+ default:
+ nSlotId = 0; // don't know this slot
+ break;
+ }
+
+ if (nSlotId)
+ rSet.Put(SfxBoolItem(nWhich, bFlag));
+
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void SwDrawTextShell::GetDrawTextCtrlState(SfxItemSet& rSet)
+{
+ if (!IsTextEdit()) // Otherwise crash!
+ return;
+
+ OutlinerView* pOLV = m_pSdrView->GetTextEditOutlinerView();
+ SfxItemSet aEditAttr(pOLV->GetAttribs());
+
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ SvtScriptType nScriptType = pOLV->GetSelectedScriptType();
+ while(nWhich)
+ {
+ sal_uInt16 nEEWhich = 0;
+ sal_uInt16 nSlotId = GetPool().GetSlotId( nWhich );
+ switch( nSlotId )
+ {
+ case SID_ATTR_CHAR_FONT:
+ case SID_ATTR_CHAR_FONTHEIGHT:
+ case SID_ATTR_CHAR_WEIGHT:
+ case SID_ATTR_CHAR_POSTURE:
+ {
+ SfxItemPool* pEditPool = aEditAttr.GetPool()->GetSecondaryPool();
+ if( !pEditPool )
+ pEditPool = aEditAttr.GetPool();
+ SvxScriptSetItem aSetItem( nSlotId, *pEditPool );
+ aSetItem.GetItemSet().Put( aEditAttr, false );
+ const SfxPoolItem* pI = aSetItem.GetItemOfScript( nScriptType );
+ if( pI )
+ {
+ rSet.Put(pI->CloneSetWhich(nWhich));
+ }
+ else
+ rSet.InvalidateItem( nWhich );
+ }
+ break;
+ case SID_ATTR_CHAR_COLOR: nEEWhich = EE_CHAR_COLOR; break;
+ case SID_ATTR_CHAR_BACK_COLOR: nEEWhich = EE_CHAR_BKGCOLOR; break;
+ case SID_ATTR_CHAR_UNDERLINE: nEEWhich = EE_CHAR_UNDERLINE;break;
+ case SID_ATTR_CHAR_OVERLINE: nEEWhich = EE_CHAR_OVERLINE;break;
+ case SID_ATTR_CHAR_CONTOUR: nEEWhich = EE_CHAR_OUTLINE; break;
+ case SID_ATTR_CHAR_SHADOWED: nEEWhich = EE_CHAR_SHADOW;break;
+ case SID_ATTR_CHAR_STRIKEOUT: nEEWhich = EE_CHAR_STRIKEOUT;break;
+ case SID_AUTOSPELL_CHECK:
+ {
+ const SfxPoolItemHolder aResult(m_rView.GetSlotState(nWhich));
+ if (nullptr != aResult.getItem())
+ rSet.Put(SfxBoolItem(nWhich, static_cast<const SfxBoolItem*>(aResult.getItem())->GetValue()));
+ else
+ rSet.DisableItem( nWhich );
+ break;
+ }
+ case SID_ATTR_CHAR_WORDLINEMODE: nEEWhich = EE_CHAR_WLM; break;
+ case SID_ATTR_CHAR_RELIEF : nEEWhich = EE_CHAR_RELIEF; break;
+ case SID_ATTR_CHAR_LANGUAGE : nEEWhich = EE_CHAR_LANGUAGE;break;
+ case SID_ATTR_CHAR_KERNING : nEEWhich = EE_CHAR_KERNING; break;
+ case SID_ATTR_CHAR_SCALEWIDTH: nEEWhich = EE_CHAR_FONTWIDTH;break;
+ case SID_ATTR_CHAR_AUTOKERN : nEEWhich = EE_CHAR_PAIRKERNING; break;
+ case SID_ATTR_CHAR_ESCAPEMENT: nEEWhich = EE_CHAR_ESCAPEMENT; break;
+ case FN_GROW_FONT_SIZE:
+ case FN_SHRINK_FONT_SIZE:
+ {
+ SfxItemPool* pEditPool = aEditAttr.GetPool()->GetSecondaryPool();
+ if( !pEditPool )
+ pEditPool = aEditAttr.GetPool();
+
+ SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONTHEIGHT, *pEditPool );
+ aSetItem.GetItemSet().Put( aEditAttr, false );
+ const SvxFontHeightItem* pSize( static_cast<const SvxFontHeightItem*>( aSetItem.GetItemOfScript( nScriptType ) ) );
+
+ if( pSize )
+ {
+ sal_uInt32 nSize = pSize->GetHeight();
+ if( nSize >= 19998 )
+ rSet.DisableItem( FN_GROW_FONT_SIZE );
+ else if( nSize <= 40 )
+ rSet.DisableItem( FN_SHRINK_FONT_SIZE );
+ }
+ }
+ }
+ if(nEEWhich)
+ {
+ rSet.Put(aEditAttr.Get(nEEWhich).CloneSetWhich(nWhich));
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void SwDrawTextShell::ExecClpbrd(SfxRequest const &rReq)
+{
+ if (!IsTextEdit()) // Otherwise crash!
+ return;
+
+ OutlinerView* pOLV = m_pSdrView->GetTextEditOutlinerView();
+
+ ESelection aSel(pOLV->GetSelection());
+ const bool bCopy = (aSel.nStartPara != aSel.nEndPara) || (aSel.nStartPos != aSel.nEndPos);
+ sal_uInt16 nId = rReq.GetSlot();
+ switch( nId )
+ {
+ case SID_CUT:
+ if (bCopy)
+ pOLV->Cut();
+ return;
+
+ case SID_COPY:
+ if (bCopy)
+ pOLV->Copy();
+ return;
+
+ case SID_PASTE:
+ pOLV->PasteSpecial();
+ break;
+
+ case SID_PASTE_UNFORMATTED:
+ pOLV->Paste();
+ break;
+
+ case SID_PASTE_SPECIAL:
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<SfxAbstractPasteDialog> pDlg(pFact->CreatePasteDialog(GetView().GetEditWin().GetFrameWeld()));
+
+ pDlg->Insert(SotClipboardFormatId::STRING, OUString());
+ pDlg->Insert(SotClipboardFormatId::RTF, OUString());
+ pDlg->Insert(SotClipboardFormatId::RICHTEXT, OUString());
+ pDlg->Insert(SotClipboardFormatId::HTML_SIMPLE, OUString());
+
+ TransferableDataHelper aDataHelper(TransferableDataHelper::CreateFromSystemClipboard(&GetView().GetEditWin()));
+ SotClipboardFormatId nFormat = pDlg->GetFormat(aDataHelper.GetTransferable());
+
+ if (nFormat != SotClipboardFormatId::NONE)
+ {
+ if (nFormat == SotClipboardFormatId::STRING)
+ pOLV->Paste();
+ else
+ pOLV->PasteSpecial(nFormat);
+ }
+
+ break;
+ }
+
+ case SID_CLIPBOARD_FORMAT_ITEMS:
+ {
+ SotClipboardFormatId nFormat = SotClipboardFormatId::NONE;
+ const SfxPoolItem* pItem;
+ if (rReq.GetArgs() && rReq.GetArgs()->GetItemState(nId, true, &pItem) == SfxItemState::SET)
+ {
+ if (const SfxUInt32Item* pUInt32Item = dynamic_cast<const SfxUInt32Item *>(pItem))
+ nFormat = static_cast<SotClipboardFormatId>(pUInt32Item->GetValue());
+ }
+
+ if (nFormat != SotClipboardFormatId::NONE)
+ {
+ if (nFormat == SotClipboardFormatId::STRING)
+ pOLV->Paste();
+ else
+ pOLV->PasteSpecial(nFormat);
+ }
+
+ break;
+ }
+
+ default:
+ OSL_FAIL("wrong dispatcher");
+ return;
+ }
+}
+
+void SwDrawTextShell::StateClpbrd(SfxItemSet &rSet)
+{
+ if (!IsTextEdit()) // Otherwise crash!
+ return;
+
+ OutlinerView* pOLV = m_pSdrView->GetTextEditOutlinerView();
+ ESelection aSel(pOLV->GetSelection());
+ const bool bCopy = (aSel.nStartPara != aSel.nEndPara) ||
+ (aSel.nStartPos != aSel.nEndPos);
+
+ TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( &GetView().GetEditWin() ) );
+ const bool bPaste = aDataHelper.HasFormat( SotClipboardFormatId::STRING ) ||
+ aDataHelper.HasFormat( SotClipboardFormatId::RTF ) ||
+ aDataHelper.HasFormat( SotClipboardFormatId::RICHTEXT ) ||
+ aDataHelper.HasFormat( SotClipboardFormatId::HTML_SIMPLE);
+
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+
+ while(nWhich)
+ {
+ switch(nWhich)
+ {
+ case SID_CUT:
+ case SID_COPY:
+ if( !bCopy || GetObjectShell()->isContentExtractionLocked())
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_PASTE:
+ case SID_PASTE_UNFORMATTED:
+ case SID_PASTE_SPECIAL:
+ if( !bPaste )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_CLIPBOARD_FORMAT_ITEMS:
+ if( bPaste )
+ {
+ SvxClipboardFormatItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS );
+
+ if ( aDataHelper.HasFormat( SotClipboardFormatId::STRING ) )
+ aFormats.AddClipbrdFormat( SotClipboardFormatId::STRING );
+ if ( aDataHelper.HasFormat( SotClipboardFormatId::RTF ) )
+ aFormats.AddClipbrdFormat( SotClipboardFormatId::RTF );
+ if ( aDataHelper.HasFormat( SotClipboardFormatId::RICHTEXT ) )
+ aFormats.AddClipbrdFormat( SotClipboardFormatId::RICHTEXT );
+ if (aDataHelper.HasFormat(SotClipboardFormatId::HTML_SIMPLE))
+ aFormats.AddClipbrdFormat(SotClipboardFormatId::HTML_SIMPLE);
+
+ rSet.Put( aFormats );
+ }
+ else
+ rSet.DisableItem( nWhich );
+ break;
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+}
+
+// Hyperlink status
+
+void SwDrawTextShell::StateInsert(SfxItemSet &rSet)
+{
+ if (!IsTextEdit()) // Otherwise crash!
+ return;
+
+ OutlinerView* pOLV = m_pSdrView->GetTextEditOutlinerView();
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+
+ while(nWhich)
+ {
+ switch(nWhich)
+ {
+ case SID_HYPERLINK_GETLINK:
+ {
+ SvxHyperlinkItem aHLinkItem;
+ aHLinkItem.SetInsertMode(HLINK_FIELD);
+
+ const SvxFieldItem* pFieldItem = pOLV->GetFieldAtSelection();
+
+ if (pFieldItem)
+ {
+ const SvxURLField* pURLField = dynamic_cast<const SvxURLField*>(pFieldItem->GetField());
+
+ if (pURLField)
+ {
+ aHLinkItem.SetName(pURLField->GetRepresentation());
+ aHLinkItem.SetURL(pURLField->GetURL());
+ aHLinkItem.SetTargetFrame(pURLField->GetTargetFrame());
+ }
+ }
+ else
+ {
+ OUString sSel(pOLV->GetSelected());
+ sSel = sSel.copy(0, std::min<sal_Int32>(255, sSel.getLength()));
+ aHLinkItem.SetName(comphelper::string::stripEnd(sSel, ' '));
+ }
+
+ sal_uInt16 nHtmlMode = ::GetHtmlMode(GetView().GetDocShell());
+ aHLinkItem.SetInsertMode(static_cast<SvxLinkInsertMode>(aHLinkItem.GetInsertMode() |
+ ((nHtmlMode & HTMLMODE_ON) != 0 ? HLINK_HTMLMODE : 0)));
+
+ rSet.Put(aHLinkItem);
+ }
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/drwtxtsh.cxx b/sw/source/uibase/shells/drwtxtsh.cxx
new file mode 100644
index 0000000000..4d9a181730
--- /dev/null
+++ b/sw/source/uibase/shells/drwtxtsh.cxx
@@ -0,0 +1,849 @@
+/* -*- 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 <i18nlangtag/lang.h>
+#include <i18nutil/transliteration.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <svl/slstitm.hxx>
+#include <svl/stritem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/editund2.hxx>
+#include <svx/svdview.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/objface.hxx>
+#include <svx/svdotext.hxx>
+#include <svx/sdooitm.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <sfx2/bindings.hxx>
+#include <svx/fontwork.hxx>
+#include <sfx2/request.hxx>
+#include <vcl/EnumContext.hxx>
+#include <svl/whiter.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/editstat.hxx>
+#include <svx/svdoutl.hxx>
+#include <com/sun/star/i18n/TextConversionOption.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <comphelper/propertysequence.hxx>
+#include <osl/diagnose.h>
+#include <swtypes.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <viewopt.hxx>
+#include <drwtxtsh.hxx>
+#include <breakit.hxx>
+
+#include <cmdid.h>
+
+#define ShellClass_SwDrawTextShell
+#include <sfx2/msg.hxx>
+#include <swslots.hxx>
+#include <uitool.hxx>
+#include <wview.hxx>
+#include <swmodule.hxx>
+#include <svx/svdoashp.hxx>
+#include <svx/svxdlg.hxx>
+#include <comphelper/processfactory.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <memory>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::i18n;
+
+SFX_IMPL_INTERFACE(SwDrawTextShell, SfxShell)
+
+void SwDrawTextShell::InitInterface_Impl()
+{
+ GetStaticInterface()->RegisterPopupMenu("drawtext");
+
+ GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Invisible, ToolbarId::Draw_Text_Toolbox_Sw);
+
+ GetStaticInterface()->RegisterChildWindow(SvxFontWorkChildWindow::GetChildWindowId());
+}
+
+
+void SwDrawTextShell::Init()
+{
+ SwWrtShell &rSh = GetShell();
+ m_pSdrView = rSh.GetDrawView();
+ SdrOutliner * pOutliner = m_pSdrView->GetTextEditOutliner();
+ //#97471# mouse click _and_ key input at the same time
+ if( !pOutliner )
+ return ;
+ OutlinerView* pOLV = m_pSdrView->GetTextEditOutlinerView();
+ EEControlBits nCtrl = pOutliner->GetControlWord();
+ nCtrl |= EEControlBits::AUTOCORRECT;
+
+ SetUndoManager(&pOutliner->GetUndoManager());
+
+ // Now let's try an AutoSpell.
+
+ const SwViewOption* pVOpt = rSh.GetViewOptions();
+ if(pVOpt->IsOnlineSpell())
+ {
+ nCtrl |= EEControlBits::ONLINESPELLING|EEControlBits::ALLOWBIGOBJS;
+ }
+ else
+ nCtrl &= ~EEControlBits::ONLINESPELLING;
+
+ pOutliner->SetControlWord(nCtrl);
+ pOLV->ShowCursor();
+}
+
+SwDrawTextShell::SwDrawTextShell(SwView &rV) :
+ SfxShell(&rV),
+ m_rView(rV)
+{
+ SwWrtShell &rSh = GetShell();
+ SetPool(rSh.GetAttrPool().GetSecondaryPool());
+
+ // Initialize and show cursor to start editing.
+ Init();
+
+ SetName("ObjectText");
+ SfxShell::SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::DrawText));
+}
+
+SwDrawTextShell::~SwDrawTextShell()
+{
+ if ( GetView().GetCurShell() == this )
+ m_rView.ResetSubShell();
+}
+
+SwWrtShell& SwDrawTextShell::GetShell()
+{
+ return m_rView.GetWrtShell();
+}
+
+// Disable slots with this status method
+
+void SwDrawTextShell::StateDisableItems( SfxItemSet &rSet )
+{
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+
+ while (nWhich)
+ {
+ rSet.DisableItem( nWhich );
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void SwDrawTextShell::SetAttrToMarked(const SfxItemSet& rAttr)
+{
+ OutlinerView* pOLV = m_pSdrView->GetTextEditOutlinerView();
+ tools::Rectangle aOutRect = pOLV->GetOutputArea();
+
+ if (tools::Rectangle() != aOutRect)
+ {
+ GetShell().GetDrawView()->SetAttributes(rAttr);
+ }
+}
+
+bool SwDrawTextShell::IsTextEdit() const
+{
+ return m_pSdrView->IsTextEdit();
+}
+
+void SwDrawTextShell::ExecFontWork(SfxRequest const & rReq)
+{
+ SwWrtShell &rSh = GetShell();
+ FieldUnit eMetric = ::GetDfltMetric( dynamic_cast<SwWebView*>( &rSh.GetView()) != nullptr );
+ SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)) );
+ SfxViewFrame& rVFrame = GetView().GetViewFrame();
+ if ( rReq.GetArgs() )
+ {
+ rVFrame.SetChildWindow(SvxFontWorkChildWindow::GetChildWindowId(),
+ static_cast<const SfxBoolItem&>( (rReq.GetArgs()->
+ Get(SID_FONTWORK))).GetValue());
+ }
+ else
+ rVFrame.ToggleChildWindow(SvxFontWorkChildWindow::GetChildWindowId());
+
+ rVFrame.GetBindings().Invalidate(SID_FONTWORK);
+}
+
+void SwDrawTextShell::StateFontWork(SfxItemSet& rSet)
+{
+ const sal_uInt16 nId = SvxFontWorkChildWindow::GetChildWindowId();
+ rSet.Put(SfxBoolItem(SID_FONTWORK, GetView().GetViewFrame().HasChildWindow(nId)));
+}
+
+// Edit SfxRequests for FontWork
+
+void SwDrawTextShell::ExecFormText(SfxRequest const & rReq)
+{
+ SwWrtShell &rSh = GetShell();
+ SdrView* pDrView = rSh.GetDrawView();
+
+ const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
+
+ if ( !(rMarkList.GetMarkCount() == 1 && rReq.GetArgs()) )
+ return;
+
+ const SfxItemSet& rSet = *rReq.GetArgs();
+
+ if ( pDrView->IsTextEdit() )
+ {
+ //#111733# Sometimes SdrEndTextEdit() initiates the change in selection and
+ // 'this' is not valid anymore
+ SwView& rTempView = GetView();
+ pDrView->SdrEndTextEdit(true);
+ //this removes the current shell from the dispatcher stack!!
+ rTempView.AttrChangedNotify(nullptr);
+ }
+
+ pDrView->SetAttributes(rSet);
+
+}
+
+// Return Status values back to FontWork
+
+void SwDrawTextShell::GetFormTextState(SfxItemSet& rSet)
+{
+ SwWrtShell &rSh = GetShell();
+ SdrView* pDrView = rSh.GetDrawView();
+ const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
+ const SdrObject* pObj = nullptr;
+
+ if ( rMarkList.GetMarkCount() == 1 )
+ pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+
+ const SdrTextObj* pTextObj = DynCastSdrTextObj(pObj);
+ const bool bDeactivate(
+ !pObj ||
+ !pTextObj ||
+ !pTextObj->HasText() ||
+ dynamic_cast< const SdrObjCustomShape* >(pObj)); // #121538# no FontWork for CustomShapes
+
+ if (bDeactivate)
+ {
+ rSet.DisableItem(XATTR_FORMTXTSTYLE);
+ rSet.DisableItem(XATTR_FORMTXTADJUST);
+ rSet.DisableItem(XATTR_FORMTXTDISTANCE);
+ rSet.DisableItem(XATTR_FORMTXTSTART);
+ rSet.DisableItem(XATTR_FORMTXTMIRROR);
+ rSet.DisableItem(XATTR_FORMTXTHIDEFORM);
+ rSet.DisableItem(XATTR_FORMTXTOUTLINE);
+ rSet.DisableItem(XATTR_FORMTXTSHADOW);
+ rSet.DisableItem(XATTR_FORMTXTSHDWCOLOR);
+ rSet.DisableItem(XATTR_FORMTXTSHDWXVAL);
+ rSet.DisableItem(XATTR_FORMTXTSHDWYVAL);
+ }
+ else
+ {
+ pDrView->GetAttributes( rSet );
+ }
+}
+
+void SwDrawTextShell::ExecDrawLingu(SfxRequest const &rReq)
+{
+ SwWrtShell &rSh = GetShell();
+ OutlinerView* pOutlinerView = m_pSdrView->GetTextEditOutlinerView();
+ if( !rSh.GetDrawView()->GetMarkedObjectList().GetMarkCount() )
+ return;
+
+ switch(rReq.GetSlot())
+ {
+ case SID_THESAURUS:
+ pOutlinerView->StartThesaurus(rReq.GetFrameWeld());
+ break;
+
+ case SID_HANGUL_HANJA_CONVERSION:
+ pOutlinerView->StartTextConversion(rReq.GetFrameWeld(),
+ LANGUAGE_KOREAN, LANGUAGE_KOREAN, nullptr,
+ i18n::TextConversionOption::CHARACTER_BY_CHARACTER, true, false);
+ break;
+
+ case SID_CHINESE_CONVERSION:
+ {
+ //open ChineseTranslationDialog
+ Reference<XComponentContext> xContext = comphelper::getProcessComponentContext();
+ if (!xContext.is())
+ return;
+
+ Reference<lang::XMultiComponentFactory> xMCF(xContext->getServiceManager());
+ if (!xMCF.is())
+ return;
+
+ Reference<ui::dialogs::XExecutableDialog> xDialog(
+ xMCF->createInstanceWithContext("com.sun.star.linguistic2.ChineseTranslationDialog", xContext), UNO_QUERY);
+
+ Reference<lang::XInitialization> xInit(xDialog, UNO_QUERY);
+
+ if (!xInit.is())
+ return;
+
+ // initialize dialog
+ uno::Sequence<uno::Any> aSequence(comphelper::InitAnyPropertySequence(
+ {
+ {"ParentWindow", uno::Any(Reference<awt::XWindow>())}
+ }));
+ xInit->initialize( aSequence );
+
+ //execute dialog
+ sal_Int16 nDialogRet = xDialog->execute();
+ if(RET_OK == nDialogRet)
+ {
+ //get some parameters from the dialog
+ bool bToSimplified = true;
+ bool bUseVariants = true;
+ bool bCommonTerms = true;
+ Reference<beans::XPropertySet> xPropertySet(xDialog, UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ try
+ {
+ xPropertySet->getPropertyValue("IsDirectionToSimplified") >>= bToSimplified;
+ xPropertySet->getPropertyValue("IsUseCharacterVariants") >>= bUseVariants;
+ xPropertySet->getPropertyValue("IsTranslateCommonTerms") >>= bCommonTerms;
+ }
+ catch (const Exception&)
+ {
+ }
+ }
+
+ //execute translation
+ LanguageType nSourceLang = bToSimplified ? LANGUAGE_CHINESE_TRADITIONAL : LANGUAGE_CHINESE_SIMPLIFIED;
+ LanguageType nTargetLang = bToSimplified ? LANGUAGE_CHINESE_SIMPLIFIED : LANGUAGE_CHINESE_TRADITIONAL;
+ sal_Int32 nOptions = bUseVariants ? i18n::TextConversionOption::USE_CHARACTER_VARIANTS : 0;
+ if(!bCommonTerms)
+ nOptions = nOptions | i18n::TextConversionOption::CHARACTER_BY_CHARACTER;
+
+ vcl::Font aTargetFont = OutputDevice::GetDefaultFont(DefaultFontType::CJK_TEXT, nTargetLang, GetDefaultFontFlags::OnlyOne);
+
+ pOutlinerView->StartTextConversion(rReq.GetFrameWeld(), nSourceLang, nTargetLang, &aTargetFont, nOptions, false, false);
+ }
+
+ Reference<lang::XComponent> xComponent(xDialog, UNO_QUERY);
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+ break;
+
+ default:
+ OSL_ENSURE(false, "unexpected slot-id");
+ }
+}
+
+void SwDrawTextShell::ExecDraw(SfxRequest &rReq)
+{
+ SwWrtShell &rSh = GetShell();
+ m_pSdrView = rSh.GetDrawView();
+ OutlinerView* pOLV = m_pSdrView->GetTextEditOutlinerView();
+
+ switch (rReq.GetSlot())
+ {
+ case FN_INSERT_SOFT_HYPHEN:
+ case FN_INSERT_HARDHYPHEN:
+ case FN_INSERT_HARD_SPACE:
+ case FN_INSERT_NNBSP:
+ case SID_INSERT_RLM :
+ case SID_INSERT_LRM :
+ case SID_INSERT_WJ :
+ case SID_INSERT_ZWSP:
+ {
+ sal_Unicode cIns = 0;
+ switch(rReq.GetSlot())
+ {
+ case FN_INSERT_SOFT_HYPHEN: cIns = CHAR_SOFTHYPHEN; break;
+ case FN_INSERT_HARDHYPHEN: cIns = CHAR_HARDHYPHEN; break;
+ case FN_INSERT_HARD_SPACE: cIns = CHAR_HARDBLANK; break;
+ case FN_INSERT_NNBSP: cIns = CHAR_NNBSP; break;
+ case SID_INSERT_RLM : cIns = CHAR_RLM ; break;
+ case SID_INSERT_LRM : cIns = CHAR_LRM ; break;
+ case SID_INSERT_ZWSP : cIns = CHAR_ZWSP ; break;
+ case SID_INSERT_WJ: cIns = CHAR_WJ; break;
+ }
+ pOLV->InsertText( OUString(cIns));
+ rReq.Done();
+ }
+ break;
+ case SID_CHARMAP:
+ { // Insert special character
+ InsertSymbol(rReq);
+ break;
+ }
+ case FN_INSERT_STRING:
+ {
+ const SfxItemSet *pNewAttrs = rReq.GetArgs();
+ sal_uInt16 nSlot = rReq.GetSlot();
+ const SfxPoolItem* pItem = nullptr;
+ if(pNewAttrs)
+ {
+ pNewAttrs->GetItemState(nSlot, false, &pItem );
+ pOLV->InsertText(static_cast<const SfxStringItem *>(pItem)->GetValue());
+ }
+ break;
+ }
+
+ case SID_SELECTALL:
+ {
+ SdrOutliner * pOutliner = m_pSdrView->GetTextEditOutliner();
+ if(pOutliner)
+ {
+ sal_Int32 nParaCount = pOutliner->GetParagraphCount();
+ if (nParaCount > 0)
+ pOLV->SelectRange(0, nParaCount );
+ }
+ }
+ break;
+
+ case FN_FORMAT_RESET: // delete hard text attributes
+ {
+ pOLV->RemoveAttribsKeepLanguages( true );
+ pOLV->GetEditView().GetEditEngine()->RemoveFields();
+ rReq.Done();
+ }
+ break;
+
+ case FN_ESCAPE:
+ if (m_pSdrView->IsTextEdit())
+ {
+ // Shell switch!
+ rSh.EndTextEdit();
+ SwView& rTempView = rSh.GetView();
+ rTempView.ExitDraw();
+ rSh.Edit();
+ return;
+ }
+ break;
+ case FN_DRAWTEXT_ATTR_DLG:
+ {
+ SfxItemSet aNewAttr(m_pSdrView->GetModel().GetItemPool());
+ m_pSdrView->GetAttributes( aNewAttr );
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateTextTabDialog(
+ GetView().GetFrameWeld(),
+ &aNewAttr, m_pSdrView ));
+ sal_uInt16 nResult = pDlg->Execute();
+
+ if (nResult == RET_OK)
+ {
+ if (m_pSdrView->AreObjectsMarked())
+ {
+ m_pSdrView->SetAttributes(*pDlg->GetOutputItemSet());
+ rReq.Done(*(pDlg->GetOutputItemSet()));
+ }
+ }
+ }
+ break;
+ case SID_TABLE_VERT_NONE:
+ case SID_TABLE_VERT_CENTER:
+ case SID_TABLE_VERT_BOTTOM:
+ {
+ sal_uInt16 nSId = rReq.GetSlot();
+ if (m_pSdrView->AreObjectsMarked())
+ {
+ SdrTextVertAdjust eTVA = SDRTEXTVERTADJUST_TOP;
+ if (nSId == SID_TABLE_VERT_CENTER)
+ eTVA = SDRTEXTVERTADJUST_CENTER;
+ else if (nSId == SID_TABLE_VERT_BOTTOM)
+ eTVA = SDRTEXTVERTADJUST_BOTTOM;
+
+ SfxItemSet aNewAttr(m_pSdrView->GetModel().GetItemPool());
+ m_pSdrView->GetAttributes( aNewAttr );
+ aNewAttr.Put(SdrTextVertAdjustItem(eTVA));
+ m_pSdrView->SetAttributes(aNewAttr);
+ rReq.Done();
+ }
+
+ }
+ break;
+
+ default:
+ OSL_ENSURE(false, "unexpected slot-id");
+ return;
+ }
+
+ GetView().GetViewFrame().GetBindings().InvalidateAll(false);
+
+ if (IsTextEdit() && pOLV->GetOutliner()->IsModified())
+ rSh.SetModified();
+}
+
+// Execute undo
+
+void SwDrawTextShell::ExecUndo(SfxRequest &rReq)
+{
+ if( !IsTextEdit() )
+ return;
+
+ bool bCallBase = true;
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ if( pArgs )
+ {
+ sal_uInt16 nId = rReq.GetSlot(), nCnt = 1;
+ const SfxPoolItem* pItem;
+ switch( nId )
+ {
+ case SID_UNDO:
+ case SID_REDO:
+ if( SfxItemState::SET == pArgs->GetItemState( nId, false, &pItem ) &&
+ 1 < (nCnt = static_cast<const SfxUInt16Item*>(pItem)->GetValue()) )
+ {
+ // then we make by ourself.
+ SfxUndoManager* pUndoManager = GetUndoManager();
+ if( pUndoManager )
+ {
+ if( SID_UNDO == nId )
+ while( nCnt-- )
+ pUndoManager->Undo();
+ else
+ while( nCnt-- )
+ pUndoManager->Redo();
+ }
+ bCallBase = false;
+ GetView().GetViewFrame().GetBindings().InvalidateAll(false);
+ }
+ break;
+ }
+ }
+ if( bCallBase )
+ {
+ SfxViewFrame& rSfxViewFrame = GetView().GetViewFrame();
+ rSfxViewFrame.ExecuteSlot(rReq, rSfxViewFrame.GetInterface());
+ }
+}
+
+// State of undo
+
+void SwDrawTextShell::StateUndo(SfxItemSet &rSet)
+{
+ if ( !IsTextEdit() )
+ return;
+
+ SfxViewFrame& rSfxViewFrame = GetView().GetViewFrame();
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while( nWhich )
+ {
+ switch ( nWhich )
+ {
+ case SID_GETUNDOSTRINGS:
+ case SID_GETREDOSTRINGS:
+ {
+ SfxUndoManager* pUndoManager = GetUndoManager();
+ if( pUndoManager )
+ {
+ OUString (SfxUndoManager::*fnGetComment)( size_t, bool const ) const;
+
+ sal_uInt16 nCount;
+ if( SID_GETUNDOSTRINGS == nWhich )
+ {
+ nCount = pUndoManager->GetUndoActionCount();
+ fnGetComment = &SfxUndoManager::GetUndoActionComment;
+ }
+ else
+ {
+ nCount = pUndoManager->GetRedoActionCount();
+ fnGetComment = &SfxUndoManager::GetRedoActionComment;
+ }
+ if( nCount )
+ {
+ OUStringBuffer sList;
+ for( sal_uInt16 n = 0; n < nCount; ++n )
+ sList.append( (pUndoManager->*fnGetComment)( n, SfxUndoManager::TopLevel ) + "\n");
+
+ SfxStringListItem aItem( nWhich );
+ aItem.SetString( sList.makeStringAndClear() );
+ rSet.Put( aItem );
+ }
+ }
+ else
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ default:
+ {
+ auto* pUndoManager = dynamic_cast<IDocumentUndoRedo*>(GetUndoManager());
+ if (pUndoManager)
+ pUndoManager->SetView(&GetView());
+ rSfxViewFrame.GetSlotState(nWhich, rSfxViewFrame.GetInterface(), &rSet);
+ if (pUndoManager)
+ pUndoManager->SetView(nullptr);
+ }
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void SwDrawTextShell::ExecTransliteration( SfxRequest const & rReq )
+{
+ if (!m_pSdrView)
+ return;
+
+ using namespace i18n;
+
+ TransliterationFlags nMode = TransliterationFlags::NONE;
+
+ switch( rReq.GetSlot() )
+ {
+ case SID_TRANSLITERATE_SENTENCE_CASE:
+ nMode = TransliterationFlags::SENTENCE_CASE;
+ break;
+ case SID_TRANSLITERATE_TITLE_CASE:
+ nMode = TransliterationFlags::TITLE_CASE;
+ break;
+ case SID_TRANSLITERATE_TOGGLE_CASE:
+ nMode = TransliterationFlags::TOGGLE_CASE;
+ break;
+ case SID_TRANSLITERATE_UPPER:
+ nMode = TransliterationFlags::LOWERCASE_UPPERCASE;
+ break;
+ case SID_TRANSLITERATE_LOWER:
+ nMode = TransliterationFlags::UPPERCASE_LOWERCASE;
+ break;
+
+ case SID_TRANSLITERATE_HALFWIDTH:
+ nMode = TransliterationFlags::FULLWIDTH_HALFWIDTH;
+ break;
+ case SID_TRANSLITERATE_FULLWIDTH:
+ nMode = TransliterationFlags::HALFWIDTH_FULLWIDTH;
+ break;
+
+ case SID_TRANSLITERATE_HIRAGANA:
+ nMode = TransliterationFlags::KATAKANA_HIRAGANA;
+ break;
+ case SID_TRANSLITERATE_KATAKANA:
+ nMode = TransliterationFlags::HIRAGANA_KATAKANA;
+ break;
+
+ default:
+ OSL_ENSURE(false, "wrong dispatcher");
+ }
+
+ if( nMode != TransliterationFlags::NONE )
+ {
+ OutlinerView* pOLV = m_pSdrView->GetTextEditOutlinerView();
+
+ if (!pOLV)
+ return;
+
+ pOLV->TransliterateText( nMode );
+ }
+}
+
+void SwDrawTextShell::ExecRotateTransliteration( SfxRequest const & rReq )
+{
+ if( rReq.GetSlot() == SID_TRANSLITERATE_ROTATE_CASE )
+ {
+ if (!m_pSdrView)
+ return;
+
+ OutlinerView* pOLV = m_pSdrView->GetTextEditOutlinerView();
+
+ if (!pOLV)
+ return;
+
+ pOLV->TransliterateText( m_aRotateCase.getNextMode() );
+ }
+}
+
+// Insert special character (see SDraw: FUBULLET.CXX)
+
+void SwDrawTextShell::InsertSymbol(SfxRequest& rReq)
+{
+ OutlinerView* pOLV = m_pSdrView->GetTextEditOutlinerView();
+ if(!pOLV)
+ return;
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ const SfxStringItem* pItem = nullptr;
+ if( pArgs )
+ pItem = pArgs->GetItemIfSet(SID_CHARMAP, false);
+
+ OUString sSym;
+ OUString sFontName;
+ if ( pItem )
+ {
+ sSym = pItem->GetValue();
+ const SfxStringItem* pFontItem = pArgs->GetItemIfSet( SID_ATTR_SPECIALCHAR, false);
+ if ( pFontItem )
+ sFontName = pFontItem->GetValue();
+ }
+
+ SfxItemSet aSet(pOLV->GetAttribs());
+ SvtScriptType nScript = pOLV->GetSelectedScriptType();
+ std::shared_ptr<SvxFontItem> aSetDlgFont(std::make_shared<SvxFontItem>(RES_CHRATR_FONT));
+ {
+ SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT, *aSet.GetPool() );
+ aSetItem.GetItemSet().Put( aSet, false );
+ const SfxPoolItem* pI = aSetItem.GetItemOfScript( nScript );
+ if( pI )
+ aSetDlgFont.reset(static_cast<SvxFontItem*>(pI->Clone()));
+ else
+ {
+ TypedWhichId<SvxFontItem> nFontWhich =
+ GetWhichOfScript(
+ SID_ATTR_CHAR_FONT,
+ SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() ) );
+ aSetDlgFont.reset(aSet.Get( nFontWhich ).Clone());
+ }
+ if (sFontName.isEmpty())
+ sFontName = aSetDlgFont->GetFamilyName();
+ }
+
+ vcl::Font aFont(sFontName, Size(1,1));
+ if(sSym.isEmpty())
+ {
+ SfxAllItemSet aAllSet( GetPool() );
+ aAllSet.Put( SfxBoolItem( FN_PARAM_1, false ) );
+
+ SwViewOption aOpt(*m_rView.GetWrtShell().GetViewOptions());
+ const OUString& sSymbolFont = aOpt.GetSymbolFont();
+ if( !sSymbolFont.isEmpty() )
+ aAllSet.Put( SfxStringItem( SID_FONT_NAME, sSymbolFont ) );
+ else
+ aAllSet.Put( SfxStringItem( SID_FONT_NAME, aSetDlgFont->GetFamilyName() ) );
+
+ // If character is selected, it can be shown
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ auto xFrame = m_rView.GetViewFrame().GetFrame().GetFrameInterface();
+ ScopedVclPtr<SfxAbstractDialog> pDlg(pFact->CreateCharMapDialog(m_rView.GetFrameWeld(), aAllSet, xFrame));
+ pDlg->Execute();
+ return;
+ }
+
+ // do not flicker
+ pOLV->HideCursor();
+ SdrOutliner * pOutliner = m_pSdrView->GetTextEditOutliner();
+ pOutliner->SetUpdateLayout(false);
+
+ SfxItemSet aOldSet( pOLV->GetAttribs() );
+ SfxItemSetFixed<
+ EE_CHAR_FONTINFO, EE_CHAR_FONTINFO,
+ EE_CHAR_FONTINFO_CJK, EE_CHAR_FONTINFO_CTL> aFontSet( *aOldSet.GetPool() );
+ aFontSet.Set( aOldSet );
+
+ // Insert string
+ pOLV->InsertText( sSym );
+
+ // assign attributes (Set font)
+ SfxItemSet aFontAttribSet( *aFontSet.GetPool(), aFontSet.GetRanges() );
+ SvxFontItem aFontItem (aFont.GetFamilyType(), aFont.GetFamilyName(),
+ aFont.GetStyleName(), aFont.GetPitch(),
+ aFont.GetCharSet(),
+ EE_CHAR_FONTINFO );
+ nScript = g_pBreakIt->GetAllScriptsOfText( sSym );
+ if( SvtScriptType::LATIN & nScript )
+ aFontAttribSet.Put( aFontItem );
+ if( SvtScriptType::ASIAN & nScript )
+ {
+ aFontItem.SetWhich(EE_CHAR_FONTINFO_CJK);
+ aFontAttribSet.Put( aFontItem );
+ }
+ if( SvtScriptType::COMPLEX & nScript )
+ {
+ aFontItem.SetWhich(EE_CHAR_FONTINFO_CTL);
+ aFontAttribSet.Put( aFontItem );
+ }
+ pOLV->SetAttribs(aFontAttribSet);
+
+ // Remove selection
+ ESelection aSel(pOLV->GetSelection());
+ aSel.nStartPara = aSel.nEndPara;
+ aSel.nStartPos = aSel.nEndPos;
+ pOLV->SetSelection(aSel);
+
+ // Restore old font
+ pOLV->SetAttribs( aFontSet );
+
+ // From now on show again
+ pOutliner->SetUpdateLayout(true);
+ pOLV->ShowCursor();
+
+ rReq.AppendItem( SfxStringItem( SID_CHARMAP, sSym ) );
+ if(!aFont.GetFamilyName().isEmpty())
+ rReq.AppendItem( SfxStringItem( SID_ATTR_SPECIALCHAR, aFont.GetFamilyName() ) );
+ rReq.Done();
+
+}
+
+SfxUndoManager* SwDrawTextShell::GetUndoManager()
+{
+ SwWrtShell &rSh = GetShell();
+ m_pSdrView = rSh.GetDrawView();
+ SdrOutliner * pOutliner = m_pSdrView->GetTextEditOutliner();
+ return &pOutliner->GetUndoManager();
+}
+
+void SwDrawTextShell::GetStatePropPanelAttr(SfxItemSet &rSet)
+{
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+
+ SwWrtShell &rSh = GetShell();
+ m_pSdrView = rSh.GetDrawView();
+
+ SfxItemSet aAttrs(m_pSdrView->GetModel().GetItemPool());
+ m_pSdrView->GetAttributes( aAttrs );
+
+ while ( nWhich )
+ {
+ sal_uInt16 nSlotId = SfxItemPool::IsWhich(nWhich)
+ ? GetPool().GetSlotId(nWhich)
+ : nWhich;
+ switch ( nSlotId )
+ {
+ case SID_TABLE_VERT_NONE:
+ case SID_TABLE_VERT_CENTER:
+ case SID_TABLE_VERT_BOTTOM:
+ bool bContour = false;
+ SfxItemState eConState = aAttrs.GetItemState( SDRATTR_TEXT_CONTOURFRAME );
+ if( eConState != SfxItemState::DONTCARE )
+ {
+ bContour = aAttrs.Get( SDRATTR_TEXT_CONTOURFRAME ).GetValue();
+ }
+ if (bContour) break;
+
+ SfxItemState eVState = aAttrs.GetItemState( SDRATTR_TEXT_VERTADJUST );
+ //SfxItemState eHState = aAttrs.GetItemState( SDRATTR_TEXT_HORZADJUST );
+
+ //if(SfxItemState::DONTCARE != eVState && SfxItemState::DONTCARE != eHState)
+ if(SfxItemState::DONTCARE != eVState)
+ {
+ SdrTextVertAdjust eTVA = aAttrs.Get(SDRATTR_TEXT_VERTADJUST).GetValue();
+ bool bSet = (nSlotId == SID_TABLE_VERT_NONE && eTVA == SDRTEXTVERTADJUST_TOP) ||
+ (nSlotId == SID_TABLE_VERT_CENTER && eTVA == SDRTEXTVERTADJUST_CENTER) ||
+ (nSlotId == SID_TABLE_VERT_BOTTOM && eTVA == SDRTEXTVERTADJUST_BOTTOM);
+ rSet.Put(SfxBoolItem(nSlotId, bSet));
+ }
+ else
+ {
+ rSet.Put(SfxBoolItem(nSlotId, false));
+ }
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/frmsh.cxx b/sw/source/uibase/shells/frmsh.cxx
new file mode 100644
index 0000000000..ac5ee0d808
--- /dev/null
+++ b/sw/source/uibase/shells/frmsh.cxx
@@ -0,0 +1,1463 @@
+/* -*- 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 <hintids.hxx>
+#include <svl/whiter.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <basic/sbstar.hxx>
+#include <svl/ptitem.hxx>
+#include <svl/stritem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/eitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/lineitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/objface.hxx>
+#include <vcl/EnumContext.hxx>
+#include <svx/hlnkitem.hxx>
+#include <svx/svdview.hxx>
+#include <svx/sdangitm.hxx>
+#include <vcl/commandinfoprovider.hxx>
+#include <sal/log.hxx>
+
+#include <doc.hxx>
+#include <drawdoc.hxx>
+#include <IDocumentSettingAccess.hxx>
+#include <IDocumentDrawModelAccess.hxx>
+#include <fmturl.hxx>
+#include <fmtclds.hxx>
+#include <fmtcnct.hxx>
+#include <swmodule.hxx>
+#include <wrtsh.hxx>
+#include <wview.hxx>
+#include <uitool.hxx>
+#include <frmfmt.hxx>
+#include <frmsh.hxx>
+#include <frmmgr.hxx>
+#include <edtwin.hxx>
+#include <swdtflvr.hxx>
+#include <viewopt.hxx>
+
+#include <cmdid.h>
+#include <strings.hrc>
+#include <swabstdlg.hxx>
+
+#include <svx/svxdlg.hxx>
+
+#include <docsh.hxx>
+#include <svx/drawitem.hxx>
+#include <memory>
+
+#define ShellClass_SwFrameShell
+#include <sfx2/msg.hxx>
+#include <swslots.hxx>
+#include <grfatr.hxx>
+#include <fldmgr.hxx>
+#include <flyfrm.hxx>
+
+using ::editeng::SvxBorderLine;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+// Prototypes
+static void lcl_FrameGetMaxLineWidth(const SvxBorderLine* pBorderLine, SvxBorderLine& rBorderLine);
+static const SwFrameFormat* lcl_GetFrameFormatByName(SwWrtShell const & rSh, std::u16string_view rName)
+{
+ const size_t nCount = rSh.GetFlyCount(FLYCNTTYPE_FRM);
+ for( size_t i = 0; i < nCount; ++i )
+ {
+ const SwFrameFormat* pFormat = rSh.GetFlyNum(i, FLYCNTTYPE_FRM);
+ if(pFormat->GetName() == rName)
+ return pFormat;
+ }
+ return nullptr;
+}
+
+SFX_IMPL_INTERFACE(SwFrameShell, SwBaseShell)
+
+void SwFrameShell::InitInterface_Impl()
+{
+ GetStaticInterface()->RegisterPopupMenu("frame");
+
+ GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Invisible, ToolbarId::Frame_Toolbox);
+}
+
+void SwFrameShell::ExecMove(SfxRequest& rReq)
+{
+ SwWrtShell& rSh = GetShell();
+ sal_uInt16 nSlot = rReq.GetSlot();
+ switch (nSlot)
+ {
+ case SID_SELECTALL:
+ rSh.SelAll();
+ rReq.Done();
+ break;
+ }
+}
+
+void SwFrameShell::ExecField(const SfxRequest& rReq)
+{
+ SwWrtShell& rSh = GetShell();
+ sal_uInt16 nSlot = rReq.GetSlot();
+ switch (nSlot)
+ {
+ case FN_POSTIT:
+ SwFieldMgr aFieldMgr(&rSh);
+ rSh.InsertPostIt(aFieldMgr, rReq);
+ break;
+ }
+}
+
+void SwFrameShell::Execute(SfxRequest &rReq)
+{
+ //First those who do not need FrameMgr.
+ SwWrtShell &rSh = GetShell();
+ bool bMore = false;
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ const SfxPoolItem* pItem;
+ sal_uInt16 nSlot = rReq.GetSlot();
+
+ switch ( nSlot )
+ {
+ case FN_FRAME_TO_ANCHOR:
+ if ( rSh.IsFrameSelected() )
+ {
+ rSh.GotoFlyAnchor();
+ rSh.EnterStdMode();
+ rSh.CallChgLnk();
+ }
+ break;
+ case SID_FRAME_TO_TOP:
+ rSh.SelectionToTop();
+ break;
+
+ case SID_FRAME_TO_BOTTOM:
+ rSh.SelectionToBottom();
+ break;
+
+ case FN_FRAME_UP:
+ rSh.SelectionToTop( false );
+ break;
+
+ case FN_FRAME_DOWN:
+ rSh.SelectionToBottom( false );
+ break;
+ case FN_INSERT_FRAME:
+ if (!pArgs)
+ {
+ // Frame already exists, open frame dialog for editing.
+ SfxStringItem aDefPage(FN_FORMAT_FRAME_DLG, "columns");
+ rSh.GetView().GetViewFrame().GetDispatcher()->ExecuteList(
+ FN_FORMAT_FRAME_DLG,
+ SfxCallMode::SYNCHRON|SfxCallMode::RECORD,
+ { &aDefPage });
+
+ }
+ else
+ {
+ // Frame already exists, only the number of columns will be changed.
+ sal_uInt16 nCols = 1;
+ if(const SfxUInt16Item* pColsItem = pArgs->GetItemIfSet(SID_ATTR_COLUMNS, false))
+ nCols = pColsItem->GetValue();
+
+ SfxItemSetFixed<RES_COL,RES_COL> aSet(GetPool());
+ rSh.GetFlyFrameAttr( aSet );
+ SwFormatCol aCol(aSet.Get(RES_COL));
+ // GutterWidth will not always passed, hence get firstly
+ // (see view2: Execute on this slot)
+ sal_uInt16 nGutterWidth = aCol.GetGutterWidth();
+ if(!nCols )
+ nCols++;
+ aCol.Init(nCols, nGutterWidth, aCol.GetWishWidth());
+ aSet.Put(aCol);
+ // Template AutoUpdate
+ SwFrameFormat* pFormat = rSh.GetSelectedFrameFormat();
+ if(pFormat && pFormat->IsAutoUpdateOnDirectFormat())
+ {
+ rSh.AutoUpdateFrame(pFormat, aSet);
+ }
+ else
+ {
+ rSh.StartAllAction();
+ rSh.SetFlyFrameAttr( aSet );
+ rSh.SetModified();
+ rSh.EndAllAction();
+ }
+
+ }
+ return;
+
+ case SID_HYPERLINK_SETLINK:
+ {
+ if(pArgs && SfxItemState::SET == pArgs->GetItemState(SID_HYPERLINK_SETLINK, false, &pItem))
+ {
+ const SvxHyperlinkItem& rHLinkItem = *static_cast<const SvxHyperlinkItem *>(pItem);
+ const OUString& rURL = rHLinkItem.GetURL();
+ const OUString& rTarget = rHLinkItem.GetTargetFrame();
+
+ SfxItemSetFixed<RES_URL, RES_URL> aSet( rSh.GetAttrPool() );
+ rSh.GetFlyFrameAttr( aSet );
+ SwFormatURL aURL( aSet.Get( RES_URL ) );
+
+ OUString sOldName(rHLinkItem.GetName().toAsciiUpperCase());
+ OUString sFlyName(rSh.GetFlyName().toAsciiUpperCase());
+ if (sOldName != sFlyName)
+ {
+ OUString sName(sOldName);
+ sal_uInt16 i = 1;
+ while (rSh.FindFlyByName(sName))
+ {
+ sName = sOldName + "_" + OUString::number(i++);
+ }
+ rSh.SetFlyName(sName);
+ }
+ aURL.SetURL( rURL, false );
+ aURL.SetTargetFrameName(rTarget);
+
+ aSet.Put( aURL );
+ rSh.SetFlyFrameAttr( aSet );
+ }
+ }
+ break;
+
+ case FN_FRAME_CHAIN:
+ rSh.GetView().GetEditWin().SetChainMode( !rSh.GetView().GetEditWin().IsChainMode() );
+ break;
+
+ case FN_FRAME_UNCHAIN:
+ rSh.Unchain( *rSh.GetFlyFrameFormat() );
+ GetView().GetViewFrame().GetBindings().Invalidate(FN_FRAME_CHAIN);
+ break;
+ case FN_FORMAT_FOOTNOTE_DLG:
+ {
+ GetView().ExecFormatFootnote();
+ break;
+ }
+ case FN_NUMBERING_OUTLINE_DLG:
+ {
+ GetView().ExecNumberingOutline(GetPool());
+ rReq.Done();
+ break;
+ }
+ case SID_OPEN_XML_FILTERSETTINGS:
+ {
+ HandleOpenXmlFilterSettings(rReq);
+ }
+ break;
+ case FN_WORDCOUNT_DIALOG:
+ {
+ GetView().UpdateWordCount(this, nSlot);
+ break;
+ }
+ case FN_UNFLOAT_FRAME:
+ {
+ rSh.UnfloatFlyFrame();
+ rReq.Done();
+ break;
+ }
+ default: bMore = true;
+ }
+
+ if ( !bMore )
+ {
+ return;
+ }
+
+ SwFlyFrameAttrMgr aMgr( false, &rSh, Frmmgr_Type::NONE, nullptr );
+ bool bUpdateMgr = true;
+ bool bCopyToFormat = false;
+ switch ( nSlot )
+ {
+ case SID_OBJECT_ALIGN_MIDDLE:
+ case FN_FRAME_ALIGN_VERT_CENTER:
+ aMgr.SetVertOrientation( text::VertOrientation::CENTER );
+ break;
+ case SID_OBJECT_ALIGN_DOWN :
+ case FN_FRAME_ALIGN_VERT_BOTTOM:
+ aMgr.SetVertOrientation( text::VertOrientation::BOTTOM );
+ break;
+ case SID_OBJECT_ALIGN_UP :
+ case FN_FRAME_ALIGN_VERT_TOP:
+ aMgr.SetVertOrientation( text::VertOrientation::TOP );
+ break;
+
+ case FN_FRAME_ALIGN_VERT_CHAR_CENTER:
+ aMgr.SetVertOrientation( text::VertOrientation::CHAR_CENTER );
+ break;
+
+ case FN_FRAME_ALIGN_VERT_CHAR_BOTTOM:
+ aMgr.SetVertOrientation( text::VertOrientation::CHAR_BOTTOM );
+ break;
+
+ case FN_FRAME_ALIGN_VERT_CHAR_TOP:
+ aMgr.SetVertOrientation( text::VertOrientation::CHAR_TOP );
+ break;
+
+ case FN_FRAME_ALIGN_VERT_ROW_CENTER:
+ aMgr.SetVertOrientation( text::VertOrientation::LINE_CENTER );
+ break;
+
+ case FN_FRAME_ALIGN_VERT_ROW_BOTTOM:
+ aMgr.SetVertOrientation( text::VertOrientation::LINE_BOTTOM );
+ break;
+
+ case FN_FRAME_ALIGN_VERT_ROW_TOP:
+ aMgr.SetVertOrientation( text::VertOrientation::LINE_TOP );
+ break;
+ case SID_OBJECT_ALIGN_CENTER :
+ case FN_FRAME_ALIGN_HORZ_CENTER:
+ aMgr.SetHorzOrientation( text::HoriOrientation::CENTER );
+ break;
+ case SID_OBJECT_ALIGN_RIGHT:
+ case FN_FRAME_ALIGN_HORZ_RIGHT:
+ aMgr.SetHorzOrientation( text::HoriOrientation::RIGHT );
+ break;
+ case SID_OBJECT_ALIGN_LEFT:
+ case FN_FRAME_ALIGN_HORZ_LEFT:
+ aMgr.SetHorzOrientation( text::HoriOrientation::LEFT );
+ break;
+
+ case FN_SET_FRM_POSITION:
+ {
+ aMgr.SetAbsPos(static_cast<const SfxPointItem &>(pArgs->Get
+ (FN_SET_FRM_POSITION)).GetValue());
+ }
+ break;
+ case SID_ATTR_BRUSH:
+ {
+ if(pArgs)
+ {
+ aMgr.SetAttrSet( *pArgs );
+ bCopyToFormat = true;
+ }
+ }
+ break;
+ case SID_ATTR_ULSPACE:
+ case SID_ATTR_LRSPACE:
+ {
+ if(pArgs && SfxItemState::SET == pArgs->GetItemState(GetPool().GetWhich(nSlot), false, &pItem))
+ {
+ aMgr.SetAttrSet( *pArgs );
+ bCopyToFormat = true;
+ }
+ }
+ break;
+
+ case SID_ATTR_TRANSFORM:
+ {
+ bool bApplyNewPos = false;
+ bool bApplyNewSize = false;
+
+ Point aNewPos = aMgr.GetPos();
+ if (pArgs)
+ {
+ if (const SfxInt32Item* pXItem = pArgs->GetItemIfSet(SID_ATTR_TRANSFORM_POS_X, false))
+ {
+ aNewPos.setX( pXItem->GetValue() );
+ bApplyNewPos = true;
+ }
+ if (const SfxInt32Item* pYItem = pArgs->GetItemIfSet(SID_ATTR_TRANSFORM_POS_Y, false))
+ {
+ aNewPos.setY( pYItem->GetValue() );
+ bApplyNewPos = true;
+ }
+ }
+
+ Size aNewSize = aMgr.GetSize();
+ if (pArgs)
+ {
+ if (const SfxUInt32Item* pWidthItem = pArgs->GetItemIfSet(SID_ATTR_TRANSFORM_WIDTH, false))
+ {
+ aNewSize.setWidth( pWidthItem->GetValue() );
+ bApplyNewSize = true;
+ }
+ if (const SfxUInt32Item* pHeightItem = pArgs->GetItemIfSet(SID_ATTR_TRANSFORM_HEIGHT, false))
+ {
+ aNewSize.setHeight( pHeightItem->GetValue() );
+ bApplyNewSize = true;
+ }
+ }
+
+ if (pArgs && (pArgs->HasItem(SID_ATTR_TRANSFORM_ANGLE) || pArgs->HasItem(SID_ATTR_TRANSFORM_DELTA_ANGLE)))
+ {
+ SfxItemSetFixed<RES_GRFATR_ROTATION, RES_GRFATR_ROTATION> aSet(rSh.GetAttrPool() );
+ rSh.GetCurAttr(aSet);
+ const SwRotationGrf& rRotation = aSet.Get(RES_GRFATR_ROTATION);
+ const Degree10 nOldRot(rRotation.GetValue());
+
+ if (const SdrAngleItem* pAngleItem = pArgs->GetItemIfSet(SID_ATTR_TRANSFORM_DELTA_ANGLE, false))
+ {
+ const Degree10 nDeltaRot = to<Degree10>(pAngleItem->GetValue());
+ aMgr.SetRotation(nOldRot, nOldRot + nDeltaRot, rRotation.GetUnrotatedSize());
+ }
+
+ // RotGrfFlyFrame: Get Value and disable is in SwGrfShell::GetAttrStateForRotation, but the
+ // value setter uses SID_ATTR_TRANSFORM and a group of three values. Rotation is
+ // added now, so use it in this central place. Do no forget to convert angle from
+ // 100th degrees in SID_ATTR_TRANSFORM_ANGLE to 10th degrees in RES_GRFATR_ROTATION
+ if (const SdrAngleItem* pTransformItem = pArgs->GetItemIfSet(SID_ATTR_TRANSFORM_ANGLE, false))
+ {
+ const Degree10 nNewRot = to<Degree10>(pTransformItem->GetValue());
+
+ // RotGrfFlyFrame: Rotation change here, SwFlyFrameAttrMgr aMgr is available
+ aMgr.SetRotation(nOldRot, nNewRot, rRotation.GetUnrotatedSize());
+ }
+ }
+
+ if (bApplyNewPos)
+ {
+ aMgr.SetAbsPos(aNewPos);
+ }
+ if ( bApplyNewSize )
+ {
+ aMgr.SetSize( aNewSize );
+ }
+ if (!bApplyNewPos && !bApplyNewSize)
+ {
+ bUpdateMgr = false;
+ }
+
+ }
+ break;
+
+ case FN_FORMAT_FRAME_DLG:
+ case FN_DRAW_WRAP_DLG:
+ {
+ const SelectionType nSel = rSh.GetSelectionType();
+ if (nSel & SelectionType::Graphic)
+ {
+ rSh.GetView().GetViewFrame().GetDispatcher()->Execute(FN_FORMAT_GRAFIC_DLG);
+ bUpdateMgr = false;
+ }
+ else
+ {
+ SfxItemSetFixed<
+ RES_FRMATR_BEGIN, RES_FRMATR_END - 1,
+ // FillAttribute support:
+ XATTR_FILL_FIRST, XATTR_FILL_LAST,
+ SID_DOCFRAME, SID_DOCFRAME,
+ SID_ATTR_BRUSH, SID_ATTR_BRUSH,
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
+ SID_ATTR_LRSPACE, SID_ATTR_ULSPACE,
+ SID_ATTR_PAGE_SIZE, SID_ATTR_PAGE_SIZE,
+ // Items to hand over XPropertyList things like
+ // XColorList, XHatchList, XGradientList, and
+ // XBitmapList to the Area TabPage
+ SID_COLOR_TABLE, SID_PATTERN_LIST,
+ SID_HTML_MODE, SID_HTML_MODE,
+ FN_GET_PRINT_AREA, FN_GET_PRINT_AREA,
+ FN_SURROUND, FN_KEEP_ASPECT_RATIO,
+ FN_SET_FRM_ALT_NAME, FN_SET_FRM_ALT_NAME,
+ FN_UNO_DESCRIPTION, FN_UNO_DESCRIPTION,
+ FN_OLE_IS_MATH, FN_MATH_BASELINE_ALIGNMENT,
+ FN_PARAM_CHAIN_PREVIOUS, FN_PARAM_CHAIN_NEXT> aSet( GetPool() );
+
+ // create needed items for XPropertyList entries from the DrawModel so that
+ // the Area TabPage can access them
+ const SwDrawModel* pDrawModel = rSh.GetView().GetDocShell()->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
+ pDrawModel->PutAreaListItems(aSet);
+
+ const SwViewOption* pVOpt = rSh.GetViewOptions();
+ if(nSel & SelectionType::Ole)
+ aSet.Put( SfxBoolItem(FN_KEEP_ASPECT_RATIO, pVOpt->IsKeepRatio()) );
+ aSet.Put(SfxUInt16Item(SID_HTML_MODE, ::GetHtmlMode(GetView().GetDocShell())));
+ aSet.Put(SfxStringItem(FN_SET_FRM_NAME, rSh.GetFlyName()));
+ aSet.Put(SfxStringItem(FN_UNO_DESCRIPTION, rSh.GetObjDescription()));
+ if( nSel & SelectionType::Ole )
+ {
+ // #i73249#
+ aSet.Put( SfxStringItem( FN_SET_FRM_ALT_NAME, rSh.GetObjTitle() ) );
+ }
+
+ const SwRect &rPg = rSh.GetAnyCurRect(CurRectType::Page);
+ SwFormatFrameSize aFrameSize(SwFrameSize::Variable, rPg.Width(), rPg.Height());
+ aFrameSize.SetWhich(GetPool().GetWhich(SID_ATTR_PAGE_SIZE));
+ aSet.Put(aFrameSize);
+
+ const SwRect &rPr = rSh.GetAnyCurRect(CurRectType::PagePrt);
+ SwFormatFrameSize aPrtSize(SwFrameSize::Variable, rPr.Width(), rPr.Height());
+ aPrtSize.SetWhich(GetPool().GetWhich(FN_GET_PRINT_AREA));
+ aSet.Put(aPrtSize);
+
+ aSet.Put(aMgr.GetAttrSet());
+ aSet.SetParent( aMgr.GetAttrSet().GetParent() );
+
+ // On % values initialize size
+ SwFormatFrameSize& rSize = const_cast<SwFormatFrameSize&>(aSet.Get(RES_FRM_SIZE));
+ if (rSize.GetWidthPercent() && rSize.GetWidthPercent() != SwFormatFrameSize::SYNCED)
+ rSize.SetWidth(rSh.GetAnyCurRect(CurRectType::FlyEmbedded).Width());
+ if (rSize.GetHeightPercent() && rSize.GetHeightPercent() != SwFormatFrameSize::SYNCED)
+ rSize.SetHeight(rSh.GetAnyCurRect(CurRectType::FlyEmbedded).Height());
+
+ // disable vertical positioning for Math Objects anchored 'as char' if baseline alignment is activated
+ aSet.Put( SfxBoolItem( FN_MATH_BASELINE_ALIGNMENT,
+ rSh.GetDoc()->getIDocumentSettingAccess().get( DocumentSettingId::MATH_BASELINE_ALIGNMENT ) ) );
+ const uno::Reference < embed::XEmbeddedObject > xObj( rSh.GetOleRef() );
+ aSet.Put( SfxBoolItem( FN_OLE_IS_MATH, xObj.is() && SotExchange::IsMath( xObj->getClassID() ) ) );
+
+ OUString sDefPage;
+ const SfxStringItem* pDlgItem;
+ if(pArgs && (pDlgItem = pArgs->GetItemIfSet(FN_FORMAT_FRAME_DLG, false)))
+ sDefPage = pDlgItem->GetValue();
+
+ aSet.Put(SfxFrameItem( SID_DOCFRAME, &GetView().GetViewFrame().GetFrame()));
+ FieldUnit eMetric = ::GetDfltMetric(dynamic_cast<SwWebView*>( &GetView()) != nullptr );
+ SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric) ));
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateFrameTabDialog(
+ nSel & SelectionType::Graphic ? OUString("PictureDialog") :
+ nSel & SelectionType::Ole ? OUString("ObjectDialog"):
+ OUString("FrameDialog"),
+ GetView().GetViewFrame(),
+ GetView().GetFrameWeld(),
+ aSet,
+ false,
+ sDefPage));
+
+ if ( nSlot == FN_DRAW_WRAP_DLG )
+ {
+ pDlg->SetCurPageId("wrap");
+ }
+
+ if ( pDlg->Execute() )
+ {
+ const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
+ if(pOutSet)
+ {
+ rReq.Done(*pOutSet);
+ const SfxBoolItem* pRatioItem = nullptr;
+ if(nSel & SelectionType::Ole &&
+ (pRatioItem = pOutSet->GetItemIfSet(FN_KEEP_ASPECT_RATIO)))
+ {
+ SwViewOption aUsrPref( *pVOpt );
+ aUsrPref.SetKeepRatio(pRatioItem->GetValue());
+ SW_MOD()->ApplyUsrPref(aUsrPref, &GetView());
+ }
+ if (const SfxStringItem* pAltNameItem = pOutSet->GetItemIfSet(FN_SET_FRM_ALT_NAME))
+ {
+ // #i73249#
+ rSh.SetObjTitle(pAltNameItem->GetValue());
+ }
+ if (const SfxStringItem* pDescripItem = pOutSet->GetItemIfSet(FN_UNO_DESCRIPTION))
+ rSh.SetObjDescription(pDescripItem->GetValue());
+
+ // Template AutoUpdate
+ SwFrameFormat* pFormat = rSh.GetSelectedFrameFormat();
+ if(pFormat && pFormat->IsAutoUpdateOnDirectFormat())
+ {
+ rSh.AutoUpdateFrame(pFormat, *pOutSet);
+ // Anything which is not supported by the format must be set hard.
+ if(const SfxStringItem* pFrameName = pOutSet->GetItemIfSet(FN_SET_FRM_NAME, false))
+ rSh.SetFlyName(pFrameName->GetValue());
+ SfxItemSetFixed<
+ RES_FRM_SIZE, RES_FRM_SIZE,
+ RES_SURROUND, RES_ANCHOR> aShellSet( GetPool() );
+ aShellSet.Put(*pOutSet);
+ aMgr.SetAttrSet(aShellSet);
+ if(const SfxStringItem* pFrameName = pOutSet->GetItemIfSet(FN_SET_FRM_NAME, false))
+ rSh.SetFlyName(pFrameName->GetValue());
+ }
+ else
+ aMgr.SetAttrSet( *pOutSet );
+
+ const SwFrameFormat* pCurrFlyFormat = rSh.GetFlyFrameFormat();
+ if(const SfxStringItem* pPreviousItem =
+ pOutSet->GetItemIfSet(FN_PARAM_CHAIN_PREVIOUS, false))
+ {
+ rSh.HideChainMarker();
+
+ OUString sPrevName = pPreviousItem->GetValue();
+ const SwFormatChain &rChain = pCurrFlyFormat->GetChain();
+ //needs cast - no non-const method available
+ SwFlyFrameFormat* pFlyFormat =
+ rChain.GetPrev();
+ if(pFlyFormat)
+ {
+ if (pFlyFormat->GetName() != sPrevName)
+ {
+ rSh.Unchain(*pFlyFormat);
+ }
+ else
+ sPrevName.clear();
+ }
+
+ if (!sPrevName.isEmpty())
+ {
+ //needs cast - no non-const method available
+ SwFrameFormat* pPrevFormat = const_cast<SwFrameFormat*>(
+ lcl_GetFrameFormatByName(rSh, sPrevName));
+ SAL_WARN_IF(!pPrevFormat, "sw.ui", "No frame found!");
+ if(pPrevFormat)
+ {
+ rSh.Chain(*pPrevFormat, *pCurrFlyFormat);
+ }
+ }
+ rSh.SetChainMarker();
+ }
+ if(const SfxStringItem* pChainNextItem =
+ pOutSet->GetItemIfSet(FN_PARAM_CHAIN_NEXT, false))
+ {
+ rSh.HideChainMarker();
+ OUString sNextName = pChainNextItem->GetValue();
+ const SwFormatChain &rChain = pCurrFlyFormat->GetChain();
+ //needs cast - no non-const method available
+ SwFlyFrameFormat* pFlyFormat =
+ rChain.GetNext();
+ if(pFlyFormat)
+ {
+ if (pFlyFormat->GetName() != sNextName)
+ {
+ rSh.Unchain(*const_cast<SwFlyFrameFormat*>(static_cast<const SwFlyFrameFormat*>( pCurrFlyFormat)));
+ }
+ else
+ sNextName.clear();
+ }
+
+ if (!sNextName.isEmpty())
+ {
+ //needs cast - no non-const method available
+ SwFrameFormat* pNextFormat = const_cast<SwFrameFormat*>(
+ lcl_GetFrameFormatByName(rSh, sNextName));
+ SAL_WARN_IF(!pNextFormat, "sw.ui", "No frame found!");
+ if(pNextFormat)
+ {
+ rSh.Chain(*const_cast<SwFrameFormat*>(
+ pCurrFlyFormat), *pNextFormat);
+ }
+ }
+ rSh.SetChainMarker();
+ }
+ }
+ }
+ else
+ bUpdateMgr = false;
+ }
+ }
+ break;
+ case FN_FRAME_MIRROR_ON_EVEN_PAGES:
+ {
+ SwFormatHoriOrient aHori(aMgr.GetHoriOrient());
+ bool bMirror = !aHori.IsPosToggle();
+ aHori.SetPosToggle(bMirror);
+ SfxItemSetFixed<RES_HORI_ORIENT, RES_HORI_ORIENT> aSet(GetPool());
+ aSet.Put(aHori);
+ aMgr.SetAttrSet(aSet);
+ bCopyToFormat = true;
+ rReq.SetReturnValue(SfxBoolItem(nSlot, bMirror));
+ }
+ break;
+ case FN_NAME_SHAPE:
+ {
+ bUpdateMgr = false;
+ SdrView* pSdrView = rSh.GetDrawViewWithValidMarkList();
+ if ( pSdrView &&
+ pSdrView->GetMarkedObjectCount() == 1 )
+ {
+ OUString aName(rSh.GetFlyName());
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxObjectNameDialog> pDlg(
+ pFact->CreateSvxObjectNameDialog(GetView().GetFrameWeld(), aName));
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName(aName);
+ rSh.SetFlyName(aName);
+ }
+ }
+ }
+ break;
+ // #i73249#
+ case FN_TITLE_DESCRIPTION_SHAPE:
+ {
+ bUpdateMgr = false;
+ SdrView* pSdrView = rSh.GetDrawViewWithValidMarkList();
+ if ( pSdrView &&
+ pSdrView->GetMarkedObjectCount() == 1 )
+ {
+ OUString aDescription(rSh.GetObjDescription());
+ OUString aTitle(rSh.GetObjTitle());
+ bool isDecorative(rSh.IsObjDecorative());
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxObjectTitleDescDialog> pDlg(
+ pFact->CreateSvxObjectTitleDescDialog(GetView().GetFrameWeld(),
+ aTitle, aDescription, isDecorative));
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetDescription(aDescription);
+ pDlg->GetTitle(aTitle);
+ pDlg->IsDecorative(isDecorative);
+
+ rSh.SetObjDescription(aDescription);
+ rSh.SetObjTitle(aTitle);
+ rSh.SetObjDecorative(isDecorative);
+ }
+ }
+ }
+ break;
+ default:
+ assert(!"wrong dispatcher");
+ return;
+ }
+ if ( bUpdateMgr )
+ {
+ SwFrameFormat* pFormat = rSh.GetSelectedFrameFormat();
+ if ( bCopyToFormat && pFormat && pFormat->IsAutoUpdateOnDirectFormat() )
+ {
+ rSh.AutoUpdateFrame(pFormat, aMgr.GetAttrSet());
+ }
+ else
+ {
+ aMgr.UpdateFlyFrame();
+ }
+ }
+
+}
+
+void SwFrameShell::GetState(SfxItemSet& rSet)
+{
+ SwWrtShell &rSh = GetShell();
+ bool bHtmlMode = 0 != ::GetHtmlMode(rSh.GetView().GetDocShell());
+ if (!rSh.IsFrameSelected())
+ return;
+
+ SfxItemSetFixed<
+ RES_LR_SPACE, RES_UL_SPACE,
+ RES_PRINT, RES_HORI_ORIENT> aSet(rSh.GetAttrPool() );
+ rSh.GetFlyFrameAttr( aSet );
+
+ bool bProtect = rSh.IsSelObjProtected(FlyProtectFlags::Pos) != FlyProtectFlags::NONE;
+ bool bParentCntProt = rSh.IsSelObjProtected( FlyProtectFlags::Content|FlyProtectFlags::Parent ) != FlyProtectFlags::NONE;
+
+ bProtect |= bParentCntProt;
+
+ const FrameTypeFlags eFrameType = rSh.GetFrameType(nullptr,true);
+ SwFlyFrameAttrMgr aMgr( false, &rSh, Frmmgr_Type::NONE, nullptr );
+
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ switch ( nWhich )
+ {
+ case RES_FRM_SIZE:
+ {
+ const SwFormatFrameSize& aSz(aMgr.GetFrameSize());
+ rSet.Put(aSz);
+ }
+ break;
+ case RES_VERT_ORIENT:
+ case RES_HORI_ORIENT:
+ case SID_ATTR_ULSPACE:
+ case SID_ATTR_LRSPACE:
+ case RES_LR_SPACE:
+ case RES_UL_SPACE:
+ case RES_PROTECT:
+ case RES_OPAQUE:
+ case RES_PRINT:
+ case RES_SURROUND:
+ {
+ rSet.Put(aSet.Get(GetPool().GetWhich(nWhich)));
+ }
+ break;
+ case SID_OBJECT_ALIGN:
+ {
+ if ( bProtect )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+ case SID_OBJECT_ALIGN_LEFT :
+ case SID_OBJECT_ALIGN_CENTER :
+ case SID_OBJECT_ALIGN_RIGHT :
+ case FN_FRAME_ALIGN_HORZ_CENTER:
+ case FN_FRAME_ALIGN_HORZ_RIGHT:
+ case FN_FRAME_ALIGN_HORZ_LEFT:
+ if ( (eFrameType & FrameTypeFlags::FLY_INCNT) ||
+ bProtect ||
+ ((nWhich == FN_FRAME_ALIGN_HORZ_CENTER || nWhich == SID_OBJECT_ALIGN_CENTER) &&
+ bHtmlMode ))
+ {
+ rSet.DisableItem( nWhich );
+ }
+ else
+ {
+ sal_Int16 nHoriOrient = -1;
+ switch(nWhich)
+ {
+ case SID_OBJECT_ALIGN_LEFT:
+ nHoriOrient = text::HoriOrientation::LEFT;
+ break;
+ case SID_OBJECT_ALIGN_CENTER:
+ nHoriOrient = text::HoriOrientation::CENTER;
+ break;
+ case SID_OBJECT_ALIGN_RIGHT:
+ nHoriOrient = text::HoriOrientation::RIGHT;
+ break;
+ default:
+ break;
+ }
+ SwFormatHoriOrient aHOrient(aMgr.GetHoriOrient());
+ if (nHoriOrient != -1)
+ rSet.Put(SfxBoolItem(nWhich, nHoriOrient == aHOrient.GetHoriOrient()));
+ }
+ break;
+ case FN_FRAME_ALIGN_VERT_ROW_TOP:
+ case FN_FRAME_ALIGN_VERT_ROW_CENTER:
+ case FN_FRAME_ALIGN_VERT_ROW_BOTTOM:
+ case FN_FRAME_ALIGN_VERT_CHAR_TOP:
+ case FN_FRAME_ALIGN_VERT_CHAR_CENTER:
+ case FN_FRAME_ALIGN_VERT_CHAR_BOTTOM:
+ if ( !(eFrameType & FrameTypeFlags::FLY_INCNT) || bProtect
+ || (bHtmlMode && FN_FRAME_ALIGN_VERT_CHAR_BOTTOM == nWhich) )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_OBJECT_ALIGN_UP :
+ case SID_OBJECT_ALIGN_MIDDLE :
+ case SID_OBJECT_ALIGN_DOWN :
+
+ case FN_FRAME_ALIGN_VERT_TOP:
+ case FN_FRAME_ALIGN_VERT_CENTER:
+ case FN_FRAME_ALIGN_VERT_BOTTOM:
+ if ( bProtect || (bHtmlMode && eFrameType & FrameTypeFlags::FLY_ATCNT))
+ rSet.DisableItem( nWhich );
+ else
+ {
+ // These slots need different labels depending on whether they are anchored in a character
+ // or on a paragraph/page etc.
+ OUString sNewLabel;
+ if (eFrameType & FrameTypeFlags::FLY_INCNT)
+ {
+ switch (nWhich)
+ {
+ case SID_OBJECT_ALIGN_UP :
+ case FN_FRAME_ALIGN_VERT_TOP:
+ sNewLabel = SwResId(STR_FRMUI_TOP_BASE);
+ break;
+ case SID_OBJECT_ALIGN_MIDDLE :
+ case FN_FRAME_ALIGN_VERT_CENTER:
+ sNewLabel = SwResId(STR_FRMUI_CENTER_BASE);
+ break;
+ case SID_OBJECT_ALIGN_DOWN :
+ case FN_FRAME_ALIGN_VERT_BOTTOM:
+ if(!bHtmlMode)
+ sNewLabel = SwResId(STR_FRMUI_BOTTOM_BASE);
+ else
+ rSet.DisableItem( nWhich );
+ break;
+ }
+ }
+ else
+ {
+ if (nWhich != FN_FRAME_ALIGN_VERT_TOP &&
+ nWhich != SID_OBJECT_ALIGN_UP )
+ {
+ if (aMgr.GetAnchor() == RndStdIds::FLY_AT_FLY)
+ {
+ const SwFrameFormat* pFormat = rSh.IsFlyInFly();
+ if (pFormat)
+ {
+ const SwFormatFrameSize& rFrameSz = pFormat->GetFrameSize();
+ if (rFrameSz.GetHeightSizeType() != SwFrameSize::Fixed)
+ {
+ rSet.DisableItem( nWhich );
+ break;
+ }
+ }
+ }
+ }
+ OUString aModuleName(vcl::CommandInfoProvider::GetModuleIdentifier(GetFrame()->GetFrame().GetFrameInterface()));
+ switch (nWhich)
+ {
+ case SID_OBJECT_ALIGN_UP :
+ case FN_FRAME_ALIGN_VERT_TOP:
+ {
+ auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(".uno:AlignTop", aModuleName);
+ sNewLabel = vcl::CommandInfoProvider::GetLabelForCommand(aProperties);
+ break;
+ }
+ case SID_OBJECT_ALIGN_MIDDLE:
+ case FN_FRAME_ALIGN_VERT_CENTER:
+ {
+ auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(".uno:AlignVerticalCenter", aModuleName);
+ sNewLabel = vcl::CommandInfoProvider::GetLabelForCommand(aProperties);
+ break;
+ }
+ case SID_OBJECT_ALIGN_DOWN:
+ case FN_FRAME_ALIGN_VERT_BOTTOM:
+ {
+ auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(".uno:AlignBottom", aModuleName);
+ sNewLabel = vcl::CommandInfoProvider::GetLabelForCommand(aProperties);
+ break;
+ }
+ }
+ }
+ if ( !sNewLabel.isEmpty() )
+ rSet.Put( SfxStringItem( nWhich, sNewLabel ));
+ }
+ break;
+ case SID_HYPERLINK_GETLINK:
+ {
+ SvxHyperlinkItem aHLinkItem;
+
+ SfxItemSetFixed<RES_URL, RES_URL> aURLSet(GetPool());
+ rSh.GetFlyFrameAttr( aURLSet );
+
+ if(const SwFormatURL* pFormatURL = aURLSet.GetItemIfSet(RES_URL))
+ {
+ aHLinkItem.SetURL(pFormatURL->GetURL());
+ aHLinkItem.SetTargetFrame(pFormatURL->GetTargetFrameName());
+ aHLinkItem.SetName(rSh.GetFlyName());
+ }
+
+ aHLinkItem.SetInsertMode(static_cast<SvxLinkInsertMode>(aHLinkItem.GetInsertMode() |
+ (bHtmlMode ? HLINK_HTMLMODE : 0)));
+
+ rSet.Put(aHLinkItem);
+ }
+ break;
+
+ case FN_FRAME_CHAIN:
+ {
+ const SelectionType nSel = rSh.GetSelectionType();
+ if (nSel & SelectionType::Graphic || nSel & SelectionType::Ole)
+ rSet.DisableItem( FN_FRAME_CHAIN );
+ else
+ {
+ const SwFrameFormat *pFormat = rSh.GetFlyFrameFormat();
+ if ( bParentCntProt || rSh.GetView().GetEditWin().GetApplyTemplate() ||
+ !pFormat || pFormat->GetChain().GetNext() )
+ {
+ rSet.DisableItem( FN_FRAME_CHAIN );
+ }
+ else
+ {
+ bool bChainMode = rSh.GetView().GetEditWin().IsChainMode();
+ rSet.Put( SfxBoolItem( FN_FRAME_CHAIN, bChainMode ) );
+ }
+ }
+ }
+ break;
+ case FN_FRAME_UNCHAIN:
+ {
+ const SelectionType nSel = rSh.GetSelectionType();
+ if (nSel & SelectionType::Graphic || nSel & SelectionType::Ole)
+ rSet.DisableItem( FN_FRAME_UNCHAIN );
+ else
+ {
+ const SwFrameFormat *pFormat = rSh.GetFlyFrameFormat();
+ if ( bParentCntProt || rSh.GetView().GetEditWin().GetApplyTemplate() ||
+ !pFormat || !pFormat->GetChain().GetNext() )
+ {
+ rSet.DisableItem( FN_FRAME_UNCHAIN );
+ }
+ }
+ }
+ break;
+ case SID_FRAME_TO_TOP:
+ case SID_FRAME_TO_BOTTOM:
+ case FN_FRAME_UP:
+ case FN_FRAME_DOWN:
+ if ( bParentCntProt )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_ATTR_TRANSFORM:
+ {
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_ATTR_TRANSFORM_PROTECT_SIZE:
+ {
+ const FlyProtectFlags eProtection = rSh.IsSelObjProtected( FlyProtectFlags::Size );
+ if ( ( eProtection & FlyProtectFlags::Content ) ||
+ ( eProtection & FlyProtectFlags::Size ) )
+ {
+ rSet.Put( SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_SIZE, true ) );
+ }
+ else
+ {
+ rSet.Put( SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_SIZE, false ) );
+ }
+ }
+ break;
+
+ case SID_ATTR_TRANSFORM_WIDTH:
+ {
+ rSet.Put( SfxUInt32Item( SID_ATTR_TRANSFORM_WIDTH, aMgr.GetSize().getWidth() ) );
+ }
+ break;
+
+ case SID_ATTR_TRANSFORM_HEIGHT:
+ {
+ rSet.Put( SfxUInt32Item( SID_ATTR_TRANSFORM_HEIGHT, aMgr.GetSize().getHeight() ) );
+ }
+ break;
+
+ case FN_FORMAT_FRAME_DLG:
+ {
+ const SelectionType nSel = rSh.GetSelectionType();
+ if ( bParentCntProt || nSel & SelectionType::Graphic)
+ rSet.DisableItem( nWhich );
+ }
+ break;
+ // #i73249#
+ case FN_TITLE_DESCRIPTION_SHAPE:
+ case FN_NAME_SHAPE:
+ {
+ SwWrtShell &rWrtSh = GetShell();
+ SdrView* pSdrView = rWrtSh.GetDrawViewWithValidMarkList();
+ if ( !pSdrView ||
+ pSdrView->GetMarkedObjectCount() != 1 )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case FN_POSTIT:
+ {
+ SwFlyFrame* pFly = rSh.GetSelectedFlyFrame();
+ if (pFly)
+ {
+ SwFrameFormat* pFormat = pFly->GetFormat();
+ if (pFormat)
+ {
+ RndStdIds eAnchorId = pFormat->GetAnchor().GetAnchorId();
+ // SwWrtShell::InsertPostIt() only works on as-char and at-char anchored
+ // images.
+ if (eAnchorId != RndStdIds::FLY_AS_CHAR && eAnchorId != RndStdIds::FLY_AT_CHAR)
+ {
+ rSet.DisableItem(nWhich);
+ }
+ }
+ }
+ }
+ break;
+
+ default:
+ /* do nothing */;
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+SwFrameShell::SwFrameShell(SwView &_rView) :
+ SwBaseShell( _rView )
+{
+ SetName("Frame");
+
+ // #96392# Use this to announce it is the frame shell who creates the selection.
+ SwTransferable::CreateSelection( _rView.GetWrtShell(), this );
+
+ SfxShell::SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::Frame));
+}
+
+SwFrameShell::~SwFrameShell()
+{
+ // #96392# Only clear the selection if it was this frame shell who created it.
+ SwTransferable::ClearSelection( GetShell(), this );
+}
+
+void SwFrameShell::ExecFrameStyle(SfxRequest const & rReq)
+{
+ SwWrtShell &rSh = GetShell();
+ bool bDefault = false;
+ if (!rSh.IsFrameSelected())
+ return;
+ // At first pick the default BoxItem out of the pool.
+ // If unequal to regular box item, then it has already
+ // been changed (New one is no default).
+ const SvxBoxItem* pPoolBoxItem = ::GetDfltAttr(RES_BOX);
+
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ SfxItemSetFixed<RES_BOX, RES_BOX> aFrameSet(rSh.GetAttrPool());
+
+ rSh.GetFlyFrameAttr( aFrameSet );
+ const SvxBoxItem& rBoxItem = aFrameSet.Get(RES_BOX);
+
+ if (SfxPoolItem::areSame(pPoolBoxItem, &rBoxItem))
+ bDefault = true;
+
+ std::unique_ptr<SvxBoxItem> aBoxItem(rBoxItem.Clone());
+
+ SvxBorderLine aBorderLine;
+
+ if(pArgs) // Any controller can sometimes deliver nothing #48169#
+ {
+ switch (rReq.GetSlot())
+ {
+ case SID_ATTR_BORDER:
+ {
+ if (const SvxBoxItem* pBoxItem = pArgs->GetItemIfSet(RES_BOX))
+ {
+ std::unique_ptr<SvxBoxItem> aNewBox(pBoxItem->Clone());
+ const SvxBorderLine* pBorderLine;
+
+ pBorderLine = aBoxItem->GetTop();
+ if (pBorderLine != nullptr)
+ lcl_FrameGetMaxLineWidth(pBorderLine, aBorderLine);
+ pBorderLine = aBoxItem->GetBottom();
+ if (pBorderLine != nullptr)
+ lcl_FrameGetMaxLineWidth(pBorderLine, aBorderLine);
+ pBorderLine = aBoxItem->GetLeft();
+ if (pBorderLine != nullptr)
+ lcl_FrameGetMaxLineWidth(pBorderLine, aBorderLine);
+ pBorderLine = aBoxItem->GetRight();
+ if (pBorderLine != nullptr)
+ lcl_FrameGetMaxLineWidth(pBorderLine, aBorderLine);
+
+ if(aBorderLine.GetOutWidth() == 0)
+ {
+ aBorderLine.SetBorderLineStyle(
+ SvxBorderLineStyle::SOLID);
+ aBorderLine.SetWidth( SvxBorderLineWidth::Hairline );
+ }
+ //Set distance only if the request is received from the controller.
+
+#if HAVE_FEATURE_SCRIPTING
+ if(!StarBASIC::IsRunning())
+#endif
+ {
+ // TODO: should this copy 4 individual Dist instead?
+ aNewBox->SetAllDistances(rBoxItem.GetSmallestDistance());
+ }
+
+ aBoxItem = std::move(aNewBox);
+
+ if( aBoxItem->GetTop() != nullptr )
+ aBoxItem->SetLine(&aBorderLine, SvxBoxItemLine::TOP);
+ if( aBoxItem->GetBottom() != nullptr )
+ aBoxItem->SetLine(&aBorderLine, SvxBoxItemLine::BOTTOM);
+ if( aBoxItem->GetLeft() != nullptr )
+ aBoxItem->SetLine(&aBorderLine, SvxBoxItemLine::LEFT);
+ if( aBoxItem->GetRight() != nullptr )
+ aBoxItem->SetLine(&aBorderLine, SvxBoxItemLine::RIGHT);
+ }
+ }
+ break;
+
+ case SID_FRAME_LINESTYLE:
+ {
+ if ( const SvxLineItem* pLineItem = pArgs->GetItemIfSet(SID_FRAME_LINESTYLE, false))
+ {
+ if ( pLineItem->GetLine() )
+ {
+ aBorderLine = *(pLineItem->GetLine());
+
+ if (!aBoxItem->GetTop() && !aBoxItem->GetBottom() &&
+ !aBoxItem->GetLeft() && !aBoxItem->GetRight())
+ {
+ aBoxItem->SetLine(&aBorderLine, SvxBoxItemLine::TOP);
+ aBoxItem->SetLine(&aBorderLine, SvxBoxItemLine::BOTTOM);
+ aBoxItem->SetLine(&aBorderLine, SvxBoxItemLine::LEFT);
+ aBoxItem->SetLine(&aBorderLine, SvxBoxItemLine::RIGHT);
+ }
+ else
+ {
+ if( aBoxItem->GetTop() )
+ {
+ aBorderLine.SetColor( aBoxItem->GetTop()->GetColor() );
+ aBoxItem->SetLine(&aBorderLine, SvxBoxItemLine::TOP);
+ }
+ if( aBoxItem->GetBottom() )
+ {
+ aBorderLine.SetColor( aBoxItem->GetBottom()->GetColor());
+ aBoxItem->SetLine(&aBorderLine, SvxBoxItemLine::BOTTOM);
+ }
+ if( aBoxItem->GetLeft() )
+ {
+ aBorderLine.SetColor( aBoxItem->GetLeft()->GetColor());
+ aBoxItem->SetLine(&aBorderLine, SvxBoxItemLine::LEFT);
+ }
+ if( aBoxItem->GetRight() )
+ {
+ aBorderLine.SetColor(aBoxItem->GetRight()->GetColor());
+ aBoxItem->SetLine(&aBorderLine, SvxBoxItemLine::RIGHT);
+ }
+ }
+ }
+ else
+ {
+ aBoxItem->SetLine(nullptr, SvxBoxItemLine::TOP);
+ aBoxItem->SetLine(nullptr, SvxBoxItemLine::BOTTOM);
+ aBoxItem->SetLine(nullptr, SvxBoxItemLine::LEFT);
+ aBoxItem->SetLine(nullptr, SvxBoxItemLine::RIGHT);
+ }
+ }
+ }
+ break;
+
+ case SID_FRAME_LINECOLOR:
+ {
+ if (const SvxColorItem* pColorItem = pArgs->GetItemIfSet(SID_FRAME_LINECOLOR, false))
+ {
+ const Color& rNewColor = pColorItem->GetValue();
+
+ if (!aBoxItem->GetTop() && !aBoxItem->GetBottom() &&
+ !aBoxItem->GetLeft() && !aBoxItem->GetRight())
+ {
+ aBorderLine.SetColor( rNewColor );
+ aBorderLine.SetBorderLineStyle(SvxBorderLineStyle::SOLID);
+ aBorderLine.SetWidth(SvxBorderLineWidth::Hairline);
+
+ aBoxItem->SetLine(&aBorderLine, SvxBoxItemLine::TOP);
+ aBoxItem->SetLine(&aBorderLine, SvxBoxItemLine::BOTTOM);
+ aBoxItem->SetLine(&aBorderLine, SvxBoxItemLine::LEFT);
+ aBoxItem->SetLine(&aBorderLine, SvxBoxItemLine::RIGHT);
+ }
+ else
+ {
+ if (aBoxItem->GetTop())
+ aBoxItem->GetTop()->SetColor(rNewColor);
+ if (aBoxItem->GetBottom())
+ aBoxItem->GetBottom()->SetColor(rNewColor);
+ if (aBoxItem->GetLeft())
+ aBoxItem->GetLeft()->SetColor(rNewColor);
+ if (aBoxItem->GetRight())
+ aBoxItem->GetRight()->SetColor(rNewColor);
+ }
+ }
+ }
+ break;
+ }
+ }
+ if (bDefault && (aBoxItem->GetTop() || aBoxItem->GetBottom() ||
+ aBoxItem->GetLeft() || aBoxItem->GetRight()))
+ {
+ aBoxItem->SetAllDistances(MIN_BORDER_DIST);
+ }
+ aFrameSet.Put( std::move(aBoxItem) );
+ // Template AutoUpdate
+ SwFrameFormat* pFormat = rSh.GetSelectedFrameFormat();
+ if(pFormat && pFormat->IsAutoUpdateOnDirectFormat())
+ {
+ rSh.AutoUpdateFrame(pFormat, aFrameSet);
+ }
+ else
+ rSh.SetFlyFrameAttr( aFrameSet );
+
+}
+
+static void lcl_FrameGetMaxLineWidth(const SvxBorderLine* pBorderLine, SvxBorderLine& rBorderLine)
+{
+ if(pBorderLine->GetWidth() > rBorderLine.GetWidth())
+ rBorderLine.SetWidth(pBorderLine->GetWidth());
+
+ rBorderLine.SetBorderLineStyle(pBorderLine->GetBorderLineStyle());
+ rBorderLine.SetColor(pBorderLine->GetColor());
+}
+
+void SwFrameShell::GetLineStyleState(SfxItemSet &rSet)
+{
+ SwWrtShell &rSh = GetShell();
+ bool bParentCntProt = rSh.IsSelObjProtected( FlyProtectFlags::Content|FlyProtectFlags::Parent ) != FlyProtectFlags::NONE;
+
+ if (bParentCntProt)
+ {
+ if (rSh.IsFrameSelected())
+ rSet.DisableItem( SID_FRAME_LINECOLOR );
+
+ rSet.DisableItem( SID_ATTR_BORDER );
+ rSet.DisableItem( SID_FRAME_LINESTYLE );
+ }
+ else
+ {
+ if (rSh.IsFrameSelected())
+ {
+ SfxItemSetFixed<RES_BOX, RES_BOX> aFrameSet( rSh.GetAttrPool() );
+
+ rSh.GetFlyFrameAttr(aFrameSet);
+
+ const SvxBorderLine* pLine = aFrameSet.Get(RES_BOX).GetTop();
+ rSet.Put(SvxColorItem(pLine ? pLine->GetColor() : Color(), SID_FRAME_LINECOLOR));
+ }
+ }
+}
+
+void SwFrameShell::StateInsert(SfxItemSet &rSet)
+{
+ const SelectionType nSel = GetShell().GetSelectionType();
+ if ( (nSel & SelectionType::Graphic)
+ || (nSel & SelectionType::Ole) )
+ {
+ rSet.DisableItem(FN_INSERT_FRAME);
+ }
+ else if ( GetShell().CursorInsideInputField() )
+ {
+ rSet.DisableItem(FN_INSERT_FRAME);
+ }
+}
+
+void SwFrameShell::GetDrawAttrStateTextFrame(SfxItemSet &rSet)
+{
+ SwWrtShell &rSh = GetShell();
+
+ if(rSh.IsFrameSelected())
+ {
+ rSh.GetFlyFrameAttr(rSet);
+ }
+ else
+ {
+ SdrView* pSdrView = rSh.GetDrawViewWithValidMarkList();
+
+ if(pSdrView)
+ {
+ rSet.Put(pSdrView->GetDefaultAttr());
+ }
+ }
+}
+
+void SwFrameShell::ExecDrawAttrArgsTextFrame(SfxRequest const & rReq)
+{
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ SwWrtShell& rSh = GetShell();
+
+ if(pArgs)
+ {
+ if(rSh.IsFrameSelected())
+ {
+ rSh.SetFlyFrameAttr(const_cast< SfxItemSet& >(*pArgs));
+ }
+ else
+ {
+ SdrView* pSdrView = rSh.GetDrawViewWithValidMarkList();
+
+ if(pSdrView)
+ {
+ pSdrView->SetDefaultAttr(*pArgs, false);
+ }
+ }
+ }
+ else
+ {
+ SfxDispatcher* pDis = rSh.GetView().GetViewFrame().GetDispatcher();
+
+ switch(rReq.GetSlot())
+ {
+ case SID_ATTR_FILL_STYLE:
+ case SID_ATTR_FILL_COLOR:
+ case SID_ATTR_FILL_GRADIENT:
+ case SID_ATTR_FILL_HATCH:
+ case SID_ATTR_FILL_BITMAP:
+ case SID_ATTR_FILL_TRANSPARENCE:
+ case SID_ATTR_FILL_FLOATTRANSPARENCE:
+ {
+ pDis->Execute(SID_ATTRIBUTES_AREA);
+ break;
+ }
+ }
+ }
+}
+
+void SwFrameShell::ExecDrawDlgTextFrame(SfxRequest const & rReq)
+{
+ switch(rReq.GetSlot())
+ {
+ case SID_ATTRIBUTES_AREA:
+ {
+ SwWrtShell& rSh = GetShell();
+
+ if(rSh.IsFrameSelected())
+ {
+ SdrModel& rModel = rSh.GetDrawView()->GetModel();
+ SfxItemSet aNewAttr(rModel.GetItemPool());
+
+ // get attributes from FlyFrame
+ rSh.GetFlyFrameAttr(aNewAttr);
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ VclPtr<AbstractSvxAreaTabDialog> pDlg(pFact->CreateSvxAreaTabDialog(
+ GetView().GetFrameWeld(),
+ &aNewAttr,
+ &rModel,
+ false,
+ false));
+
+ pDlg->StartExecuteAsync([pDlg, this](sal_Int32 nResult){
+ if(nResult == RET_OK)
+ {
+ // set attributes at FlyFrame
+ GetShell().SetFlyFrameAttr(const_cast< SfxItemSet& >(*pDlg->GetOutputItemSet()));
+
+ static sal_uInt16 aInval[] =
+ {
+ SID_ATTR_FILL_STYLE,
+ SID_ATTR_FILL_COLOR,
+ SID_ATTR_FILL_TRANSPARENCE,
+ SID_ATTR_FILL_FLOATTRANSPARENCE,
+ 0
+ };
+
+ SfxBindings &rBnd = GetView().GetViewFrame().GetBindings();
+
+ rBnd.Invalidate(aInval);
+ rBnd.Update(SID_ATTR_FILL_STYLE);
+ rBnd.Update(SID_ATTR_FILL_COLOR);
+ rBnd.Update(SID_ATTR_FILL_TRANSPARENCE);
+ rBnd.Update(SID_ATTR_FILL_FLOATTRANSPARENCE);
+ }
+ pDlg->disposeOnce();
+ });
+ }
+
+ break;
+ }
+ }
+}
+
+void SwFrameShell::DisableStateTextFrame(SfxItemSet &rSet)
+{
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich(aIter.FirstWhich());
+
+ while(nWhich)
+ {
+ switch(nWhich)
+ {
+ case SID_ATTRIBUTES_AREA:
+ {
+ SwWrtShell& rSh = GetShell();
+
+ if(!rSh.IsFrameSelected())
+ {
+ rSet.DisableItem(nWhich);
+ }
+
+ break;
+ }
+ default:
+ {
+ rSet.DisableItem(nWhich);
+ break;
+ }
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/grfsh.cxx b/sw/source/uibase/shells/grfsh.cxx
new file mode 100644
index 0000000000..bb090fed46
--- /dev/null
+++ b/sw/source/uibase/shells/grfsh.cxx
@@ -0,0 +1,1018 @@
+/* -*- 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 <cmdid.h>
+#include <hintids.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/UnitConversion.hxx>
+#include <svl/stritem.hxx>
+#include <svl/whiter.hxx>
+#include <svl/urihelper.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <editeng/sizeitem.hxx>
+#include <sfx2/request.hxx>
+#include <vcl/EnumContext.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <svx/svdview.hxx>
+#include <editeng/brushitem.hxx>
+#include <svx/grfflt.hxx>
+#include <svx/compressgraphicdialog.hxx>
+#include <svx/tbxcolor.hxx>
+#include <svx/sdangitm.hxx>
+#include <osl/diagnose.h>
+#include <drawdoc.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <viewopt.hxx>
+#include <swmodule.hxx>
+#include <swundo.hxx>
+#include <uitool.hxx>
+#include <docsh.hxx>
+#include <grfsh.hxx>
+#include <frmmgr.hxx>
+#include <frmfmt.hxx>
+#include <grfatr.hxx>
+#include <swwait.hxx>
+#include <svx/extedit.hxx>
+#include <svx/graphichelper.hxx>
+#include <doc.hxx>
+#include <IDocumentDrawModelAccess.hxx>
+#include <svx/drawitem.hxx>
+#define ShellClass_SwGrfShell
+
+#include <sfx2/msg.hxx>
+#include <swslots.hxx>
+#include <swabstdlg.hxx>
+#include <unocrsr.hxx>
+#include <flyfrm.hxx>
+#include <memory>
+
+constexpr OUString TOOLBOX_NAME = u"colorbar"_ustr;
+
+class SwGrfShell::SwExternalToolEdit
+ : public ExternalToolEdit
+{
+private:
+ SwWrtShell *const m_pShell;
+ std::shared_ptr<SwUnoCursor> const m_pCursor;
+
+public:
+ explicit SwExternalToolEdit(SwWrtShell *const pShell)
+ : m_pShell(pShell)
+ , m_pCursor( // need only Point, must point to SwGrfNode
+ pShell->GetDoc()->CreateUnoCursor(
+ *pShell->GetCurrentShellCursor().GetPoint()))
+ {
+ }
+
+ virtual void Update(Graphic & rGraphic) override
+ {
+ DBG_TESTSOLARMUTEX();
+ m_pShell->Push();
+ m_pShell->GetCurrentShellCursor().DeleteMark();
+ *m_pShell->GetCurrentShellCursor().GetPoint() = *m_pCursor->GetPoint();
+ m_pShell->ReRead(OUString(), OUString(), &rGraphic);
+ m_pShell->Pop();
+ }
+};
+
+SFX_IMPL_INTERFACE(SwGrfShell, SwBaseShell)
+
+void SwGrfShell::InitInterface_Impl()
+{
+ GetStaticInterface()->RegisterPopupMenu("graphic");
+
+ GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Invisible, ToolbarId::Grafik_Toolbox);
+}
+
+void SwGrfShell::Execute(SfxRequest &rReq)
+{
+ SwWrtShell &rSh = GetShell();
+
+ sal_uInt16 nSlot = rReq.GetSlot();
+ switch(nSlot)
+ {
+ case SID_OBJECT_ROTATE:
+ {
+ // RotGrfFlyFrame: start rotation when possible
+ SdrView* pSdrView = rSh.GetDrawViewWithValidMarkList();
+
+ if(rSh.IsRotationOfSwGrfNodePossible() && pSdrView->IsRotateAllowed())
+ {
+ if(GetView().IsDrawRotate())
+ {
+ rSh.SetDragMode(SdrDragMode::Move);
+ }
+ else
+ {
+ rSh.SetDragMode(SdrDragMode::Rotate);
+ }
+
+ GetView().FlipDrawRotate();
+ }
+ }
+ break;
+
+ case SID_TWAIN_TRANSFER:
+ {
+ GetView().ExecuteScan( rReq );
+ break;
+ }
+
+ case SID_SAVE_GRAPHIC:
+ {
+ GraphicAttr aGraphicAttr;
+ rSh.GetGraphicAttr(aGraphicAttr);
+
+ short nState = RET_CANCEL;
+ if (aGraphicAttr != GraphicAttr()) // the image has been modified
+ {
+ weld::Window* pWin = GetView().GetFrameWeld();
+ if (pWin)
+ {
+ nState = GraphicHelper::HasToSaveTransformedImage(pWin);
+ }
+ }
+ else
+ {
+ nState = RET_NO;
+ }
+
+ if (nState == RET_YES)
+ {
+ const GraphicObject* pGraphicObj = rSh.GetGraphicObj();
+ if (pGraphicObj)
+ {
+ Graphic aGraphic = pGraphicObj->GetTransformedGraphic(pGraphicObj->GetPrefSize(), pGraphicObj->GetPrefMapMode(), aGraphicAttr);
+ OUString sGrfNm;
+ OUString sFilterNm;
+ rSh.GetGrfNms( &sGrfNm, &sFilterNm );
+ GraphicHelper::ExportGraphic(GetView().GetFrameWeld(), aGraphic, sGrfNm);
+ }
+ }
+ else if (nState == RET_NO)
+ {
+ const Graphic *pGraphic = rSh.GetGraphic();
+ if(nullptr != pGraphic)
+ {
+ OUString sGrfNm;
+ OUString sFilterNm;
+ rSh.GetGrfNms( &sGrfNm, &sFilterNm );
+ GraphicHelper::ExportGraphic(GetView().GetFrameWeld(), *pGraphic, sGrfNm);
+ }
+ }
+ }
+ break;
+
+ case SID_COMPRESS_GRAPHIC:
+ {
+ const Graphic* pGraphic = rSh.GetGraphic();
+ if( pGraphic )
+ {
+ Size aSize (
+ convertTwipToMm100(rSh.GetAnyCurRect(CurRectType::FlyEmbedded).Width()),
+ convertTwipToMm100(rSh.GetAnyCurRect(CurRectType::FlyEmbedded).Height()));
+
+ SfxItemSetFixed<RES_GRFATR_MIRRORGRF, RES_GRFATR_CROPGRF> aSet( rSh.GetAttrPool() );
+ rSh.GetCurAttr( aSet );
+ SwMirrorGrf aMirror( aSet.Get(RES_GRFATR_MIRRORGRF) );
+ SwCropGrf aCrop( aSet.Get(RES_GRFATR_CROPGRF) );
+
+ tools::Rectangle aCropRectangle(
+ convertTwipToMm100(aCrop.GetLeft()),
+ convertTwipToMm100(aCrop.GetTop()),
+ convertTwipToMm100(aCrop.GetRight()),
+ convertTwipToMm100(aCrop.GetBottom()) );
+
+ Graphic aGraphic = *pGraphic;
+
+ CompressGraphicsDialog aDialog(GetView().GetFrameWeld(), std::move(aGraphic), aSize, aCropRectangle, GetView().GetViewFrame().GetBindings());
+ if (aDialog.run() == RET_OK)
+ {
+ rSh.StartAllAction();
+ rSh.StartUndo(SwUndoId::START);
+ tools::Rectangle aScaledCropedRectangle = aDialog.GetScaledCropRectangle();
+
+ aCrop.SetLeft( o3tl::toTwips( aScaledCropedRectangle.Left(), o3tl::Length::mm100 ));
+ aCrop.SetTop( o3tl::toTwips( aScaledCropedRectangle.Top(), o3tl::Length::mm100 ));
+ aCrop.SetRight( o3tl::toTwips( aScaledCropedRectangle.Right(), o3tl::Length::mm100 ));
+ aCrop.SetBottom( o3tl::toTwips( aScaledCropedRectangle.Bottom(), o3tl::Length::mm100 ));
+
+ Graphic aCompressedGraphic( aDialog.GetCompressedGraphic() );
+ rSh.ReRead(OUString(), OUString(), const_cast<const Graphic*>(&aCompressedGraphic));
+
+ rSh.SetAttrItem(aCrop);
+ rSh.SetAttrItem(aMirror);
+
+ rSh.EndUndo(SwUndoId::END);
+ rSh.EndAllAction();
+ }
+ }
+ }
+ break;
+ case SID_EXTERNAL_EDIT:
+ {
+ // When the graphic is selected to be opened via some external tool
+ // for advanced editing
+ GraphicObject const*const pGraphicObject(rSh.GetGraphicObj());
+ if(nullptr != pGraphicObject)
+ {
+ m_ExternalEdits.push_back(std::make_unique<SwExternalToolEdit>(
+ &rSh));
+ m_ExternalEdits.back()->Edit(pGraphicObject);
+ }
+ }
+ break;
+ case SID_CHANGE_PICTURE:
+ case SID_INSERT_GRAPHIC:
+ {
+ // #i123922# implement slot independent from the two below to
+ // bring up the insert graphic dialog and associated actions
+ SwView& rLclView = GetView();
+ rReq.SetReturnValue(SfxBoolItem(nSlot, rLclView.InsertGraphicDlg( rReq )));
+ break;
+ }
+ case FN_FORMAT_GRAFIC_DLG:
+ case FN_DRAW_WRAP_DLG:
+ {
+ SwFlyFrameAttrMgr aMgr( false, &rSh, rSh.IsFrameSelected() ?
+ Frmmgr_Type::NONE : Frmmgr_Type::GRF, nullptr);
+ const SwViewOption* pVOpt = rSh.GetViewOptions();
+ SwViewOption aUsrPref( *pVOpt );
+
+ SfxItemSetFixed<
+ RES_FRMATR_BEGIN, RES_GRFATR_CROPGRF,
+ // FillAttribute support:
+ XATTR_FILL_FIRST, XATTR_FILL_LAST,
+ SID_DOCFRAME, SID_DOCFRAME,
+ SID_REFERER, SID_REFERER,
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
+ SID_ATTR_PAGE_SIZE, SID_ATTR_PAGE_SIZE, // 10051
+ // RotGrfFlyFrame: Need RotationAngle now
+ SID_ATTR_TRANSFORM_ANGLE, SID_ATTR_TRANSFORM_ANGLE, // 10095
+ // Items to hand over XPropertyList things like
+ // XColorList, XHatchList, XGradientList, and XBitmapList to
+ // the Area TabPage:
+ SID_COLOR_TABLE, SID_PATTERN_LIST, //10179
+ SID_HTML_MODE, SID_HTML_MODE, //10414
+ SID_ATTR_GRAF_KEEP_ZOOM, SID_ATTR_GRAF_KEEP_ZOOM, //10882
+ SID_ATTR_GRAF_FRMSIZE, SID_ATTR_GRAF_GRAPHIC, // 10884
+ // contains SID_ATTR_GRAF_FRMSIZE_PERCENT
+ FN_GET_PRINT_AREA, FN_GET_PRINT_AREA,
+ FN_PARAM_GRF_CONNECT, FN_PARAM_GRF_CONNECT,
+ FN_SET_FRM_NAME, FN_KEEP_ASPECT_RATIO,
+ FN_SET_FRM_ALT_NAME, FN_SET_FRM_ALT_NAME,
+ FN_UNO_DESCRIPTION, FN_UNO_DESCRIPTION> aSet( GetPool() );
+
+ // create needed items for XPropertyList entries from the DrawModel so that
+ // the Area TabPage can access them
+ const SwDrawModel* pDrawModel = rSh.GetView().GetDocShell()->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
+
+ aSet.Put(SvxColorListItem(pDrawModel->GetColorList(), SID_COLOR_TABLE));
+ aSet.Put(SvxGradientListItem(pDrawModel->GetGradientList(), SID_GRADIENT_LIST));
+ aSet.Put(SvxHatchListItem(pDrawModel->GetHatchList(), SID_HATCH_LIST));
+ aSet.Put(SvxBitmapListItem(pDrawModel->GetBitmapList(), SID_BITMAP_LIST));
+ aSet.Put(SvxPatternListItem(pDrawModel->GetPatternList(), SID_PATTERN_LIST));
+
+ sal_uInt16 nHtmlMode = ::GetHtmlMode(GetView().GetDocShell());
+ aSet.Put(SfxUInt16Item(SID_HTML_MODE, nHtmlMode));
+ FieldUnit eMetric = ::GetDfltMetric(0 != (nHtmlMode&HTMLMODE_ON));
+ SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)) );
+
+ const SwRect* pRect = &rSh.GetAnyCurRect(CurRectType::Page);
+ SwFormatFrameSize aFrameSize( SwFrameSize::Variable, pRect->Width(), pRect->Height());
+ aFrameSize.SetWhich( GetPool().GetWhich( SID_ATTR_PAGE_SIZE ) );
+ aSet.Put( aFrameSize );
+
+ aSet.Put(SfxStringItem(FN_SET_FRM_NAME, rSh.GetFlyName()));
+ aSet.Put(SfxStringItem(FN_UNO_DESCRIPTION, rSh.GetObjDescription()));
+ if ( nSlot == FN_FORMAT_GRAFIC_DLG )
+ {
+ // #i73249#
+ aSet.Put( SfxStringItem( FN_SET_FRM_ALT_NAME, rSh.GetObjTitle() ) );
+ }
+
+ pRect = &rSh.GetAnyCurRect(CurRectType::PagePrt);
+ aFrameSize.SetWidth( pRect->Width() );
+ aFrameSize.SetHeight( pRect->Height() );
+ aFrameSize.SetWhich( GetPool().GetWhich(FN_GET_PRINT_AREA) );
+ aSet.Put( aFrameSize );
+
+ aSet.Put( aMgr.GetAttrSet() );
+ SwFlyFrame* pFly = rSh.GetSelectedFlyFrame();
+ if (pFly)
+ {
+ // Work with the up to date layout size if possible.
+ SwFormatFrameSize aSize = aSet.Get(RES_FRM_SIZE);
+ aSize.SetWidth(pFly->getFrameArea().Width());
+ aSize.SetHeight(pFly->getFrameArea().Height());
+ aSet.Put(aSize);
+ }
+ aSet.SetParent( aMgr.GetAttrSet().GetParent() );
+
+ // At percentage values initialize size
+ SwFormatFrameSize aSizeCopy = aSet.Get(RES_FRM_SIZE);
+ if (aSizeCopy.GetWidthPercent() && aSizeCopy.GetWidthPercent() != SwFormatFrameSize::SYNCED)
+ aSizeCopy.SetWidth(rSh.GetAnyCurRect(CurRectType::FlyEmbedded).Width());
+ if (aSizeCopy.GetHeightPercent() && aSizeCopy.GetHeightPercent() != SwFormatFrameSize::SYNCED)
+ aSizeCopy.SetHeight(rSh.GetAnyCurRect(CurRectType::FlyEmbedded).Height());
+ // and now set the size for "external" tabpages
+ {
+ SvxSizeItem aSzItm( SID_ATTR_GRAF_FRMSIZE, aSizeCopy.GetSize() );
+ aSet.Put( aSzItm );
+
+ Size aSz( aSizeCopy.GetWidthPercent(), aSizeCopy.GetHeightPercent() );
+ if( SwFormatFrameSize::SYNCED == aSz.Width() ) aSz.setWidth( 0 );
+ if( SwFormatFrameSize::SYNCED == aSz.Height() ) aSz.setHeight( 0 );
+
+ aSzItm.SetSize( aSz );
+ aSzItm.SetWhich( SID_ATTR_GRAF_FRMSIZE_PERCENT );
+ aSet.Put( aSzItm );
+ }
+
+ OUString sGrfNm;
+ OUString sFilterNm;
+ rSh.GetGrfNms( &sGrfNm, &sFilterNm );
+ if( !sGrfNm.isEmpty() )
+ {
+ aSet.Put( SvxBrushItem( INetURLObject::decode( sGrfNm,
+ INetURLObject::DecodeMechanism::Unambiguous ),
+ sFilterNm, GPOS_LT,
+ SID_ATTR_GRAF_GRAPHIC ));
+ }
+ else
+ {
+ // #119353# - robust
+ const GraphicObject* pGrfObj = rSh.GetGraphicObj();
+ if ( pGrfObj )
+ {
+ aSet.Put( SvxBrushItem( *pGrfObj, GPOS_LT,
+ SID_ATTR_GRAF_GRAPHIC ) );
+ }
+ }
+ aSet.Put( SfxBoolItem( FN_PARAM_GRF_CONNECT, !sGrfNm.isEmpty() ) );
+
+ // get Mirror and Crop
+ {
+ SfxItemSetFixed<RES_GRFATR_MIRRORGRF, RES_GRFATR_CROPGRF> aTmpSet( rSh.GetAttrPool() );
+
+ rSh.GetCurAttr( aTmpSet );
+ aSet.Put( aTmpSet );
+ }
+
+ aSet.Put(SfxBoolItem(FN_KEEP_ASPECT_RATIO, aUsrPref.IsKeepRatio()));
+ aSet.Put(SfxBoolItem( SID_ATTR_GRAF_KEEP_ZOOM, aUsrPref.IsGrfKeepZoom()));
+
+ aSet.Put(SfxFrameItem( SID_DOCFRAME, &GetView().GetViewFrame().GetFrame()));
+
+ SfxObjectShell * sh = rSh.GetDoc()->GetPersist();
+ if (sh != nullptr && sh->HasName())
+ {
+ aSet.Put(
+ SfxStringItem(SID_REFERER, sh->GetMedium()->GetName()));
+ }
+
+ Size aUnrotatedSize;
+ Degree10 nCurrentRotation;
+ { // RotGrfFlyFrame: Add current RotationAngle value, convert from
+ // RES_GRFATR_ROTATION to SID_ATTR_TRANSFORM_ANGLE. Do not forget to
+ // convert from 10th degrees to 100th degrees
+ SfxItemSetFixed<RES_GRFATR_ROTATION, RES_GRFATR_ROTATION> aTmpSet( rSh.GetAttrPool() );
+ rSh.GetCurAttr( aTmpSet );
+ const SwRotationGrf& rRotation = aTmpSet.Get(RES_GRFATR_ROTATION);
+ nCurrentRotation = rRotation.GetValue();
+ aUnrotatedSize = rRotation.GetUnrotatedSize();
+ aSet.Put(SdrAngleItem(SID_ATTR_TRANSFORM_ANGLE, to<Degree100>(nCurrentRotation)));
+ }
+
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateFrameTabDialog("PictureDialog",
+ GetView().GetViewFrame(),
+ GetView().GetFrameWeld(),
+ aSet, false));
+ if (nSlot == FN_DRAW_WRAP_DLG)
+ pDlg->SetCurPageId("wrap");
+
+ if (pDlg->Execute() == RET_OK)
+ {
+ rSh.StartAllAction();
+ rSh.StartUndo(SwUndoId::START);
+ SfxItemSet* pSet = const_cast<SfxItemSet*>(pDlg->GetOutputItemSet());
+ rReq.Done(*pSet);
+ // change the 2 frmsize SizeItems to the correct SwFrameSizeItem
+ if( const SvxSizeItem* pSizeItem = pSet->GetItemIfSet(
+ SID_ATTR_GRAF_FRMSIZE, false ))
+ {
+ SwFormatFrameSize aSize;
+ const Size& rSz = pSizeItem->GetSize();
+ aSize.SetWidth( rSz.Width() );
+ aSize.SetHeight( rSz.Height() );
+
+ pSizeItem = pSet->GetItemIfSet( SID_ATTR_GRAF_FRMSIZE_PERCENT, false );
+ if( pSizeItem )
+ {
+ const Size& rRelativeSize = pSizeItem->GetSize();
+ aSize.SetWidthPercent( static_cast< sal_uInt8 >( rRelativeSize.Width() ) );
+ aSize.SetHeightPercent( static_cast< sal_uInt8 >( rRelativeSize.Height() ) );
+ }
+ pSet->Put( aSize );
+ }
+
+ // Templates AutoUpdate
+ SwFrameFormat* pFormat = rSh.GetSelectedFrameFormat();
+ if(pFormat && pFormat->IsAutoUpdateOnDirectFormat())
+ {
+ pFormat->SetFormatAttr(*pSet);
+ SfxItemSetFixed<
+ RES_FRM_SIZE, RES_FRM_SIZE,
+ RES_SURROUND, RES_ANCHOR> aShellSet( GetPool() );
+ aShellSet.Put(*pSet);
+ aMgr.SetAttrSet(aShellSet);
+ }
+ else
+ {
+ aMgr.SetAttrSet(*pSet);
+ }
+ aMgr.UpdateFlyFrame();
+
+ bool bApplyUsrPref = false;
+ if (const SfxBoolItem* pRatioItem = pSet->GetItemIfSet(
+ FN_KEEP_ASPECT_RATIO ))
+ {
+ aUsrPref.SetKeepRatio( pRatioItem->GetValue() );
+ bApplyUsrPref = true;
+ }
+ if( const SfxBoolItem* pZoomItem = pSet->GetItemIfSet(
+ SID_ATTR_GRAF_KEEP_ZOOM ))
+ {
+ aUsrPref.SetGrfKeepZoom( pZoomItem->GetValue() );
+ bApplyUsrPref = true;
+ }
+
+ if( bApplyUsrPref )
+ SW_MOD()->ApplyUsrPref(aUsrPref, &GetView());
+
+ // and now set all the graphic attributes and other stuff
+ if( const SvxBrushItem* pGraphicBrushItem = pSet->GetItemIfSet(
+ SID_ATTR_GRAF_GRAPHIC ))
+ {
+ if( !pGraphicBrushItem->GetGraphicLink().isEmpty() )
+ sGrfNm = pGraphicBrushItem->GetGraphicLink();
+ else
+ sGrfNm.clear();
+
+ if( !pGraphicBrushItem->GetGraphicFilter().isEmpty() )
+ sFilterNm = pGraphicBrushItem->GetGraphicFilter();
+ else
+ sFilterNm.clear();
+
+ if( !sGrfNm.isEmpty() )
+ {
+ SwDocShell* pDocSh = GetView().GetDocShell();
+ SwWait aWait( *pDocSh, true );
+ SfxMedium* pMedium = pDocSh->GetMedium();
+ INetURLObject aAbs;
+ if( pMedium )
+ aAbs = pMedium->GetURLObject();
+ rSh.ReRead( URIHelper::SmartRel2Abs(
+ aAbs, sGrfNm,
+ URIHelper::GetMaybeFileHdl() ),
+ sFilterNm );
+ }
+ }
+ if ( const SfxStringItem* pNameItem = pSet->GetItemIfSet(
+ FN_SET_FRM_ALT_NAME ))
+ {
+ // #i73249#
+ rSh.SetObjTitle( pNameItem->GetValue() );
+ }
+
+ if ( const SfxStringItem* pDescriptionItem = pSet->GetItemIfSet(
+ FN_UNO_DESCRIPTION ))
+ rSh.SetObjDescription( pDescriptionItem->GetValue() );
+
+ // RotGrfFlyFrame: Get and process evtl. changed RotationAngle
+ if ( const SdrAngleItem* pAngleItem = pSet->GetItemIfSet(SID_ATTR_TRANSFORM_ANGLE, false ))
+ {
+ const Degree10 aNewRotation = to<Degree10>(pAngleItem->GetValue() % 36000_deg100);
+
+ // RotGrfFlyFrame: Possible rotation change here, SwFlyFrameAttrMgr aMgr is available
+ aMgr.SetRotation(nCurrentRotation, aNewRotation, aUnrotatedSize);
+ }
+
+ SfxItemSetFixed<RES_GRFATR_BEGIN, RES_GRFATR_END-1> aGrfSet( rSh.GetAttrPool() );
+ aGrfSet.Put( *pSet );
+ if( aGrfSet.Count() )
+ rSh.SetAttrSet( aGrfSet );
+
+ rSh.EndUndo(SwUndoId::END);
+ rSh.EndAllAction();
+ }
+ }
+ break;
+
+ case FN_GRAPHIC_MIRROR_ON_EVEN_PAGES:
+ {
+ SfxItemSetFixed<RES_GRFATR_MIRRORGRF, RES_GRFATR_MIRRORGRF> aSet(rSh.GetAttrPool());
+ rSh.GetCurAttr( aSet );
+ SwMirrorGrf aGrf(aSet.Get(RES_GRFATR_MIRRORGRF));
+ aGrf.SetGrfToggle(!aGrf.IsGrfToggle());
+ rSh.SetAttrItem(aGrf);
+ }
+ break;
+
+ case SID_OBJECT_CROP:
+ {
+ GraphicObject const *pGraphicObject = rSh.GetGraphicObj();
+ if (nullptr != pGraphicObject && SdrDragMode::Crop != rSh.GetDragMode()) {
+ rSh.StartCropImage();
+ }
+ }
+ break;
+
+ default:
+ OSL_ENSURE(false, "wrong dispatcher");
+ return;
+ }
+}
+
+void SwGrfShell::ExecAttr( SfxRequest const &rReq )
+{
+ GraphicType nGrfType = GraphicType::NONE;
+ if (CNT_GRF == GetShell().GetCntType())
+ nGrfType = GetShell().GetGraphicType();
+ if (GraphicType::Bitmap == nGrfType ||
+ GraphicType::GdiMetafile == nGrfType)
+ {
+ SfxItemSetFixed<RES_GRFATR_BEGIN, RES_GRFATR_END -1> aGrfSet( GetShell().GetAttrPool() );
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ const SfxPoolItem* pItem;
+ sal_uInt16 nSlot = rReq.GetSlot();
+ if( !pArgs || SfxItemState::SET != pArgs->GetItemState( nSlot, false, &pItem ))
+ pItem = nullptr;
+
+ switch( nSlot )
+ {
+ case SID_FLIP_VERTICAL:
+ case SID_FLIP_HORIZONTAL:
+ {
+ GetShell().GetCurAttr( aGrfSet );
+ SwMirrorGrf aMirror( aGrfSet.Get( RES_GRFATR_MIRRORGRF ) );
+ MirrorGraph nMirror = aMirror.GetValue();
+ if ( nSlot==SID_FLIP_HORIZONTAL )
+ switch( nMirror )
+ {
+ case MirrorGraph::Dont: nMirror = MirrorGraph::Vertical;
+ break;
+ case MirrorGraph::Horizontal: nMirror = MirrorGraph::Both;
+ break;
+ case MirrorGraph::Vertical: nMirror = MirrorGraph::Dont;
+ break;
+ case MirrorGraph::Both: nMirror = MirrorGraph::Horizontal;
+ break;
+ }
+ else
+ switch( nMirror )
+ {
+ case MirrorGraph::Dont: nMirror = MirrorGraph::Horizontal;
+ break;
+ case MirrorGraph::Vertical: nMirror = MirrorGraph::Both;
+ break;
+ case MirrorGraph::Horizontal: nMirror = MirrorGraph::Dont;
+ break;
+ case MirrorGraph::Both: nMirror = MirrorGraph::Vertical;
+ break;
+ }
+ aMirror.SetValue( nMirror );
+ aGrfSet.ClearItem();
+ aGrfSet.Put( aMirror );
+ }
+ break;
+
+ case SID_ATTR_GRAF_LUMINANCE:
+ if( pItem )
+ aGrfSet.Put( SwLuminanceGrf(
+ static_cast<const SfxInt16Item*>(pItem)->GetValue() ));
+ break;
+
+ case SID_ATTR_GRAF_CONTRAST:
+ if( pItem )
+ aGrfSet.Put( SwContrastGrf(
+ static_cast<const SfxInt16Item*>(pItem)->GetValue() ));
+ break;
+
+ case SID_ATTR_GRAF_RED:
+ if( pItem )
+ aGrfSet.Put( SwChannelRGrf(
+ static_cast<const SfxInt16Item*>(pItem)->GetValue() ));
+ break;
+
+ case SID_ATTR_GRAF_GREEN:
+ if( pItem )
+ aGrfSet.Put( SwChannelGGrf(
+ static_cast<const SfxInt16Item*>(pItem)->GetValue() ));
+ break;
+
+ case SID_ATTR_GRAF_BLUE:
+ if( pItem )
+ aGrfSet.Put( SwChannelBGrf(
+ static_cast<const SfxInt16Item*>(pItem)->GetValue() ));
+ break;
+
+ case SID_ATTR_GRAF_GAMMA:
+ if( pItem )
+ {
+ double fVal = static_cast<const SfxUInt32Item*>(pItem)->GetValue();
+ aGrfSet.Put( SwGammaGrf(fVal/100. ));
+ }
+ break;
+
+ case SID_ATTR_GRAF_TRANSPARENCE:
+ if( pItem )
+ aGrfSet.Put( SwTransparencyGrf(
+ static_cast< sal_Int8 >( static_cast<const SfxUInt16Item*>(pItem )->GetValue() ) ) );
+ break;
+
+ case SID_ATTR_GRAF_INVERT:
+ if( pItem )
+ aGrfSet.Put( SwInvertGrf(
+ static_cast<const SfxBoolItem*>(pItem)->GetValue() ));
+ break;
+
+ case SID_ATTR_GRAF_MODE:
+ if( pItem )
+ aGrfSet.Put( SwDrawModeGrf(
+ static_cast<GraphicDrawMode>(static_cast<const SfxUInt16Item*>(pItem)->GetValue()) ));
+ break;
+
+ case SID_COLOR_SETTINGS:
+ {
+ svx::ToolboxAccess aToolboxAccess( TOOLBOX_NAME );
+ aToolboxAccess.toggleToolbox();
+ break;
+ }
+
+ case SID_GRFFILTER:
+ case SID_GRFFILTER_INVERT:
+ case SID_GRFFILTER_SMOOTH:
+ case SID_GRFFILTER_SHARPEN:
+ case SID_GRFFILTER_REMOVENOISE:
+ case SID_GRFFILTER_SOBEL:
+ case SID_GRFFILTER_MOSAIC:
+ case SID_GRFFILTER_EMBOSS:
+ case SID_GRFFILTER_POSTER:
+ case SID_GRFFILTER_POPART:
+ case SID_GRFFILTER_SEPIA:
+ case SID_GRFFILTER_SOLARIZE:
+ if( GraphicType::Bitmap == nGrfType )
+ {
+ // #119353# - robust
+ const GraphicObject* pFilterObj( GetShell().GetGraphicObj() );
+ if ( pFilterObj )
+ {
+ GraphicObject aFilterObj( *pFilterObj );
+ if( SvxGraphicFilterResult::NONE ==
+ SvxGraphicFilter::ExecuteGrfFilterSlot( rReq, aFilterObj ))
+ GetShell().ReRead( OUString(), OUString(),
+ &aFilterObj.GetGraphic() );
+ }
+ }
+ break;
+
+ default:
+ OSL_ENSURE(false, "wrong dispatcher");
+ }
+
+ if( aGrfSet.Count() )
+ GetShell().SetAttrSet( aGrfSet );
+ }
+ GetView().GetViewFrame().GetBindings().Invalidate(rReq.GetSlot());
+}
+
+void SwGrfShell::GetAttrState(SfxItemSet &rSet)
+{
+ SwWrtShell &rSh = GetShell();
+ SfxItemSet aCoreSet( GetPool(), aNoTextNodeSetRange );
+ rSh.GetCurAttr( aCoreSet );
+ bool bParentCntProt = FlyProtectFlags::NONE != rSh.IsSelObjProtected( FlyProtectFlags::Content|FlyProtectFlags::Parent );
+ bool bIsGrfContent = CNT_GRF == GetShell().GetCntType();
+
+ SetGetStateSet( &rSet );
+
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while( nWhich )
+ {
+ bool bDisable = bParentCntProt;
+ switch( nWhich )
+ {
+ case SID_OBJECT_ROTATE:
+ {
+ // RotGrfFlyFrame: steer rotation state
+ const bool bIsRotate(GetView().IsDrawRotate());
+ SdrView* pSdrView = rSh.GetDrawViewWithValidMarkList();
+
+ if(!bIsRotate && !pSdrView->IsRotateAllowed())
+ {
+ rSet.DisableItem(nWhich);
+ }
+ else
+ {
+ rSet.Put(SfxBoolItem(nWhich, bIsRotate));
+ }
+
+ break;
+ }
+ case SID_INSERT_GRAPHIC:
+ case FN_FORMAT_GRAFIC_DLG:
+ case SID_TWAIN_TRANSFER:
+ if( bParentCntProt || !bIsGrfContent )
+ bDisable = true;
+ else if ( nWhich == SID_INSERT_GRAPHIC
+ && rSh.CursorInsideInputField() )
+ {
+ bDisable = true;
+ }
+ break;
+
+ case SID_SAVE_GRAPHIC:
+ case SID_EXTERNAL_EDIT:
+ if( rSh.GetGraphicType() == GraphicType::NONE || GetObjectShell()->isExportLocked())
+ bDisable = true;
+ break;
+
+ case SID_COLOR_SETTINGS:
+ {
+ if ( bParentCntProt || !bIsGrfContent )
+ bDisable = true;
+ else
+ {
+ svx::ToolboxAccess aToolboxAccess( TOOLBOX_NAME );
+ rSet.Put( SfxBoolItem( nWhich, aToolboxAccess.isToolboxVisible() ) );
+ }
+ break;
+ }
+
+ case SID_FLIP_HORIZONTAL:
+ if( !bParentCntProt )
+ {
+ MirrorGraph nState = aCoreSet.Get(
+ RES_GRFATR_MIRRORGRF ).GetValue();
+
+ rSet.Put(SfxBoolItem( nWhich, nState == MirrorGraph::Vertical ||
+ nState == MirrorGraph::Both));
+ }
+ break;
+
+ case SID_FLIP_VERTICAL:
+ if( !bParentCntProt )
+ {
+ MirrorGraph nState = aCoreSet.GetItem<SwMirrorGrf>( RES_GRFATR_MIRRORGRF )->GetValue();
+ rSet.Put(SfxBoolItem( nWhich, nState == MirrorGraph::Horizontal ||
+ nState == MirrorGraph::Both));
+ }
+ break;
+
+ case SID_ATTR_GRAF_LUMINANCE:
+ if( !bParentCntProt )
+ rSet.Put( SfxInt16Item( nWhich,
+ aCoreSet.Get(RES_GRFATR_LUMINANCE).GetValue() ));
+ break;
+
+ case SID_ATTR_GRAF_CONTRAST:
+ if( !bParentCntProt )
+ rSet.Put( SfxInt16Item( nWhich,
+ aCoreSet.Get(RES_GRFATR_CONTRAST).GetValue() ));
+ break;
+
+ case SID_ATTR_GRAF_RED:
+ if( !bParentCntProt )
+ rSet.Put( SfxInt16Item( nWhich,
+ aCoreSet.Get(RES_GRFATR_CHANNELR).GetValue() ));
+ break;
+
+ case SID_ATTR_GRAF_GREEN:
+ if( !bParentCntProt )
+ rSet.Put( SfxInt16Item( nWhich,
+ aCoreSet.Get(RES_GRFATR_CHANNELG).GetValue() ));
+ break;
+
+ case SID_ATTR_GRAF_BLUE:
+ if( !bParentCntProt )
+ rSet.Put( SfxInt16Item( nWhich,
+ aCoreSet.Get(RES_GRFATR_CHANNELB).GetValue() ));
+ break;
+
+ case SID_ATTR_GRAF_GAMMA:
+ if( !bParentCntProt )
+ rSet.Put( SfxUInt32Item( nWhich, static_cast< sal_uInt32 >(
+ aCoreSet.Get( RES_GRFATR_GAMMA ).GetValue() * 100 ) ) );
+ break;
+
+ case SID_ATTR_GRAF_TRANSPARENCE:
+ if( !bParentCntProt )
+ {
+ // #119353# - robust
+ const GraphicObject* pGrafObj = rSh.GetGraphicObj();
+ if ( pGrafObj )
+ {
+ if( pGrafObj->IsAnimated() ||
+ GraphicType::GdiMetafile == pGrafObj->GetType() )
+ bDisable = true;
+ else
+ rSet.Put( SfxUInt16Item( nWhich,
+ aCoreSet.Get(RES_GRFATR_TRANSPARENCY).GetValue() ));
+ }
+ }
+ break;
+
+ case SID_ATTR_GRAF_INVERT:
+ if( !bParentCntProt )
+ rSet.Put( SfxBoolItem( nWhich,
+ aCoreSet.Get(RES_GRFATR_INVERT).GetValue() ));
+ break;
+
+ case SID_ATTR_GRAF_MODE:
+ if( !bParentCntProt )
+ rSet.Put( SfxUInt16Item( nWhich, static_cast<sal_uInt16>(aCoreSet.Get(RES_GRFATR_DRAWMODE).GetValue()) ));
+ break;
+
+ case SID_GRFFILTER:
+ case SID_GRFFILTER_INVERT:
+ case SID_GRFFILTER_SMOOTH:
+ case SID_GRFFILTER_SHARPEN:
+ case SID_GRFFILTER_REMOVENOISE:
+ case SID_GRFFILTER_SOBEL:
+ case SID_GRFFILTER_MOSAIC:
+ case SID_GRFFILTER_EMBOSS:
+ case SID_GRFFILTER_POSTER:
+ case SID_GRFFILTER_POPART:
+ case SID_GRFFILTER_SEPIA:
+ case SID_GRFFILTER_SOLARIZE:
+ {
+ if( bParentCntProt || !bIsGrfContent )
+ bDisable = true;
+ // #i59688# load graphic only if type is unknown
+ else
+ {
+ const GraphicType eGraphicType( rSh.GetGraphicType() );
+ if ( ( eGraphicType == GraphicType::NONE ||
+ eGraphicType == GraphicType::Default ) &&
+ rSh.IsLinkedGrfSwapOut() )
+ {
+ rSet.DisableItem( nWhich );
+ if( AddGrfUpdateSlot( nWhich ))
+ rSh.GetGraphic(false); // start the loading
+ }
+ else
+ {
+ bDisable = eGraphicType != GraphicType::Bitmap;
+ }
+ }
+ }
+ break;
+
+ case SID_OBJECT_CROP:
+ {
+ bDisable = FlyProtectFlags::NONE != rSh.IsSelObjProtected( FlyProtectFlags::Content|FlyProtectFlags::Parent );
+ if( rSh.GetGraphicType() == GraphicType::NONE )
+ bDisable = true;
+ }
+ break;
+
+ default:
+ bDisable = false;
+ }
+
+ if( bDisable )
+ rSet.DisableItem( nWhich );
+ nWhich = aIter.NextWhich();
+ }
+ SetGetStateSet( nullptr );
+}
+
+void SwGrfShell::ExecuteRotation(SfxRequest const &rReq)
+{
+ // RotGrfFlyFrame: Modify rotation attribute instead of manipulating the graphic
+ Degree10 aRotation;
+
+ if (rReq.GetSlot() == SID_ROTATE_GRAPHIC_LEFT)
+ {
+ aRotation = 900_deg10;
+ }
+ else if (rReq.GetSlot() == SID_ROTATE_GRAPHIC_RIGHT)
+ {
+ aRotation = 2700_deg10;
+ }
+ else if (rReq.GetSlot() == SID_ROTATE_GRAPHIC_180)
+ {
+ aRotation = 1800_deg10;
+ }
+
+ if (rReq.GetSlot() != SID_ROTATE_GRAPHIC_RESET && 0_deg10 == aRotation)
+ return;
+
+ SwWrtShell& rShell = GetShell();
+ SfxItemSetFixed<RES_GRFATR_ROTATION, RES_GRFATR_ROTATION> aSet( rShell.GetAttrPool() );
+ rShell.GetCurAttr( aSet );
+ const SwRotationGrf& rRotation = aSet.Get(RES_GRFATR_ROTATION);
+ SwFlyFrameAttrMgr aMgr(false, &rShell, rShell.IsFrameSelected() ? Frmmgr_Type::NONE : Frmmgr_Type::GRF, nullptr);
+
+ // RotGrfFlyFrame: Possible rotation change here, SwFlyFrameAttrMgr aMgr is available
+ if (rReq.GetSlot() == SID_ROTATE_GRAPHIC_RESET)
+ {
+ aMgr.SetRotation(rRotation.GetValue(), 0_deg10, rRotation.GetUnrotatedSize());
+ }
+ else if(0_deg10 != aRotation)
+ {
+ const Degree10 aNewRotation((aRotation + rRotation.GetValue()) % 3600_deg10);
+
+ aMgr.SetRotation(rRotation.GetValue(), aNewRotation, rRotation.GetUnrotatedSize());
+ }
+}
+
+void SwGrfShell::GetAttrStateForRotation(SfxItemSet &rSet)
+{
+ SwWrtShell& rShell = GetShell();
+ bool bIsParentContentProtected = FlyProtectFlags::NONE != rShell.IsSelObjProtected( FlyProtectFlags::Content|FlyProtectFlags::Parent );
+
+ SetGetStateSet( &rSet );
+
+ SfxWhichIter aIterator( rSet );
+ sal_uInt16 nWhich = aIterator.FirstWhich();
+ while( nWhich )
+ {
+ bool bDisable = bIsParentContentProtected;
+ switch( nWhich )
+ {
+ case SID_ROTATE_GRAPHIC_LEFT:
+ case SID_ROTATE_GRAPHIC_RIGHT:
+ case SID_ROTATE_GRAPHIC_180:
+ {
+ if( rShell.GetGraphicType() == GraphicType::NONE )
+ {
+ bDisable = true;
+ }
+ break;
+ }
+ case SID_ROTATE_GRAPHIC_RESET:
+ {
+ // RotGrfFlyFrame: disable when already no rotation
+ SfxItemSetFixed<RES_GRFATR_ROTATION, RES_GRFATR_ROTATION> aSet( rShell.GetAttrPool() );
+ rShell.GetCurAttr( aSet );
+ const SwRotationGrf& rRotation = aSet.Get(RES_GRFATR_ROTATION);
+ bDisable = (0_deg10 == rRotation.GetValue());
+ break;
+ }
+ case SID_ATTR_TRANSFORM_ANGLE:
+ {
+ // RotGrfFlyFrame: get rotation value from RES_GRFATR_ROTATION and copy to rSet as
+ // SID_ATTR_TRANSFORM_ANGLE, convert from 10th degrees to 100th degrees
+ SfxItemSetFixed<RES_GRFATR_ROTATION, RES_GRFATR_ROTATION> aSet( rShell.GetAttrPool() );
+ rShell.GetCurAttr( aSet );
+ const SwRotationGrf& rRotation = aSet.Get(RES_GRFATR_ROTATION);
+ rSet.Put(SdrAngleItem(SID_ATTR_TRANSFORM_ANGLE, to<Degree100>(rRotation.GetValue())));
+ break;
+ }
+ default:
+ bDisable = false;
+ }
+
+ if( bDisable )
+ rSet.DisableItem( nWhich );
+ nWhich = aIterator.NextWhich();
+ }
+ SetGetStateSet( nullptr );
+}
+
+SwGrfShell::~SwGrfShell()
+{
+}
+
+SwGrfShell::SwGrfShell(SwView &_rView) :
+ SwBaseShell(_rView)
+{
+ SetName("Graphic");
+ SfxShell::SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::Graphic));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/grfshex.cxx b/sw/source/uibase/shells/grfshex.cxx
new file mode 100644
index 0000000000..45d4076452
--- /dev/null
+++ b/sw/source/uibase/shells/grfshex.cxx
@@ -0,0 +1,155 @@
+/* -*- 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 <wrtsh.hxx>
+#include <view.hxx>
+#include <textsh.hxx>
+#include <drawdoc.hxx>
+#include <doc.hxx>
+#include <IDocumentDrawModelAccess.hxx>
+#include <docsh.hxx>
+#include <avmedia/mediawindow.hxx>
+#include <editeng/sizeitem.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svl/stritem.hxx>
+#include <svx/svdomedia.hxx>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/media/XPlayer.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::sfx2;
+
+bool SwTextShell::InsertMediaDlg( SfxRequest const & rReq )
+{
+ bool bRet = false;
+
+#if !HAVE_FEATURE_AVMEDIA
+ (void) rReq;
+#else
+ OUString aURL;
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ vcl::Window& rWindow = GetView().GetViewFrame().GetWindow();
+ bool bAPI = false;
+
+ const SvxSizeItem* pSizeItem = rReq.GetArg<SvxSizeItem>(FN_PARAM_1);
+ const SfxBoolItem* pLinkItem = rReq.GetArg<SfxBoolItem>(FN_PARAM_2);
+ const bool bSizeUnknown = !pSizeItem;
+
+ if( pReqArgs )
+ {
+ const SfxStringItem* pStringItem = dynamic_cast<const SfxStringItem*>( &pReqArgs->Get( rReq.GetSlot() ) );
+ if( pStringItem )
+ {
+ aURL = pStringItem->GetValue();
+ bAPI = !aURL.isEmpty();
+ }
+ }
+
+ bool bLink(pLinkItem ? pLinkItem->GetValue() : true);
+
+ if (bAPI || ::avmedia::MediaWindow::executeMediaURLDialog(rWindow.GetFrameWeld(), aURL, & bLink))
+ {
+ Size aPrefSize;
+
+ if (!bSizeUnknown)
+ aPrefSize = pSizeItem->GetSize();
+ else
+ {
+ rWindow.EnterWait();
+
+ css::uno::Reference<css::frame::XDispatchProvider> xDispatchProvider(GetView().GetViewFrame().GetFrame().GetFrameInterface(), css::uno::UNO_QUERY);
+
+ rtl::Reference<avmedia::PlayerListener> xPlayerListener(new avmedia::PlayerListener(
+ [xDispatchProvider, aURL, bLink](const css::uno::Reference<css::media::XPlayer>& rPlayer){
+ css::awt::Size aSize = rPlayer->getPreferredPlayerWindowSize();
+ avmedia::MediaWindow::dispatchInsertAVMedia(xDispatchProvider, aSize, aURL, bLink);
+ }));
+
+ const bool bIsMediaURL = ::avmedia::MediaWindow::isMediaURL(aURL, "", true, xPlayerListener);
+
+ rWindow.LeaveWait();
+
+ if (!bIsMediaURL)
+ {
+ if( !bAPI )
+ ::avmedia::MediaWindow::executeFormatErrorBox(rWindow.GetFrameWeld());
+
+ return bRet;
+ }
+
+ return true;
+ }
+
+ rWindow.EnterWait();
+
+ SwWrtShell& rSh = GetShell();
+
+ if( !rSh.HasDrawView() )
+ rSh.MakeDrawView();
+
+ Size aDocSz( rSh.GetDocSize() );
+ const SwRect& rVisArea = rSh.VisArea();
+ Point aPos( rVisArea.Center() );
+ Size aSize;
+
+ if( rVisArea.Width() > aDocSz.Width())
+ aPos.setX( aDocSz.Width() / 2 + rVisArea.Left() );
+
+ if(rVisArea.Height() > aDocSz.Height())
+ aPos.setY( aDocSz.Height() / 2 + rVisArea.Top() );
+
+ if( aPrefSize.Width() && aPrefSize.Height() )
+ aSize = rWindow.PixelToLogic(aPrefSize, MapMode(MapUnit::MapTwip));
+ else
+ aSize = Size( 2835, 2835 );
+
+ OUString realURL;
+ if (bLink)
+ {
+ realURL = aURL;
+ }
+ else
+ {
+ uno::Reference<frame::XModel> const xModel(
+ rSh.GetDoc()->GetDocShell()->GetModel());
+ bRet = ::avmedia::EmbedMedia(xModel, aURL, realURL);
+ if (!bRet) { return bRet; }
+ }
+
+ rtl::Reference<SdrMediaObj> pObj = new SdrMediaObj(
+ *rSh.GetDoc()->getIDocumentDrawModelAccess().GetDrawModel(),
+ tools::Rectangle(aPos, aSize));
+
+ pObj->setURL( realURL, "" );
+ rSh.EnterStdMode();
+ rSh.SwFEShell::InsertDrawObj( *pObj, aPos );
+ bRet = true;
+
+ rWindow.LeaveWait();
+ }
+#endif
+
+ return bRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/langhelper.cxx b/sw/source/uibase/shells/langhelper.cxx
new file mode 100644
index 0000000000..453e0c1d93
--- /dev/null
+++ b/sw/source/uibase/shells/langhelper.cxx
@@ -0,0 +1,549 @@
+/* -*- 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 <string.h>
+
+#include <wrtsh.hxx>
+#include <doc.hxx>
+#include <docary.hxx>
+#include <charfmt.hxx>
+
+#include <sfx2/bindings.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/sfxdlg.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/langitem.hxx>
+
+#include <svl/languageoptions.hxx>
+#include <svtools/langtab.hxx>
+#include <svl/slstitm.hxx>
+#include <svl/stritem.hxx>
+#include <svx/svxids.hrc>
+#include <osl/diagnose.h>
+
+#include <ndtxt.hxx>
+#include <pam.hxx>
+#include <view.hxx>
+#include <viewopt.hxx>
+
+#include <langhelper.hxx>
+
+using namespace ::com::sun::star;
+
+namespace SwLangHelper
+{
+
+ void GetLanguageStatus( OutlinerView* pOLV, SfxItemSet& rSet )
+ {
+ ESelection aSelection = pOLV->GetSelection();
+ EditView& rEditView=pOLV->GetEditView();
+ EditEngine* pEditEngine=rEditView.GetEditEngine();
+
+ // the value of used script types
+ const SvtScriptType nScriptType =pOLV->GetSelectedScriptType();
+ OUString aScriptTypesInUse( OUString::number( static_cast<int>(nScriptType) ) );//pEditEngine->GetScriptType(aSelection)
+
+ // get keyboard language
+ OUString aKeyboardLang;
+ LanguageType nLang = rEditView.GetInputLanguage();
+ if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
+ aKeyboardLang = SvtLanguageTable::GetLanguageString( nLang );
+
+ // get the language that is in use
+ OUString aCurrentLang("*");
+ SfxItemSet aSet(pOLV->GetAttribs());
+ nLang = SwLangHelper::GetCurrentLanguage( aSet,nScriptType );
+ if (nLang != LANGUAGE_DONTKNOW)
+ aCurrentLang = SvtLanguageTable::GetLanguageString( nLang );
+
+ // build sequence for status value
+ uno::Sequence< OUString > aSeq{ aCurrentLang,
+ aScriptTypesInUse,
+ aKeyboardLang,
+ SwLangHelper::GetTextForLanguageGuessing( pEditEngine,
+ aSelection ) };
+
+ // set sequence as status value
+ SfxStringListItem aItem( SID_LANGUAGE_STATUS );
+ aItem.SetStringList( aSeq );
+ rSet.Put( aItem );
+ }
+
+ bool SetLanguageStatus( OutlinerView* pOLV, SfxRequest &rReq, SwView const &rView, SwWrtShell &rSh )
+ {
+ bool bRestoreSelection = false;
+ ESelection aSelection = pOLV->GetSelection();
+ EditView & rEditView = pOLV->GetEditView();
+ SfxItemSet aEditAttr(rEditView.GetEmptyItemSet());
+
+ // get the language
+ OUString aNewLangText;
+
+ const SfxStringItem* pItem = rReq.GetArg<SfxStringItem>(SID_LANGUAGE_STATUS);
+ if (pItem)
+ aNewLangText = pItem->GetValue();
+
+ //!! Remember the view frame right now...
+ //!! (call to GetView().GetViewFrame() will break if the
+ //!! SwTextShell got destroyed meanwhile.)
+ SfxViewFrame& rViewFrame = rView.GetViewFrame();
+
+ if (aNewLangText == "*" )
+ {
+ // open the dialog "Tools/Options/Languages and Locales - General"
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateVclDialog( rView.GetFrameWeld(), SID_LANGUAGE_OPTIONS ));
+ pDlg->Execute();
+ }
+ else
+ {
+ // setting the new language...
+ if (!aNewLangText.isEmpty())
+ {
+ static constexpr OUString aSelectionLangPrefix(u"Current_"_ustr);
+ static constexpr OUString aParagraphLangPrefix(u"Paragraph_"_ustr);
+ static constexpr OUString aDocumentLangPrefix(u"Default_"_ustr);
+
+ sal_Int32 nPos = 0;
+ bool bForSelection = true;
+ bool bForParagraph = false;
+ if (-1 != (nPos = aNewLangText.indexOf( aSelectionLangPrefix )))
+ {
+ // ... for the current selection
+ aNewLangText = aNewLangText.replaceAt(nPos, aSelectionLangPrefix.getLength(), u"");
+ bForSelection = true;
+ }
+ else if (-1 != (nPos = aNewLangText.indexOf( aParagraphLangPrefix )))
+ {
+ // ... for the current paragraph language
+ aNewLangText = aNewLangText.replaceAt(nPos, aParagraphLangPrefix.getLength(), u"");
+ bForSelection = true;
+ bForParagraph = true;
+ }
+ else if (-1 != (nPos = aNewLangText.indexOf( aDocumentLangPrefix )))
+ {
+ // ... as default document language
+ aNewLangText = aNewLangText.replaceAt(nPos, aDocumentLangPrefix.getLength(), u"");
+ bForSelection = false;
+ }
+
+ if (bForParagraph)
+ {
+ bRestoreSelection = true;
+ SwLangHelper::SelectPara( rEditView, aSelection );
+ aSelection = pOLV->GetSelection();
+ }
+ if (!bForSelection) // document language to be changed...
+ {
+ rSh.StartAction();
+ rSh.LockView( true );
+ rSh.Push();
+
+ // prepare to apply new language to all text in document
+ rSh.SelAll();
+ rSh.ExtendedSelectAll();
+ }
+
+ if (aNewLangText == "LANGUAGE_NONE")
+ SwLangHelper::SetLanguage_None( rSh, pOLV, aSelection, bForSelection, aEditAttr );
+ else if (aNewLangText == "RESET_LANGUAGES")
+ SwLangHelper::ResetLanguages( rSh, pOLV );
+ else
+ SwLangHelper::SetLanguage( rSh, pOLV, aSelection, aNewLangText, bForSelection, aEditAttr );
+
+ if (!bForSelection)
+ {
+ // need to release view and restore selection...
+ rSh.Pop(SwCursorShell::PopMode::DeleteCurrent);
+ rSh.LockView( false );
+ rSh.EndAction();
+ }
+ }
+ }
+
+ // invalidate slot to get the new language displayed
+ rViewFrame.GetBindings().Invalidate( rReq.GetSlot() );
+
+ rReq.Done();
+ return bRestoreSelection;
+ }
+
+ void SetLanguage( SwWrtShell &rWrtSh, std::u16string_view rLangText, bool bIsForSelection, SfxItemSet &rCoreSet )
+ {
+ SetLanguage( rWrtSh, nullptr , ESelection(), rLangText, bIsForSelection, rCoreSet );
+ }
+
+ void SetLanguage( SwWrtShell &rWrtSh, OutlinerView const * pOLV, const ESelection& rSelection, std::u16string_view rLangText, bool bIsForSelection, SfxItemSet &rCoreSet )
+ {
+ const LanguageType nLang = SvtLanguageTable::GetLanguageType( rLangText );
+ if (nLang == LANGUAGE_DONTKNOW)
+ return;
+
+ EditEngine* pEditEngine = pOLV ? pOLV->GetEditView().GetEditEngine() : nullptr;
+ OSL_ENSURE( !pOLV || pEditEngine, "OutlinerView without EditEngine???" );
+
+ //get ScriptType
+ TypedWhichId<SvxLanguageItem> nLangWhichId(0);
+ bool bIsSingleScriptType = true;
+ switch (SvtLanguageOptions::GetScriptTypeOfLanguage( nLang ))
+ {
+ case SvtScriptType::LATIN : nLangWhichId = pEditEngine ? EE_CHAR_LANGUAGE : RES_CHRATR_LANGUAGE; break;
+ case SvtScriptType::ASIAN : nLangWhichId = pEditEngine ? EE_CHAR_LANGUAGE_CJK : RES_CHRATR_CJK_LANGUAGE; break;
+ case SvtScriptType::COMPLEX : nLangWhichId = pEditEngine ? EE_CHAR_LANGUAGE_CTL : RES_CHRATR_CTL_LANGUAGE; break;
+ default:
+ bIsSingleScriptType = false;
+ OSL_FAIL("unexpected case" );
+ }
+ if (!bIsSingleScriptType)
+ return;
+
+ // change language for selection or paragraph
+ // (for paragraph is handled by previously having set the selection to the
+ // whole paragraph)
+ if (bIsForSelection)
+ {
+ // apply language to current selection
+ if (pEditEngine)
+ {
+ rCoreSet.Put( SvxLanguageItem( nLang, nLangWhichId ));
+ pEditEngine->QuickSetAttribs(rCoreSet, rSelection);
+ }
+ else
+ {
+ rWrtSh.GetCurAttr( rCoreSet );
+ rCoreSet.Put( SvxLanguageItem( nLang, nLangWhichId ));
+ rWrtSh.SetAttrSet( rCoreSet );
+ }
+ }
+ else // change language for all text
+ {
+ // set document default language
+ switch (nLangWhichId)
+ {
+ case EE_CHAR_LANGUAGE : nLangWhichId = RES_CHRATR_LANGUAGE; break;
+ case EE_CHAR_LANGUAGE_CJK : nLangWhichId = RES_CHRATR_CJK_LANGUAGE; break;
+ case EE_CHAR_LANGUAGE_CTL : nLangWhichId = RES_CHRATR_CTL_LANGUAGE; break;
+ }
+ //Set the default document language
+ rWrtSh.SetDefault( SvxLanguageItem( nLang, nLangWhichId ) );
+ rWrtSh.GetDoc()->GetDocShell()->Broadcast(SfxHint(SfxHintId::LanguageChanged));
+
+ // #i102191: hard set respective language attribute in text document
+ // (for all text in the document - which should be selected by now...)
+ rWrtSh.SetAttrItem( SvxLanguageItem( nLang, nLangWhichId ) );
+ }
+ }
+
+ void SetLanguage_None( SwWrtShell &rWrtSh, bool bIsForSelection, SfxItemSet &rCoreSet )
+ {
+ SetLanguage_None( rWrtSh,nullptr,ESelection(),bIsForSelection,rCoreSet );
+ }
+
+ void SetLanguage_None( SwWrtShell &rWrtSh, OutlinerView const * pOLV, const ESelection& rSelection, bool bIsForSelection, SfxItemSet &rCoreSet )
+ {
+ // EditEngine IDs
+ const sal_uInt16 aLangWhichId_EE[3] =
+ {
+ EE_CHAR_LANGUAGE,
+ EE_CHAR_LANGUAGE_CJK,
+ EE_CHAR_LANGUAGE_CTL
+ };
+
+ // Writer IDs
+ const sal_uInt16 aLangWhichId_Writer[3] =
+ {
+ RES_CHRATR_LANGUAGE,
+ RES_CHRATR_CJK_LANGUAGE,
+ RES_CHRATR_CTL_LANGUAGE
+ };
+
+ if (bIsForSelection)
+ {
+ // change language for selection or paragraph
+ // (for paragraph is handled by previously having set the selection to the
+ // whole paragraph)
+
+ EditEngine* pEditEngine = pOLV ? pOLV->GetEditView().GetEditEngine() : nullptr;
+ OSL_ENSURE( !pOLV || pEditEngine, "OutlinerView without EditEngine???" );
+ if (pEditEngine)
+ {
+ for (sal_uInt16 i : aLangWhichId_EE)
+ rCoreSet.Put( SvxLanguageItem( LANGUAGE_NONE, i ));
+ pEditEngine->QuickSetAttribs(rCoreSet, rSelection);
+ }
+ else
+ {
+ rWrtSh.GetCurAttr( rCoreSet );
+ for (sal_uInt16 i : aLangWhichId_Writer)
+ rCoreSet.Put( SvxLanguageItem( LANGUAGE_NONE, i ));
+ rWrtSh.SetAttrSet( rCoreSet );
+ }
+ }
+ else // change language for all text
+ {
+ o3tl::sorted_vector<sal_uInt16> aAttribs;
+ for (sal_uInt16 i : aLangWhichId_Writer)
+ {
+ rWrtSh.SetDefault( SvxLanguageItem( LANGUAGE_NONE, i ) );
+ aAttribs.insert( i );
+ }
+ rWrtSh.GetDoc()->GetDocShell()->Broadcast(SfxHint(SfxHintId::LanguageChanged));
+
+ // set all language attributes to default
+ // (for all text in the document - which should be selected by now...)
+ rWrtSh.ResetAttr( aAttribs );
+ }
+ }
+
+ void ResetLanguages( SwWrtShell &rWrtSh, OutlinerView const * pOLV )
+ {
+ // reset language for current selection.
+ // The selection should already have been expanded to the whole paragraph or
+ // to all text in the document if those are the ranges where to reset
+ // the language attributes
+
+ if (pOLV)
+ {
+ EditView &rEditView = pOLV->GetEditView();
+ rEditView.RemoveAttribs( true, EE_CHAR_LANGUAGE );
+ rEditView.RemoveAttribs( true, EE_CHAR_LANGUAGE_CJK );
+ rEditView.RemoveAttribs( true, EE_CHAR_LANGUAGE_CTL );
+
+ // ugly hack, as it seems that EditView/EditEngine does not update their spellchecking marks
+ // when setting a new language attribute
+ EditEngine* pEditEngine = rEditView.GetEditEngine();
+ EEControlBits nCntrl = pEditEngine->GetControlWord();
+ // turn off
+ pEditEngine->SetControlWord(nCntrl & ~EEControlBits::ONLINESPELLING);
+ //turn back on
+ pEditEngine->SetControlWord(nCntrl);
+ pEditEngine->CompleteOnlineSpelling();
+
+ rEditView.Invalidate();
+ }
+ else
+ {
+ rWrtSh.ResetAttr(
+ { RES_CHRATR_LANGUAGE, RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CTL_LANGUAGE });
+ }
+ }
+
+ /// @returns : the language for the selected text that is set for the
+ /// specified attribute (script type).
+ /// If there are more than one languages used LANGUAGE_DONTKNOW will be returned.
+ /// @param nLangWhichId : one of
+ /// RES_CHRATR_LANGUAGE, RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CTL_LANGUAGE,
+ LanguageType GetLanguage( SwWrtShell &rSh, TypedWhichId<SvxLanguageItem> nLangWhichId )
+ {
+ SfxItemSet aSet( rSh.GetAttrPool(), nLangWhichId, nLangWhichId );
+ rSh.GetCurAttr( aSet );
+
+ return GetLanguage(aSet,nLangWhichId);
+ }
+
+ LanguageType GetLanguage( SfxItemSet const & aSet, TypedWhichId<SvxLanguageItem> nLangWhichId )
+ {
+
+ LanguageType nLang = LANGUAGE_SYSTEM;
+
+ const SvxLanguageItem *pItem = nullptr;
+ SfxItemState nState = aSet.GetItemState( nLangWhichId, true, &pItem );
+ if (nState > SfxItemState::DEFAULT && pItem)
+ {
+ // the item is set and can be used
+ nLang = pItem->GetLanguage();
+ }
+ else if (nState == SfxItemState::DEFAULT)
+ {
+ // since the attribute is not set: retrieve the default value
+ nLang = aSet.GetPool()->GetDefaultItem( nLangWhichId ).GetLanguage();
+ }
+ else if (nState == SfxItemState::DONTCARE)
+ {
+ // there is more than one language...
+ nLang = LANGUAGE_DONTKNOW;
+ }
+ OSL_ENSURE( nLang != LANGUAGE_SYSTEM, "failed to get the language?" );
+
+ return nLang;
+ }
+
+ /// @returns: the language in use for the selected text.
+ /// 'In use' means the language(s) matching the script type(s) of the
+ /// selected text. Or in other words, the language a spell checker would use.
+ /// If there is more than one language LANGUAGE_DONTKNOW will be returned.
+ LanguageType GetCurrentLanguage( SwWrtShell &rSh )
+ {
+ //set language attribute to use according to the script type
+ TypedWhichId<SvxLanguageItem> nLangWhichId(0);
+ bool bIsSingleScriptType = true;
+ switch (rSh.GetScriptType())
+ {
+ case SvtScriptType::LATIN : nLangWhichId = RES_CHRATR_LANGUAGE; break;
+ case SvtScriptType::ASIAN : nLangWhichId = RES_CHRATR_CJK_LANGUAGE; break;
+ case SvtScriptType::COMPLEX : nLangWhichId = RES_CHRATR_CTL_LANGUAGE; break;
+ default: bIsSingleScriptType = false; break;
+ }
+
+ // get language according to the script type(s) in use
+ LanguageType nCurrentLang = LANGUAGE_SYSTEM;
+ if (bIsSingleScriptType)
+ nCurrentLang = GetLanguage( rSh, nLangWhichId );
+ else
+ {
+ // check if all script types are set to LANGUAGE_NONE and return
+ // that if this is the case. Otherwise, having multiple script types
+ // in use always means there are several languages in use...
+ const TypedWhichId<SvxLanguageItem> aScriptTypes[3] =
+ {
+ RES_CHRATR_LANGUAGE,
+ RES_CHRATR_CJK_LANGUAGE,
+ RES_CHRATR_CTL_LANGUAGE
+ };
+ nCurrentLang = LANGUAGE_NONE;
+ for (const TypedWhichId<SvxLanguageItem>& aScriptType : aScriptTypes)
+ {
+ LanguageType nTmpLang = GetLanguage( rSh, aScriptType );
+ if (nTmpLang != LANGUAGE_NONE)
+ {
+ nCurrentLang = LANGUAGE_DONTKNOW;
+ break;
+ }
+ }
+ }
+ OSL_ENSURE( nCurrentLang != LANGUAGE_SYSTEM, "failed to get the language?" );
+
+ return nCurrentLang;
+ }
+
+ /// @returns: the language in use for the selected text.
+ /// 'In use' means the language(s) matching the script type(s) of the
+ /// selected text. Or in other words, the language a spell checker would use.
+ /// If there is more than one language LANGUAGE_DONTKNOW will be returned.
+ LanguageType GetCurrentLanguage( SfxItemSet const & aSet, SvtScriptType nScriptType )
+ {
+ //set language attribute to use according to the script type
+ TypedWhichId<SvxLanguageItem> nLangWhichId(0);
+ bool bIsSingleScriptType = true;
+ switch (nScriptType)
+ {
+ case SvtScriptType::LATIN : nLangWhichId = EE_CHAR_LANGUAGE; break;
+ case SvtScriptType::ASIAN : nLangWhichId = EE_CHAR_LANGUAGE_CJK; break;
+ case SvtScriptType::COMPLEX : nLangWhichId = EE_CHAR_LANGUAGE_CTL; break;
+ default: bIsSingleScriptType = false;
+ }
+
+ // get language according to the script type(s) in use
+ LanguageType nCurrentLang = LANGUAGE_SYSTEM;
+ if (bIsSingleScriptType)
+ nCurrentLang = GetLanguage( aSet, nLangWhichId );
+ else
+ {
+ // check if all script types are set to LANGUAGE_NONE and return
+ // that if this is the case. Otherwise, having multiple script types
+ // in use always means there are several languages in use...
+ const TypedWhichId<SvxLanguageItem> aScriptTypes[3] =
+ {
+ EE_CHAR_LANGUAGE,
+ EE_CHAR_LANGUAGE_CJK,
+ EE_CHAR_LANGUAGE_CTL
+ };
+ nCurrentLang = LANGUAGE_NONE;
+ for (const TypedWhichId<SvxLanguageItem>& aScriptType : aScriptTypes)
+ {
+ LanguageType nTmpLang = GetLanguage( aSet, aScriptType );
+ if (nTmpLang != LANGUAGE_NONE)
+ {
+ nCurrentLang = LANGUAGE_DONTKNOW;
+ break;
+ }
+ }
+ }
+ OSL_ENSURE( nCurrentLang != LANGUAGE_SYSTEM, "failed to get the language?" );
+
+ return nCurrentLang;
+ }
+
+ OUString GetTextForLanguageGuessing( SwWrtShell const &rSh )
+ {
+ // string for guessing language
+ OUString aText;
+ SwPaM *pCursor = rSh.GetCursor();
+ SwTextNode *pNode = pCursor->GetPointNode().GetTextNode();
+ if (pNode)
+ {
+ aText = pNode->GetText();
+ if (!aText.isEmpty())
+ {
+ sal_Int32 nEnd = pCursor->GetPoint()->GetContentIndex();
+ // at most 100 chars to the left...
+ const sal_Int32 nStt = nEnd > 100 ? nEnd - 100 : 0;
+ // ... and 100 to the right of the cursor position
+ nEnd = aText.getLength() - nEnd > 100 ? nEnd + 100 : aText.getLength();
+ aText = aText.copy( nStt, nEnd - nStt );
+ }
+ }
+ return aText;
+ }
+
+ OUString GetTextForLanguageGuessing(EditEngine const * rEditEngine, const ESelection& rDocSelection)
+ {
+ // string for guessing language
+
+ // get the full text of the paragraph that the end of selection is in
+ OUString aText = rEditEngine->GetText(rDocSelection.nEndPos);
+ if (!aText.isEmpty())
+ {
+ sal_Int32 nStt = 0;
+ sal_Int32 nEnd = rDocSelection.nEndPos;
+ // at most 100 chars to the left...
+ nStt = nEnd > 100 ? nEnd - 100 : 0;
+ // ... and 100 to the right of the cursor position
+ nEnd = aText.getLength() - nEnd > 100 ? nEnd + 100 : aText.getLength();
+ aText = aText.copy( nStt, nEnd - nStt );
+ }
+
+ return aText;
+ }
+
+ void SelectPara( EditView &rEditView, const ESelection &rCurSel )
+ {
+ ESelection aParaSel( rCurSel.nStartPara, 0, rCurSel.nStartPara, EE_TEXTPOS_ALL );
+ rEditView.SetSelection( aParaSel );
+ }
+
+ void SelectCurrentPara( SwWrtShell &rWrtSh )
+ {
+ // select current para
+ if (!rWrtSh.IsSttPara())
+ rWrtSh.MovePara( GoCurrPara, fnParaStart );
+ if (!rWrtSh.HasMark())
+ rWrtSh.SetMark();
+ rWrtSh.SwapPam();
+ if (!rWrtSh.IsEndPara())
+ rWrtSh.MovePara( GoCurrPara, fnParaEnd );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/listsh.cxx b/sw/source/uibase/shells/listsh.cxx
new file mode 100644
index 0000000000..f6100cc0a4
--- /dev/null
+++ b/sw/source/uibase/shells/listsh.cxx
@@ -0,0 +1,264 @@
+/* -*- 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 <cmdid.h>
+#include <sfx2/request.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svl/eitem.hxx>
+#include <svl/whiter.hxx>
+#include <osl/diagnose.h>
+
+#include <numrule.hxx>
+#include <wrtsh.hxx>
+#include <listsh.hxx>
+#include <view.hxx>
+
+#define ShellClass_SwListShell
+#include <sfx2/msg.hxx>
+#include <swslots.hxx>
+
+#include <IDocumentOutlineNodes.hxx>
+
+SFX_IMPL_INTERFACE(SwListShell, SwBaseShell)
+
+void SwListShell::InitInterface_Impl()
+{
+ GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Invisible, ToolbarId::Num_Toolbox);
+}
+
+
+// #i35572# Functionality of Numbering/Bullet toolbar
+// for outline numbered paragraphs should match the functions for outlines
+// available in the navigator. Therefore the code in the following
+// function is quite similar the code in SwContentTree::ExecCommand.
+static void lcl_OutlineUpDownWithSubPoints( SwWrtShell& rSh, bool bMove, bool bUp )
+{
+ const SwOutlineNodes::size_type nActPos = rSh.GetOutlinePos();
+ if ( !(nActPos < SwOutlineNodes::npos && rSh.IsOutlineMovable( nActPos )) )
+ return;
+
+ rSh.Push();
+ rSh.MakeOutlineSel( nActPos, nActPos, true );
+
+ if ( bMove )
+ {
+ const IDocumentOutlineNodes* pIDoc( rSh.getIDocumentOutlineNodesAccess() );
+ const int nActLevel = pIDoc->getOutlineLevel( nActPos );
+ SwOutlineNodes::difference_type nDir = 0;
+
+ if ( !bUp )
+ {
+ // Move down with subpoints:
+ SwOutlineNodes::size_type nActEndPos = nActPos + 1;
+ while ( nActEndPos < pIDoc->getOutlineNodesCount() &&
+ (!pIDoc->isOutlineInLayout(nActEndPos, *rSh.GetLayout())
+ || nActLevel < pIDoc->getOutlineLevel(nActEndPos)))
+ {
+ ++nActEndPos;
+ }
+
+ if ( nActEndPos < pIDoc->getOutlineNodesCount() )
+ {
+ // The current subpoint which should be moved
+ // starts at nActPos and ends at nActEndPos - 1
+ --nActEndPos;
+ SwOutlineNodes::size_type nDest = nActEndPos + 2;
+ while ( nDest < pIDoc->getOutlineNodesCount() &&
+ (!pIDoc->isOutlineInLayout(nDest, *rSh.GetLayout())
+ || nActLevel < pIDoc->getOutlineLevel(nDest)))
+ {
+ ++nDest;
+ }
+
+ nDir = nDest - 1 - nActEndPos;
+ }
+ }
+ else
+ {
+ // Move up with subpoints:
+ if ( nActPos > 0 )
+ {
+ SwOutlineNodes::size_type nDest = nActPos - 1;
+ while (nDest > 0 &&
+ (!pIDoc->isOutlineInLayout(nDest, *rSh.GetLayout())
+ || nActLevel < pIDoc->getOutlineLevel(nDest)))
+ {
+ --nDest;
+ }
+
+ nDir = nDest - nActPos;
+ }
+ }
+
+ if ( nDir )
+ {
+ rSh.MoveOutlinePara( nDir );
+ rSh.GotoOutline( nActPos + nDir );
+ }
+ }
+ else
+ {
+ // Up/down with subpoints:
+ rSh.OutlineUpDown( bUp ? -1 : 1 );
+ }
+
+ rSh.ClearMark();
+ rSh.Pop(SwCursorShell::PopMode::DeleteCurrent);
+}
+
+void SwListShell::Execute(SfxRequest &rReq)
+{
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ const sal_uInt16 nSlot = rReq.GetSlot();
+ SwWrtShell& rSh = GetShell();
+
+ // #i35572#
+ const SwNumRule* pCurRule = rSh.GetNumRuleAtCurrCursorPos();
+ OSL_ENSURE( pCurRule, "SwListShell::Execute without NumRule" );
+ bool bOutline = pCurRule && pCurRule->IsOutlineRule();
+
+ switch (nSlot)
+ {
+ case FN_NUM_BULLET_DOWN:
+ case FN_NUM_BULLET_UP:
+ {
+ SfxViewFrame& rFrame = GetView().GetViewFrame();
+
+ rReq.Done();
+ rSh.NumUpDown( nSlot == FN_NUM_BULLET_DOWN );
+ rFrame.GetBindings().Invalidate( SID_TABLE_CELL ); // Update status line!
+ }
+ break;
+
+ case FN_NUM_BULLET_NEXT:
+ rSh.GotoNextNum();
+ rReq.Done();
+ break;
+
+ case FN_NUM_BULLET_NONUM:
+ rSh.NoNum();
+ rReq.Done();
+ break;
+
+ case FN_NUM_BULLET_OUTLINE_DOWN:
+ if ( bOutline )
+ lcl_OutlineUpDownWithSubPoints( rSh, false, false );
+ else
+ rSh.MoveNumParas(false, false);
+ rReq.Done();
+ break;
+
+ case FN_NUM_BULLET_OUTLINE_MOVEDOWN:
+ if ( bOutline )
+ lcl_OutlineUpDownWithSubPoints( rSh, true, false );
+ else
+ rSh.MoveNumParas(true, false);
+ rReq.Done();
+ break;
+
+ case FN_NUM_BULLET_OUTLINE_MOVEUP:
+ if ( bOutline )
+ lcl_OutlineUpDownWithSubPoints( rSh, true, true );
+ else
+ rSh.MoveNumParas(true, true);
+ rReq.Done();
+ break;
+
+ case FN_NUM_BULLET_OUTLINE_UP:
+ if ( bOutline )
+ lcl_OutlineUpDownWithSubPoints( rSh, false, true );
+ else
+ rSh.MoveNumParas(false, true);
+ rReq.Done();
+ break;
+
+ case FN_NUM_BULLET_PREV:
+ rSh.GotoPrevNum();
+ rReq.Done();
+ break;
+
+ case FN_NUM_OR_NONUM:
+ {
+ bool bApi = rReq.IsAPI();
+ bool bDelete = !rSh.IsNoNum(!bApi);
+ if(pArgs )
+ bDelete = static_cast<const SfxBoolItem &>(pArgs->Get(rReq.GetSlot())).GetValue();
+ rSh.NumOrNoNum( bDelete, !bApi );
+ rReq.AppendItem( SfxBoolItem( nSlot, bDelete ) );
+ rReq.Done();
+ }
+ break;
+ default:
+ OSL_ENSURE(false, "wrong dispatcher");
+ return;
+ }
+}
+
+void SwListShell::GetState(SfxItemSet &rSet)
+{
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ SwWrtShell& rSh = GetShell();
+ sal_uInt8 nCurrentNumLevel = rSh.GetNumLevel();
+ while ( nWhich )
+ {
+ switch( nWhich )
+ {
+ case FN_NUM_OR_NONUM:
+ rSet.Put(SfxBoolItem(nWhich, GetShell().IsNoNum(false)));
+ break;
+ case FN_NUM_BULLET_OUTLINE_UP:
+ case FN_NUM_BULLET_UP:
+ if(!nCurrentNumLevel)
+ rSet.DisableItem(nWhich);
+ break;
+ case FN_NUM_BULLET_OUTLINE_DOWN :
+ {
+ sal_uInt8 nUpper = 0;
+ sal_uInt8 nLower = 0;
+ rSh.GetCurrentOutlineLevels( nUpper, nLower );
+ if(nLower == (MAXLEVEL - 1))
+ rSet.DisableItem(nWhich);
+ }
+ break;
+ case FN_NUM_BULLET_DOWN:
+ if(nCurrentNumLevel == (MAXLEVEL - 1))
+ rSet.DisableItem(nWhich);
+ break;
+
+ case FN_NUM_BULLET_NONUM:
+ if ( rSh.CursorInsideInputField() )
+ {
+ rSet.DisableItem(nWhich);
+ }
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+SwListShell::SwListShell(SwView &_rView) :
+ SwBaseShell(_rView)
+{
+ SetName("List");
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/mediash.cxx b/sw/source/uibase/shells/mediash.cxx
new file mode 100644
index 0000000000..ab3628bfe1
--- /dev/null
+++ b/sw/source/uibase/shells/mediash.cxx
@@ -0,0 +1,99 @@
+/* -*- 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 <cmdid.h>
+#include <sfx2/request.hxx>
+#include <svx/svdview.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <mediash.hxx>
+
+#include <sfx2/objface.hxx>
+#include <vcl/EnumContext.hxx>
+#include <svx/MediaShellHelpers.hxx>
+
+#define ShellClass_SwMediaShell
+#include <swslots.hxx>
+
+using namespace svx;
+
+SFX_IMPL_INTERFACE(SwMediaShell, SwBaseShell)
+
+void SwMediaShell::InitInterface_Impl()
+{
+ GetStaticInterface()->RegisterPopupMenu("media");
+
+ GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Invisible,
+ ToolbarId::Media_Toolbox);
+}
+
+void SwMediaShell::ExecMedia(SfxRequest const& rReq)
+{
+ SwWrtShell* pSh = &GetShell();
+ SdrView* pSdrView = pSh->GetDrawView();
+
+ if (!pSdrView)
+ return;
+
+ const bool bChanged = pSdrView->GetModel().IsChanged();
+ pSdrView->GetModel().SetChanged(false);
+
+ switch (rReq.GetSlot())
+ {
+ case SID_DELETE:
+ if (pSh->IsObjSelected())
+ {
+ pSh->SetModified();
+ pSh->DelSelectedObj();
+
+ if (pSh->IsSelFrameMode())
+ pSh->LeaveSelFrameMode();
+
+ GetView().AttrChangedNotify(nullptr);
+ }
+ break;
+
+ case SID_AVMEDIA_TOOLBOX:
+ if (pSh->IsObjSelected())
+ MediaShellHelpers::Execute(pSdrView, rReq);
+ break;
+
+ default:
+ break;
+ }
+
+ if (pSdrView->GetModel().IsChanged())
+ GetShell().SetModified();
+ else if (bChanged)
+ pSdrView->GetModel().SetChanged();
+}
+
+void SwMediaShell::GetMediaState(SfxItemSet& rSet)
+{
+ MediaShellHelpers::GetState(GetShell().GetDrawView(), rSet);
+}
+
+SwMediaShell::SwMediaShell(SwView& _rView)
+ : SwBaseShell(_rView)
+{
+ SetName("Media Playback");
+ SfxShell::SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::Media));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/navsh.cxx b/sw/source/uibase/shells/navsh.cxx
new file mode 100644
index 0000000000..c34bebdbc7
--- /dev/null
+++ b/sw/source/uibase/shells/navsh.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/.
+ */
+
+#include <cmdid.h>
+#include <svx/svdview.hxx>
+#include <svl/whiter.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/objface.hxx>
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <navsh.hxx>
+#define ShellClass_SwNavigationShell
+#include <swslots.hxx>
+#include <navmgr.hxx>
+
+SFX_IMPL_INTERFACE(SwNavigationShell, SwBaseShell)
+
+void SwNavigationShell::InitInterface_Impl() {}
+
+SwNavigationShell::SwNavigationShell(SwView& _rView)
+ : SwBaseShell(_rView)
+{
+ SetName("Navigation");
+}
+
+void SwNavigationShell::Execute(SfxRequest const& rReq)
+{
+ SwWrtShell* pSh = &GetShell();
+ SdrView* pSdrView = pSh->GetDrawView();
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ const sal_uInt16 nSlotId = rReq.GetSlot();
+ bool bChanged = pSdrView->GetModel().IsChanged();
+ pSdrView->GetModel().SetChanged(false);
+ SwNavigationMgr& aSwNavigationMgr = pSh->GetNavigationMgr();
+ const SfxPoolItem* pItem;
+ if (pArgs)
+ pArgs->GetItemState(nSlotId, false, &pItem);
+
+ if (pSdrView->IsTextEdit())
+ pSh->EndTextEdit();
+ if (pSh->GetView().IsDrawMode())
+ pSh->GetView().LeaveDrawCreate();
+ pSh->EnterStdMode();
+
+ switch (nSlotId)
+ {
+ case FN_NAVIGATION_BACK:
+ aSwNavigationMgr.goBack();
+ break;
+
+ case FN_NAVIGATION_FORWARD:
+ aSwNavigationMgr.goForward();
+ break;
+ default:
+ break;
+ }
+ if (pSdrView->GetModel().IsChanged())
+ GetShell().SetModified();
+ else if (bChanged)
+ pSdrView->GetModel().SetChanged();
+}
+
+// determine if the buttons should be enabled/disabled
+
+void SwNavigationShell::GetState(SfxItemSet& rSet)
+{
+ SwWrtShell* pSh = &GetShell();
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ SwNavigationMgr& aNavigationMgr = pSh->GetNavigationMgr();
+ while (nWhich)
+ {
+ switch (nWhich)
+ {
+ case FN_NAVIGATION_BACK:
+ if (!aNavigationMgr.backEnabled())
+ {
+ rSet.DisableItem(FN_NAVIGATION_BACK);
+ }
+ break;
+ case FN_NAVIGATION_FORWARD:
+ if (!aNavigationMgr.forwardEnabled())
+ {
+ rSet.DisableItem(FN_NAVIGATION_FORWARD);
+ }
+ break;
+ default:
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/olesh.cxx b/sw/source/uibase/shells/olesh.cxx
new file mode 100644
index 0000000000..28e8e153ee
--- /dev/null
+++ b/sw/source/uibase/shells/olesh.cxx
@@ -0,0 +1,95 @@
+/* -*- 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 <sfx2/objface.hxx>
+#include <vcl/EnumContext.hxx>
+#include <view.hxx>
+#include <frmsh.hxx>
+#include <olesh.hxx>
+
+#include <sfx2/sidebar/SidebarController.hxx>
+
+#define ShellClass_SwOleShell
+#include <sfx2/msg.hxx>
+#include <swslots.hxx>
+
+using namespace css::uno;
+using namespace sfx2::sidebar;
+
+namespace {
+
+bool inChartOrMathContext(const SwView& rViewShell)
+{
+ SidebarController* pSidebar = SidebarController::GetSidebarControllerForView(&rViewShell);
+ if (pSidebar)
+ return pSidebar->hasChartOrMathContextCurrently();
+
+ return false;
+}
+
+} // anonymous namespace
+
+SFX_IMPL_INTERFACE(SwOleShell, SwFrameShell)
+
+void SwOleShell::InitInterface_Impl()
+{
+ GetStaticInterface()->RegisterPopupMenu("oleobject");
+
+ GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Invisible, ToolbarId::Ole_Toolbox);
+}
+
+void SwOleShell::Activate(bool bMDI)
+{
+ if(!inChartOrMathContext(GetView()))
+ SwFrameShell::Activate(bMDI);
+ else
+ {
+ // Avoid context changes for chart/math during activation / deactivation.
+ const bool bIsContextBroadcasterEnabled (SfxShell::SetContextBroadcasterEnabled(false));
+
+ SwFrameShell::Activate(bMDI);
+
+ SfxShell::SetContextBroadcasterEnabled(bIsContextBroadcasterEnabled);
+ }
+}
+
+void SwOleShell::Deactivate(bool bMDI)
+{
+ if(!inChartOrMathContext(GetView()))
+ SwFrameShell::Deactivate(bMDI);
+ else
+ {
+ // Avoid context changes for chart/math during activation / deactivation.
+ const bool bIsContextBroadcasterEnabled (SfxShell::SetContextBroadcasterEnabled(false));
+
+ SwFrameShell::Deactivate(bMDI);
+
+ SfxShell::SetContextBroadcasterEnabled(bIsContextBroadcasterEnabled);
+ }
+}
+
+SwOleShell::SwOleShell(SwView &_rView) :
+ SwFrameShell(_rView)
+
+{
+ SetName("Object");
+ SfxShell::SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::OLE));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/slotadd.cxx b/sw/source/uibase/shells/slotadd.cxx
new file mode 100644
index 0000000000..b8253ce75f
--- /dev/null
+++ b/sw/source/uibase/shells/slotadd.cxx
@@ -0,0 +1,134 @@
+/* -*- 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_options.h>
+
+#include <cmdid.h>
+#include <unomid.h>
+#include <svx/unomid.hxx>
+
+#include <svl/globalnameitem.hxx>
+#include <editeng/memberids.h>
+#include <svl/imageitm.hxx>
+#include <svl/rectitem.hxx>
+#include <sfx2/objitem.hxx>
+#include <sfx2/objsh.hxx>
+#include <svx/rulritem.hxx>
+#include <svx/statusitem.hxx>
+#include <sfx2/zoomitem.hxx>
+#include <svx/viewlayoutitem.hxx>
+#include <svx/zoomslideritem.hxx>
+#include <svx/hlnkitem.hxx>
+#include <svx/SmartTagItem.hxx>
+#include <svl/ptitem.hxx>
+#include <svx/pageitem.hxx>
+#include <svl/srchitem.hxx>
+#include <sfx2/tplpitem.hxx>
+#include <sfx2/watermarkitem.hxx>
+#include <editeng/wrlmitem.hxx>
+#include <editeng/protitem.hxx>
+#include <editeng/opaqitem.hxx>
+#include <editeng/tstpitem.hxx>
+#include <editeng/autokernitem.hxx>
+#include <editeng/keepitem.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/spltitem.hxx>
+#include <editeng/brushitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/shaditem.hxx>
+#include <editeng/pbinitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/prntitem.hxx>
+#include <editeng/orphitem.hxx>
+#include <editeng/widwitem.hxx>
+#include <editeng/lineitem.hxx>
+#include <editeng/pmdlitem.hxx>
+#include <editeng/cmapitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/formatbreakitem.hxx>
+#include <editeng/hyphenzoneitem.hxx>
+#include <editeng/escapementitem.hxx>
+#include <editeng/lspcitem.hxx>
+#include <editeng/adjustitem.hxx>
+#include <editeng/crossedoutitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/contouritem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <svx/sdmetitm.hxx>
+#include <svx/sdprcitm.hxx>
+#include <svx/xlnstit.hxx>
+#include <svx/xlnedit.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/xlineit0.hxx>
+#include <svx/xlnwtit.hxx>
+#include <svx/xlndsit.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xtextit0.hxx>
+#include <svx/xftadit.hxx>
+#include <svx/xftdiit.hxx>
+#include <svx/xftstit.hxx>
+#include <svx/xftmrit.hxx>
+#include <svx/xftouit.hxx>
+#include <svx/xftshit.hxx>
+#include <svx/xftshcit.hxx>
+#include <svx/xftshxy.hxx>
+#include <svx/grafctrl.hxx>
+
+#include <paratr.hxx>
+#include <fmtinfmt.hxx>
+#include <fmtsrnd.hxx>
+#include <envimg.hxx>
+#include <fmtline.hxx>
+#include <svx/clipfmtitem.hxx>
+#include <editeng/blinkitem.hxx>
+#include <svl/slstitm.hxx>
+#include <editeng/paravertalignitem.hxx>
+#include <editeng/charreliefitem.hxx>
+#include <editeng/charrotateitem.hxx>
+#include <editeng/charscaleitem.hxx>
+#include <svx/postattr.hxx>
+#include <sfx2/frame.hxx>
+#include <svx/chrtitem.hxx>
+#include <svx/drawitem.hxx>
+#include <avmedia/mediaitem.hxx>
+
+#define avmedia_MediaItem ::avmedia::MediaItem
+
+#include <svx/xflftrit.hxx>
+#include <svx/xlncapit.hxx>
+#include <svx/xlinjoit.hxx>
+#include <svx/galleryitem.hxx>
+#include <svx/sdangitm.hxx>
+
+#define SFX_TYPEMAP
+#include <sfx2/msg.hxx>
+#include <swslots.hxx>
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/tabsh.cxx b/sw/source/uibase/shells/tabsh.cxx
new file mode 100644
index 0000000000..87df4f059d
--- /dev/null
+++ b/sw/source/uibase/shells/tabsh.cxx
@@ -0,0 +1,1682 @@
+/* -*- 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 <svl/imageitm.hxx>
+#include <svl/numformat.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/stritem.hxx>
+#include <svl/whiter.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/brushitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/shaditem.hxx>
+#include <editeng/spltitem.hxx>
+#include <editeng/keepitem.hxx>
+#include <editeng/lineitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <svx/numinf.hxx>
+#include <svx/svddef.hxx>
+#include <svx/svxdlg.hxx>
+#include <sfx2/bindings.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <vcl/EnumContext.hxx>
+#include <o3tl/enumrange.hxx>
+#include <comphelper/lok.hxx>
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
+#include <editeng/itemtype.hxx>
+#include <osl/diagnose.h>
+
+#include <fmtornt.hxx>
+#include <fmtlsplt.hxx>
+#include <fmtrowsplt.hxx>
+#include <fmtfsize.hxx>
+#include <swmodule.hxx>
+#include <wrtsh.hxx>
+#include <rootfrm.hxx>
+#include <wview.hxx>
+#include <frmatr.hxx>
+#include <uitool.hxx>
+#include <inputwin.hxx>
+#include <uiitems.hxx>
+#include <tabsh.hxx>
+#include <swtablerep.hxx>
+#include <tablemgr.hxx>
+#include <cellatr.hxx>
+#include <frmfmt.hxx>
+#include <swundo.hxx>
+#include <swtable.hxx>
+#include <docsh.hxx>
+#include <tblsel.hxx>
+#include <viewopt.hxx>
+#include <tabfrm.hxx>
+
+#include <strings.hrc>
+#include <cmdid.h>
+#include <unobaseclass.hxx>
+
+#define ShellClass_SwTableShell
+#include <sfx2/msg.hxx>
+#include <swslots.hxx>
+
+#include <swabstdlg.hxx>
+
+#include <memory>
+
+using ::editeng::SvxBorderLine;
+using namespace ::com::sun::star;
+
+SFX_IMPL_INTERFACE(SwTableShell, SwBaseShell)
+
+void SwTableShell::InitInterface_Impl()
+{
+ GetStaticInterface()->RegisterPopupMenu("table");
+ GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Invisible, ToolbarId::Table_Toolbox);
+}
+
+
+const WhichRangesContainer aUITableAttrRange(svl::Items<
+ RES_LR_SPACE, RES_UL_SPACE,
+ RES_PAGEDESC, RES_BREAK,
+ RES_BACKGROUND, RES_BACKGROUND,
+ RES_BOX, RES_SHADOW,
+ RES_KEEP, RES_KEEP,
+ RES_LAYOUT_SPLIT, RES_LAYOUT_SPLIT,
+ RES_FRAMEDIR, RES_FRAMEDIR,
+ RES_ROW_SPLIT, RES_ROW_SPLIT,
+// #i29550#
+ RES_COLLAPSING_BORDERS, RES_COLLAPSING_BORDERS,
+// <-- collapsing borders
+ XATTR_FILL_FIRST, XATTR_FILL_LAST,
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_SHADOW,
+ SID_RULER_BORDERS, SID_RULER_BORDERS,
+ SID_ATTR_BRUSH_ROW, SID_ATTR_BRUSH_TABLE, // ??? This is very strange range
+// SID_BACKGRND_DESTINATION, SID_BACKGRND_DESTINATION, // included into above
+// SID_HTML_MODE, SID_HTML_MODE, // included into above
+ FN_TABLE_REP, FN_TABLE_REP,
+ FN_TABLE_SET_VERT_ALIGN, FN_TABLE_SET_VERT_ALIGN,
+ FN_TABLE_BOX_TEXTORIENTATION, FN_TABLE_BOX_TEXTORIENTATION,
+ FN_PARAM_TABLE_NAME, FN_PARAM_TABLE_NAME,
+ FN_PARAM_TABLE_HEADLINE, FN_PARAM_TABLE_HEADLINE
+>);
+
+const WhichRangesContainer& SwuiGetUITableAttrRange()
+{
+ return aUITableAttrRange;
+}
+
+static void lcl_SetAttr( SwWrtShell &rSh, const SfxPoolItem &rItem )
+{
+ SfxItemSet aSet( rSh.GetView().GetPool(), rItem.Which(), rItem.Which());
+ aSet.Put( rItem );
+ rSh.SetTableAttr( aSet );
+}
+
+static std::shared_ptr<SwTableRep> lcl_TableParamToItemSet( SfxItemSet& rSet, SwWrtShell &rSh )
+{
+ std::shared_ptr<SwTableRep> pRep;
+
+ SwFrameFormat *pFormat = rSh.GetTableFormat();
+ SwTabCols aCols;
+ rSh.GetTabCols( aCols );
+
+ //At first get the simple attributes.
+ rSet.Put( SfxStringItem( FN_PARAM_TABLE_NAME, pFormat->GetName()));
+ rSet.Put( SfxUInt16Item( FN_PARAM_TABLE_HEADLINE, rSh.GetRowsToRepeat() ) );
+ rSet.Put( pFormat->GetShadow() );
+ rSet.Put(SfxUInt16Item(FN_TABLE_SET_VERT_ALIGN, rSh.GetBoxAlign()));
+ rSet.Put( pFormat->GetFrameDir() );
+
+ SvxULSpaceItem aULSpace( pFormat->GetULSpace() );
+ rSet.Put( aULSpace );
+
+ const sal_uInt16 nBackgroundDestination = rSh.GetViewOptions()->GetTableDest();
+ rSet.Put(SfxUInt16Item(SID_BACKGRND_DESTINATION, nBackgroundDestination ));
+ std::unique_ptr<SvxBrushItem> aBrush(std::make_unique<SvxBrushItem>(RES_BACKGROUND));
+ if(rSh.GetRowBackground(aBrush))
+ {
+ aBrush->SetWhich(SID_ATTR_BRUSH_ROW);
+ rSet.Put( *aBrush );
+ }
+ else
+ rSet.InvalidateItem(SID_ATTR_BRUSH_ROW);
+ rSh.GetTabBackground(aBrush);
+ aBrush->SetWhich(SID_ATTR_BRUSH_TABLE);
+ rSet.Put( *aBrush );
+
+ // text direction in boxes
+ std::unique_ptr<SvxFrameDirectionItem> aBoxDirection(std::make_unique<SvxFrameDirectionItem>(SvxFrameDirection::Environment, RES_FRAMEDIR));
+ if(rSh.GetBoxDirection( aBoxDirection ))
+ {
+ aBoxDirection->SetWhich(FN_TABLE_BOX_TEXTORIENTATION);
+ rSet.Put(*aBoxDirection);
+ }
+
+ bool bSelectAll = rSh.StartsWith_() == SwCursorShell::StartsWith::Table && rSh.ExtendedSelectedAll();
+ bool bTableSel = rSh.IsTableMode() || bSelectAll;
+ if(!bTableSel)
+ {
+ rSh.StartAllAction();
+ rSh.Push();
+ rSh.GetView().GetViewFrame().GetDispatcher()->Execute( FN_TABLE_SELECT_ALL );
+ }
+ SvxBoxInfoItem aBoxInfo( SID_ATTR_BORDER_INNER );
+
+ // Table variant: If multiple table cells are selected.
+ rSh.GetCursor(); //Thus GetCursorCnt() returns the right thing
+ aBoxInfo.SetTable ((rSh.IsTableMode() && rSh.GetCursorCnt() > 1) ||
+ !bTableSel);
+ // Always show distance field.
+ aBoxInfo.SetDist (true);
+ // Set minimum size in tables and paragraphs.
+ aBoxInfo.SetMinDist( !bTableSel || rSh.IsTableMode() ||
+ rSh.GetSelectionType() &
+ (SelectionType::Text | SelectionType::Table));
+ // Always set the default spacing.
+ aBoxInfo.SetDefDist (MIN_BORDER_DIST);
+ // Individual lines can have DontCare status only in tables.
+ aBoxInfo.SetValid( SvxBoxInfoItemValidFlags::DISABLE, !bTableSel || !rSh.IsTableMode() );
+
+ rSet.Put(aBoxInfo);
+ rSh.GetTabBorders( rSet );
+
+ //row split
+ std::unique_ptr<SwFormatRowSplit> pSplit = rSh.GetRowSplit();
+ if(pSplit)
+ rSet.Put(std::move(pSplit));
+
+ if(!bTableSel)
+ {
+ rSh.ClearMark();
+ rSh.Pop(SwCursorShell::PopMode::DeleteCurrent);
+ rSh.EndAllAction();
+ }
+
+ SwTabCols aTabCols;
+ rSh.GetTabCols( aTabCols );
+
+ // Pointer will be deleted after the dialogue execution.
+ pRep = std::make_shared<SwTableRep>(aTabCols);
+ pRep->SetSpace(aCols.GetRightMax());
+
+ sal_uInt16 nPercent = 0;
+ auto nWidth = ::GetTableWidth(pFormat, aCols, &nPercent, &rSh );
+ // The table width is wrong for relative values.
+ if (nPercent)
+ nWidth = pRep->GetSpace() * nPercent / 100;
+ const sal_uInt16 nAlign = pFormat->GetHoriOrient().GetHoriOrient();
+ pRep->SetAlign(nAlign);
+ SvxLRSpaceItem aLRSpace( pFormat->GetLRSpace() );
+ SwTwips nLeft = aLRSpace.GetLeft();
+ SwTwips nRight = aLRSpace.GetRight();
+ SwTwips nDiff = pRep->GetSpace() - nRight - nLeft - nWidth;
+ if(nAlign != text::HoriOrientation::FULL && std::abs(nDiff) > 2)
+ {
+ SwTwips nLR = pRep->GetSpace() - nWidth;
+ switch ( nAlign )
+ {
+ case text::HoriOrientation::CENTER:
+ nLeft = nRight = nLR / 2;
+ break;
+ case text::HoriOrientation::LEFT:
+ nRight = nLR;
+ nLeft = 0;
+ break;
+ case text::HoriOrientation::RIGHT:
+ nLeft = nLR;
+ nRight = 0;
+ break;
+ case text::HoriOrientation::LEFT_AND_WIDTH:
+ nRight = nLR - nLeft;
+ break;
+ case text::HoriOrientation::NONE:
+ if(!nPercent)
+ nWidth = pRep->GetSpace() - nLeft - nRight;
+ break;
+ }
+ }
+ pRep->SetLeftSpace(nLeft);
+ pRep->SetRightSpace(nRight);
+
+ pRep->SetWidth(nWidth);
+ pRep->SetWidthPercent(nPercent);
+ // Are individual rows / cells are selected, the column processing will be changed.
+ pRep->SetLineSelected(bTableSel && ! rSh.HasWholeTabSelection());
+ rSet.Put(SwPtrItem(FN_TABLE_REP, pRep.get()));
+ return pRep;
+}
+
+void ItemSetToTableParam( const SfxItemSet& rSet,
+ SwWrtShell &rSh )
+{
+ rSh.StartAllAction();
+ rSh.StartUndo( SwUndoId::TABLE_ATTR );
+
+ if(const SfxUInt16Item* pDestItem = rSet.GetItemIfSet(SID_BACKGRND_DESTINATION, false))
+ {
+ SwViewOption aUsrPref( *rSh.GetViewOptions() );
+ aUsrPref.SetTableDest(static_cast<sal_uInt8>(pDestItem->GetValue()));
+ SW_MOD()->ApplyUsrPref(aUsrPref, &rSh.GetView());
+ }
+ bool bBorder = ( SfxItemState::SET == rSet.GetItemState( RES_BOX ) ||
+ SfxItemState::SET == rSet.GetItemState( SID_ATTR_BORDER_INNER ) );
+ const SvxBrushItem* pBackgroundItem = rSet.GetItemIfSet( RES_BACKGROUND, false );
+ const SvxBrushItem* pRowItem = rSet.GetItemIfSet( SID_ATTR_BRUSH_ROW, false );
+ const SvxBrushItem* pTableItem = rSet.GetItemIfSet( SID_ATTR_BRUSH_TABLE, false );
+ bool bBackground = pBackgroundItem || pRowItem || pTableItem;
+ const SwFormatRowSplit* pSplit = rSet.GetItemIfSet( RES_ROW_SPLIT, false );
+ bool bRowSplit = pSplit != nullptr;
+ const SvxFrameDirectionItem* pBoxDirection = rSet.GetItemIfSet( FN_TABLE_BOX_TEXTORIENTATION, false );
+ bool bBoxDirection = pBoxDirection != nullptr;
+ if( bBackground || bBorder || bRowSplit || bBoxDirection)
+ {
+ // The border will be applied to the present selection.
+ // If there is no selection, the table will be completely selected.
+ // The background will always be applied to the current state.
+ bool bTableSel = rSh.IsTableMode();
+ rSh.StartAllAction();
+
+ if(bBackground)
+ {
+ if(pBackgroundItem)
+ rSh.SetBoxBackground( *pBackgroundItem );
+ if(pRowItem)
+ {
+ std::unique_ptr<SvxBrushItem> aBrush(pRowItem->Clone());
+ aBrush->SetWhich(RES_BACKGROUND);
+ rSh.SetRowBackground(*aBrush);
+ }
+ if(pTableItem)
+ {
+ std::unique_ptr<SvxBrushItem> aBrush(pTableItem->Clone());
+ aBrush->SetWhich(RES_BACKGROUND);
+ rSh.SetTabBackground( *aBrush );
+ }
+ }
+
+ if(bBoxDirection)
+ {
+ SvxFrameDirectionItem aDirection( SvxFrameDirection::Environment, RES_FRAMEDIR );
+ aDirection.SetValue(pBoxDirection->GetValue());
+ rSh.SetBoxDirection(aDirection);
+ }
+
+ if(bBorder || bRowSplit)
+ {
+ rSh.Push();
+ if(!bTableSel)
+ {
+ rSh.GetView().GetViewFrame().GetDispatcher()->Execute( FN_TABLE_SELECT_ALL );
+ }
+ if(bBorder)
+ rSh.SetTabBorders( rSet );
+
+ if(bRowSplit)
+ {
+ rSh.SetRowSplit(*pSplit);
+ }
+
+ if(!bTableSel)
+ {
+ rSh.ClearMark();
+ }
+ rSh.Pop(SwCursorShell::PopMode::DeleteCurrent);
+ }
+
+ rSh.EndAllAction();
+ }
+
+ SwTabCols aTabCols;
+ bool bTabCols = false;
+ SwTableRep* pRep = nullptr;
+ SwFrameFormat *pFormat = rSh.GetTableFormat();
+ SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END-1> aSet( rSh.GetAttrPool() );
+ if(const SwPtrItem* pRepItem = rSet.GetItemIfSet( FN_TABLE_REP, false ))
+ {
+ pRep = static_cast<SwTableRep*>(pRepItem->GetValue());
+
+ const SwTwips nWidth = pRep->GetWidth();
+ if ( text::HoriOrientation::FULL == pRep->GetAlign() )
+ {
+ SwFormatHoriOrient aAttr( pFormat->GetHoriOrient() );
+ aAttr.SetHoriOrient( text::HoriOrientation::FULL );
+ aSet.Put( aAttr );
+ }
+ else
+ {
+ SwFormatFrameSize aSz( SwFrameSize::Variable, nWidth );
+ if(pRep->GetWidthPercent())
+ {
+ aSz.SetWidthPercent( static_cast<sal_uInt8>(pRep->GetWidthPercent()) );
+ }
+ aSet.Put(aSz);
+ }
+
+ SvxLRSpaceItem aLRSpace( RES_LR_SPACE );
+ aLRSpace.SetLeft(pRep->GetLeftSpace());
+ aLRSpace.SetRight(pRep->GetRightSpace());
+ aSet.Put( aLRSpace );
+
+ sal_Int16 eOrient = pRep->GetAlign();
+ SwFormatHoriOrient aAttr( 0, eOrient );
+ aSet.Put( aAttr );
+ // The item must only be recorded while manual alignment, so that the
+ // alignment is not overwritten by the distances while recording.
+ if(eOrient != text::HoriOrientation::NONE)
+ const_cast<SfxItemSet&>(rSet).ClearItem( SID_ATTR_LRSPACE );
+
+ if(pRep->HasColsChanged())
+ {
+ bTabCols = true;
+ }
+ }
+
+ if( const SfxUInt16Item* pHeadlineItem = rSet.GetItemIfSet( FN_PARAM_TABLE_HEADLINE, false ))
+ rSh.SetRowsToRepeat( pHeadlineItem->GetValue() );
+
+ if( const SfxUInt16Item* pAlignItem = rSet.GetItemIfSet( FN_TABLE_SET_VERT_ALIGN, false ))
+ rSh.SetBoxAlign(pAlignItem->GetValue());
+
+ if( const SfxStringItem* pNameItem = rSet.GetItemIfSet( FN_PARAM_TABLE_NAME, false ))
+ rSh.SetTableName( *pFormat, pNameItem->GetValue() );
+
+ // Copy the chosen attributes in the ItemSet.
+ static const sal_uInt16 aIds[] =
+ {
+ RES_PAGEDESC,
+ RES_BREAK,
+ RES_KEEP,
+ RES_LAYOUT_SPLIT,
+ RES_UL_SPACE,
+ RES_SHADOW,
+ RES_FRAMEDIR,
+ // #i29550#
+ RES_COLLAPSING_BORDERS,
+ // <-- collapsing borders
+ 0
+ };
+ const SfxPoolItem* pItem = nullptr;
+ for( const sal_uInt16* pIds = aIds; *pIds; ++pIds )
+ if( SfxItemState::SET == rSet.GetItemState( *pIds, false, &pItem))
+ aSet.Put( *pItem );
+
+ if(bTabCols)
+ {
+ rSh.GetTabCols( aTabCols );
+ bool bSingleLine = pRep->FillTabCols( aTabCols );
+ rSh.SetTabCols( aTabCols, bSingleLine );
+ }
+
+ if( aSet.Count() )
+ rSh.SetTableAttr( aSet );
+
+ rSh.EndUndo( SwUndoId::TABLE_ATTR );
+ rSh.EndAllAction();
+}
+
+static void lcl_TabGetMaxLineWidth(const SvxBorderLine* pBorderLine, SvxBorderLine& rBorderLine)
+{
+ if(pBorderLine->GetWidth() > rBorderLine.GetWidth())
+ rBorderLine.SetWidth(pBorderLine->GetWidth());
+
+ rBorderLine.SetBorderLineStyle(pBorderLine->GetBorderLineStyle());
+ rBorderLine.SetColor(pBorderLine->GetColor());
+}
+
+static bool lcl_BoxesInTrackedRows(SwWrtShell &rSh, const SwSelBoxes& rBoxes)
+{
+ // cursor and selection are there only in tracked rows
+ bool bRet = true;
+ SwRedlineTable::size_type nRedlinePos = 0;
+ if ( rBoxes.empty() )
+ bRet = rSh.GetCursor()->GetPointNode().GetTableBox()->GetUpper()->IsTracked(nRedlinePos);
+ else
+ {
+ tools::Long nBoxes = rBoxes.size();
+ SwTableLine* pPrevLine = nullptr;
+ for ( tools::Long i = 0; i < nBoxes; i++ )
+ {
+ SwTableLine* pLine = rBoxes[i]->GetUpper();
+ if ( pLine != pPrevLine )
+ bRet &= pLine->IsTracked(nRedlinePos);
+ pPrevLine = pLine;
+ }
+ }
+
+ return bRet;
+}
+
+static bool lcl_CursorInDeletedTable(SwWrtShell &rSh)
+{
+ // cursor and selection are there only in deleted table in Show Changes mode
+ if ( rSh.GetLayout()->IsHideRedlines() )
+ return false;
+
+ SwTableNode* pTableNd = rSh.GetCursor()->GetPoint()->GetNode().FindTableNode();
+ return pTableNd && pTableNd->GetTable().IsDeleted();
+}
+
+void SwTableShell::Execute(SfxRequest &rReq)
+{
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ SwWrtShell &rSh = GetShell();
+
+ // At first the slots which doesn't need a FrameMgr.
+ bool bMore = false;
+ const SfxPoolItem* pItem = nullptr;
+ sal_uInt16 nSlot = rReq.GetSlot();
+ if(pArgs)
+ pArgs->GetItemState(GetPool().GetWhich(nSlot), false, &pItem);
+ bool bCallDone = false;
+ switch ( nSlot )
+ {
+ case SID_ATTR_BORDER:
+ {
+ if(!pArgs)
+ break;
+ // Create items, because we have to rework anyway.
+ std::shared_ptr<SvxBoxItem> aBox(std::make_shared<SvxBoxItem>(RES_BOX));
+ SfxItemSetFixed<RES_BOX, RES_BOX,
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER>
+ aCoreSet( GetPool() );
+ SvxBoxInfoItem aCoreInfo( SID_ATTR_BORDER_INNER );
+ aCoreSet.Put(aCoreInfo);
+ rSh.GetTabBorders( aCoreSet );
+ const SvxBoxItem& rCoreBox = aCoreSet.Get(RES_BOX);
+ const SvxBoxItem *pBoxItem = pArgs->GetItemIfSet(RES_BOX);
+ if ( pBoxItem )
+ {
+ aBox.reset(pBoxItem->Clone());
+ sal_Int16 nDefValue = MIN_BORDER_DIST;
+ if ( !rReq.IsAPI() )
+ nDefValue = 55;
+ if (!rReq.IsAPI() || aBox->GetSmallestDistance() < MIN_BORDER_DIST)
+ {
+ for( SvxBoxItemLine k : o3tl::enumrange<SvxBoxItemLine>() )
+ aBox->SetDistance( std::max(rCoreBox.GetDistance(k), nDefValue) , k );
+ }
+ }
+ else
+ OSL_ENSURE( false, "where is BoxItem?" );
+
+ //since the drawing layer also supports borders the which id might be a different one
+ std::shared_ptr<SvxBoxInfoItem> aInfo(std::make_shared<SvxBoxInfoItem>(SID_ATTR_BORDER_INNER));
+ if (const SvxBoxInfoItem* pBoxInfoItem = pArgs->GetItemIfSet(SID_ATTR_BORDER_INNER))
+ {
+ aInfo.reset(pBoxInfoItem->Clone());
+ }
+ else if( const SvxBoxInfoItem* pBoxInfoInnerItem = pArgs->GetItemIfSet(SDRATTR_TABLE_BORDER_INNER))
+ {
+ aInfo.reset(pBoxInfoInnerItem->Clone());
+ aInfo->SetWhich(SID_ATTR_BORDER_INNER);
+ }
+
+ aInfo->SetTable( true );
+ aInfo->SetValid( SvxBoxInfoItemValidFlags::DISABLE, false );
+
+// The attributes of all lines will be read and the strongest wins.
+ const SvxBorderLine* pBorderLine;
+ SvxBorderLine aBorderLine;
+ if ((pBorderLine = rCoreBox.GetTop()) != nullptr)
+ lcl_TabGetMaxLineWidth(pBorderLine, aBorderLine);
+ if ((pBorderLine = rCoreBox.GetBottom()) != nullptr)
+ lcl_TabGetMaxLineWidth(pBorderLine, aBorderLine);
+ if ((pBorderLine = rCoreBox.GetLeft()) != nullptr)
+ lcl_TabGetMaxLineWidth(pBorderLine, aBorderLine);
+ if ((pBorderLine = rCoreBox.GetRight()) != nullptr)
+ lcl_TabGetMaxLineWidth(pBorderLine, aBorderLine);
+ if ((pBorderLine = aCoreInfo.GetHori()) != nullptr)
+ lcl_TabGetMaxLineWidth(pBorderLine, aBorderLine);
+ if ((pBorderLine = aCoreInfo.GetVert()) != nullptr)
+ lcl_TabGetMaxLineWidth(pBorderLine, aBorderLine);
+
+ if(aBorderLine.GetOutWidth() == 0)
+ {
+ aBorderLine.SetBorderLineStyle(SvxBorderLineStyle::SOLID);
+ aBorderLine.SetWidth( SvxBorderLineWidth::VeryThin );
+ }
+
+ if( aBox->GetTop() != nullptr )
+ {
+ aBox->SetLine(&aBorderLine, SvxBoxItemLine::TOP);
+ }
+ if( aBox->GetBottom() != nullptr )
+ {
+ aBox->SetLine(&aBorderLine, SvxBoxItemLine::BOTTOM);
+ }
+ if( aBox->GetLeft() != nullptr )
+ {
+ aBox->SetLine(&aBorderLine, SvxBoxItemLine::LEFT);
+ }
+ if( aBox->GetRight() != nullptr )
+ {
+ aBox->SetLine(&aBorderLine, SvxBoxItemLine::RIGHT);
+ }
+ if( aInfo->GetHori() != nullptr )
+ {
+ aInfo->SetLine(&aBorderLine, SvxBoxInfoItemLine::HORI);
+ }
+ if( aInfo->GetVert() != nullptr )
+ {
+ aInfo->SetLine(&aBorderLine, SvxBoxInfoItemLine::VERT);
+ }
+
+ aCoreSet.Put( *aBox );
+ aCoreSet.Put( *aInfo );
+ rSh.SetTabBorders( aCoreSet );
+
+ // we must record the "real" values because otherwise the lines can't be reconstructed on playtime
+ // the coding style of the controller (setting lines with width 0) is not transportable via Query/PutValue in
+ // the SvxBoxItem
+ rReq.AppendItem( *aBox );
+ rReq.AppendItem( *aInfo );
+ bCallDone = true;
+ break;
+ }
+ case FN_INSERT_TABLE:
+ InsertTable( rReq );
+ break;
+ case FN_FORMAT_TABLE_DLG:
+ {
+ //#127012# get the bindings before the dialog is called
+ // it might happen that this shell is removed after closing the dialog
+ SfxBindings& rBindings = GetView().GetViewFrame().GetBindings();
+ SfxItemSet aCoreSet( GetPool(), aUITableAttrRange);
+
+ FieldUnit eMetric = ::GetDfltMetric(dynamic_cast<SwWebView*>( &rSh.GetView()) != nullptr );
+ SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)));
+ std::shared_ptr<SwTableRep> pTableRep(::lcl_TableParamToItemSet(aCoreSet, rSh));
+
+ aCoreSet.Put(SfxUInt16Item(SID_HTML_MODE, ::GetHtmlMode(GetView().GetDocShell())));
+ rSh.GetTableAttr(aCoreSet);
+ // GetTableAttr overwrites the background!
+ std::unique_ptr<SvxBrushItem> aBrush(std::make_unique<SvxBrushItem>(RES_BACKGROUND));
+ if(rSh.GetBoxBackground(aBrush))
+ aCoreSet.Put( *aBrush );
+ else
+ aCoreSet.InvalidateItem( RES_BACKGROUND );
+
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ VclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateSwTableTabDlg(GetView().GetFrameWeld(), &aCoreSet, &rSh));
+
+ if (pDlg)
+ {
+ if (pItem)
+ pDlg->SetCurPageId(static_cast<const SfxStringItem *>(pItem)->GetValue());
+
+ auto pRequest = std::make_shared<SfxRequest>(rReq);
+ rReq.Ignore(); // the 'old' request is not relevant any more
+
+ const bool bTableMode = rSh.IsTableMode();
+ SwPaM* pCursor = bTableMode ? rSh.GetTableCrs() : rSh.GetCursor(); // tdf#142165 use table cursor if in table mode
+ auto vCursors = CopyPaMRing(*pCursor); // tdf#135636 make a copy to use at later apply
+ pDlg->StartExecuteAsync([pDlg, pRequest, pTableRep, &rBindings, &rSh, vCursors, bTableMode](sal_Int32 nResult){
+ if (RET_OK == nResult)
+ {
+ if (!bTableMode && rSh.IsTableMode()) // tdf#140977 drop current table-cursor if setting a replacement
+ rSh.TableCursorToCursor(); // non-table one
+
+ // tdf#135636 set the selection at dialog launch as current selection
+ rSh.SetSelection(*vCursors->front()); // UpdateCursor() will be called which in the case
+ // of a table selection should recreate a
+ // SwShellTableCursor if the selection is more than a single cell
+
+ if (bTableMode && !rSh.IsTableMode()) // tdf#142721 ensure the new selection is a SwShellTableCursor in
+ rSh.SelTableBox(); // the case of a single cell
+
+ const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
+
+ //to record FN_INSERT_TABLE correctly
+ pRequest->SetSlot(FN_FORMAT_TABLE_DLG);
+ pRequest->Done(*pOutSet);
+
+ ItemSetToTableParam(*pOutSet, rSh);
+ }
+
+ rBindings.Update(SID_RULER_BORDERS);
+ rBindings.Update(SID_ATTR_TABSTOP);
+ rBindings.Update(SID_RULER_BORDERS_VERTICAL);
+ rBindings.Update(SID_ATTR_TABSTOP_VERTICAL);
+
+ pDlg->disposeOnce();
+ });
+ }
+ else
+ {
+ if (rReq.GetArgs())
+ ItemSetToTableParam(*rReq.GetArgs(), rSh);
+
+ rBindings.Update(SID_RULER_BORDERS);
+ rBindings.Update(SID_ATTR_TABSTOP);
+ rBindings.Update(SID_RULER_BORDERS_VERTICAL);
+ rBindings.Update(SID_ATTR_TABSTOP_VERTICAL);
+ }
+
+ break;
+ }
+ case SID_ATTR_BRUSH:
+ case SID_ATTR_BRUSH_ROW :
+ case SID_ATTR_BRUSH_TABLE :
+ if(rReq.GetArgs())
+ ItemSetToTableParam(*rReq.GetArgs(), rSh);
+ break;
+ case FN_NUM_FORMAT_TABLE_DLG:
+ {
+ if (SwView* pView = GetActiveView())
+ {
+ FieldUnit eMetric = ::GetDfltMetric(dynamic_cast<SwWebView*>( pView) != nullptr );
+ SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)));
+ SvNumberFormatter* pFormatter = rSh.GetNumberFormatter();
+ auto pCoreSet = std::make_shared<SfxItemSetFixed<SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_INFO>>( GetPool() );
+
+ SfxItemSetFixed<RES_BOXATR_FORMAT, RES_BOXATR_FORMAT,
+ RES_BOXATR_VALUE, RES_BOXATR_VALUE>
+ aBoxSet( *pCoreSet->GetPool() );
+ rSh.GetTableBoxFormulaAttrs( aBoxSet );
+
+ SfxItemState eState = aBoxSet.GetItemState(RES_BOXATR_FORMAT);
+ if(eState == SfxItemState::DEFAULT)
+ {
+ pCoreSet->Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE,
+ pFormatter->GetFormatIndex(NF_TEXT, LANGUAGE_SYSTEM)));
+ }
+ else
+ pCoreSet->Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE,
+ aBoxSet.Get(
+ RES_BOXATR_FORMAT ).GetValue() ));
+
+ pCoreSet->Put( SvxNumberInfoItem( pFormatter,
+ aBoxSet.Get(
+ RES_BOXATR_VALUE).GetValue(),
+ rSh.GetTableBoxText(), SID_ATTR_NUMBERFORMAT_INFO ));
+
+ SwWrtShell* pSh = &rSh;
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ VclPtr<SfxAbstractDialog> pDlg(pFact->CreateNumFormatDialog(GetView().GetFrameWeld(), *pCoreSet));
+
+ pDlg->StartExecuteAsync([pDlg, pCoreSet, pSh](sal_uInt32 nResult){
+ if (RET_OK == nResult)
+ {
+ const SvxNumberInfoItem* pNumberFormatItem
+ = pSh->GetView().GetDocShell()->GetItem( SID_ATTR_NUMBERFORMAT_INFO );
+
+ if( pNumberFormatItem )
+ {
+ for ( sal_uInt32 key : pNumberFormatItem->GetDelFormats() )
+ pNumberFormatItem->GetNumberFormatter()->DeleteEntry( key );
+ }
+
+ const SfxPoolItem* pNumberFormatValueItem =
+ pDlg->GetOutputItemSet()->GetItemIfSet(
+ SID_ATTR_NUMBERFORMAT_VALUE, false);
+ if( pNumberFormatValueItem )
+ {
+ SfxItemSetFixed<RES_BOXATR_FORMAT, RES_BOXATR_FORMAT>
+ aBoxFormatSet( *pCoreSet->GetPool() );
+ aBoxFormatSet.Put( SwTableBoxNumFormat(
+ static_cast<const SfxUInt32Item*>(pNumberFormatValueItem)->GetValue() ));
+ pSh->SetTableBoxFormulaAttrs( aBoxFormatSet );
+
+ }
+ }
+
+ pDlg->disposeOnce();
+ });
+ }
+ break;
+ }
+ case FN_CALC_TABLE:
+ rSh.UpdateTable();
+ bCallDone = true;
+ break;
+ case FN_TABLE_DELETE_COL:
+ if ( rSh.DeleteCol() && rSh.HasSelection() )
+ rSh.EnterStdMode();
+ bCallDone = true;
+ break;
+ case FN_END_TABLE:
+ rSh.MoveTable( GotoCurrTable, fnTableEnd );
+ bCallDone = true;
+ break;
+ case FN_START_TABLE:
+ rSh.MoveTable( GotoCurrTable, fnTableStart );
+ bCallDone = true;
+ break;
+ case FN_GOTO_NEXT_CELL:
+ {
+ bool bAppendLine = true;
+ if( pItem )
+ bAppendLine = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ rReq.SetReturnValue( SfxBoolItem( nSlot,
+ rSh.GoNextCell( bAppendLine ) ) );
+ bCallDone = true;
+ break;
+ }
+ case FN_GOTO_PREV_CELL:
+ rReq.SetReturnValue( SfxBoolItem( nSlot, rSh.GoPrevCell() ) );
+ bCallDone = true;
+ break;
+ case FN_TABLE_DELETE_ROW:
+ if ( rSh.DeleteRow() && rSh.HasSelection() )
+ rSh.EnterStdMode();
+ bCallDone = true;
+ break;
+ case FN_TABLE_MERGE_CELLS:
+ if ( rSh.IsTableMode() )
+ switch ( rSh.MergeTab() )
+ {
+ case TableMergeErr::Ok:
+ bCallDone = true;
+ [[fallthrough]];
+ case TableMergeErr::NoSelection:
+ break;
+ case TableMergeErr::TooComplex:
+ {
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(GetView().GetFrameWeld(),
+ VclMessageType::Info, VclButtonsType::Ok,
+ SwResId(STR_ERR_TABLE_MERGE)));
+ xInfoBox->run();
+ break;
+ }
+ default:
+ OSL_ENSURE( false, "unknown return value MergeTab.");
+ break;
+ }
+ break;
+ case SID_TABLE_MINIMAL_COLUMN_WIDTH:
+ case FN_TABLE_ADJUST_CELLS:
+ case FN_TABLE_BALANCE_CELLS:
+ {
+ bool bBalance = (FN_TABLE_BALANCE_CELLS == nSlot);
+ const bool bNoShrink = FN_TABLE_ADJUST_CELLS == nSlot;
+ if ( rSh.IsAdjustCellWidthAllowed(bBalance) )
+ {
+ {
+ // remove actions to make a valid table selection
+ UnoActionRemoveContext aRemoveContext(rSh.GetDoc());
+ }
+ rSh.AdjustCellWidth(bBalance, bNoShrink);
+ }
+ bCallDone = true;
+ break;
+ }
+ case SID_TABLE_MINIMAL_ROW_HEIGHT:
+ {
+ const SwFormatFrameSize aSz;
+ rSh.SetRowHeight( aSz );
+ bCallDone = true;
+ break;
+ }
+ case FN_TABLE_OPTIMAL_HEIGHT:
+ {
+ rSh.BalanceRowHeight(/*bTstOnly=*/false, /*bOptimize=*/true);
+ rSh.BalanceRowHeight(/*bTstOnly=*/false, /*bOptimize=*/false);
+ bCallDone = true;
+ break;
+ }
+ case FN_TABLE_BALANCE_ROWS:
+ if ( rSh.BalanceRowHeight(true) )
+ rSh.BalanceRowHeight(false);
+ bCallDone = true;
+ break;
+ case FN_TABLE_SELECT_ALL:
+ rSh.EnterStdMode();
+ rSh.MoveTable( GotoCurrTable, fnTableStart );
+ rSh.SttSelect();
+ rSh.MoveTable( GotoCurrTable, fnTableEnd );
+ rSh.EndSelect();
+ bCallDone = true;
+ break;
+ case FN_TABLE_SELECT_COL:
+ rSh.EnterStdMode();
+ rSh.SelectTableCol();
+ bCallDone = true;
+ break;
+ case FN_TABLE_SELECT_ROW:
+ rSh.EnterStdMode();
+ rSh.SelectTableRow();
+ bCallDone = true;
+ break;
+ case FN_TABLE_SET_READ_ONLY_CELLS:
+ rSh.ProtectCells();
+ rSh.ResetSelect( nullptr, false );
+ bCallDone = true;
+ break;
+ case FN_TABLE_UNSET_READ_ONLY_CELLS:
+ rSh.UnProtectCells();
+ bCallDone = true;
+ break;
+ case SID_AUTOFORMAT:
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSwAutoFormatDlg> pDlg(pFact->CreateSwAutoFormatDlg(GetView().GetFrameWeld(), &rSh));
+ pDlg->Execute();
+ break;
+ }
+ case FN_TABLE_SET_ROW_HEIGHT:
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSwTableHeightDialog(GetView().GetFrameWeld(), rSh));
+ pDlg->Execute();
+ break;
+ }
+ case FN_NUMBER_BULLETS:
+ case FN_NUM_BULLET_ON:
+ OSL_ENSURE( false, "function may not be called now." );
+ break;
+
+
+ // 2015/06 The following two are deprecated but kept for ascending
+ // compatibility
+ case FN_TABLE_INSERT_COL:
+ case FN_TABLE_INSERT_ROW:
+ // fallback
+ case FN_TABLE_INSERT_COL_BEFORE:
+ case FN_TABLE_INSERT_ROW_BEFORE:
+ case FN_TABLE_INSERT_COL_AFTER:
+ case FN_TABLE_INSERT_ROW_AFTER:
+ {
+ bool bColumn = rReq.GetSlot() == FN_TABLE_INSERT_COL_BEFORE
+ || rReq.GetSlot() == FN_TABLE_INSERT_COL_AFTER
+ || rReq.GetSlot() == FN_TABLE_INSERT_COL;
+ sal_uInt16 nCount = 0;
+ bool bAfter = true;
+ if (pItem)
+ {
+ nCount = static_cast<const SfxInt16Item* >(pItem)->GetValue();
+ if(const SfxBoolItem* pAfterItem = pArgs->GetItemIfSet(FN_PARAM_INSERT_AFTER))
+ bAfter = pAfterItem->GetValue();
+ }
+ else if( !rReq.IsAPI() )
+ {
+ SwSelBoxes aBoxes;
+ ::GetTableSel( rSh, aBoxes );
+ if ( !aBoxes.empty() )
+ {
+ tools::Long maxX = 0;
+ tools::Long maxY = 0;
+ tools::Long minX = std::numeric_limits<tools::Long>::max();
+ tools::Long minY = std::numeric_limits<tools::Long>::max();
+ tools::Long nbBoxes = aBoxes.size();
+ for ( tools::Long i = 0; i < nbBoxes; i++ )
+ {
+ Point aCoord ( aBoxes[i]->GetCoordinates() );
+ if ( aCoord.X() < minX ) minX = aCoord.X();
+ if ( aCoord.X() > maxX ) maxX = aCoord.X();
+ if ( aCoord.Y() < minY ) minY = aCoord.Y();
+ if ( aCoord.Y() > maxY ) maxY = aCoord.Y();
+ }
+ if (bColumn)
+ nCount = maxX - minX + 1;
+ else
+ nCount = maxY - minY + 1;
+ }
+ bAfter = rReq.GetSlot() == FN_TABLE_INSERT_COL_AFTER
+ || rReq.GetSlot() == FN_TABLE_INSERT_ROW_AFTER
+ || rReq.GetSlot() == FN_TABLE_INSERT_ROW
+ || rReq.GetSlot() == FN_TABLE_INSERT_COL;
+ }
+
+ if( nCount )
+ {
+ // i74180: Table border patch submitted by chensuchun:
+ // -->get the SvxBoxInfoItem of the table before insert
+ SfxItemSet aCoreSet( GetPool(), aUITableAttrRange);
+ ::lcl_TableParamToItemSet( aCoreSet, rSh );
+ bool bSetInnerBorders = false;
+ SwUndoId nUndoId = SwUndoId::EMPTY;
+ // <--End
+
+ if( bColumn )
+ {
+ rSh.StartUndo( SwUndoId::TABLE_INSCOL );
+ rSh.InsertCol( nCount, bAfter );
+ bSetInnerBorders = true;
+ nUndoId = SwUndoId::TABLE_INSCOL;
+ }
+ else if ( !rSh.IsInRepeatedHeadline() )
+ {
+ rSh.StartUndo( SwUndoId::TABLE_INSROW );
+ rSh.InsertRow( nCount, bAfter );
+ bSetInnerBorders = true;
+ nUndoId = SwUndoId::TABLE_INSROW;
+ }
+
+ // -->after inserting,reset the inner table borders
+ if ( bSetInnerBorders )
+ {
+ const SvxBoxInfoItem& aBoxInfo(aCoreSet.Get(SID_ATTR_BORDER_INNER));
+ SfxItemSetFixed<SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER> aSet( GetPool() );
+ aSet.Put( aBoxInfo );
+ ItemSetToTableParam( aSet, rSh );
+ rSh.EndUndo( nUndoId );
+ }
+
+ bCallDone = true;
+ break;
+ }
+
+ nSlot = bColumn ? FN_TABLE_INSERT_COL_DLG : FN_TABLE_INSERT_ROW_DLG;
+
+ [[fallthrough]]; // on Count = 0 appears the dialog
+ }
+ case FN_TABLE_INSERT_COL_DLG:
+ case FN_TABLE_INSERT_ROW_DLG:
+ {
+ const SfxSlot* pSlot = GetStaticInterface()->GetSlot(nSlot);
+ if ( FN_TABLE_INSERT_ROW_DLG != nSlot || !rSh.IsInRepeatedHeadline())
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<SvxAbstractInsRowColDlg> pDlg(pFact->CreateSvxInsRowColDlg(GetView().GetFrameWeld(),
+ nSlot == FN_TABLE_INSERT_COL_DLG, pSlot->GetCommand()));
+ if( pDlg->Execute() == 1 )
+ {
+ const TypedWhichId<SfxUInt16Item> nDispatchSlot = (nSlot == FN_TABLE_INSERT_COL_DLG)
+ ? FN_TABLE_INSERT_COL_AFTER : FN_TABLE_INSERT_ROW_AFTER;
+ SfxUInt16Item aCountItem( nDispatchSlot, pDlg->getInsertCount() );
+ SfxBoolItem aAfter( FN_PARAM_INSERT_AFTER, !pDlg->isInsertBefore() );
+ SfxViewFrame& rVFrame = GetView().GetViewFrame();
+ rVFrame.GetDispatcher()->ExecuteList(nDispatchSlot,
+ SfxCallMode::SYNCHRON|SfxCallMode::RECORD,
+ { &aCountItem, &aAfter });
+ }
+ }
+ break;
+ }
+ case FN_TABLE_SPLIT_CELLS:
+ {
+ tools::Long nCount=0;
+ bool bHorizontal=true;
+ bool bProportional = false;
+ const SfxInt32Item* pSplit = rReq.GetArg<SfxInt32Item>(FN_TABLE_SPLIT_CELLS);
+ const SfxBoolItem* pHor = rReq.GetArg<SfxBoolItem>(FN_PARAM_1);
+ const SfxBoolItem* pProp = rReq.GetArg<SfxBoolItem>(FN_PARAM_2);
+ if ( pSplit )
+ {
+ nCount = pSplit->GetValue();
+ if ( pHor )
+ bHorizontal = pHor->GetValue();
+ if ( pProp )
+ bProportional = pProp->GetValue();
+ }
+ else
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ SwWrtShell* pSh = &rSh;
+ const tools::Long nMaxVert = rSh.GetAnyCurRect( CurRectType::Frame ).Width() / MINLAY;
+ VclPtr<SvxAbstractSplitTableDialog> pDlg(pFact->CreateSvxSplitTableDialog(GetView().GetFrameWeld(), rSh.IsTableVertical(), nMaxVert));
+ if(rSh.IsSplitVerticalByDefault())
+ pDlg->SetSplitVerticalByDefault();
+ pDlg->StartExecuteAsync([pDlg, pSh](int nResult) {
+ if (nResult == RET_OK)
+ {
+ tools::Long nCount2 = pDlg->GetCount();
+ bool bHorizontal2 = pDlg->IsHorizontal();
+ bool bProportional2 = pDlg->IsProportional();
+
+ // tdf#60242: remember choice for next time
+ bool bVerticalWasChecked = !pDlg->IsHorizontal();
+ pSh->SetSplitVerticalByDefault(bVerticalWasChecked);
+
+ if ( nCount2 > 1 )
+ pSh->SplitTab(!bHorizontal2, static_cast< sal_uInt16 >( nCount2-1 ), bProportional2 );
+ }
+
+ pDlg->disposeOnce();
+ });
+ }
+
+ if ( nCount>1 )
+ {
+ rSh.SplitTab(!bHorizontal, static_cast< sal_uInt16 >( nCount-1 ), bProportional );
+ bCallDone = true;
+ }
+ else
+ rReq.Ignore();
+ break;
+ }
+
+ case FN_TABLE_SPLIT_TABLE:
+ {
+ const SfxUInt16Item* pType = rReq.GetArg<SfxUInt16Item>(FN_PARAM_1);
+ if( pType )
+ {
+ switch( static_cast<SplitTable_HeadlineOption>(pType->GetValue()) )
+ {
+ case SplitTable_HeadlineOption::NONE :
+ case SplitTable_HeadlineOption::BorderCopy:
+ case SplitTable_HeadlineOption::ContentCopy:
+ case SplitTable_HeadlineOption::BoxAttrCopy:
+ case SplitTable_HeadlineOption::BoxAttrAllCopy:
+ rSh.SplitTable(static_cast<SplitTable_HeadlineOption>(pType->GetValue())) ;
+ break;
+ default: ;//wrong parameter, do nothing
+ }
+ }
+ else
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ VclPtr<AbstractSplitTableDialog> pDlg(pFact->CreateSplitTableDialog(GetView().GetFrameWeld(), rSh));
+
+ SwWrtShell* pSh = &rSh;
+
+ pDlg->StartExecuteAsync([pDlg, pSh](int nResult) {
+ if (nResult == RET_OK)
+ {
+ const auto aSplitMode = pDlg->GetSplitMode();
+ pSh->SplitTable( aSplitMode );
+ }
+
+ pDlg->disposeOnce();
+ });
+ rReq.Ignore(); // We're already handling the request in our async bit
+ }
+ break;
+ }
+
+ case FN_TABLE_MERGE_TABLE:
+ {
+ bool bPrev = rSh.CanMergeTable();
+ bool bNext = rSh.CanMergeTable( false );
+
+ if( bPrev && bNext )
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateTableMergeDialog(GetView().GetFrameWeld(), bPrev));
+ if( RET_OK != pDlg->Execute())
+ bPrev = bNext = false;
+ }
+
+ if( bPrev || bNext )
+ rSh.MergeTable( bPrev );
+ break;
+ }
+
+ case FN_TABLE_MODE_FIX :
+ case FN_TABLE_MODE_FIX_PROP :
+ case FN_TABLE_MODE_VARIABLE :
+ {
+ rSh.SetTableChgMode( FN_TABLE_MODE_FIX == nSlot
+ ? TableChgMode::FixedWidthChangeAbs
+ : FN_TABLE_MODE_FIX_PROP == nSlot
+ ? TableChgMode::FixedWidthChangeProp
+ : TableChgMode::VarWidthChangeAbs );
+
+ SfxBindings& rBind = GetView().GetViewFrame().GetBindings();
+ static sal_uInt16 aInva[] =
+ { FN_TABLE_MODE_FIX,
+ FN_TABLE_MODE_FIX_PROP,
+ FN_TABLE_MODE_VARIABLE,
+ 0
+ };
+ rBind.Invalidate( aInva );
+ bCallDone = true;
+ break;
+ }
+ case FN_TABLE_AUTOSUM:
+ {
+ SfxViewFrame& rVFrame = GetView().GetViewFrame();
+ rVFrame.GetDispatcher()->Execute(FN_EDIT_FORMULA, SfxCallMode::SYNCHRON);
+ const sal_uInt16 nId = SwInputChild::GetChildWindowId();
+ SwInputChild* pChildWin = static_cast<SwInputChild*>(rVFrame.
+ GetChildWindow( nId ));
+ OUString sSum;
+ GetShell().GetAutoSum(sSum);
+ if( pChildWin )
+ pChildWin->SetFormula( sSum );
+
+ break;
+ }
+ case FN_TABLE_HEADLINE_REPEAT:
+ if(0 != rSh.GetRowsToRepeat())
+ rSh.SetRowsToRepeat( 0 );
+ else
+ rSh.SetRowsToRepeat(rSh.GetRowSelectionFromTop());
+ break;
+ case FN_TABLE_SELECT_CELL :
+ rSh.SelectTableCell();
+ break;
+ case FN_TABLE_DELETE_TABLE :
+ {
+ rSh.StartAction();
+ rSh.StartUndo();
+ rSh.GetView().GetViewFrame().GetDispatcher()->Execute(FN_TABLE_SELECT_ALL);
+ rSh.DeleteTable();
+ rSh.EndUndo();
+ rSh.EndAction();
+ //'this' is already destroyed
+ return;
+ }
+ case SID_ATTR_TABLE_ROW_HEIGHT:
+ {
+ const SfxUInt32Item* pItem2 = rReq.GetArg<SfxUInt32Item>(SID_ATTR_TABLE_ROW_HEIGHT);
+ if (pItem2)
+ {
+ tools::Long nNewHeight = pItem2->GetValue();
+ std::unique_ptr<SwFormatFrameSize> pHeight = rSh.GetRowHeight();
+ if ( pHeight )
+ {
+ if (pHeight->GetHeightSizeType() == SwFrameSize::Variable)
+ pHeight->SetHeightSizeType(SwFrameSize::Minimum);
+ pHeight->SetHeight(nNewHeight);
+ rSh.SetRowHeight(*pHeight);
+ }
+ }
+ return;
+ }
+ case SID_ATTR_TABLE_COLUMN_WIDTH:
+ {
+ const SfxUInt32Item* pItem2 = rReq.GetArg<SfxUInt32Item>(SID_ATTR_TABLE_COLUMN_WIDTH);
+ if (pItem2)
+ {
+ tools::Long nNewWidth = pItem2->GetValue();
+ SwTableFUNC aFunc( &rSh );
+ aFunc.InitTabCols();
+ aFunc.SetColWidth(aFunc.GetCurColNum(), nNewWidth);
+ }
+ return;
+ }
+ default:
+ bMore = true;
+ }
+
+ if ( !bMore )
+ {
+ if(bCallDone)
+ rReq.Done();
+ return;
+ }
+
+ // Now the slots which are working directly on the TableFormat.
+ switch ( nSlot )
+ {
+ case SID_ATTR_ULSPACE:
+ if(pItem)
+ {
+ SvxULSpaceItem aULSpace( *static_cast<const SvxULSpaceItem*>(pItem) );
+ aULSpace.SetWhich( RES_UL_SPACE );
+ ::lcl_SetAttr( rSh, aULSpace );
+ }
+ break;
+
+ case SID_ATTR_LRSPACE:
+ if(pItem)
+ {
+ SfxItemSetFixed<RES_LR_SPACE, RES_LR_SPACE,
+ RES_HORI_ORIENT, RES_HORI_ORIENT> aSet( GetPool() );
+ SvxLRSpaceItem aLRSpace( *static_cast<const SvxLRSpaceItem*>(pItem) );
+ aLRSpace.SetWhich( RES_LR_SPACE );
+ aSet.Put( aLRSpace );
+ rSh.SetTableAttr( aSet );
+ }
+ break;
+ // The last case branch which needs a table manager!!
+ case FN_TABLE_SET_COL_WIDTH:
+ {
+ SwTableFUNC aMgr( &rSh );
+ aMgr.ColWidthDlg(GetView().GetFrameWeld());
+ break;
+ }
+ case SID_TABLE_VERT_NONE:
+ case SID_TABLE_VERT_CENTER:
+ case SID_TABLE_VERT_BOTTOM:
+ {
+ const sal_uInt16 nAlign = nSlot == SID_TABLE_VERT_NONE ?
+ text::VertOrientation::NONE :
+ nSlot == SID_TABLE_VERT_CENTER ?
+ text::VertOrientation::CENTER : text::VertOrientation::BOTTOM;
+ rSh.SetBoxAlign(nAlign);
+ bCallDone = true;
+ break;
+ }
+
+ case SID_ATTR_PARA_SPLIT:
+ if ( pItem )
+ {
+ SwFormatLayoutSplit aSplit( static_cast<const SvxFormatSplitItem*>(pItem)->GetValue());
+ SfxItemSetFixed<RES_LAYOUT_SPLIT, RES_LAYOUT_SPLIT> aSet(GetPool());
+ aSet.Put(aSplit);
+ rSh.SetTableAttr(aSet);
+ }
+ break;
+
+ case SID_ATTR_PARA_KEEP:
+ if ( pItem )
+ {
+ SvxFormatKeepItem aKeep( *static_cast<const SvxFormatKeepItem*>(pItem) );
+ aKeep.SetWhich( RES_KEEP );
+ SfxItemSetFixed<RES_KEEP, RES_KEEP> aSet(GetPool());
+ aSet.Put(aKeep);
+ rSh.SetTableAttr(aSet);
+ }
+ break;
+ case FN_TABLE_ROW_SPLIT :
+ {
+ const SfxBoolItem* pBool = static_cast<const SfxBoolItem*>(pItem);
+ std::unique_ptr<SwFormatRowSplit> pSplit;
+ if(!pBool)
+ {
+ pSplit = rSh.GetRowSplit();
+ if(pSplit)
+ pSplit->SetValue(!pSplit->GetValue());
+ else
+ pSplit.reset(new SwFormatRowSplit(true));
+ }
+ else
+ {
+ pSplit.reset(new SwFormatRowSplit(pBool->GetValue()));
+ }
+ rSh.SetRowSplit( *pSplit );
+ break;
+ }
+
+ default:
+ OSL_ENSURE( false, "wrong Dispatcher" );
+ return;
+ }
+ if(bCallDone)
+ rReq.Done();
+}
+
+void SwTableShell::GetState(SfxItemSet &rSet)
+{
+ SfxWhichIter aIter( rSet );
+ SwWrtShell &rSh = GetShell();
+ SwFrameFormat *pFormat = rSh.GetTableFormat();
+ // os #124829# crash report: in case of an invalid shell selection return immediately
+ if(!pFormat)
+ return;
+ sal_uInt16 nSlot = aIter.FirstWhich();
+ while ( nSlot )
+ {
+ switch ( nSlot )
+ {
+ case FN_TABLE_MERGE_CELLS:
+ if ( !rSh.IsTableMode() )
+ rSet.DisableItem(FN_TABLE_MERGE_CELLS);
+ break;
+ case SID_TABLE_MINIMAL_COLUMN_WIDTH:
+ case FN_TABLE_ADJUST_CELLS:
+ if ( !rSh.IsAdjustCellWidthAllowed() )
+ rSet.DisableItem(nSlot);
+ break;
+
+ case FN_TABLE_BALANCE_CELLS:
+ if ( !rSh.IsAdjustCellWidthAllowed(true) )
+ rSet.DisableItem(FN_TABLE_BALANCE_CELLS);
+ break;
+
+ case FN_TABLE_OPTIMAL_HEIGHT:
+ case FN_TABLE_BALANCE_ROWS:
+ if ( !rSh.BalanceRowHeight(true) )
+ rSet.DisableItem(nSlot);
+ break;
+ case FN_OPTIMIZE_TABLE:
+ if ( !rSh.IsTableMode() &&
+ !rSh.IsAdjustCellWidthAllowed() &&
+ !rSh.IsAdjustCellWidthAllowed(true) &&
+ !rSh.BalanceRowHeight(true) )
+ rSet.DisableItem(FN_OPTIMIZE_TABLE);
+ break;
+ case SID_INSERT_DIAGRAM:
+ {
+ SvtModuleOptions aMOpt;
+ if ( !aMOpt.IsMath() || rSh.IsTableComplexForChart() )
+ rSet.DisableItem(nSlot);
+ }
+ break;
+
+ case FN_INSERT_TABLE:
+ if ( rSh.CursorInsideInputField() )
+ {
+ rSet.DisableItem( nSlot );
+ }
+ break;
+
+ case SID_TABLE_MINIMAL_ROW_HEIGHT:
+ {
+ // Disable if auto height already is enabled.
+ std::unique_ptr<SwFormatFrameSize> pSz = rSh.GetRowHeight();
+ if ( pSz )
+ {
+ if ( SwFrameSize::Variable == pSz->GetHeightSizeType() )
+ rSet.DisableItem( nSlot );
+ }
+ break;
+ }
+ case FN_TABLE_INSERT_COL_BEFORE:
+ case FN_TABLE_INSERT_COL_AFTER:
+ {
+ SfxImageItem aImageItem(nSlot);
+ if (pFormat->GetFrameDir().GetValue() == SvxFrameDirection::Environment)
+ {
+ // Inherited from superordinate object (page or frame).
+ // If the table spans multiple pages, direction is set by the first page.
+ SwIterator<SwTabFrame, SwFrameFormat> aIterT(*pFormat);
+ for (SwTabFrame* pFrame = aIterT.First(); pFrame;
+ pFrame = static_cast<SwTabFrame*>(pFrame->GetPrecede()))
+ aImageItem.SetMirrored(pFrame->IsRightToLeft());
+ }
+ else
+ aImageItem.SetMirrored(pFormat->GetFrameDir().GetValue() == SvxFrameDirection::Horizontal_RL_TB);
+ rSet.Put(aImageItem);
+ break;
+ }
+ case FN_TABLE_INSERT_ROW:
+ case FN_TABLE_INSERT_ROW_AFTER:
+ case FN_TABLE_INSERT_ROW_DLG:
+ if ( rSh.IsInRepeatedHeadline() )
+ rSet.DisableItem( nSlot );
+ break;
+ case RES_LR_SPACE:
+ rSet.Put(pFormat->GetLRSpace());
+ break;
+ case RES_UL_SPACE:
+ rSet.Put(pFormat->GetULSpace());
+ break;
+
+ case SID_TABLE_VERT_NONE:
+ case SID_TABLE_VERT_CENTER:
+ case SID_TABLE_VERT_BOTTOM:
+ {
+ const sal_uInt16 nAlign = rSh.GetBoxAlign();
+ bool bSet = (nSlot == SID_TABLE_VERT_NONE && nAlign == text::VertOrientation::NONE) ||
+ (nSlot == SID_TABLE_VERT_CENTER && nAlign == text::VertOrientation::CENTER) ||
+ (nSlot == SID_TABLE_VERT_BOTTOM && nAlign == text::VertOrientation::BOTTOM);
+ rSet.Put(SfxBoolItem(nSlot, bSet));
+ break;
+ }
+
+ case FN_TABLE_MODE_FIX :
+ case FN_TABLE_MODE_FIX_PROP :
+ case FN_TABLE_MODE_VARIABLE :
+ {
+ TableChgMode nMode = rSh.GetTableChgMode();
+ bool bSet = (nSlot == FN_TABLE_MODE_FIX && nMode == TableChgMode::FixedWidthChangeAbs) ||
+ (nSlot == FN_TABLE_MODE_FIX_PROP && nMode == TableChgMode::FixedWidthChangeProp) ||
+ (nSlot == FN_TABLE_MODE_VARIABLE && nMode == TableChgMode::VarWidthChangeAbs);
+ rSet.Put(SfxBoolItem(nSlot, bSet));
+ }
+ break;
+
+ case SID_ATTR_PARA_SPLIT:
+ rSet.Put( pFormat->GetKeep() );
+ break;
+
+ case SID_ATTR_PARA_KEEP:
+ rSet.Put( pFormat->GetLayoutSplit() );
+ break;
+ case FN_TABLE_SPLIT_TABLE:
+ if ( rSh.IsInHeadline() )
+ rSet.DisableItem( nSlot );
+ break;
+ case FN_TABLE_MERGE_TABLE:
+ {
+ bool bAsk;
+ if( !rSh.CanMergeTable( true, &bAsk ))
+ rSet.DisableItem( nSlot );
+ break;
+ }
+
+ case FN_TABLE_DELETE_ROW:
+ {
+ SwSelBoxes aBoxes;
+ ::GetTableSel( rSh, aBoxes, SwTableSearchType::Row );
+ if( ::HasProtectedCells( aBoxes ) || lcl_BoxesInTrackedRows( rSh, aBoxes ) )
+ rSet.DisableItem( nSlot );
+ }
+ break;
+ case FN_TABLE_DELETE_COL:
+ {
+ SwSelBoxes aBoxes;
+ ::GetTableSel( rSh, aBoxes, SwTableSearchType::Col );
+ if( ::HasProtectedCells( aBoxes ) || lcl_CursorInDeletedTable( rSh ) )
+ rSet.DisableItem( nSlot );
+ }
+ break;
+ case FN_TABLE_DELETE_TABLE:
+ if( lcl_CursorInDeletedTable( rSh ) )
+ rSet.DisableItem( nSlot );
+ break;
+
+ case FN_TABLE_UNSET_READ_ONLY_CELLS:
+ // disable in readonly sections, but enable in protected cells
+ if( !rSh.CanUnProtectCells() )
+ rSet.DisableItem( nSlot );
+ break;
+ case RES_ROW_SPLIT:
+ {
+ const SwFormatLayoutSplit& rTabSplit = pFormat->GetLayoutSplit();
+ if ( !rTabSplit.GetValue() )
+ {
+ rSet.DisableItem( nSlot );
+ }
+ else
+ {
+ std::unique_ptr<SwFormatRowSplit> pSplit = rSh.GetRowSplit();
+ if(pSplit)
+ rSet.Put(std::move(pSplit));
+ else
+ rSet.InvalidateItem( nSlot );
+ }
+ break;
+ }
+ case FN_TABLE_HEADLINE_REPEAT:
+ if(0 != rSh.GetRowsToRepeat())
+ rSet.Put(SfxBoolItem(nSlot, true));
+ else if(!rSh.GetRowSelectionFromTop())
+ rSet.DisableItem( nSlot );
+ else
+ rSet.Put(SfxBoolItem(nSlot, false));
+ break;
+ case FN_TABLE_SELECT_CELL :
+ if(rSh.HasBoxSelection())
+ rSet.DisableItem( nSlot );
+ break;
+ case SID_ATTR_TABLE_ROW_HEIGHT:
+ {
+ SfxUInt32Item aRowHeight(SID_ATTR_TABLE_ROW_HEIGHT);
+ std::unique_ptr<SwFormatFrameSize> pHeight = rSh.GetRowHeight();
+ if (pHeight)
+ {
+ tools::Long nHeight = pHeight->GetHeight();
+ aRowHeight.SetValue(nHeight);
+ rSet.Put(aRowHeight);
+
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ // TODO: set correct unit
+ MapUnit eTargetUnit = MapUnit::MapInch;
+ OUString sHeight = GetMetricText(nHeight,
+ MapUnit::MapTwip, eTargetUnit, nullptr);
+
+ OUString sPayload = ".uno:TableRowHeight=" + sHeight;
+
+ GetViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED,
+ OUStringToOString(sPayload, RTL_TEXTENCODING_ASCII_US));
+ }
+ }
+ break;
+ }
+ case SID_ATTR_TABLE_COLUMN_WIDTH:
+ {
+ SfxUInt32Item aColumnWidth(SID_ATTR_TABLE_COLUMN_WIDTH);
+ SwTableFUNC aFunc( &rSh );
+ aFunc.InitTabCols();
+ SwTwips nWidth = aFunc.GetColWidth(aFunc.GetCurColNum());
+ aColumnWidth.SetValue(nWidth);
+ rSet.Put(aColumnWidth);
+
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ // TODO: set correct unit
+ MapUnit eTargetUnit = MapUnit::MapInch;
+ OUString sWidth = GetMetricText(nWidth,
+ MapUnit::MapTwip, eTargetUnit, nullptr);
+
+ OUString sPayload = ".uno:TableColumWidth=" + sWidth;
+
+ GetViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED,
+ OUStringToOString(sPayload, RTL_TEXTENCODING_ASCII_US));
+ }
+
+ break;
+ }
+ }
+ nSlot = aIter.NextWhich();
+ }
+}
+
+SwTableShell::SwTableShell(SwView &_rView) :
+ SwBaseShell(_rView)
+{
+ SetName("Table");
+ SfxShell::SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::Table));
+}
+
+void SwTableShell::GetFrameBorderState(SfxItemSet &rSet)
+{
+ SfxItemSetFixed<RES_BOX, RES_BOX,
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER> aCoreSet( GetPool() );
+ SvxBoxInfoItem aBoxInfo( SID_ATTR_BORDER_INNER );
+ aCoreSet.Put( aBoxInfo );
+ GetShell().GetTabBorders( aCoreSet );
+ rSet.Put( aCoreSet );
+}
+
+void SwTableShell::ExecTableStyle(SfxRequest& rReq)
+{
+ SwWrtShell &rSh = GetShell();
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ if(!pArgs)
+ return;
+
+ switch ( rReq.GetSlot() )
+ {
+ case SID_FRAME_LINESTYLE:
+ case SID_FRAME_LINECOLOR:
+ if ( rReq.GetSlot() == SID_FRAME_LINESTYLE )
+ {
+ const SvxLineItem &rLineItem = pArgs->Get( SID_FRAME_LINESTYLE );
+ const SvxBorderLine* pBorderLine = rLineItem.GetLine();
+ rSh.SetTabLineStyle( nullptr, true, pBorderLine);
+ }
+ else
+ {
+ const SvxColorItem &rNewColorItem = pArgs->Get( SID_FRAME_LINECOLOR );
+ rSh.SetTabLineStyle( &rNewColorItem.GetValue() );
+ }
+
+ rReq.Done();
+
+ break;
+ }
+}
+
+void SwTableShell::GetLineStyleState(SfxItemSet &rSet)
+{
+ SfxItemSetFixed<RES_BOX, RES_BOX,
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER> aCoreSet( GetPool() );
+ SvxBoxInfoItem aCoreInfo( SID_ATTR_BORDER_INNER );
+ aCoreSet.Put(aCoreInfo);
+ GetShell().GetTabBorders( aCoreSet );
+
+ const SvxBoxItem& rBoxItem = aCoreSet.Get( RES_BOX );
+ const SvxBorderLine* pLine = rBoxItem.GetTop();
+
+ rSet.Put( SvxColorItem( pLine ? pLine->GetColor() : Color(), SID_FRAME_LINECOLOR ) );
+ SvxLineItem aLine( SID_FRAME_LINESTYLE );
+ aLine.SetLine(pLine);
+ rSet.Put( aLine );
+}
+
+void SwTableShell::ExecNumberFormat(SfxRequest const & rReq)
+{
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ SwWrtShell &rSh = GetShell();
+
+ // At first the slots, which doesn't need a FrameMgr.
+ const SfxPoolItem* pItem = nullptr;
+ const sal_uInt16 nSlot = rReq.GetSlot();
+ if(pArgs)
+ pArgs->GetItemState(GetPool().GetWhich(nSlot), false, &pItem);
+
+ // Always acquire the language from the current cursor position.
+ LanguageType eLang = rSh.GetCurLang();
+ SvNumberFormatter* pFormatter = rSh.GetNumberFormatter();
+ sal_uInt32 nNumberFormat = NUMBERFORMAT_ENTRY_NOT_FOUND;
+ SvNumFormatType nFormatType = SvNumFormatType::ALL;
+ sal_uInt16 nOffset = 0;
+
+ switch ( nSlot )
+ {
+ case FN_NUMBER_FORMAT:
+ if( pItem )
+ {
+ // Determine index for string.
+ OUString aCode( static_cast<const SfxStringItem*>(pItem)->GetValue() );
+ nNumberFormat = pFormatter->GetEntryKey( aCode, eLang );
+ if( NUMBERFORMAT_ENTRY_NOT_FOUND == nNumberFormat )
+ {
+ // Re-enter
+ sal_Int32 nErrPos;
+ SvNumFormatType nType;
+ if( !pFormatter->PutEntry( aCode, nErrPos, nType,
+ nNumberFormat, eLang ))
+ nNumberFormat = NUMBERFORMAT_ENTRY_NOT_FOUND;
+ }
+ }
+ break;
+ case FN_NUMBER_STANDARD: nFormatType = SvNumFormatType::NUMBER; break;
+ case FN_NUMBER_SCIENTIFIC: nFormatType = SvNumFormatType::SCIENTIFIC; break;
+ case FN_NUMBER_DATE: nFormatType = SvNumFormatType::DATE; break;
+ case FN_NUMBER_TIME: nFormatType = SvNumFormatType::TIME; break;
+ case FN_NUMBER_CURRENCY: nFormatType = SvNumFormatType::CURRENCY; break;
+ case FN_NUMBER_PERCENT: nFormatType = SvNumFormatType::PERCENT; break;
+
+ case FN_NUMBER_TWODEC: // #.##0,00
+ nFormatType = SvNumFormatType::NUMBER;
+ nOffset = NF_NUMBER_1000DEC2;
+ break;
+
+ default:
+ OSL_FAIL("wrong dispatcher");
+ return;
+ }
+
+ if( nFormatType != SvNumFormatType::ALL )
+ nNumberFormat = pFormatter->GetStandardFormat( nFormatType, eLang ) + nOffset;
+
+ if( NUMBERFORMAT_ENTRY_NOT_FOUND != nNumberFormat )
+ {
+ SfxItemSetFixed<RES_BOXATR_FORMAT, RES_BOXATR_FORMAT> aBoxSet( GetPool() );
+ aBoxSet.Put( SwTableBoxNumFormat( nNumberFormat ));
+ rSh.SetTableBoxFormulaAttrs( aBoxSet );
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/textdrw.cxx b/sw/source/uibase/shells/textdrw.cxx
new file mode 100644
index 0000000000..881468c5d7
--- /dev/null
+++ b/sw/source/uibase/shells/textdrw.cxx
@@ -0,0 +1,126 @@
+/* -*- 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 <svx/svdview.hxx>
+#include <tools/urlobj.hxx>
+#include <svx/svdobjkind.hxx>
+#include <svx/svdouno.hxx>
+#include <com/sun/star/form/FormButtonType.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <osl/diagnose.h>
+
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <edtwin.hxx>
+#include <swundo.hxx>
+#include <basesh.hxx>
+
+#include <docsh.hxx>
+#include <sfx2/docfile.hxx>
+#include <svl/urihelper.hxx>
+#include <avmedia/mediawindow.hxx>
+
+using namespace ::com::sun::star;
+
+void SwBaseShell::InsertURLButton(const OUString& rURL, const OUString& rTarget, const OUString& rText)
+{
+ SwWrtShell& rSh = GetShell();
+
+ if (!rSh.HasDrawView())
+ rSh.MakeDrawView();
+ SdrView *pSdrView = rSh.GetDrawView();
+
+ // OBJ_FM_BUTTON
+ pSdrView->SetDesignMode();
+ pSdrView->SetCurrentObj(SdrObjKind::FormButton);
+ pSdrView->SetEditMode(false);
+
+ Point aStartPos(rSh.GetCharRect().Pos() + Point(0, 1));
+
+ rSh.StartAction();
+ rSh.StartUndo( SwUndoId::UI_INSERT_URLBTN );
+ if (rSh.BeginCreate(SdrObjKind::FormButton, SdrInventor::FmForm, aStartPos))
+ {
+ pSdrView->SetOrtho(false);
+ Size aSz(GetView().GetEditWin().PixelToLogic(Size(140, 20)));
+ Point aEndPos(aSz.Width(), aSz.Height());
+
+ rSh.MoveCreate(aStartPos + aEndPos);
+ rSh.EndCreate(SdrCreateCmd::ForceEnd);
+
+ const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
+ if (rMarkList.GetMark(0))
+ {
+ SdrUnoObj* pUnoCtrl = dynamic_cast<SdrUnoObj*>( rMarkList.GetMark(0)->GetMarkedSdrObj() );
+ OSL_ENSURE( pUnoCtrl, "not an SdrUnoObj" );
+ if (!pUnoCtrl)
+ return;
+
+ uno::Reference< awt::XControlModel > xControlModel = pUnoCtrl->GetUnoControlModel();
+
+ OSL_ENSURE( xControlModel.is(), "UNO-Control without Model" );
+ if (!xControlModel.is())
+ return;
+
+ uno::Reference< beans::XPropertySet > xPropSet(xControlModel, uno::UNO_QUERY);
+
+ uno::Any aTmp;
+
+ aTmp <<= rText;
+ xPropSet->setPropertyValue( "Label", aTmp );
+
+ SfxMedium* pMedium = rSh.GetView().GetDocShell()->GetMedium();
+ INetURLObject aAbs;
+ if( pMedium )
+ aAbs = pMedium->GetURLObject();
+
+ aTmp <<= URIHelper::SmartRel2Abs(aAbs, rURL);
+ xPropSet->setPropertyValue( "TargetURL", aTmp );
+
+ if( !rTarget.isEmpty() )
+ {
+ aTmp <<= rTarget;
+ xPropSet->setPropertyValue( "TargetFrame", aTmp );
+ }
+
+ aTmp <<= form::FormButtonType_URL;
+ xPropSet->setPropertyValue( "ButtonType", aTmp );
+
+#if HAVE_FEATURE_AVMEDIA
+ if ( ::avmedia::MediaWindow::isMediaURL( rURL, ""/*TODO?*/ ) )
+ {
+ // #105638# OJ
+ aTmp <<= true;
+ xPropSet->setPropertyValue("DispatchURLInternal", aTmp );
+ }
+#endif
+ }
+
+ if (rSh.IsObjSelected())
+ {
+ rSh.UnSelectFrame();
+ }
+ }
+ rSh.EndUndo( SwUndoId::UI_INSERT_URLBTN );
+ rSh.EndAction();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/textfld.cxx b/sw/source/uibase/shells/textfld.cxx
new file mode 100644
index 0000000000..68561d8b8d
--- /dev/null
+++ b/sw/source/uibase/shells/textfld.cxx
@@ -0,0 +1,1805 @@
+/* -*- 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 <com/sun/star/beans/PropertyValues.hpp>
+#include <AnnotationWin.hxx>
+#include <comphelper/lok.hxx>
+#include <hintids.hxx>
+#include <IDocumentFieldsAccess.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/lnkbase.hxx>
+#include <txtfld.hxx>
+#include <svl/itempool.hxx>
+#include <svl/numformat.hxx>
+#include <tools/lineend.hxx>
+#include <svl/whiter.hxx>
+#include <svl/eitem.hxx>
+#include <svl/macitem.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/request.hxx>
+#include <svx/postattr.hxx>
+#include <svx/hlnkitem.hxx>
+#include <svx/svxdlg.hxx>
+#include <osl/diagnose.h>
+#include <fmthdft.hxx>
+#include <fmtinfmt.hxx>
+#include <fldwrap.hxx>
+#include <redline.hxx>
+#include <view.hxx>
+#include <viewopt.hxx>
+#include <wrtsh.hxx>
+#include <textsh.hxx>
+#include <docufld.hxx>
+#include <ddefld.hxx>
+#include <fldmgr.hxx>
+#include <uitool.hxx>
+#include <cmdid.h>
+#include <strings.hrc>
+#include <sfx2/event.hxx>
+#include <swabstdlg.hxx>
+#include <doc.hxx>
+#include <PostItMgr.hxx>
+#include <swmodule.hxx>
+#include <svtools/strings.hrc>
+#include <svtools/svtresid.hxx>
+
+#include <editeng/ulspitem.hxx>
+#include <xmloff/odffields.hxx>
+#include <IDocumentContentOperations.hxx>
+#include <IDocumentRedlineAccess.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/pageitem.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <IMark.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <officecfg/Office/Compatibility.hxx>
+#include <ndtxt.hxx>
+#include <translatehelper.hxx>
+#include <sfx2/dispatch.hxx>
+
+
+using namespace nsSwDocInfoSubType;
+
+static OUString lcl_BuildTitleWithRedline( const SwRangeRedline *pRedline )
+{
+ const OUString sTitle(SwResId(STR_REDLINE_COMMENT));
+
+ TranslateId pResId;
+ switch( pRedline->GetType() )
+ {
+ case RedlineType::Insert:
+ pResId = STR_REDLINE_INSERTED;
+ break;
+ case RedlineType::Delete:
+ pResId = STR_REDLINE_DELETED;
+ break;
+ case RedlineType::Format:
+ case RedlineType::ParagraphFormat:
+ pResId = STR_REDLINE_FORMATTED;
+ break;
+ case RedlineType::Table:
+ pResId = STR_REDLINE_TABLECHG;
+ break;
+ case RedlineType::FmtColl:
+ pResId = STR_REDLINE_FMTCOLLSET;
+ break;
+ default:
+ return sTitle;
+ }
+
+ return sTitle + SwResId(pResId);
+}
+
+void SwTextShell::ExecField(SfxRequest &rReq)
+{
+ SwWrtShell& rSh = GetShell();
+ const SfxPoolItem* pItem = nullptr;
+
+ sal_uInt16 nSlot = rReq.GetSlot();
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ if(pArgs)
+ pArgs->GetItemState(GetPool().GetWhich(nSlot), false, &pItem);
+
+ bool bMore = false;
+ bool bIsText = true;
+ SwFieldTypesEnum nInsertType = SwFieldTypesEnum::Date;
+ sal_uInt16 nInsertSubType = 0;
+ sal_uInt32 nInsertFormat = 0;
+
+ switch(nSlot)
+ {
+ case FN_EDIT_FIELD:
+ {
+ SwField* pField = rSh.GetCurField(true);
+ if( pField )
+ {
+ switch ( pField->GetTypeId() )
+ {
+ case SwFieldTypesEnum::DDE:
+ {
+ ::sfx2::SvBaseLink& rLink = static_cast<SwDDEFieldType*>(pField->GetTyp())->
+ GetBaseLink();
+ if(rLink.IsVisible())
+ {
+ if (officecfg::Office::Common::Security::Scripting::DisableActiveContent::get())
+ {
+ std::unique_ptr<weld::MessageDialog> xError(
+ Application::CreateMessageDialog(
+ nullptr, VclMessageType::Warning, VclButtonsType::Ok,
+ SvtResId(STR_WARNING_EXTERNAL_LINK_EDIT_DISABLED)));
+ xError->run();
+ break;
+ }
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<SfxAbstractLinksDialog> pDlg(pFact->CreateLinksDialog(GetView().GetFrameWeld(), &rSh.GetLinkManager(), false, &rLink));
+ pDlg->Execute();
+ }
+ break;
+ }
+ default:
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<SfxAbstractDialog> pDlg(pFact->CreateSwFieldEditDlg( GetView() ));
+ pDlg->Execute();
+ }
+ }
+ }
+ break;
+ }
+ case FN_UPDATE_SEL_FIELD:
+ {
+ SwField *pField = rSh.GetCurField();
+
+ if (pField)
+ {
+ rSh.UpdateOneField(*pField);
+ }
+ break;
+ }
+ case FN_EXECUTE_MACROFIELD:
+ {
+ SwField* pField = rSh.GetCurField();
+ if(pField && pField->GetTyp()->Which() == SwFieldIds::Macro)
+ {
+
+ const OUString& rMacro = static_cast<SwMacroField*>(pField)->GetMacro();
+ sal_Int32 nPos = rMacro.indexOf('.');
+ if(nPos != -1)
+ {
+ SvxMacro aMacro( rMacro.copy(nPos + 1), rMacro.copy(0,nPos), STARBASIC );
+ rSh.ExecMacro(aMacro);
+ }
+ }
+ }
+ break;
+
+ case FN_GOTO_NEXT_INPUTFLD:
+ case FN_GOTO_PREV_INPUTFLD:
+ {
+ bool bRet = false;
+ SwFieldType* pField = rSh.GetFieldType( 0, SwFieldIds::Input );
+ const bool bAddSetExpressionFields = !( rSh.GetViewOptions()->IsReadonly() );
+ if ( pField != nullptr
+ && rSh.MoveFieldType(
+ pField,
+ FN_GOTO_NEXT_INPUTFLD == nSlot,
+ SwFieldIds::Unknown,
+ bAddSetExpressionFields ) )
+ {
+ rSh.ClearMark();
+ if (!rSh.IsMultiSelection()
+ && (nullptr != dynamic_cast<const SwTextInputField*>(
+ SwCursorShell::GetTextFieldAtCursor(rSh.GetCursor(), ::sw::GetTextAttrMode::Default))))
+ {
+ rSh.SttSelect();
+ rSh.SelectTextModel(
+ SwCursorShell::StartOfInputFieldAtPos( *(rSh.GetCursor()->Start()) ) + 1,
+ SwCursorShell::EndOfInputFieldAtPos( *(rSh.GetCursor()->Start()) ) - 1 );
+ }
+ else if (SwField* pCurrentField = rSh.GetCurField(true))
+ {
+ rSh.StartInputFieldDlg(pCurrentField, false, false, GetView().GetFrameWeld());
+ }
+ bRet = true;
+ }
+
+ rReq.SetReturnValue( SfxBoolItem( nSlot, bRet ));
+ }
+ break;
+
+ case FN_GOTO_MARK:
+ {
+ const SfxStringItem* pName = rReq.GetArg<SfxStringItem>(FN_GOTO_MARK);
+ if (pName)
+ {
+ rSh.GotoMark(pName->GetValue());
+ }
+ }
+ break;
+ default:
+ bMore = true;
+ }
+ if(!bMore)
+ return;
+
+ // Here come the slots with FieldMgr.
+ SwFieldMgr aFieldMgr(GetShellPtr());
+ switch(nSlot)
+ {
+ case FN_INSERT_DBFIELD:
+ {
+ bool bRes = false;
+ if( pItem )
+ {
+ sal_uInt32 nFormat = 0;
+ SwFieldTypesEnum nType = SwFieldTypesEnum::Date;
+ OUString aPar1 = static_cast<const SfxStringItem *>(pItem)->GetValue();
+ OUString aPar2;
+ sal_Int32 nCommand = 0;
+
+ if( const SfxUInt16Item* pFieldItem = pArgs->GetItemIfSet( FN_PARAM_FIELD_TYPE,
+ false ))
+ nType = static_cast<SwFieldTypesEnum>(pFieldItem->GetValue());
+ aPar1 += OUStringChar(DB_DELIM);
+ if( SfxItemState::SET == pArgs->GetItemState(
+ FN_PARAM_1, false, &pItem ))
+ {
+ aPar1 += static_cast<const SfxStringItem *>(pItem)->GetValue();
+ }
+ if( SfxItemState::SET == pArgs->GetItemState(
+ FN_PARAM_3, false, &pItem ))
+ nCommand = static_cast<const SfxInt32Item*>(pItem)->GetValue();
+ aPar1 += OUStringChar(DB_DELIM)
+ + OUString::number(nCommand)
+ + OUStringChar(DB_DELIM);
+ if( SfxItemState::SET == pArgs->GetItemState(
+ FN_PARAM_2, false, &pItem ))
+ {
+ aPar1 += static_cast<const SfxStringItem *>(pItem)->GetValue();
+ }
+ if( const SfxStringItem* pContentItem = pArgs->GetItemIfSet(
+ FN_PARAM_FIELD_CONTENT, false ))
+ aPar2 = pContentItem->GetValue();
+ if( const SfxUInt32Item* pFormatItem = pArgs->GetItemIfSet(
+ FN_PARAM_FIELD_FORMAT, false ))
+ nFormat = pFormatItem->GetValue();
+ OSL_FAIL("Command is not yet used");
+ SwInsertField_Data aData(nType, 0, aPar1, aPar2, nFormat, GetShellPtr(), ' '/*separator*/ );
+ bRes = aFieldMgr.InsertField(aData);
+ }
+ rReq.SetReturnValue(SfxBoolItem( nSlot, bRes ));
+ }
+ break;
+ case FN_INSERT_FIELD_CTRL:
+ case FN_INSERT_FIELD:
+ {
+ bool bRes = false;
+ if( pItem && nSlot != FN_INSERT_FIELD_CTRL)
+ {
+ sal_uInt32 nFormat = 0;
+ SwFieldTypesEnum nType = SwFieldTypesEnum::Date;
+ sal_uInt16 nSubType = 0;
+ OUString aPar1 = static_cast<const SfxStringItem *>(pItem)->GetValue();
+ OUString aPar2;
+ sal_Unicode cSeparator = ' ';
+
+ if( const SfxUInt16Item* pTypeItem = pArgs->GetItemIfSet( FN_PARAM_FIELD_TYPE,
+ false ))
+ nType = static_cast<SwFieldTypesEnum>(pTypeItem->GetValue());
+ else if (pArgs->GetItemState(FN_PARAM_4, false, &pItem) == SfxItemState::SET)
+ {
+ const OUString& rTypeName = static_cast<const SfxStringItem *>(pItem)->GetValue();
+ nType = SwFieldTypeFromString(rTypeName);
+ }
+ if( const SfxUInt16Item* pSubtypeItem = pArgs->GetItemIfSet( FN_PARAM_FIELD_SUBTYPE,
+ false ))
+ nSubType = pSubtypeItem->GetValue();
+ if( const SfxStringItem* pContentItem = pArgs->GetItemIfSet(
+ FN_PARAM_FIELD_CONTENT, false ))
+ aPar2 = pContentItem->GetValue();
+ if( const SfxUInt32Item* pFormatItem = pArgs->GetItemIfSet(
+ FN_PARAM_FIELD_FORMAT, false ))
+ nFormat = pFormatItem->GetValue();
+ if( SfxItemState::SET == pArgs->GetItemState(
+ FN_PARAM_3, false, &pItem ))
+ {
+ OUString sTmp = static_cast<const SfxStringItem *>(pItem)->GetValue();
+ if(!sTmp.isEmpty())
+ cSeparator = sTmp[0];
+ }
+ if (pArgs->GetItemState(FN_PARAM_5, false, &pItem) == SfxItemState::SET)
+ {
+ // Wrap the field in the requested container instead of inserting it
+ // directly at the cursor position.
+ const OUString& rWrapper = static_cast<const SfxStringItem *>(pItem)->GetValue();
+ if (rWrapper == "Footnote")
+ {
+ GetShellPtr()->InsertFootnote(OUString());
+ }
+ else if (rWrapper == "Endnote")
+ {
+ GetShellPtr()->InsertFootnote(OUString(), /*bEndNote=*/true);
+ }
+ }
+ SwInsertField_Data aData(nType, nSubType, aPar1, aPar2, nFormat, GetShellPtr(), cSeparator );
+ bRes = aFieldMgr.InsertField( aData );
+ }
+ else
+ {
+ //#i5788# prevent closing of the field dialog while a modal dialog ( Input field dialog ) is active
+ if(!GetView().GetViewFrame().IsInModalMode())
+ {
+ SfxViewFrame& rVFrame = GetView().GetViewFrame();
+ rVFrame.ToggleChildWindow(FN_INSERT_FIELD);
+ bRes = rVFrame.GetChildWindow( nSlot ) != nullptr;
+ Invalidate(rReq.GetSlot());
+ Invalidate(FN_INSERT_FIELD_CTRL);
+ rReq.Ignore();
+ }
+ }
+ rReq.SetReturnValue(SfxBoolItem( nSlot, bRes ));
+ }
+ break;
+
+ case FN_INSERT_REF_FIELD:
+ {
+ SfxViewFrame& rVFrame = GetView().GetViewFrame();
+ if (!rVFrame.HasChildWindow(FN_INSERT_FIELD))
+ rVFrame.ToggleChildWindow(FN_INSERT_FIELD); // Show dialog
+
+ // Switch Fielddlg at a new TabPage
+ sal_uInt16 nId = SwFieldDlgWrapper::GetChildWindowId();
+ SwFieldDlgWrapper *pWrp = static_cast<SwFieldDlgWrapper*>(rVFrame.GetChildWindow(nId));
+ if (pWrp)
+ pWrp->ShowReferencePage();
+ rReq.Ignore();
+ }
+ break;
+ case FN_DELETE_COMMENT:
+ {
+ const SvxPostItIdItem* pIdItem = rReq.GetArg<SvxPostItIdItem>(SID_ATTR_POSTIT_ID);
+ if (pIdItem && !pIdItem->GetValue().isEmpty() && GetView().GetPostItMgr())
+ {
+ GetView().GetPostItMgr()->Delete(pIdItem->GetValue().toUInt32());
+ }
+ else if ( GetView().GetPostItMgr() &&
+ GetView().GetPostItMgr()->HasActiveSidebarWin() )
+ {
+ GetView().GetPostItMgr()->DeleteActiveSidebarWin();
+ }
+ break;
+ }
+ case FN_DELETE_COMMENT_THREAD:
+ {
+ const SvxPostItIdItem* pIdItem = rReq.GetArg<SvxPostItIdItem>(SID_ATTR_POSTIT_ID);
+ if (pIdItem && !pIdItem->GetValue().isEmpty() && GetView().GetPostItMgr())
+ {
+ GetView().GetPostItMgr()->DeleteCommentThread(pIdItem->GetValue().toUInt32());
+ }
+ else if ( GetView().GetPostItMgr() &&
+ GetView().GetPostItMgr()->HasActiveSidebarWin() )
+ {
+ GetView().GetPostItMgr()->DeleteActiveSidebarWin();
+ }
+ break;
+ }
+ case FN_RESOLVE_NOTE:
+ {
+ const SvxPostItIdItem* pIdItem = rReq.GetArg<SvxPostItIdItem>(SID_ATTR_POSTIT_ID);
+ if (pIdItem && !pIdItem->GetValue().isEmpty() && GetView().GetPostItMgr())
+ {
+ GetView().GetPostItMgr()->ToggleResolved(pIdItem->GetValue().toUInt32());
+ }
+ break;
+ }
+ case FN_RESOLVE_NOTE_THREAD:
+ {
+ const SvxPostItIdItem* pIdItem = rReq.GetArg<SvxPostItIdItem>(SID_ATTR_POSTIT_ID);
+ if (pIdItem && !pIdItem->GetValue().isEmpty() && GetView().GetPostItMgr())
+ {
+ GetView().GetPostItMgr()->ToggleResolvedForThread(pIdItem->GetValue().toUInt32());
+ }
+ break;
+ }
+ case FN_DELETE_ALL_NOTES:
+ if ( GetView().GetPostItMgr() )
+ GetView().GetPostItMgr()->Delete();
+ break;
+ case FN_FORMAT_ALL_NOTES:
+ {
+ SwPostItMgr* pPostItMgr = GetView().GetPostItMgr();
+ if (pPostItMgr)
+ pPostItMgr->ExecuteFormatAllDialog(GetView());
+ }
+ break;
+ case FN_DELETE_NOTE_AUTHOR:
+ {
+ const SfxStringItem* pNoteItem = rReq.GetArg<SfxStringItem>(nSlot);
+ if ( pNoteItem && GetView().GetPostItMgr() )
+ GetView().GetPostItMgr()->Delete( pNoteItem->GetValue() );
+ }
+ break;
+ case FN_HIDE_NOTE:
+ if ( GetView().GetPostItMgr() &&
+ GetView().GetPostItMgr()->HasActiveSidebarWin() )
+ {
+ GetView().GetPostItMgr()->HideActiveSidebarWin();
+ }
+ break;
+ case FN_HIDE_ALL_NOTES:
+ if ( GetView().GetPostItMgr() )
+ GetView().GetPostItMgr()->Hide();
+ break;
+ case FN_HIDE_NOTE_AUTHOR:
+ {
+ const SfxStringItem* pNoteItem = rReq.GetArg<SfxStringItem>(nSlot);
+ if ( pNoteItem && GetView().GetPostItMgr() )
+ GetView().GetPostItMgr()->Hide( pNoteItem->GetValue() );
+ }
+ break;
+ case FN_REPLY:
+ {
+ const SvxPostItIdItem* pIdItem = rReq.GetArg<SvxPostItIdItem>(SID_ATTR_POSTIT_ID);
+ if (pIdItem && !pIdItem->GetValue().isEmpty())
+ {
+ SwFieldType* pType = rSh.GetDoc()->getIDocumentFieldsAccess().GetFieldType(SwFieldIds::Postit, OUString(), false);
+ if(pType->FindFormatForPostItId(pIdItem->GetValue().toUInt32()))
+ {
+ auto pMgr = GetView().GetPostItMgr();
+ auto pWin = pMgr->GetAnnotationWin(pIdItem->GetValue().toUInt32());
+ if(pWin)
+ {
+ OUString sText;
+ if(const auto pTextItem = rReq.GetArg<SvxPostItTextItem>(SID_ATTR_POSTIT_TEXT))
+ sText = pTextItem->GetValue();
+ pMgr->RegisterAnswerText(sText);
+ pWin->ExecuteCommand(nSlot);
+
+ SwPostItField* pLatestPostItField = pMgr->GetLatestPostItField();
+ if (pLatestPostItField)
+ {
+ // Set the parent postit id of the reply.
+ pLatestPostItField->SetParentPostItId(pIdItem->GetValue().toUInt32());
+
+ // If name of the replied comment is empty, we need to set a name in order to connect them in the xml file.
+ pWin->GeneratePostItName(); // Generates a name if the current name is empty.
+
+ pLatestPostItField->SetParentName(pWin->GetPostItField()->GetName());
+ }
+ }
+ }
+ }
+ }
+ break;
+ case FN_POSTIT:
+ {
+ rSh.InsertPostIt(aFieldMgr, rReq);
+ }
+ break;
+ case SID_EDIT_POSTIT:
+ {
+ const SvxPostItIdItem* pIdItem = rReq.GetArg<SvxPostItIdItem>(SID_ATTR_POSTIT_ID);
+ if (pIdItem && !pIdItem->GetValue().isEmpty())
+ {
+ const SvxPostItTextItem* pTextItem = rReq.GetArg<SvxPostItTextItem>(SID_ATTR_POSTIT_TEXT);
+ OUString sText;
+ if ( pTextItem )
+ sText = pTextItem->GetValue();
+
+ sw::annotation::SwAnnotationWin* pAnnotationWin = GetView().GetPostItMgr()->GetAnnotationWin(pIdItem->GetValue().toUInt32());
+ if (pAnnotationWin)
+ {
+ pAnnotationWin->UpdateText(sText);
+
+ // explicit state update to get the Undo state right
+ GetView().AttrChangedNotify(nullptr);
+ }
+ }
+ }
+ break;
+ case FN_REDLINE_COMMENT:
+ {
+ /* this code can be used once we want redline comments in the margin, all other stuff can
+ then be deleted
+ String sComment;
+ const SwRangeRedline *pRedline = rSh.GetCurrRedline();
+
+ if (pRedline)
+ {
+ sComment = pRedline->GetComment();
+ if ( !sComment.Len() )
+ GetView().GetDocShell()->Broadcast(SwRedlineHint(pRedline,SWREDLINE_INSERTED));
+ const_cast<SwRangeRedline*>(pRedline)->Broadcast(SwRedlineHint(pRedline,SWREDLINE_FOCUS,&GetView()));
+ }
+ */
+
+ const SwRangeRedline *pRedline = rSh.GetCurrRedline();
+ SwDoc *pDoc = rSh.GetDoc();
+ // If index is specified, goto and select the appropriate redline
+ if (pArgs && pArgs->GetItemState(nSlot, false, &pItem) == SfxItemState::SET)
+ {
+ const sal_uInt32 nChangeId = static_cast<const SfxUInt32Item*>(pItem)->GetValue();
+ const SwRedlineTable& rRedlineTable = pDoc->getIDocumentRedlineAccess().GetRedlineTable();
+ for (SwRedlineTable::size_type nRedline = 0; nRedline < rRedlineTable.size(); ++nRedline)
+ {
+ if (nChangeId == rRedlineTable[nRedline]->GetId())
+ pRedline = rSh.GotoRedline(nRedline, true);
+ }
+ }
+
+ OUString sCommentText;
+ const SfxStringItem* pTextItem = rReq.GetArg<SvxPostItTextItem>(SID_ATTR_POSTIT_TEXT);
+ if (pTextItem)
+ sCommentText = pTextItem->GetValue();
+
+ if (pRedline)
+ {
+ // In case of LOK and comment text is already provided, skip
+ // dialog creation and just change the redline comment directly
+ if (comphelper::LibreOfficeKit::isActive() && !sCommentText.isEmpty())
+ {
+ rSh.SetRedlineComment(sCommentText);
+ GetView().AttrChangedNotify(nullptr);
+ MaybeNotifyRedlineModification(const_cast<SwRangeRedline&>(*pRedline), pRedline->GetDoc());
+ break;
+ }
+
+ OUString sComment = convertLineEnd(pRedline->GetComment(), GetSystemLineEnd());
+
+ bool bTravel = false;
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ::DialogGetRanges fnGetRange = pFact->GetDialogGetRangesFunc();
+ SfxItemSet aSet(GetPool(), fnGetRange());
+ aSet.Put(SvxPostItTextItem(sComment, SID_ATTR_POSTIT_TEXT));
+ aSet.Put(SvxPostItAuthorItem(pRedline->GetAuthorString(), SID_ATTR_POSTIT_AUTHOR));
+
+ aSet.Put( SvxPostItDateItem( GetAppLangDateTimeString(
+ pRedline->GetRedlineData().GetTimeStamp() ),
+ SID_ATTR_POSTIT_DATE ));
+
+ // Traveling only if more than one field.
+ rSh.StartAction();
+
+ rSh.Push();
+ const SwRangeRedline *pActRed = rSh.SelPrevRedline();
+
+ if (pActRed == pRedline)
+ { // New cursor is at the beginning of the current redlines.
+ rSh.Pop(); // Throw old cursor away
+ rSh.Push();
+ pActRed = rSh.SelPrevRedline();
+ }
+
+ bool bPrev = pActRed != nullptr;
+ rSh.Pop(SwCursorShell::PopMode::DeleteCurrent);
+ rSh.EndAction();
+
+ rSh.ClearMark();
+ // Select current redline.
+ pActRed = rSh.SelNextRedline();
+ if (pActRed != pRedline)
+ rSh.SelPrevRedline();
+
+ rSh.StartAction();
+ rSh.Push();
+ pActRed = rSh.SelNextRedline();
+ bool bNext = pActRed != nullptr;
+ rSh.Pop(SwCursorShell::PopMode::DeleteCurrent); // Restore cursor position
+
+ if( rSh.IsCursorPtAtEnd() )
+ rSh.SwapPam();
+
+ rSh.EndAction();
+
+ bTravel |= bNext || bPrev;
+
+ SvxAbstractDialogFactory* pFact2 = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxPostItDialog> pDlg(pFact2->CreateSvxPostItDialog(GetView().GetFrameWeld(), aSet, bTravel));
+ pDlg->HideAuthor();
+
+ pDlg->SetText(lcl_BuildTitleWithRedline(pRedline));
+
+ if (bTravel)
+ {
+ pDlg->EnableTravel(bNext, bPrev);
+ pDlg->SetPrevHdl(LINK(this, SwTextShell, RedlinePrevHdl));
+ pDlg->SetNextHdl(LINK(this, SwTextShell, RedlineNextHdl));
+ }
+
+ SwViewShell::SetCareDialog(pDlg->GetDialog());
+ g_bNoInterrupt = true;
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
+ OUString sMsg(pOutSet->Get(SID_ATTR_POSTIT_TEXT).GetValue());
+
+ // Insert or change a comment
+ rSh.SetRedlineComment(sMsg);
+ }
+
+ SwViewShell::SetCareDialog(nullptr);
+ pDlg.disposeAndClear();
+ g_bNoInterrupt = false;
+ rSh.ClearMark();
+ GetView().AttrChangedNotify(nullptr);
+ }
+ }
+ break;
+
+ case FN_JAVAEDIT:
+ {
+ OUString aType, aText;
+ bool bIsUrl=false;
+ bool bNew=false;
+ bool bUpdate = false;
+ SwFieldMgr aMgr;
+ if ( pItem )
+ {
+ aText = static_cast<const SfxStringItem*>(pItem)->GetValue();
+ const SfxStringItem* pType = rReq.GetArg<SfxStringItem>(FN_PARAM_2);
+ const SfxBoolItem* pIsUrl = rReq.GetArg<SfxBoolItem>(FN_PARAM_1);
+ if ( pType )
+ aType = pType->GetValue();
+ if ( pIsUrl )
+ bIsUrl = pIsUrl->GetValue();
+
+ SwScriptField* pField = static_cast<SwScriptField*>(aMgr.GetCurField());
+ bNew = !pField || (pField->GetTyp()->Which() != SwFieldIds::Script);
+ bUpdate = pField && ( bIsUrl != static_cast<bool>(pField->GetFormat()) || pField->GetPar2() != aType || pField->GetPar1() != aText );
+ }
+ else
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractJavaEditDialog> pDlg(pFact->CreateJavaEditDialog(GetView().GetFrameWeld(), &rSh));
+ if ( pDlg->Execute() )
+ {
+ aType = pDlg->GetScriptType();
+ aText = pDlg->GetScriptText();
+ bIsUrl = pDlg->IsUrl();
+ bNew = pDlg->IsNew();
+ bUpdate = pDlg->IsUpdate();
+ rReq.AppendItem( SfxStringItem( FN_JAVAEDIT, aText ) );
+ rReq.AppendItem( SfxStringItem( FN_PARAM_2, aType ) );
+ rReq.AppendItem( SfxBoolItem( FN_PARAM_1, bIsUrl ) );
+ }
+ }
+
+ if( bNew )
+ {
+ SwInsertField_Data aData(SwFieldTypesEnum::Script, 0, aType, aText, bIsUrl ? 1 : 0);
+ aMgr.InsertField(aData);
+ rReq.Done();
+ }
+ else if( bUpdate )
+ {
+ aMgr.UpdateCurField( bIsUrl ? 1 : 0, aType, aText );
+ rSh.SetUndoNoResetModified();
+ rReq.Done();
+ }
+ else
+ rReq.Ignore();
+ }
+ break;
+
+ case FN_INSERT_FLD_DATE :
+ case FN_INSERT_FLD_DATE_VAR:
+ {
+ nInsertType = SwFieldTypesEnum::Date;
+ nInsertSubType = nSlot == FN_INSERT_FLD_DATE ? 0 : 1;
+ bIsText = false;
+ // use long date format for Hungarian
+ SwPaM* pCursorPos = rSh.GetCursor();
+ if( pCursorPos )
+ {
+ LanguageType nLang = pCursorPos->GetPoint()->GetNode().GetTextNode()->GetLang(pCursorPos->GetPoint()->GetContentIndex());
+ if (nLang == LANGUAGE_HUNGARIAN)
+ nInsertFormat = rSh.GetNumberFormatter()->GetFormatIndex(NF_DATE_SYSTEM_LONG, nLang);
+ }
+ goto FIELD_INSERT;
+ }
+ case FN_INSERT_FLD_TIME :
+ case FN_INSERT_FLD_TIME_VAR:
+ nInsertType = SwFieldTypesEnum::Time;
+ nInsertSubType = nSlot == FN_INSERT_FLD_TIME ? 0 : 1;
+ bIsText = false;
+ goto FIELD_INSERT;
+ case FN_INSERT_FLD_PGNUMBER:
+ nInsertType = SwFieldTypesEnum::PageNumber;
+ nInsertFormat = SVX_NUM_PAGEDESC; // Like page template
+ bIsText = false;
+ goto FIELD_INSERT;
+ case FN_INSERT_FLD_PGCOUNT :
+ nInsertType = SwFieldTypesEnum::DocumentStatistics;
+ nInsertSubType = 0;
+ bIsText = false;
+ nInsertFormat = SVX_NUM_PAGEDESC;
+ goto FIELD_INSERT;
+ case FN_INSERT_FLD_TOPIC :
+ nInsertType = SwFieldTypesEnum::DocumentInfo;
+ nInsertSubType = DI_SUBJECT;
+ goto FIELD_INSERT;
+ case FN_INSERT_FLD_TITLE :
+ nInsertType = SwFieldTypesEnum::DocumentInfo;
+ nInsertSubType = DI_TITLE;
+ goto FIELD_INSERT;
+ case FN_INSERT_FLD_AUTHOR :
+ nInsertType = SwFieldTypesEnum::DocumentInfo;
+ nInsertSubType = DI_CREATE|DI_SUB_AUTHOR;
+
+FIELD_INSERT:
+ {
+ //format conversion should only be done for number formatter formats
+ if(!nInsertFormat)
+ nInsertFormat = aFieldMgr.GetDefaultFormat(nInsertType, bIsText, rSh.GetNumberFormatter());
+ SwInsertField_Data aData(nInsertType, nInsertSubType,
+ OUString(), OUString(), nInsertFormat);
+ aFieldMgr.InsertField(aData);
+ rReq.Done();
+ }
+ break;
+
+ case FN_INSERT_TEXT_FORMFIELD:
+ {
+ OUString aFieldType(ODF_FORMTEXT);
+ const SfxStringItem* pFieldType = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ if (pFieldType)
+ {
+ // Allow overwriting the default type.
+ aFieldType = pFieldType->GetValue();
+ }
+
+ OUString aFieldCode;
+ const SfxStringItem* pFieldCode = rReq.GetArg<SfxStringItem>(FN_PARAM_2);
+ if (pFieldCode)
+ {
+ // Allow specifying a field code/command.
+ aFieldCode = pFieldCode->GetValue();
+ }
+
+ if (rSh.HasReadonlySel())
+ {
+ // Inform the user that the request has been ignored.
+ auto xInfo = std::make_shared<weld::GenericDialogController>(
+ GetView().GetFrameWeld(), "modules/swriter/ui/inforeadonlydialog.ui",
+ "InfoReadonlyDialog");
+ weld::DialogController::runAsync(xInfo, [](sal_Int32 /*nResult*/) {});
+ break;
+ }
+
+ rSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT_FORM_FIELD, nullptr);
+
+ SwPaM* pCursorPos = rSh.GetCursor();
+ if(pCursorPos)
+ {
+ // Insert five En Space into the text field so the field has extent
+ static constexpr OUStringLiteral vEnSpaces = u"\u2002\u2002\u2002\u2002\u2002";
+ OUString aFieldResult(vEnSpaces);
+ const SfxStringItem* pFieldResult = rReq.GetArg<SfxStringItem>(FN_PARAM_3);
+ if (pFieldResult)
+ {
+ // Allow specifying a field result / expanded value.
+ aFieldResult = pFieldResult->GetValue();
+ }
+
+ const SfxStringItem* pWrapper = rReq.GetArg<SfxStringItem>(FN_PARAM_4);
+ if (pWrapper)
+ {
+ // Wrap the fieldmark in the requested container instead of inserting it
+ // directly at the cursor position.
+ OUString aWrapper = pWrapper->GetValue();
+ if (aWrapper == "Footnote")
+ {
+ rSh.InsertFootnote(OUString());
+ }
+ else if (aWrapper == "Endnote")
+ {
+ // It's important that there is no Start/EndAction() around this, so the
+ // inner EndAction() triggers a layout update and the cursor can jump to the
+ // created SwFootnoteFrame.
+ rSh.InsertFootnote(OUString(), /*bEndNote=*/true);
+ }
+ }
+
+ // Don't update the layout after inserting content and before deleting temporary
+ // text nodes.
+ rSh.StartAction();
+
+ // Split node to remember where the start position is.
+ bool bSuccess = rSh.GetDoc()->getIDocumentContentOperations().SplitNode(
+ *pCursorPos->GetPoint(), false);
+ if(bSuccess)
+ {
+ SwPaM aFieldPam(*pCursorPos->GetPoint());
+ aFieldPam.Move(fnMoveBackward, GoInContent);
+ if (pFieldResult)
+ {
+ // Paste HTML content.
+ SwTranslateHelper::PasteHTMLToPaM(rSh, pCursorPos, aFieldResult.toUtf8());
+ if (pCursorPos->GetPoint()->GetContentIndex() == 0)
+ {
+ // The paste created a last empty text node, remove it.
+ SwPaM aPam(*pCursorPos->GetPoint());
+ aPam.SetMark();
+ aPam.Move(fnMoveBackward, GoInContent);
+ rSh.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(aPam);
+ }
+ }
+ else
+ {
+ // Insert default placeholder.
+ rSh.GetDoc()->getIDocumentContentOperations().InsertString(*pCursorPos,
+ aFieldResult);
+ }
+ // Undo the above SplitNode().
+ aFieldPam.SetMark();
+ aFieldPam.Move(fnMoveForward, GoInContent);
+ rSh.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(aFieldPam);
+ *aFieldPam.GetMark() = *pCursorPos->GetPoint();
+
+ IDocumentMarkAccess* pMarksAccess = rSh.GetDoc()->getIDocumentMarkAccess();
+ sw::mark::IFieldmark* pFieldmark = pMarksAccess->makeFieldBookmark(
+ aFieldPam, OUString(), aFieldType, aFieldPam.Start());
+ if (pFieldmark && !aFieldCode.isEmpty())
+ {
+ pFieldmark->GetParameters()->insert(
+ std::pair<OUString, uno::Any>(ODF_CODE_PARAM, uno::Any(aFieldCode)));
+ }
+ }
+ rSh.EndAction();
+ }
+
+ rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD, nullptr);
+ rSh.GetView().GetViewFrame().GetBindings().Invalidate( SID_UNDO );
+ }
+ break;
+ case FN_INSERT_CHECKBOX_FORMFIELD:
+ {
+ rSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT_FORM_FIELD, nullptr);
+
+ SwPaM* pCursorPos = rSh.GetCursor();
+ if(pCursorPos)
+ {
+ IDocumentMarkAccess* pMarksAccess = rSh.GetDoc()->getIDocumentMarkAccess();
+ pMarksAccess->makeNoTextFieldBookmark(*pCursorPos, OUString(), ODF_FORMCHECKBOX);
+ }
+
+ rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD, nullptr);
+ rSh.GetView().GetViewFrame().GetBindings().Invalidate( SID_UNDO );
+ }
+ break;
+ case FN_INSERT_DROPDOWN_FORMFIELD:
+ {
+ rSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT_FORM_FIELD, nullptr);
+
+ SwPaM* pCursorPos = rSh.GetCursor();
+ if(pCursorPos)
+ {
+ IDocumentMarkAccess* pMarksAccess = rSh.GetDoc()->getIDocumentMarkAccess();
+ pMarksAccess->makeNoTextFieldBookmark(*pCursorPos, OUString(), ODF_FORMDROPDOWN);
+ }
+
+ rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD, nullptr);
+ rSh.GetView().GetViewFrame().GetBindings().Invalidate( SID_UNDO );
+ }
+ break;
+ case FN_INSERT_DATE_FORMFIELD:
+ {
+ rSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT_FORM_FIELD, nullptr);
+
+ SwPaM* pCursorPos = rSh.GetCursor();
+ if(pCursorPos)
+ {
+ // Insert five enspaces into the text field so the field has extent
+ sal_Unicode vEnSpaces[ODF_FORMFIELD_DEFAULT_LENGTH] = {8194, 8194, 8194, 8194, 8194};
+ bool bSuccess = rSh.GetDoc()->getIDocumentContentOperations().InsertString(*pCursorPos, OUString(vEnSpaces, ODF_FORMFIELD_DEFAULT_LENGTH));
+ if(bSuccess)
+ {
+ IDocumentMarkAccess* pMarksAccess = rSh.GetDoc()->getIDocumentMarkAccess();
+ SwPaM aFieldPam(pCursorPos->GetPoint()->GetNode(), pCursorPos->GetPoint()->GetContentIndex() - ODF_FORMFIELD_DEFAULT_LENGTH,
+ pCursorPos->GetPoint()->GetNode(), pCursorPos->GetPoint()->GetContentIndex());
+ sw::mark::IFieldmark* pFieldBM = pMarksAccess->makeFieldBookmark(aFieldPam, OUString(), ODF_FORMDATE,
+ aFieldPam.Start());
+
+ // Use a default date format and language
+ sw::mark::IFieldmark::parameter_map_t* pParameters = pFieldBM->GetParameters();
+ SvNumberFormatter* pFormatter = rSh.GetDoc()->GetNumberFormatter();
+ sal_uInt32 nStandardFormat = pFormatter->GetStandardFormat(SvNumFormatType::DATE);
+ const SvNumberformat* pFormat = pFormatter->GetEntry(nStandardFormat);
+
+ (*pParameters)[ODF_FORMDATE_DATEFORMAT] <<= pFormat->GetFormatstring();
+ (*pParameters)[ODF_FORMDATE_DATEFORMAT_LANGUAGE] <<= LanguageTag(pFormat->GetLanguage()).getBcp47();
+ }
+ }
+
+ rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD, nullptr);
+ rSh.GetView().GetViewFrame().GetBindings().Invalidate( SID_UNDO );
+ }
+ break;
+ case FN_UPDATE_TEXT_FORMFIELDS:
+ {
+ // This updates multiple fieldmarks in a document, based on their field name & field command
+ // prefix.
+ OUString aFieldType;
+ const SfxStringItem* pFieldType = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ if (pFieldType)
+ {
+ aFieldType = pFieldType->GetValue();
+ }
+ OUString aFieldCommandPrefix;
+ const SfxStringItem* pFieldCommandPrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_2);
+ if (pFieldCommandPrefix)
+ {
+ aFieldCommandPrefix = pFieldCommandPrefix->GetValue();
+ }
+ uno::Sequence<beans::PropertyValues> aFields;
+ const SfxUnoAnyItem* pFields = rReq.GetArg<SfxUnoAnyItem>(FN_PARAM_3);
+ if (pFields)
+ {
+ pFields->GetValue() >>= aFields;
+ }
+
+ rSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::UPDATE_FORM_FIELDS, nullptr);
+ rSh.StartAction();
+
+ IDocumentMarkAccess* pMarkAccess = rSh.GetDoc()->getIDocumentMarkAccess();
+ sal_Int32 nFieldIndex = 0;
+ for (auto it = pMarkAccess->getFieldmarksBegin(); it != pMarkAccess->getFieldmarksEnd(); ++it)
+ {
+ auto pFieldmark = dynamic_cast<sw::mark::IFieldmark*>(*it);
+ assert(pFieldmark);
+ if (pFieldmark->GetFieldname() != aFieldType)
+ {
+ continue;
+ }
+
+ auto itParam = pFieldmark->GetParameters()->find(ODF_CODE_PARAM);
+ if (itParam == pFieldmark->GetParameters()->end())
+ {
+ continue;
+ }
+
+ OUString aCommand;
+ itParam->second >>= aCommand;
+ if (!aCommand.startsWith(aFieldCommandPrefix))
+ {
+ continue;
+ }
+
+ if (aFields.getLength() <= nFieldIndex)
+ {
+ continue;
+ }
+
+ comphelper::SequenceAsHashMap aMap(aFields[nFieldIndex++]);
+ itParam->second = aMap["FieldCommand"];
+ SwPaM aPaM(pFieldmark->GetMarkPos(), pFieldmark->GetOtherMarkPos());
+ aPaM.Normalize();
+ // Skip field start & separator.
+ aPaM.GetPoint()->AdjustContent(2);
+ // Skip field end.
+ aPaM.GetMark()->AdjustContent(-1);
+ rSh.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(aPaM);
+ OUString aFieldResult;
+ aMap["FieldResult"] >>= aFieldResult;
+ SwTranslateHelper::PasteHTMLToPaM(rSh, &aPaM, aFieldResult.toUtf8());
+ }
+
+ rSh.EndAction();
+ rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::UPDATE_FORM_FIELDS, nullptr);
+ }
+ break;
+ case FN_DELETE_TEXT_FORMFIELDS:
+ {
+ // This deletes all fieldmarks that match the provided field type & field command prefix.
+ OUString aFieldType;
+ const SfxStringItem* pFieldType = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ if (pFieldType)
+ {
+ aFieldType = pFieldType->GetValue();
+ }
+ OUString aFieldCommandPrefix;
+ const SfxStringItem* pFieldCommandPrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_2);
+ if (pFieldCommandPrefix)
+ {
+ aFieldCommandPrefix = pFieldCommandPrefix->GetValue();
+ }
+ rSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::DELETE_FORM_FIELDS, nullptr);
+ rSh.StartAction();
+
+ IDocumentMarkAccess* pMarkAccess = rSh.GetDoc()->getIDocumentMarkAccess();
+ std::vector<sw::mark::IMark*> aRemovals;
+ for (auto it = pMarkAccess->getFieldmarksBegin(); it != pMarkAccess->getFieldmarksEnd(); ++it)
+ {
+ auto pFieldmark = dynamic_cast<sw::mark::IFieldmark*>(*it);
+ assert(pFieldmark);
+ if (pFieldmark->GetFieldname() != aFieldType)
+ {
+ continue;
+ }
+
+ if (!aFieldCommandPrefix.isEmpty())
+ {
+ auto itParam = pFieldmark->GetParameters()->find(ODF_CODE_PARAM);
+ if (itParam == pFieldmark->GetParameters()->end())
+ {
+ continue;
+ }
+
+ OUString aCommand;
+ itParam->second >>= aCommand;
+ if (!aCommand.startsWith(aFieldCommandPrefix))
+ {
+ continue;
+ }
+ }
+
+ aRemovals.push_back(pFieldmark);
+ }
+
+ for (const auto& pMark : aRemovals)
+ {
+ pMarkAccess->deleteMark(pMark);
+ }
+
+ rSh.EndAction();
+ rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::DELETE_FORM_FIELDS, nullptr);
+ }
+ break;
+ case FN_PGNUMBER_WIZARD:
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ VclPtr<AbstractSwPageNumberDlg> pDlg(
+ pFact->CreateSwPageNumberDlg(GetView().GetFrameWeld()));
+ auto pShell = GetShellPtr();
+
+ const SwPageDesc& rCurrDesc = rSh.GetPageDesc(rSh.GetCurPageDesc());
+ pDlg->SetPageNumberType(rCurrDesc.GetNumType().GetNumberingType());
+
+ pDlg->StartExecuteAsync([pShell, &rSh, pDlg](int nResult) {
+ if ( nResult == RET_OK )
+ {
+ auto rDoc = rSh.GetDoc();
+
+ rSh.LockView(true);
+ rSh.StartAllAction();
+ rSh.SwCursorShell::Push();
+ rDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT_PAGE_NUMBER, nullptr);
+
+ const size_t nPageDescIndex = rSh.GetCurPageDesc();
+ const SwPageDesc& rDesc = rSh.GetPageDesc(nPageDescIndex);
+ const bool bHeader = !pDlg->GetPageNumberPosition();
+ const bool bHeaderAlreadyOn = rDesc.GetMaster().GetHeader().IsActive();
+ const bool bFooterAlreadyOn = rDesc.GetMaster().GetFooter().IsActive();
+ const bool bIsSinglePage = rDesc.GetFollow() != &rDesc;
+ const size_t nMirrorPagesNeeded = rDesc.IsFirstShared() ? 2 : 3;
+ const OUString sBookmarkName = OUString::Concat("PageNumWizard_")
+ + (bHeader ? "HEADER" : "FOOTER") + "_" + rDesc.GetName();
+ IDocumentMarkAccess& rIDMA = *rSh.getIDocumentMarkAccess();
+
+ // Allow wizard to be re-run: delete previously wizard-inserted page number.
+ // Try before creating non-shared header: avoid copying ODD bookmark onto EVEN page.
+ IDocumentMarkAccess::const_iterator_t ppMark = rIDMA.findMark(
+ sBookmarkName + OUString::number(rSh.GetVirtPageNum()));
+ if (ppMark != rIDMA.getAllMarksEnd() && *ppMark)
+ {
+ SwPaM aDeleteOldPageNum((*ppMark)->GetMarkStart(), (*ppMark)->GetMarkEnd());
+ rDoc->getIDocumentContentOperations().DeleteAndJoin(aDeleteOldPageNum);
+ }
+
+ SwPageDesc aNewDesc(rDesc);
+ bool bChangePageDesc = false;
+ if (pDlg->GetPageNumberType() != aNewDesc.GetNumType().GetNumberingType())
+ {
+ bChangePageDesc = true;
+ SvxNumberType aNewType(rDesc.GetNumType());
+ aNewType.SetNumberingType(pDlg->GetPageNumberType());
+ aNewDesc.SetNumType(aNewType);
+ }
+
+ // Insert header/footer
+ if ((bHeader && !bHeaderAlreadyOn) || (!bHeader && !bFooterAlreadyOn))
+ {
+ bChangePageDesc = true;
+ SwFrameFormat &rMaster = aNewDesc.GetMaster();
+ if (bHeader)
+ rMaster.SetFormatAttr(SwFormatHeader(/*On=*/true));
+ else
+ rMaster.SetFormatAttr(SwFormatFooter(/*On=*/true));
+
+ // Init copied from ChangeHeaderOrFooter: keep in sync
+ constexpr tools::Long constTwips_5mm = o3tl::toTwips(5, o3tl::Length::mm);
+ const SvxULSpaceItem aUL(bHeader ? 0 : constTwips_5mm,
+ bHeader ? constTwips_5mm : 0,
+ RES_UL_SPACE);
+ const XFillStyleItem aFill(drawing::FillStyle_NONE);
+ SwFrameFormat& rFormat
+ = bHeader
+ ? const_cast<SwFrameFormat&>(*rMaster.GetHeader().GetHeaderFormat())
+ : const_cast<SwFrameFormat&>(*rMaster.GetFooter().GetFooterFormat());
+ rFormat.SetFormatAttr(aUL);
+ rFormat.SetFormatAttr(aFill);
+
+ // Might as well turn on margin mirroring too - if appropriate
+ if (pDlg->GetMirrorOnEvenPages() && !bHeaderAlreadyOn && !bFooterAlreadyOn
+ && !bIsSinglePage
+ && (aNewDesc.ReadUseOn() & UseOnPage::Mirror) == UseOnPage::All)
+ {
+ aNewDesc.WriteUseOn(rDesc.ReadUseOn() | UseOnPage::Mirror);
+ }
+ }
+
+ const bool bCreateMirror = !bIsSinglePage && pDlg->GetMirrorOnEvenPages()
+ && nMirrorPagesNeeded <= rSh.GetPageCnt();
+ if (bCreateMirror)
+ {
+ // Use different left/right header/footer
+ if ((bHeader && rDesc.IsHeaderShared()) || (!bHeader && rDesc.IsFooterShared()))
+ {
+ bChangePageDesc = true;
+ if (bHeader)
+ aNewDesc.ChgHeaderShare(/*Share=*/false);
+ else
+ aNewDesc.ChgFooterShare(/*Share=*/false);
+ }
+ }
+
+ if (bChangePageDesc)
+ rSh.ChgPageDesc(nPageDescIndex, aNewDesc);
+
+ // Go to the header or footer insert position
+ bool bInHF = false;
+ bool bSkipMirror = true;
+ size_t nEvenPage = 0;
+ if (bCreateMirror || !rSh.GetCurrFrame())
+ {
+ // Come here if Currframe can't be found, otherwise Goto*Text will crash.
+ // Get*PageNum will also be invalid (0), so we have no idea where we are.
+ // (Since not asking for mirror, the likelihood is that the bHeader is shared,
+ // in which case it doesn't matter anyway, and we just hope for the best.)
+ // Read the code in this block assuming that bCreateMirror is true.
+
+ // There are enough pages that there probably is a valid odd page.
+ // However, that is not guaranteed: perhaps the page style switched,
+ // or a blank page was forced, or some other complexity.
+ bInHF = rSh.SetCursorInHdFt(nPageDescIndex, bHeader, /*Even=*/true);
+ if (bInHF)
+ {
+ // Remember valid EVEN page. Mirror it if also a valid ODD or FIRST page
+ nEvenPage = rSh.GetVirtPageNum();
+ assert (nEvenPage && "couldn't find page number. Use a bool instead");
+ }
+
+ bInHF = rSh.SetCursorInHdFt(nPageDescIndex, bHeader, /*Even=*/false);
+ if (bInHF && nEvenPage)
+ {
+ // Even though the cursor may be on a FIRST page,
+ // the user requested mirrored pages, and we have both ODD and EVEN,
+ // so set page numbers on these two pages, and leave FIRST alone.
+ bSkipMirror = false;
+ }
+ if (!bInHF)
+ {
+ // no ODD page, look for FIRST page
+ bInHF = rSh.SetCursorInHdFt(nPageDescIndex, bHeader, false, /*First=*/true);
+ if (bInHF && nEvenPage)
+ {
+ // Unlikely but valid situation: EVEN and FIRST pages, but no ODD page.
+ // In this case, the first header gets the specified page number
+ // and the even header is mirrored, with an empty odd header,
+ // as the user (somewhat) requested.
+ bSkipMirror = false;
+ }
+ }
+ assert((bInHF || nEvenPage) && "Impossible - why couldn't the move happen?");
+ assert((bInHF || nEvenPage == rSh.GetVirtPageNum()) && "Unexpected move");
+ }
+ else
+ {
+ if (bHeader)
+ bInHF = rSh.GotoHeaderText();
+ else
+ bInHF = rSh.GotoFooterText();
+ assert(bInHF && "shouldn't have a problem going to text when no mirroring");
+ }
+
+ // Allow wizard to be re-run: delete previously wizard-inserted page number.
+ // Now that the cursor may have moved to a different page, try delete again.
+ ppMark = rIDMA.findMark(sBookmarkName + OUString::number(rSh.GetVirtPageNum()));
+ if (ppMark != rIDMA.getAllMarksEnd() && *ppMark)
+ {
+ SwPaM aDeleteOldPageNum((*ppMark)->GetMarkStart(), (*ppMark)->GetMarkEnd());
+ rDoc->getIDocumentContentOperations().DeleteAndJoin(aDeleteOldPageNum);
+ }
+
+ SwTextNode* pTextNode = rSh.GetCursor()->GetPoint()->GetNode().GetTextNode();
+
+ // Insert new line if there is already text in header/footer
+ if (pTextNode && !pTextNode->GetText().isEmpty())
+ {
+ rDoc->getIDocumentContentOperations().SplitNode(*rSh.GetCursor()->GetPoint(), false);
+
+ // Go back to start of header/footer
+ if (bHeader)
+ rSh.GotoHeaderText();
+ else
+ rSh.GotoFooterText();
+ }
+
+ // Set alignment for the new line
+ switch (pDlg->GetPageNumberAlignment())
+ {
+ case 0:
+ {
+ SvxAdjustItem aAdjustItem(SvxAdjust::Left, RES_PARATR_ADJUST);
+ rSh.SetAttrItem(aAdjustItem);
+ break;
+ }
+ case 1:
+ {
+ SvxAdjustItem aAdjustItem(SvxAdjust::Center, RES_PARATR_ADJUST);
+ rSh.SetAttrItem(aAdjustItem);
+ break;
+ }
+ case 2:
+ {
+ SvxAdjustItem aAdjustItem(SvxAdjust::Right, RES_PARATR_ADJUST);
+ rSh.SetAttrItem(aAdjustItem);
+ break;
+ }
+ }
+
+ sal_Int32 nStartContentIndex = rSh.GetCursor()->Start()->GetContentIndex();
+ assert(!nStartContentIndex && "earlier split node if not empty, but not zero?");
+
+ // Insert page number
+ SwFieldMgr aMgr(pShell);
+ SwInsertField_Data aData(SwFieldTypesEnum::PageNumber, 0,
+ OUString(), OUString(), SVX_NUM_PAGEDESC);
+ aMgr.InsertField(aData);
+ if (pDlg->GetIncludePageTotal())
+ {
+ rDoc->getIDocumentContentOperations().InsertString(*rSh.GetCursor(), " / ");
+ SwInsertField_Data aPageTotalData(SwFieldTypesEnum::DocumentStatistics, DS_PAGE,
+ OUString(), OUString(), SVX_NUM_PAGEDESC);
+ aMgr.InsertField(aPageTotalData);
+ }
+
+ // Mark inserted fields with a bookmark - so it can be found/removed if re-run
+ SwPaM aNewBookmarkPaM(*rSh.GetCursor()->Start());
+ aNewBookmarkPaM.SetMark();
+ assert(aNewBookmarkPaM.GetPointContentNode() && "only SetContent on content node");
+ aNewBookmarkPaM.Start()->SetContent(nStartContentIndex);
+ rIDMA.makeMark(aNewBookmarkPaM,
+ sBookmarkName + OUString::number(rSh.GetVirtPageNum()),
+ IDocumentMarkAccess::MarkType::BOOKMARK,
+ sw::mark::InsertMode::New);
+
+ // Mirror on the even pages
+ if (!bSkipMirror && bCreateMirror
+ && rSh.SetCursorInHdFt(nPageDescIndex, bHeader, /*Even=*/true))
+ {
+ assert(nEvenPage && "what? no even page and yet we got here?");
+ ppMark = rIDMA.findMark(sBookmarkName + OUString::number(rSh.GetVirtPageNum()));
+ if (ppMark != rIDMA.getAllMarksEnd() && *ppMark)
+ {
+ SwPaM aDeleteOldPageNum((*ppMark)->GetMarkStart(), (*ppMark)->GetMarkEnd());
+ rDoc->getIDocumentContentOperations().DeleteAndJoin(aDeleteOldPageNum);
+ }
+
+ pTextNode = rSh.GetCursor()->GetPoint()->GetNode().GetTextNode();
+
+ // Insert new line if there is already text in header/footer
+ if (pTextNode && !pTextNode->GetText().isEmpty())
+ {
+ rDoc->getIDocumentContentOperations().SplitNode(
+ *rSh.GetCursor()->GetPoint(), false);
+ // Go back to start of header/footer
+ rSh.SetCursorInHdFt(nPageDescIndex, bHeader, /*Even=*/true);
+ }
+
+ // mirror the adjustment
+ assert(pDlg->GetPageNumberAlignment() != 1 && "cannot have Center and bMirror");
+ SvxAdjust eAdjust = SvxAdjust::Left;
+ if (!pDlg->GetPageNumberAlignment())
+ eAdjust = SvxAdjust::Right;
+ SvxAdjustItem aMirrorAdjustItem(eAdjust, RES_PARATR_ADJUST);
+ rSh.SetAttrItem(aMirrorAdjustItem);
+
+ nStartContentIndex = rSh.GetCursor()->Start()->GetContentIndex();
+
+ // Insert page number
+ SwFieldMgr aEvenMgr(pShell);
+ aEvenMgr.InsertField(aData);
+ if (pDlg->GetIncludePageTotal())
+ {
+ rDoc->getIDocumentContentOperations().InsertString(*rSh.GetCursor(), " / ");
+ SwInsertField_Data aPageTotalData(SwFieldTypesEnum::DocumentStatistics,
+ DS_PAGE, OUString(), OUString(),
+ SVX_NUM_PAGEDESC);
+ aMgr.InsertField(aPageTotalData);
+ }
+
+ // Mark inserted fields with a bookmark - so it can be found/removed if re-run
+ SwPaM aNewEvenBookmarkPaM(*rSh.GetCursor()->Start());
+ aNewEvenBookmarkPaM.SetMark();
+ aNewEvenBookmarkPaM.Start()->SetContent(nStartContentIndex);
+ rIDMA.makeMark(aNewEvenBookmarkPaM,
+ sBookmarkName + OUString::number(rSh.GetVirtPageNum()),
+ IDocumentMarkAccess::MarkType::BOOKMARK,
+ sw::mark::InsertMode::New);
+ }
+
+ rSh.SwCursorShell::Pop(SwCursorShell::PopMode::DeleteCurrent);
+ rSh.EndAllAction();
+ rSh.LockView(false);
+ rDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_PAGE_NUMBER, nullptr);
+ }
+ pDlg->disposeOnce();
+ });
+ rReq.Done();
+ }
+ break;
+ case FN_UPDATE_TEXT_FORMFIELD:
+ {
+ // This updates a single fieldmark under the current cursor.
+ OUString aFieldType;
+ const SfxStringItem* pFieldType = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ if (pFieldType)
+ {
+ aFieldType = pFieldType->GetValue();
+ }
+ OUString aFieldCommandPrefix;
+ const SfxStringItem* pFieldCommandPrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_2);
+ if (pFieldCommandPrefix)
+ {
+ aFieldCommandPrefix = pFieldCommandPrefix->GetValue();
+ }
+ uno::Sequence<beans::PropertyValue> aField;
+ const SfxUnoAnyItem* pFields = rReq.GetArg<SfxUnoAnyItem>(FN_PARAM_3);
+ if (pFields)
+ {
+ pFields->GetValue() >>= aField;
+ }
+
+ IDocumentMarkAccess& rIDMA = *rSh.getIDocumentMarkAccess();
+ SwPosition& rCursor = *rSh.GetCursor()->GetPoint();
+ sw::mark::IFieldmark* pFieldmark = rIDMA.getInnerFieldmarkFor(rCursor);
+ if (!pFieldmark)
+ {
+ break;
+ }
+
+ if (pFieldmark->GetFieldname() != aFieldType)
+ {
+ break;
+ }
+
+ auto itParam = pFieldmark->GetParameters()->find(ODF_CODE_PARAM);
+ if (itParam == pFieldmark->GetParameters()->end())
+ {
+ break;
+ }
+
+ OUString aCommand;
+ itParam->second >>= aCommand;
+ if (!aCommand.startsWith(aFieldCommandPrefix))
+ {
+ break;
+ }
+
+ rSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::UPDATE_FORM_FIELD, nullptr);
+ rSh.StartAction();
+ comphelper::SequenceAsHashMap aMap(aField);
+ itParam->second = aMap["FieldCommand"];
+ SwPaM aPaM(pFieldmark->GetMarkPos(), pFieldmark->GetOtherMarkPos());
+ aPaM.Normalize();
+ // Skip field start & separator.
+ aPaM.GetPoint()->AdjustContent(2);
+ // Skip field end.
+ aPaM.GetMark()->AdjustContent(-1);
+ rSh.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(aPaM);
+ OUString aFieldResult;
+ aMap["FieldResult"] >>= aFieldResult;
+ SwTranslateHelper::PasteHTMLToPaM(rSh, &aPaM, aFieldResult.toUtf8());
+
+ rSh.EndAction();
+ rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::UPDATE_FORM_FIELD, nullptr);
+ }
+ break;
+ default:
+ OSL_FAIL("wrong dispatcher");
+ return;
+ }
+}
+
+void SwTextShell::StateField( SfxItemSet &rSet )
+{
+ SwWrtShell& rSh = GetShell();
+ SfxWhichIter aIter( rSet );
+ const SwField* pField = nullptr;
+ bool bGetField = false;
+ sal_uInt16 nWhich = aIter.FirstWhich();
+
+ while (nWhich)
+ {
+ switch (nWhich)
+ {
+ case FN_DELETE_COMMENT:
+ case FN_DELETE_NOTE_AUTHOR:
+ case FN_DELETE_ALL_NOTES:
+ case FN_FORMAT_ALL_NOTES:
+ case FN_HIDE_NOTE:
+ case FN_HIDE_NOTE_AUTHOR:
+ case FN_HIDE_ALL_NOTES:
+ {
+ SwPostItMgr* pPostItMgr = GetView().GetPostItMgr();
+ if ( !pPostItMgr )
+ rSet.InvalidateItem( nWhich );
+ else if ( !pPostItMgr->HasActiveSidebarWin() )
+ {
+ rSet.InvalidateItem( FN_DELETE_COMMENT );
+ rSet.InvalidateItem( FN_HIDE_NOTE );
+ }
+ // tdf#137568 do not offer comment formatting, if no comments are present
+ if (!pPostItMgr || !pPostItMgr->HasNotes())
+ rSet.DisableItem( FN_FORMAT_ALL_NOTES );
+ }
+ break;
+
+ case FN_EDIT_FIELD:
+ {
+ if( !bGetField )
+ {
+ pField = rSh.GetCurField(true);
+ bGetField = true;
+ }
+
+ SwFieldIds nTempWhich = pField ? pField->GetTyp()->Which() : SwFieldIds::Unknown;
+ if( SwFieldIds::Unknown == nTempWhich ||
+ SwFieldIds::Postit == nTempWhich ||
+ SwFieldIds::Script == nTempWhich ||
+ SwFieldIds::TableOfAuthorities == nTempWhich )
+ rSet.DisableItem( nWhich );
+ else if( SwFieldIds::Dde == nTempWhich &&
+ !static_cast<SwDDEFieldType*>(pField->GetTyp())->GetBaseLink().IsVisible())
+ {
+ // nested links cannot be edited
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case FN_UPDATE_SEL_FIELD:
+ {
+ pField = rSh.GetCurField();
+
+ if (!pField)
+ rSet.DisableItem( nWhich );
+ }
+
+ break;
+
+ case FN_EXECUTE_MACROFIELD:
+ {
+ if(!bGetField)
+ {
+ pField = rSh.GetCurField();
+ bGetField = true;
+ }
+ if(!pField || pField->GetTyp()->Which() != SwFieldIds::Macro)
+ rSet.DisableItem(nWhich);
+ }
+ break;
+
+ case FN_INSERT_FIELD:
+ {
+ if ( rSh.CursorInsideInputField() )
+ {
+ rSet.DisableItem(nWhich);
+ }
+ else
+ {
+ SfxViewFrame& rVFrame = GetView().GetViewFrame();
+ //#i5788# prevent closing of the field dialog while a modal dialog ( Input field dialog ) is active
+ if(!rVFrame.IsInModalMode() &&
+ rVFrame.KnowsChildWindow(FN_INSERT_FIELD) && !rVFrame.HasChildWindow(FN_INSERT_FIELD_DATA_ONLY) )
+ rSet.Put(SfxBoolItem( FN_INSERT_FIELD, rVFrame.HasChildWindow(nWhich)));
+ else
+ rSet.DisableItem(FN_INSERT_FIELD);
+ }
+ }
+ break;
+
+ case FN_INSERT_REF_FIELD:
+ {
+ SfxViewFrame& rVFrame = GetView().GetViewFrame();
+ if ( !rVFrame.KnowsChildWindow(FN_INSERT_FIELD)
+ || rSh.CursorInsideInputField() )
+ {
+ rSet.DisableItem(FN_INSERT_REF_FIELD);
+ }
+ }
+ break;
+
+ case FN_INSERT_FIELD_CTRL:
+ if ( rSh.CursorInsideInputField() )
+ {
+ rSet.DisableItem(nWhich);
+ }
+ else
+ {
+ rSet.Put(SfxBoolItem( nWhich, GetView().GetViewFrame().HasChildWindow(FN_INSERT_FIELD)));
+ }
+ break;
+
+ case FN_REDLINE_COMMENT:
+ if (!comphelper::LibreOfficeKit::isActive() && !rSh.GetCurrRedline())
+ rSet.DisableItem(nWhich);
+ break;
+
+ case FN_REPLY:
+ if (!comphelper::LibreOfficeKit::isActive())
+ rSet.DisableItem(nWhich);
+ break;
+
+ case FN_POSTIT :
+ case FN_JAVAEDIT :
+ {
+ bool bCurField = false;
+ pField = rSh.GetCurField();
+ if(nWhich == FN_POSTIT)
+ bCurField = pField && pField->GetTyp()->Which() == SwFieldIds::Postit;
+ else
+ bCurField = pField && pField->GetTyp()->Which() == SwFieldIds::Script;
+
+ if( !bCurField && rSh.IsReadOnlyAvailable() && rSh.HasReadonlySel() )
+ {
+ rSet.DisableItem(nWhich);
+ }
+ else if ( rSh.CursorInsideInputField() )
+ {
+ rSet.DisableItem(nWhich);
+ }
+ // tdf#86188, tdf#135794: Allow disabling comment insertion
+ // on footnote/endnote/header/frames for better OOXML interoperability
+ else if (!officecfg::Office::Compatibility::View::AllowCommentsInFootnotes::get() &&
+ (rSh.IsCursorInFootnote() || rSh.IsInHeaderFooter() ||
+ rSh.GetCurrFlyFrame(/*bCalcFrame=*/false)))
+ {
+ rSet.DisableItem(nWhich);
+ }
+ }
+
+ break;
+
+ case FN_INSERT_FLD_AUTHOR:
+ case FN_INSERT_FLD_DATE:
+ case FN_INSERT_FLD_PGCOUNT:
+ case FN_INSERT_FLD_PGNUMBER:
+ case FN_INSERT_FLD_TIME:
+ case FN_INSERT_FLD_TITLE:
+ case FN_INSERT_FLD_TOPIC:
+ case FN_INSERT_DBFIELD:
+ if ( rSh.CursorInsideInputField() )
+ {
+ rSet.DisableItem(nWhich);
+ }
+ break;
+
+ case FN_INSERT_TEXT_FORMFIELD:
+ case FN_INSERT_CHECKBOX_FORMFIELD:
+ case FN_INSERT_DROPDOWN_FORMFIELD:
+ case FN_INSERT_DATE_FORMFIELD:
+ if ( rSh.CursorInsideInputField() )
+ {
+ rSet.DisableItem(nWhich);
+ }
+ else
+ {
+ // Check whether we are in a text form field
+ SwPosition aCursorPos(*rSh.GetCursor()->GetPoint());
+ sw::mark::IFieldmark* pFieldBM = GetShell().getIDocumentMarkAccess()->getInnerFieldmarkFor(aCursorPos);
+ if ((!pFieldBM || pFieldBM->GetFieldname() != ODF_FORMTEXT)
+ && aCursorPos.GetContentIndex() > 0)
+ {
+ SwPosition aPos(*aCursorPos.GetContentNode(), aCursorPos.GetContentIndex() - 1);
+ pFieldBM = GetShell().getIDocumentMarkAccess()->getInnerFieldmarkFor(aPos);
+ }
+ if (pFieldBM && pFieldBM->GetFieldname() == ODF_FORMTEXT &&
+ (aCursorPos > pFieldBM->GetMarkStart() && aCursorPos < pFieldBM->GetMarkEnd() ))
+ {
+ rSet.DisableItem(nWhich);
+ }
+ }
+ break;
+
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void SwTextShell::InsertHyperlink(const SvxHyperlinkItem& rHlnkItem)
+{
+ const OUString& rName = rHlnkItem.GetName();
+ const OUString& rURL = rHlnkItem.GetURL();
+ const OUString& rTarget = rHlnkItem.GetTargetFrame();
+ const OUString& rReplacementText = rHlnkItem.GetReplacementText();
+ sal_uInt16 nType = o3tl::narrowing<sal_uInt16>(rHlnkItem.GetInsertMode());
+ nType &= ~HLINK_HTMLMODE;
+ const SvxMacroTableDtor* pMacroTable = rHlnkItem.GetMacroTable();
+
+ SwWrtShell& rSh = GetShell();
+
+ if( !(rSh.GetSelectionType() & SelectionType::Text) )
+ return;
+
+ rSh.StartAction();
+ SfxItemSetFixed<RES_TXTATR_INETFMT, RES_TXTATR_INETFMT> aSet(GetPool());
+ rSh.GetCurAttr( aSet );
+
+ if(SfxItemState::SET == aSet.GetItemState(RES_TXTATR_INETFMT, false))
+ {
+ // Select links
+ rSh.SwCursorShell::SelectTextAttr(RES_TXTATR_INETFMT, false);
+ }
+ switch (nType)
+ {
+ case HLINK_DEFAULT:
+ case HLINK_FIELD:
+ {
+ SwFormatINetFormat aINetFormat( rURL, rTarget );
+ aINetFormat.SetName(rHlnkItem.GetIntName());
+ if(pMacroTable)
+ {
+ const SvxMacro *pMacro = pMacroTable->Get( SvMacroItemId::OnMouseOver );
+ if( pMacro )
+ aINetFormat.SetMacro(SvMacroItemId::OnMouseOver, *pMacro);
+ pMacro = pMacroTable->Get( SvMacroItemId::OnClick );
+ if( pMacro )
+ aINetFormat.SetMacro(SvMacroItemId::OnClick, *pMacro);
+ pMacro = pMacroTable->Get( SvMacroItemId::OnMouseOut );
+ if( pMacro )
+ aINetFormat.SetMacro(SvMacroItemId::OnMouseOut, *pMacro);
+ }
+ rSh.SttSelect();
+ // inserting mention
+ if (comphelper::LibreOfficeKit::isActive() && !rReplacementText.isEmpty())
+ {
+ SwPaM* pCursorPos = rSh.GetCursor();
+ // move cursor backwards to select @mention
+ for(int i=0; i < rReplacementText.getLength(); i++)
+ pCursorPos->Move(fnMoveBackward);
+ rSh.InsertURL( aINetFormat, rName, false );
+ }
+ else
+ {
+ rSh.InsertURL( aINetFormat, rName, true );
+ }
+ rSh.EndSelect();
+ }
+ break;
+
+ case HLINK_BUTTON:
+ bool bSel = rSh.HasSelection();
+ if(bSel)
+ rSh.DelRight();
+ InsertURLButton( rURL, rTarget, rName );
+ rSh.EnterStdMode();
+ break;
+ }
+ rSh.EndAction();
+}
+
+IMPL_LINK( SwTextShell, RedlineNextHdl, AbstractSvxPostItDialog&, rDlg, void )
+{
+ SwWrtShell* pSh = GetShellPtr();
+
+ // Insert or change a comment.
+ pSh->SetRedlineComment(rDlg.GetNote());
+
+ const SwRangeRedline *pRedline = pSh->GetCurrRedline();
+
+ if (!pRedline)
+ return;
+
+ // Traveling only if more than one field.
+ if( !pSh->IsCursorPtAtEnd() )
+ pSh->SwapPam(); // Move the cursor behind the Redline.
+
+ pSh->Push();
+ const SwRangeRedline *pActRed = pSh->SelNextRedline();
+ pSh->Pop((pActRed != nullptr) ? SwCursorShell::PopMode::DeleteStack : SwCursorShell::PopMode::DeleteCurrent);
+
+ bool bEnable = false;
+
+ if (pActRed)
+ {
+ pSh->StartAction();
+ pSh->Push();
+ bEnable = pSh->SelNextRedline() != nullptr;
+ pSh->Pop(SwCursorShell::PopMode::DeleteCurrent);
+ pSh->EndAction();
+ }
+
+ rDlg.EnableTravel(bEnable, true);
+
+ if( pSh->IsCursorPtAtEnd() )
+ pSh->SwapPam();
+
+ pRedline = pSh->GetCurrRedline();
+ OUString sComment = convertLineEnd(pRedline->GetComment(), GetSystemLineEnd());
+
+ rDlg.SetNote(sComment);
+ rDlg.ShowLastAuthor( pRedline->GetAuthorString(),
+ GetAppLangDateTimeString(
+ pRedline->GetRedlineData().GetTimeStamp() ));
+
+ rDlg.SetText(lcl_BuildTitleWithRedline(pRedline));
+
+}
+
+IMPL_LINK( SwTextShell, RedlinePrevHdl, AbstractSvxPostItDialog&, rDlg, void )
+{
+ SwWrtShell* pSh = GetShellPtr();
+
+ // Insert or change a comment.
+ pSh->SetRedlineComment(rDlg.GetNote());
+
+ const SwRangeRedline *pRedline = pSh->GetCurrRedline();
+
+ if (!pRedline)
+ return;
+
+ // Traveling only if more than one field.
+ pSh->Push();
+ const SwRangeRedline *pActRed = pSh->SelPrevRedline();
+ pSh->Pop((pActRed != nullptr) ? SwCursorShell::PopMode::DeleteStack : SwCursorShell::PopMode::DeleteCurrent);
+
+ bool bEnable = false;
+
+ if (pActRed)
+ {
+ pSh->StartAction();
+ pSh->Push();
+ bEnable = pSh->SelPrevRedline() != nullptr;
+ pSh->Pop(SwCursorShell::PopMode::DeleteCurrent);
+ pSh->EndAction();
+ }
+
+ rDlg.EnableTravel(true, bEnable);
+
+ pRedline = pSh->GetCurrRedline();
+ OUString sComment = convertLineEnd(pRedline->GetComment(), GetSystemLineEnd());
+
+ rDlg.SetNote(sComment);
+ rDlg.ShowLastAuthor(pRedline->GetAuthorString(),
+ GetAppLangDateTimeString(
+ pRedline->GetRedlineData().GetTimeStamp() ));
+
+ rDlg.SetText(lcl_BuildTitleWithRedline(pRedline));
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/textglos.cxx b/sw/source/uibase/shells/textglos.cxx
new file mode 100644
index 0000000000..d229964d20
--- /dev/null
+++ b/sw/source/uibase/shells/textglos.cxx
@@ -0,0 +1,126 @@
+/* -*- 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 <sfx2/request.hxx>
+#include <svl/eitem.hxx>
+#include <svl/stritem.hxx>
+#include <osl/diagnose.h>
+
+#include <view.hxx>
+#include <cmdid.h>
+#include <textsh.hxx>
+#include <initui.hxx>
+#include <gloshdl.hxx>
+#include <glosdoc.hxx>
+#include <gloslst.hxx>
+#include <swabstdlg.hxx>
+
+void SwTextShell::ExecGlossary(SfxRequest &rReq)
+{
+ const sal_uInt16 nSlot = rReq.GetSlot();
+ ::GetGlossaries()->UpdateGlosPath(!rReq.IsAPI() ||
+ FN_GLOSSARY_DLG == nSlot );
+ SwGlossaryHdl* pGlosHdl = GetView().GetGlosHdl();
+ // Update SwGlossaryList?
+ bool bUpdateList = false;
+
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ const SfxPoolItem* pItem = nullptr;
+ if(pArgs)
+ pArgs->GetItemState(nSlot, false, &pItem );
+
+ switch( nSlot )
+ {
+ case FN_GLOSSARY_DLG:
+ pGlosHdl->GlossaryDlg();
+ bUpdateList = true;
+ rReq.Ignore();
+ break;
+ case FN_EXPAND_GLOSSARY:
+ {
+ bool bReturn;
+ bReturn = pGlosHdl->ExpandGlossary(rReq.GetFrameWeld());
+ rReq.SetReturnValue( SfxBoolItem( nSlot, bReturn ) );
+ rReq.Done();
+ }
+ break;
+ case FN_NEW_GLOSSARY:
+ if(pItem && pArgs->Count() == 3 )
+ {
+ OUString aGroup = static_cast<const SfxStringItem *>(pItem)->GetValue();
+ OUString aName;
+ if(SfxItemState::SET == pArgs->GetItemState(FN_PARAM_1, false, &pItem ))
+ aName = static_cast<const SfxStringItem *>(pItem)->GetValue();
+ OUString aShortName;
+ if(SfxItemState::SET == pArgs->GetItemState(FN_PARAM_2, false, &pItem ))
+ aShortName = static_cast<const SfxStringItem *>(pItem)->GetValue();
+
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ::GlossarySetActGroup fnSetActGroup = pFact->SetGlossaryActGroupFunc();
+ if ( fnSetActGroup )
+ (*fnSetActGroup)( aGroup );
+ pGlosHdl->SetCurGroup(aGroup, true);
+ // Chosen group must be created in NewGlossary if necessary!
+ pGlosHdl->NewGlossary( aName, aShortName, true );
+ rReq.Done();
+ }
+ bUpdateList = true;
+ break;
+ case FN_SET_ACT_GLOSSARY:
+ if(pItem)
+ {
+ OUString aGroup = static_cast<const SfxStringItem *>(pItem)->GetValue();
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ::GlossarySetActGroup fnSetActGroup = pFact->SetGlossaryActGroupFunc();
+ if ( fnSetActGroup )
+ (*fnSetActGroup)( aGroup );
+ rReq.Done();
+ }
+ break;
+ case FN_INSERT_GLOSSARY:
+ {
+ if(pItem && pArgs->Count() > 1)
+ {
+ OUString aGroup = static_cast<const SfxStringItem *>(pItem)->GetValue();
+ OUString aName;
+ if(SfxItemState::SET == pArgs->GetItemState(FN_PARAM_1, false, &pItem ))
+ aName = static_cast<const SfxStringItem *>(pItem)->GetValue();
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ::GlossarySetActGroup fnSetActGroup = pFact->SetGlossaryActGroupFunc();
+ if ( fnSetActGroup )
+ (*fnSetActGroup)( aGroup );
+ pGlosHdl->SetCurGroup(aGroup, true);
+ rReq.SetReturnValue(SfxBoolItem(nSlot, pGlosHdl->InsertGlossary( aName )));
+ rReq.Done();
+ }
+ }
+ break;
+ default:
+ OSL_FAIL("wrong dispatcher");
+ return;
+ }
+ if(bUpdateList)
+ {
+ SwGlossaryList* pList = ::GetGlossaryList();
+ if(pList->IsActive())
+ pList->Update();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/textidx.cxx b/sw/source/uibase/shells/textidx.cxx
new file mode 100644
index 0000000000..35642a73f1
--- /dev/null
+++ b/sw/source/uibase/shells/textidx.cxx
@@ -0,0 +1,324 @@
+/* -*- 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 <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svl/eitem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <osl/diagnose.h>
+#include <fmtfsize.hxx>
+#include <fldbas.hxx>
+#include <uiitems.hxx>
+#include <viewopt.hxx>
+#include <cmdid.h>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <textsh.hxx>
+#include <idxmrk.hxx>
+#include <toxmgr.hxx>
+#include <swabstdlg.hxx>
+
+#include <ndtxt.hxx>
+#include <fmtfld.hxx>
+#include <IDocumentFieldsAccess.hxx>
+
+void SwTextShell::ExecIdx(SfxRequest const &rReq)
+{
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ const SfxPoolItem* pItem = nullptr;
+ const sal_uInt16 nSlot = rReq.GetSlot();
+ if (pArgs)
+ pArgs->GetItemState(nSlot, false, &pItem);
+
+ SfxViewFrame& rVFrame = GetView().GetViewFrame();
+
+ switch (nSlot)
+ {
+ case FN_EDIT_AUTH_ENTRY_DLG:
+ {
+ SwWrtShell& rShell = GetShell();
+
+ const bool bWasViewLocked = rShell.IsViewLocked();
+ rShell.LockView(true);
+
+ if (const SwField* const pCurrentField = rShell.GetCurField();
+ !rShell.HasReadonlySel() && pCurrentField != nullptr
+ && pCurrentField->GetTyp()->Which() == SwFieldIds::TableOfAuthorities)
+ {
+ // Since the cursor is on a bibliography mark (e.g. "[1]"), open the edit dialog as usual
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<VclAbstractDialog> pDlg(
+ pFact->CreateSwAutoMarkDialog(GetView().GetFrameWeld(), rShell));
+ pDlg->Execute();
+ }
+ else if (const SwTOXBase* const pCurrentTOX = rShell.GetCurTOX();
+ pCurrentTOX != nullptr && pCurrentTOX->GetType() == TOX_AUTHORITIES
+ && (rShell.GetCursor()->GetPoint()->GetNode()
+ .FindSectionNode()->GetSection().GetType()
+ == SectionType::ToxContent))
+ {
+ // Since the cursor is in the bibliography table, find the first mark that would match the given row
+ const SwNode* const pTableRowNode = &rShell.GetCursor()->GetPoint()->GetNode();
+ const OUString& rTableRowText
+ = static_cast<const SwTextNode*>(pTableRowNode)->GetText();
+
+ const SwFieldType* pAuthField
+ = rShell.GetDoc()->getIDocumentFieldsAccess().GetFieldType(
+ SwFieldIds::TableOfAuthorities, OUString(), false);
+
+ if (pAuthField)
+ {
+ bool bMatchingMarkFound = false;
+ {
+ std::vector<SwFormatField*> vFields;
+ pAuthField->GatherFields(vFields);
+ for (auto pFormatField : vFields)
+ {
+ if (const SwField* pIteratedField = nullptr;
+ pFormatField != nullptr
+ && (pIteratedField = pFormatField->GetField()) != nullptr
+ && (pIteratedField->GetTyp()->Which()
+ == SwFieldIds::TableOfAuthorities))
+ {
+ OUString sMarkText
+ = static_cast<const SwAuthorityField*>(pIteratedField)
+ ->GetAuthority(rShell.GetLayout(),
+ &pCurrentTOX->GetTOXForm());
+
+ if (sMarkText == rTableRowText)
+ {
+ // Since the text generated from the mark would match the given row
+ // move cursor to it, set bMatchingMarkFound and break
+ rShell.GotoFormatField(*pFormatField);
+ bMatchingMarkFound = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (bMatchingMarkFound)
+ {
+ // Since matching mark has been found and cursor has been moved to it,
+ // open the edit dialog
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<VclAbstractDialog> pDlg(
+ pFact->CreateSwAutoMarkDialog(GetView().GetFrameWeld(), rShell));
+ pDlg->Execute();
+
+ // Refresh TOX
+ rShell.GetCursor_()->GetPoint()->Assign(*pTableRowNode);
+ rShell.UpdateTableOf(*pCurrentTOX);
+ }
+ else
+ {
+ // I think this ideally should be a pop-up warning, right?
+ SAL_WARN("sw", "No matching bibliography mark found. "
+ "This feature is only guaranteed to work if the bibliography table is up to date.");
+ }
+ }
+ }
+
+ if (!bWasViewLocked)
+ rShell.LockView(false);
+ }
+ break;
+ case FN_INSERT_AUTH_ENTRY_DLG:
+ {
+ // no BASIC support
+ rVFrame.ToggleChildWindow(FN_INSERT_AUTH_ENTRY_DLG);
+ Invalidate(rReq.GetSlot());
+ }
+ break;
+ case FN_INSERT_IDX_ENTRY_DLG:
+ {
+ rVFrame.ToggleChildWindow(FN_INSERT_IDX_ENTRY_DLG);
+ Invalidate(rReq.GetSlot());
+ }
+ break;
+ case FN_EDIT_IDX_ENTRY_DLG:
+ {
+ SwTOXMgr aMgr(GetShellPtr());
+ short nRet = RET_OK;
+ if(aMgr.GetTOXMarkCount() > 1)
+ { // Several marks, which should it be?
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<VclAbstractDialog> pMultDlg(pFact->CreateMultiTOXMarkDlg(GetView().GetFrameWeld(), aMgr));
+ nRet = pMultDlg->Execute();
+ }
+ if( nRet == RET_OK)
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateIndexMarkModalDlg(GetView().GetFrameWeld(), GetShell(), aMgr.GetCurTOXMark()));
+ pDlg->Execute();
+ }
+ break;
+ }
+ case FN_IDX_MARK_TO_IDX:
+ {
+ GetShell().GotoTOXMarkBase();
+ break;
+ }
+ case FN_INSERT_MULTI_TOX:
+ {
+ SfxItemSetFixed<
+ RES_FRM_SIZE, RES_FRM_SIZE,
+ RES_LR_SPACE, RES_LR_SPACE,
+ RES_BACKGROUND, RES_BACKGROUND,
+ RES_COL, RES_COL,
+ XATTR_FILL_FIRST, XATTR_FILL_LAST,
+ SID_ATTR_PAGE_SIZE, SID_ATTR_PAGE_SIZE,
+ FN_PARAM_TOX_TYPE, FN_PARAM_TOX_TYPE> aSet( GetPool() );
+ SwWrtShell& rSh = GetShell();
+ SwRect aRect;
+ rSh.CalcBoundRect(aRect, RndStdIds::FLY_AS_CHAR);
+
+ tools::Long nWidth = aRect.Width();
+ aSet.Put(SwFormatFrameSize(SwFrameSize::Variable, nWidth));
+ // Height = width for a more consistent preview (analogous to edit range)
+ aSet.Put(SvxSizeItem(SID_ATTR_PAGE_SIZE, Size(nWidth, nWidth)));
+ const SwTOXBase* pCurTOX = nullptr;
+ bool bGlobal = false;
+ if(pItem)
+ {
+ pCurTOX = static_cast<const SwTOXBase*>(static_cast<const SwPtrItem*>(pItem)->GetValue());
+ bGlobal = true;
+ }
+ else
+ pCurTOX = rSh.GetCurTOX();
+ if(pCurTOX)
+ {
+ const SfxItemSet* pSet = pCurTOX->GetAttrSet();
+ if(pSet)
+ aSet.Put(*pSet);
+ }
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ VclPtr<AbstractMultiTOXTabDialog> pDlg(pFact->CreateMultiTOXTabDialog(
+ GetView().GetFrameWeld(), aSet, rSh, const_cast<SwTOXBase*>(pCurTOX),
+ bGlobal));
+ pDlg->StartExecuteAsync([pDlg](sal_Int32 /*nResult*/){
+ pDlg->disposeOnce();
+ });
+ }
+ break;
+ case FN_REMOVE_CUR_TOX:
+ {
+ SwWrtShell& rSh = GetShell();
+ const SwTOXBase* pBase = rSh.GetCurTOX();
+ OSL_ENSURE(pBase, "no TOXBase to remove");
+ if( pBase )
+ rSh.DeleteTOX(*pBase, true);
+ }
+ break;
+ default:
+ OSL_ENSURE(false, "wrong dispatcher");
+ return;
+ }
+}
+
+void SwTextShell::GetIdxState(SfxItemSet &rSet)
+{
+ SwWrtShell& rSh = GetShell();
+ SfxViewFrame& rVFrame = GetView().GetViewFrame();
+ SwInsertIdxMarkWrapper *pIdxMrk = static_cast<SwInsertIdxMarkWrapper*>(
+ rVFrame.GetChildWindow(FN_INSERT_IDX_ENTRY_DLG));
+
+ SfxChildWindow* pAuthMark = rVFrame.GetChildWindow(FN_INSERT_AUTH_ENTRY_DLG);
+
+ const bool bHtmlMode = 0 != ::GetHtmlMode( GetView().GetDocShell() );
+ const SwTOXBase* pBase = nullptr;
+ if( bHtmlMode || nullptr != ( pBase = rSh.GetCurTOX()) )
+ {
+ if( pBase )
+ {
+ if(pBase->IsTOXBaseInReadonly())
+ {
+ rSet.DisableItem( FN_INSERT_MULTI_TOX );
+ }
+ }
+
+ rSet.DisableItem( FN_EDIT_IDX_ENTRY_DLG );
+ if(pBase == nullptr // tdf#72955: Hide the "Bibliography Entry" command if there is no TOX in the selection
+ || pBase->GetType() != TOX_AUTHORITIES // or if it is not a bibliography table
+ || (rSh.GetCursor()->GetPoint()->GetNode().FindSectionNode()->GetSection().GetType() != SectionType::ToxContent)) // or if it's the heading
+ rSet.DisableItem(FN_EDIT_AUTH_ENTRY_DLG);
+
+ if(!pIdxMrk)
+ rSet.DisableItem( FN_INSERT_IDX_ENTRY_DLG );
+ else
+ rSet.Put(SfxBoolItem(FN_INSERT_IDX_ENTRY_DLG, true));
+
+ if(!pAuthMark)
+ rSet.DisableItem( FN_INSERT_AUTH_ENTRY_DLG );
+ else
+ rSet.Put(SfxBoolItem(FN_INSERT_AUTH_ENTRY_DLG, true));
+
+ }
+ else if ( rSh.CursorInsideInputField() )
+ {
+ rSet.DisableItem( FN_INSERT_IDX_ENTRY_DLG );
+ rSet.DisableItem( FN_INSERT_AUTH_ENTRY_DLG );
+ rSet.DisableItem( FN_EDIT_AUTH_ENTRY_DLG );
+ rSet.DisableItem( FN_EDIT_IDX_ENTRY_DLG );
+ rSet.DisableItem( FN_INSERT_MULTI_TOX );
+ rSet.DisableItem( FN_REMOVE_CUR_TOX );
+ }
+ else
+ {
+
+ bool bEnableEdit = true;
+ bool bInReadonly = rSh.HasReadonlySel();
+ if(bInReadonly)
+ bEnableEdit = false;
+ else
+ {
+ SwTOXMarks aArr;
+ rSh.GetCurTOXMarks( aArr );
+ if( aArr.empty())
+ bEnableEdit = false;
+ }
+
+ if(!bEnableEdit)
+ rSet.DisableItem( FN_EDIT_IDX_ENTRY_DLG );
+
+ if(bInReadonly)
+ {
+ rSet.DisableItem(FN_INSERT_IDX_ENTRY_DLG);
+ rSet.DisableItem( FN_INSERT_MULTI_TOX );
+ }
+ else
+ rSet.Put(SfxBoolItem(FN_INSERT_IDX_ENTRY_DLG,
+ nullptr != pIdxMrk));
+
+ SwField* pField = rSh.GetCurField();
+
+ if(bInReadonly)
+ rSet.DisableItem(FN_INSERT_AUTH_ENTRY_DLG);
+ else
+ rSet.Put(SfxBoolItem(FN_INSERT_AUTH_ENTRY_DLG, nullptr != pAuthMark));
+
+ if( bInReadonly || !pField ||
+ pField->GetTyp()->Which() != SwFieldIds::TableOfAuthorities)
+ rSet.DisableItem(FN_EDIT_AUTH_ENTRY_DLG);
+ rSet.DisableItem(FN_REMOVE_CUR_TOX);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/textsh.cxx b/sw/source/uibase/shells/textsh.cxx
new file mode 100644
index 0000000000..0924935b3d
--- /dev/null
+++ b/sw/source/uibase/shells/textsh.cxx
@@ -0,0 +1,1107 @@
+/* -*- 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 <hintids.hxx>
+#include <comphelper/string.hxx>
+#include <svl/globalnameitem.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/frmdescr.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/viewfrm.hxx>
+
+#include <i18nutil/transliteration.hxx>
+#include <svl/eitem.hxx>
+#include <svl/ptitem.hxx>
+#include <svl/stritem.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <svx/hlnkitem.hxx>
+#include <svl/whiter.hxx>
+#include <sfx2/request.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/svxacorr.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <svtools/htmlcfg.hxx>
+#include <com/sun/star/embed/Aspects.hpp>
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
+#include <osl/diagnose.h>
+
+#include <comphelper/classids.hxx>
+#include <editeng/acorrcfg.hxx>
+#include <wdocsh.hxx>
+#include <fmtinfmt.hxx>
+#include <fmtclds.hxx>
+#include <fmtfsize.hxx>
+#include <swmodule.hxx>
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <docsh.hxx>
+#include <doc.hxx>
+#include <IDocumentChartDataProviderAccess.hxx>
+#include <uitool.hxx>
+#include <cmdid.h>
+#include <globals.hrc>
+#include <frmmgr.hxx>
+#include <textsh.hxx>
+#include <frmfmt.hxx>
+#include <tablemgr.hxx>
+#include <swundo.hxx>
+#include <breakit.hxx>
+#include <edtwin.hxx>
+#include <strings.hrc>
+#include <unochart.hxx>
+#include <chartins.hxx>
+#include <viewopt.hxx>
+
+#define ShellClass_SwTextShell
+#include <sfx2/msg.hxx>
+#include <vcl/EnumContext.hxx>
+#include <swslots.hxx>
+#include <SwRewriter.hxx>
+#include <SwCapObjType.hxx>
+
+#include <svx/svxdlg.hxx>
+#include <swabstdlg.hxx>
+#include <IDocumentDrawModelAccess.hxx>
+#include <drawdoc.hxx>
+#include <svtools/embedhlp.hxx>
+#include <sfx2/event.hxx>
+#include <com/sun/star/ui/dialogs/DialogClosedEvent.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <IDocumentUndoRedo.hxx>
+#include <formatcontentcontrol.hxx>
+
+using namespace ::com::sun::star;
+
+SFX_IMPL_INTERFACE(SwTextShell, SwBaseShell)
+
+IMPL_STATIC_LINK( SwTextShell, DialogClosedHdl, css::ui::dialogs::DialogClosedEvent*, pEvent, void )
+{
+ if (SwView* pView = GetActiveView())
+ {
+ SwWrtShell& rWrtShell = pView->GetWrtShell();
+
+ sal_Int16 nDialogRet = pEvent->DialogResult;
+ if( nDialogRet == ui::dialogs::ExecutableDialogResults::CANCEL )
+ {
+ rWrtShell.Undo();
+ rWrtShell.GetIDocumentUndoRedo().ClearRedo();
+ }
+ else
+ {
+ OSL_ENSURE( nDialogRet == ui::dialogs::ExecutableDialogResults::OK,
+ "dialog execution failed" );
+ }
+ }
+}
+
+void SwTextShell::InitInterface_Impl()
+{
+ GetStaticInterface()->RegisterPopupMenu("text");
+
+ GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Invisible, ToolbarId::Text_Toolbox_Sw);
+
+ GetStaticInterface()->RegisterChildWindow(FN_EDIT_FORMULA);
+ GetStaticInterface()->RegisterChildWindow(FN_INSERT_FIELD);
+ GetStaticInterface()->RegisterChildWindow(FN_INSERT_IDX_ENTRY_DLG);
+ GetStaticInterface()->RegisterChildWindow(FN_INSERT_AUTH_ENTRY_DLG);
+ GetStaticInterface()->RegisterChildWindow(SID_RUBY_DIALOG);
+ GetStaticInterface()->RegisterChildWindow(FN_WORDCOUNT_DIALOG);
+}
+
+
+void SwTextShell::ExecInsert(SfxRequest &rReq)
+{
+ SwWrtShell &rSh = GetShell();
+
+ OSL_ENSURE( !rSh.IsObjSelected() && !rSh.IsFrameSelected(),
+ "wrong shell on dispatcher" );
+
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ const SfxPoolItem* pItem = nullptr;
+ const sal_uInt16 nSlot = rReq.GetSlot();
+ if(pArgs)
+ pArgs->GetItemState(nSlot, false, &pItem );
+
+ switch( nSlot )
+ {
+ case FN_INSERT_STRING:
+ if( pItem )
+ rSh.InsertByWord(static_cast<const SfxStringItem *>(pItem)->GetValue());
+ break;
+
+ case FN_INSERT_SOFT_HYPHEN:
+ if( CHAR_SOFTHYPHEN != rSh.SwCursorShell::GetChar() &&
+ CHAR_SOFTHYPHEN != rSh.SwCursorShell::GetChar( true, -1 ))
+ rSh.Insert( OUString( CHAR_SOFTHYPHEN ) );
+ break;
+
+ case FN_INSERT_HARDHYPHEN:
+ case FN_INSERT_HARD_SPACE:
+ {
+ const sal_Unicode cIns = FN_INSERT_HARD_SPACE == nSlot ? CHAR_HARDBLANK : CHAR_HARDHYPHEN;
+
+ SvxAutoCorrCfg& rACfg = SvxAutoCorrCfg::Get();
+ SvxAutoCorrect* pACorr = rACfg.GetAutoCorrect();
+ if( pACorr && rACfg.IsAutoFormatByInput()
+ && pACorr->IsAutoCorrFlag(
+ ACFlags::CapitalStartSentence | ACFlags::CapitalStartWord |
+ ACFlags::AddNonBrkSpace | ACFlags::ChgOrdinalNumber | ACFlags::TransliterateRTL |
+ ACFlags::ChgToEnEmDash | ACFlags::SetINetAttr | ACFlags::Autocorrect |
+ ACFlags::SetDOIAttr ) )
+ {
+ rSh.AutoCorrect( *pACorr, cIns );
+ }
+ else
+ {
+ rSh.Insert( OUString( cIns ) );
+ }
+ }
+ break;
+
+ case FN_INSERT_NNBSP: // shift+mod2/alt+space inserts some other character w/o going through SwEditWin::KeyInput(), at least on macOS
+ case SID_INSERT_RLM :
+ case SID_INSERT_LRM :
+ case SID_INSERT_WJ :
+ case SID_INSERT_ZWSP:
+ {
+ sal_Unicode cIns = 0;
+ switch(nSlot)
+ {
+ case SID_INSERT_RLM : cIns = CHAR_RLM ; break;
+ case SID_INSERT_LRM : cIns = CHAR_LRM ; break;
+ case SID_INSERT_ZWSP : cIns = CHAR_ZWSP ; break;
+ case SID_INSERT_WJ: cIns = CHAR_WJ; break;
+ case FN_INSERT_NNBSP: cIns = CHAR_NNBSP; break;
+ }
+ rSh.Insert( OUString( cIns ) );
+ }
+ break;
+
+ case FN_INSERT_BREAK:
+ {
+ if (!rSh.CursorInsideInputField() && !rSh.CursorInsideContentControl())
+ {
+ rSh.SplitNode();
+ }
+ else
+ {
+ rSh.InsertLineBreak();
+ }
+ }
+ rReq.Done();
+ break;
+
+ case FN_INSERT_PAGEBREAK:
+ rSh.InsertPageBreak();
+ rReq.Done();
+ break;
+
+ case FN_INSERT_LINEBREAK:
+ rSh.InsertLineBreak();
+ rReq.Done();
+ break;
+
+ case FN_INSERT_CONTENT_CONTROL:
+ rSh.InsertContentControl(SwContentControlType::RICH_TEXT);
+ rReq.Done();
+ break;
+
+ case FN_INSERT_CHECKBOX_CONTENT_CONTROL:
+ rSh.InsertContentControl(SwContentControlType::CHECKBOX);
+ rReq.Done();
+ break;
+
+ case FN_INSERT_DROPDOWN_CONTENT_CONTROL:
+ rSh.InsertContentControl(SwContentControlType::DROP_DOWN_LIST);
+ rReq.Done();
+ break;
+
+ case FN_INSERT_PICTURE_CONTENT_CONTROL:
+ rSh.InsertContentControl(SwContentControlType::PICTURE);
+ rReq.Done();
+ break;
+
+ case FN_INSERT_DATE_CONTENT_CONTROL:
+ rSh.InsertContentControl(SwContentControlType::DATE);
+ rReq.Done();
+ break;
+
+ case FN_INSERT_PLAIN_TEXT_CONTENT_CONTROL:
+ rSh.InsertContentControl(SwContentControlType::PLAIN_TEXT);
+ rReq.Done();
+ break;
+
+ case FN_INSERT_COMBO_BOX_CONTENT_CONTROL:
+ rSh.InsertContentControl(SwContentControlType::COMBO_BOX);
+ rReq.Done();
+ break;
+
+ case FN_CONTENT_CONTROL_PROPERTIES:
+ {
+ SwWrtShell& rWrtSh = GetShell();
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSwContentControlDlg(GetView().GetFrameWeld(), rWrtSh));
+ VclAbstractDialog::AsyncContext aContext;
+ aContext.maEndDialogFn = [](sal_Int32){};
+ pDlg->StartExecuteAsync(aContext);
+ rReq.Done();
+ break;
+ }
+
+ case FN_INSERT_COLUMN_BREAK:
+ rSh.InsertColumnBreak();
+ rReq.Done();
+ break;
+
+ case SID_HYPERLINK_SETLINK:
+ if (pItem)
+ InsertHyperlink(*static_cast<const SvxHyperlinkItem *>(pItem));
+ rReq.Done();
+ break;
+
+#if HAVE_FEATURE_AVMEDIA
+ case SID_INSERT_AVMEDIA:
+ rReq.SetReturnValue(SfxBoolItem(nSlot, InsertMediaDlg( rReq )));
+ break;
+#endif
+
+ case SID_INSERT_OBJECT:
+ {
+ const SfxGlobalNameItem* pNameItem = rReq.GetArg<SfxGlobalNameItem>(SID_INSERT_OBJECT);
+ SvGlobalName *pName = nullptr;
+ SvGlobalName aName;
+ if ( pNameItem )
+ {
+ aName = pNameItem->GetValue();
+ pName = &aName;
+ }
+
+ svt::EmbeddedObjectRef xObj;
+ rSh.InsertObject( xObj, pName, nSlot);
+ rReq.Done();
+ break;
+ }
+ case SID_INSERT_FLOATINGFRAME:
+ {
+ svt::EmbeddedObjectRef xObj;
+ const SfxStringItem* pNameItem = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ const SfxStringItem* pURLItem = rReq.GetArg<SfxStringItem>(FN_PARAM_2);
+ const SvxSizeItem* pMarginItem = rReq.GetArg<SvxSizeItem>(FN_PARAM_3);
+ const SfxByteItem* pScrollingItem = rReq.GetArg<SfxByteItem>(FN_PARAM_4);
+ const SfxBoolItem* pBorderItem = rReq.GetArg<SfxBoolItem>(FN_PARAM_5);
+
+ if(pURLItem) // URL is a _must_
+ {
+ comphelper::EmbeddedObjectContainer aCnt;
+ OUString aName;
+ xObj.Assign( aCnt.CreateEmbeddedObject( SvGlobalName( SO3_IFRAME_CLASSID ).GetByteSequence(), aName ),
+ embed::Aspects::MSOLE_CONTENT );
+ (void)svt::EmbeddedObjectRef::TryRunningState( xObj.GetObject() );
+ uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
+ if ( xSet.is() )
+ {
+ try
+ {
+ ScrollingMode eScroll = ScrollingMode::Auto;
+ if( pScrollingItem && pScrollingItem->GetValue() <= int(ScrollingMode::Auto) )
+ eScroll = static_cast<ScrollingMode>(pScrollingItem->GetValue());
+
+ Size aMargin;
+ if ( pMarginItem )
+ aMargin = pMarginItem->GetSize();
+
+ xSet->setPropertyValue("FrameURL", uno::Any( pURLItem->GetValue() ) );
+ if ( pNameItem )
+ xSet->setPropertyValue("FrameName", uno::Any( pNameItem->GetValue() ) );
+
+ if ( eScroll == ScrollingMode::Auto )
+ xSet->setPropertyValue("FrameIsAutoScroll",
+ uno::Any( true ) );
+ else
+ xSet->setPropertyValue("FrameIsScrollingMode",
+ uno::Any( eScroll == ScrollingMode::Yes ) );
+
+ if ( pBorderItem )
+ xSet->setPropertyValue("FrameIsBorder",
+ uno::Any( pBorderItem->GetValue() ) );
+
+ if ( pMarginItem )
+ {
+ xSet->setPropertyValue("FrameMarginWidth",
+ uno::Any( sal_Int32( aMargin.Width() ) ) );
+
+ xSet->setPropertyValue("FrameMarginHeight",
+ uno::Any( sal_Int32( aMargin.Height() ) ) );
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ }
+ }
+
+ rSh.InsertOleObject( xObj );
+ }
+ else
+ {
+ rSh.InsertObject( xObj, nullptr, nSlot);
+ rReq.Done();
+ }
+ }
+ break;
+ case SID_INSERT_DIAGRAM:
+ {
+ SvtModuleOptions aMOpt;
+ if ( !aMOpt.IsChart() )
+ break;
+ if(!rReq.IsAPI())
+ {
+ SwInsertChart( LINK( this, SwTextShell, DialogClosedHdl ) );
+ }
+ else
+ {
+ uno::Reference< chart2::data::XDataProvider > xDataProvider;
+ bool bFillWithData = true;
+ OUString aRangeString;
+ if (!GetShell().IsTableComplexForChart())
+ {
+ SwFrameFormat* pTableFormat = GetShell().GetTableFormat();
+ aRangeString = pTableFormat->GetName() + "."
+ + GetShell().GetBoxNms();
+
+ // get table data provider
+ xDataProvider.set( GetView().GetDocShell()->getIDocumentChartDataProviderAccess().GetChartDataProvider() );
+ }
+ else
+ bFillWithData = false; // will create chart with only it's default image
+
+ SwTableFUNC( &rSh ).InsertChart( xDataProvider, bFillWithData, aRangeString );
+ rSh.LaunchOLEObj();
+
+ svt::EmbeddedObjectRef& xObj = rSh.GetOLEObject();
+ if(pItem && xObj.is())
+ {
+ Size aSize(static_cast<const SvxSizeItem*>(pItem)->GetSize());
+ aSize = o3tl::convert(aSize, o3tl::Length::twip, o3tl::Length::mm100);
+
+ if(aSize.Width() > MINLAY&& aSize.Height()> MINLAY)
+ {
+ awt::Size aSz;
+ aSz.Width = aSize.Width();
+ aSz.Height = aSize.Height();
+ xObj->setVisualAreaSize( xObj.GetViewAspect(), aSz );
+ }
+ }
+ }
+ }
+ break;
+
+ case FN_INSERT_SMA:
+ {
+ // #i34343# Inserting a math object into an autocompletion crashes
+ // the suggestion has to be removed before
+ GetView().GetEditWin().StopQuickHelp();
+ SvGlobalName aGlobalName( SO3_SM_CLASSID );
+ rSh.InsertObject( svt::EmbeddedObjectRef(), &aGlobalName );
+ }
+ break;
+
+ case FN_INSERT_TABLE:
+ InsertTable( rReq );
+ break;
+
+ case FN_INSERT_FRAME_INTERACT_NOCOL:
+ case FN_INSERT_FRAME_INTERACT:
+ {
+ sal_uInt16 nCols = 1;
+ bool bModifier1 = rReq.GetModifier() == KEY_MOD1;
+ if(pArgs)
+ {
+ const SfxUInt16Item* pColsItem = nullptr;
+ if(FN_INSERT_FRAME_INTERACT_NOCOL != nSlot &&
+ (pColsItem = pArgs->GetItemIfSet(SID_ATTR_COLUMNS, false)))
+ nCols = pColsItem->GetValue();
+ if(const SfxUInt16Item* pModifierItem = pArgs->GetItemIfSet(SID_MODIFIER, false))
+ bModifier1 |= KEY_MOD1 == pModifierItem->GetValue();
+ }
+ if(bModifier1 )
+ {
+ SwEditWin& rEdtWin = GetView().GetEditWin();
+ Size aWinSize = rEdtWin.GetSizePixel();
+ Point aStartPos(aWinSize.Width()/2, aWinSize.Height() / 2);
+ aStartPos = rEdtWin.PixelToLogic(aStartPos);
+ constexpr tools::Long constTwips_2cm = o3tl::toTwips(2, o3tl::Length::cm);
+ constexpr tools::Long constTwips_4cm = o3tl::toTwips(4, o3tl::Length::cm);
+ aStartPos.AdjustX(-constTwips_4cm);
+ aStartPos.AdjustY(-constTwips_2cm);
+ Size aSize(2 * constTwips_4cm, 2 * constTwips_2cm);
+ GetShell().LockPaint(LockPaintReason::InsertFrame);
+ GetShell().StartAllAction();
+ SwFlyFrameAttrMgr aMgr( true, GetShellPtr(), Frmmgr_Type::TEXT, nullptr );
+ if(nCols > 1)
+ {
+ SwFormatCol aCol;
+ aCol.Init( nCols, aCol.GetGutterWidth(), aCol.GetWishWidth() );
+ aMgr.SetCol( aCol );
+ }
+ aMgr.InsertFlyFrame(RndStdIds::FLY_AT_PARA, aStartPos, aSize);
+ GetShell().EndAllAction();
+ GetShell().UnlockPaint();
+ }
+ else
+ {
+ GetView().InsFrameMode(nCols);
+ }
+ rReq.Ignore();
+ }
+ break;
+ case FN_INSERT_FRAME:
+ {
+ bool bSingleCol = false;
+ if( nullptr!= dynamic_cast< SwWebDocShell*>( GetView().GetDocShell()) )
+ {
+ if( HTML_CFG_MSIE == SvxHtmlOptions::GetExportMode() )
+ {
+ bSingleCol = true;
+ }
+
+ }
+ // Create new border
+ SwFlyFrameAttrMgr aMgr( true, GetShellPtr(), Frmmgr_Type::TEXT, nullptr );
+ if(pArgs)
+ {
+ Size aSize(aMgr.GetSize());
+ aSize.setWidth( GetShell().GetAnyCurRect(CurRectType::PagePrt).Width() );
+ Point aPos = aMgr.GetPos();
+ RndStdIds eAnchor = RndStdIds::FLY_AT_PARA;
+ if(pArgs->GetItemState(nSlot, false, &pItem) == SfxItemState::SET)
+ eAnchor = static_cast<RndStdIds>(static_cast<const SfxUInt16Item *>(pItem)->GetValue());
+ if(pArgs->GetItemState(FN_PARAM_1, false, &pItem) == SfxItemState::SET)
+ aPos = static_cast<const SfxPointItem *>(pItem)->GetValue();
+ if(pArgs->GetItemState(FN_PARAM_2, false, &pItem) == SfxItemState::SET)
+ aSize = static_cast<const SvxSizeItem *>(pItem)->GetSize();
+ if(const SfxUInt16Item* pColsItem = pArgs->GetItemIfSet(SID_ATTR_COLUMNS, false))
+ {
+ const sal_uInt16 nCols = pColsItem->GetValue();
+ if( !bSingleCol && 1 < nCols )
+ {
+ SwFormatCol aFormatCol;
+ aFormatCol.Init( nCols , (rReq.IsAPI() ? 0
+ : DEF_GUTTER_WIDTH), USHRT_MAX );
+ aMgr.SetCol(aFormatCol);
+ }
+ }
+
+ GetShell().LockPaint(LockPaintReason::InsertFrame);
+ GetShell().StartAllAction();
+
+ aMgr.InsertFlyFrame(eAnchor, aPos, aSize);
+
+ GetShell().EndAllAction();
+ GetShell().UnlockPaint();
+ }
+ else
+ {
+ SfxItemSet aSet = CreateInsertFrameItemSet(aMgr);
+
+ FieldUnit eMetric = ::GetDfltMetric(dynamic_cast<SwWebDocShell*>( GetView().GetDocShell()) != nullptr );
+ SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)));
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ VclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateFrameTabDialog("FrameDialog",
+ GetView().GetViewFrame(),
+ GetView().GetFrameWeld(),
+ aSet));
+ pDlg->StartExecuteAsync([aSet, pDlg, nSlot, this](sal_Int32 nResult) {
+ if (nResult == RET_OK && pDlg->GetOutputItemSet())
+ {
+ SwFlyFrameAttrMgr aAttrMgr( true, GetShellPtr(), Frmmgr_Type::TEXT, nullptr );
+ //local variable necessary at least after call of .AutoCaption() because this could be deleted at this point
+ SwWrtShell& rShell = GetShell();
+ rShell.LockPaint(LockPaintReason::InsertFrame);
+ rShell.StartAllAction();
+ rShell.StartUndo(SwUndoId::INSERT);
+
+ SfxItemSet aOutSet(*pDlg->GetOutputItemSet());
+ const SvxBoxItem* pBox = aSet.GetItem(RES_BOX);
+ if (pBox && !aOutSet.HasItem(RES_BOX))
+ {
+ // The input set had border info but the output set not, then copy it over
+ // to not lose the custom border info. This can happen when a whole table
+ // is selected and that case has its own defaults, not matching the frame
+ // style.
+ aOutSet.Put(*pBox);
+ }
+ aAttrMgr.SetAttrSet(aOutSet);
+
+ // At first delete the selection at the ClickToEditField.
+ if( rShell.IsInClickToEdit() )
+ rShell.DelRight();
+
+ aAttrMgr.InsertFlyFrame();
+
+ uno::Reference< frame::XDispatchRecorder > xRecorder =
+ GetView().GetViewFrame().GetBindings().GetRecorder();
+ if ( xRecorder.is() )
+ {
+ //FN_INSERT_FRAME
+ sal_uInt16 nAnchor = static_cast<sal_uInt16>(aAttrMgr.GetAnchor());
+ SfxRequest aReq(GetView().GetViewFrame(), FN_INSERT_FRAME);
+ aReq.AppendItem(SfxUInt16Item(nSlot, nAnchor));
+ aReq.AppendItem(SfxPointItem(FN_PARAM_1, rShell.GetObjAbsPos()));
+ aReq.AppendItem(SvxSizeItem(FN_PARAM_2, rShell.GetObjSize()));
+ aReq.Done();
+ }
+
+ GetView().AutoCaption(FRAME_CAP);
+
+ {
+ SwRewriter aRewriter;
+
+ aRewriter.AddRule(UndoArg1, SwResId(STR_FRAME));
+
+ rShell.EndUndo(SwUndoId::INSERT, &aRewriter);
+ }
+ rShell.EndAllAction();
+ rShell.UnlockPaint();
+ }
+ pDlg->disposeOnce();
+ });
+ }
+ break;
+ }
+ case FN_FORMAT_COLUMN :
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ VclPtr<VclAbstractDialog> pColDlg(pFact->CreateSwColumnDialog(GetView().GetFrameWeld(), rSh));
+ pColDlg->StartExecuteAsync([=](sal_Int32 /*nResult*/){
+ pColDlg->disposeOnce();
+ });
+ }
+ break;
+
+ default:
+ OSL_ENSURE(false, "wrong dispatcher");
+ return;
+ }
+}
+
+static bool lcl_IsMarkInSameSection( SwWrtShell& rWrtSh, const SwSection* pSect )
+{
+ rWrtSh.SwapPam();
+ bool bRet = pSect == rWrtSh.GetCurrSection();
+ rWrtSh.SwapPam();
+ return bRet;
+}
+
+void SwTextShell::StateInsert( SfxItemSet &rSet )
+{
+ const bool bHtmlModeOn = ::GetHtmlMode(GetView().GetDocShell()) & HTMLMODE_ON;
+ SfxWhichIter aIter( rSet );
+ SwWrtShell &rSh = GetShell();
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ SvtModuleOptions aMOpt;
+ SfxObjectCreateMode eCreateMode =
+ GetView().GetDocShell()->GetCreateMode();
+ const bool bCursorInHidden = rSh.IsInHiddenRange(/*bSelect=*/false);
+
+ while ( nWhich )
+ {
+ switch ( nWhich )
+ {
+ case SID_INSERT_AVMEDIA:
+ if ( GetShell().IsSelFrameMode()
+ || GetShell().CursorInsideInputField()
+ || SfxObjectCreateMode::EMBEDDED == eCreateMode
+ || bCursorInHidden )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_INSERT_DIAGRAM:
+ if( !aMOpt.IsChart()
+ || GetShell().CursorInsideInputField()
+ || eCreateMode == SfxObjectCreateMode::EMBEDDED
+ || bCursorInHidden )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case FN_INSERT_SMA:
+ if( !aMOpt.IsMath()
+ || eCreateMode == SfxObjectCreateMode::EMBEDDED
+ || bCursorInHidden
+ || rSh.CursorInsideInputField() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_INSERT_FLOATINGFRAME:
+ case SID_INSERT_OBJECT:
+ {
+ if( eCreateMode == SfxObjectCreateMode::EMBEDDED || bCursorInHidden )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ else if( GetShell().IsSelFrameMode()
+ || GetShell().CursorInsideInputField() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ else if(SID_INSERT_FLOATINGFRAME == nWhich && bHtmlModeOn)
+ {
+ const sal_uInt16 nExport = SvxHtmlOptions::GetExportMode();
+ if(HTML_CFG_MSIE != nExport && HTML_CFG_WRITER != nExport )
+ rSet.DisableItem(nWhich);
+ }
+ }
+ break;
+
+ case FN_INSERT_FRAME_INTERACT_NOCOL :
+ case FN_INSERT_FRAME_INTERACT:
+ {
+ if( GetShell().IsSelFrameMode()
+ || rSh.IsTableMode()
+ || GetShell().CursorInsideInputField()
+ || bCursorInHidden )
+ rSet.DisableItem(nWhich);
+ }
+ break;
+
+ case SID_HYPERLINK_GETLINK:
+ {
+ SfxItemSetFixed<RES_TXTATR_INETFMT, RES_TXTATR_INETFMT> aSet(GetPool());
+ rSh.GetCurAttr( aSet );
+
+ SvxHyperlinkItem aHLinkItem;
+ if(const SwFormatINetFormat* pINetFormat = aSet.GetItemIfSet(RES_TXTATR_INETFMT, false))
+ {
+ aHLinkItem.SetURL(pINetFormat->GetValue());
+ aHLinkItem.SetTargetFrame(pINetFormat->GetTargetFrame());
+ aHLinkItem.SetIntName(pINetFormat->GetName());
+ const SvxMacro *pMacro = pINetFormat->GetMacro( SvMacroItemId::OnMouseOver );
+ if( pMacro )
+ aHLinkItem.SetMacro(HyperDialogEvent::MouseOverObject, *pMacro);
+
+ pMacro = pINetFormat->GetMacro( SvMacroItemId::OnClick );
+ if( pMacro )
+ aHLinkItem.SetMacro(HyperDialogEvent::MouseClickObject, *pMacro);
+
+ pMacro = pINetFormat->GetMacro( SvMacroItemId::OnMouseOut );
+ if( pMacro )
+ aHLinkItem.SetMacro(HyperDialogEvent::MouseOutObject, *pMacro);
+
+ // Get the text of the Link.
+ rSh.StartAction();
+ const bool bAtEnd(rSh.IsCursorPtAtEnd());
+ if(!bAtEnd) // tdf#91832: ensure forward selection
+ rSh.SwapPam();
+ rSh.CreateCursor();
+ if(!bAtEnd)
+ rSh.SwapPam();
+ rSh.SwCursorShell::SelectTextAttr(RES_TXTATR_INETFMT,true);
+ OUString sLinkName = rSh.GetSelText();
+ aHLinkItem.SetName(sLinkName);
+ aHLinkItem.SetInsertMode(HLINK_FIELD);
+ rSh.DestroyCursor();
+ rSh.EndAction();
+ }
+ else
+ {
+ OUString sReturn = rSh.GetSelText();
+ sReturn = sReturn.copy(0, std::min<sal_Int32>(255, sReturn.getLength()));
+ aHLinkItem.SetName(comphelper::string::stripEnd(sReturn, ' '));
+ }
+
+ aHLinkItem.SetInsertMode(static_cast<SvxLinkInsertMode>(aHLinkItem.GetInsertMode() |
+ (bHtmlModeOn ? HLINK_HTMLMODE : 0)));
+ aHLinkItem.SetMacroEvents ( HyperDialogEvent::MouseOverObject|
+ HyperDialogEvent::MouseClickObject | HyperDialogEvent::MouseOutObject );
+
+ rSet.Put(aHLinkItem);
+ }
+ break;
+
+ case FN_INSERT_FRAME:
+ if (rSh.IsSelFrameMode() )
+ {
+ const SelectionType nSel = rSh.GetSelectionType();
+ if( ((SelectionType::Graphic | SelectionType::Ole ) & nSel ) || bCursorInHidden )
+ rSet.DisableItem(nWhich);
+ }
+ else if ( rSh.CursorInsideInputField() )
+ {
+ rSet.DisableItem(nWhich);
+ }
+ break;
+
+ case FN_FORMAT_COLUMN :
+ {
+ //#i80458# column dialog cannot work if the selection contains different page styles and different sections
+ bool bDisable = true;
+ if( rSh.GetFlyFrameFormat() || rSh.GetSelectedPageDescs() )
+ bDisable = false;
+ if( bDisable )
+ {
+ const SwSection* pCurrSection = rSh.GetCurrSection();
+ const sal_uInt16 nFullSectCnt = rSh.GetFullSelectedSectionCount();
+ if( pCurrSection && ( !rSh.HasSelection() || 0 != nFullSectCnt ))
+ bDisable = false;
+ else if(
+ rSh.HasSelection() && rSh.IsInsRegionAvailable() &&
+ ( !pCurrSection || ( 1 != nFullSectCnt &&
+ lcl_IsMarkInSameSection( rSh, pCurrSection ) )))
+ bDisable = false;
+ }
+ if(bDisable)
+ rSet.DisableItem(nWhich);
+ }
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void SwTextShell::ExecDelete(SfxRequest &rReq)
+{
+ SwWrtShell &rSh = GetShell();
+ switch( rReq.GetSlot() )
+ {
+ case FN_DELETE_SENT:
+ if( rSh.IsTableMode() )
+ {
+ rSh.DeleteRow();
+ rSh.EnterStdMode();
+ }
+ else
+ rSh.DelToEndOfSentence();
+ break;
+ case FN_DELETE_BACK_SENT:
+ rSh.DelToStartOfSentence();
+ break;
+ case FN_DELETE_WORD:
+ rSh.DelNxtWord();
+ break;
+ case FN_DELETE_BACK_WORD:
+ rSh.DelPrvWord();
+ break;
+ case FN_DELETE_LINE:
+ rSh.DelToEndOfLine();
+ break;
+ case FN_DELETE_BACK_LINE:
+ rSh.DelToStartOfLine();
+ break;
+ case FN_DELETE_PARA:
+ rSh.DelToEndOfPara();
+ break;
+ case FN_DELETE_BACK_PARA:
+ rSh.DelToStartOfPara();
+ break;
+ case FN_DELETE_WHOLE_LINE:
+ rSh.DelLine();
+ break;
+ default:
+ OSL_ENSURE(false, "wrong dispatcher");
+ return;
+ }
+ rReq.Done();
+}
+
+void SwTextShell::ExecTransliteration( SfxRequest const & rReq )
+{
+ using namespace ::com::sun::star::i18n;
+ TransliterationFlags nMode = TransliterationFlags::NONE;
+
+ switch( rReq.GetSlot() )
+ {
+ case SID_TRANSLITERATE_SENTENCE_CASE:
+ nMode = TransliterationFlags::SENTENCE_CASE;
+ break;
+ case SID_TRANSLITERATE_TITLE_CASE:
+ nMode = TransliterationFlags::TITLE_CASE;
+ break;
+ case SID_TRANSLITERATE_TOGGLE_CASE:
+ nMode = TransliterationFlags::TOGGLE_CASE;
+ break;
+ case SID_TRANSLITERATE_UPPER:
+ nMode = TransliterationFlags::LOWERCASE_UPPERCASE;
+ break;
+ case SID_TRANSLITERATE_LOWER:
+ nMode = TransliterationFlags::UPPERCASE_LOWERCASE;
+ break;
+
+ case SID_TRANSLITERATE_HALFWIDTH:
+ nMode = TransliterationFlags::FULLWIDTH_HALFWIDTH;
+ break;
+ case SID_TRANSLITERATE_FULLWIDTH:
+ nMode = TransliterationFlags::HALFWIDTH_FULLWIDTH;
+ break;
+
+ case SID_TRANSLITERATE_HIRAGANA:
+ nMode = TransliterationFlags::KATAKANA_HIRAGANA;
+ break;
+ case SID_TRANSLITERATE_KATAKANA:
+ nMode = TransliterationFlags::HIRAGANA_KATAKANA;
+ break;
+
+ default:
+ OSL_ENSURE(false, "wrong dispatcher");
+ }
+
+ if( nMode != TransliterationFlags::NONE )
+ GetShell().TransliterateText( nMode );
+}
+
+void SwTextShell::ExecRotateTransliteration( SfxRequest const & rReq )
+{
+ if( rReq.GetSlot() == SID_TRANSLITERATE_ROTATE_CASE )
+ GetShell().TransliterateText( m_aRotateCase.getNextMode() );
+}
+
+SwTextShell::SwTextShell(SwView &_rView) :
+ SwBaseShell(_rView)
+{
+ SetName("Text");
+ SfxShell::SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::Text));
+}
+
+SwTextShell::~SwTextShell()
+{
+}
+
+SfxItemSet SwTextShell::CreateInsertFrameItemSet(SwFlyFrameAttrMgr& rMgr)
+{
+ SfxItemSet aSet(GetPool(), svl::Items<
+ RES_FRMATR_BEGIN, RES_FRMATR_END-1,
+ XATTR_FILL_FIRST, XATTR_FILL_LAST, // tdf#95003
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
+ SID_ATTR_PAGE_SIZE, SID_ATTR_PAGE_SIZE,
+ SID_COLOR_TABLE, SID_PATTERN_LIST,
+ SID_HTML_MODE, SID_HTML_MODE,
+ FN_GET_PRINT_AREA, FN_GET_PRINT_AREA,
+ FN_SET_FRM_NAME, FN_SET_FRM_NAME>);
+ aSet.Put(SfxUInt16Item(SID_HTML_MODE, ::GetHtmlMode(GetView().GetDocShell())));
+
+ // For the Area tab page.
+ GetShell().GetDoc()->getIDocumentDrawModelAccess().GetDrawModel()->PutAreaListItems(aSet);
+
+ const SwRect &rPg = GetShell().GetAnyCurRect(CurRectType::Page);
+ SwFormatFrameSize aFrameSize(SwFrameSize::Variable, rPg.Width(), rPg.Height());
+ aFrameSize.SetWhich(GetPool().GetWhich(SID_ATTR_PAGE_SIZE));
+ aSet.Put(aFrameSize);
+
+ const SwRect &rPr = GetShell().GetAnyCurRect(CurRectType::PagePrt);
+ SwFormatFrameSize aPrtSize(SwFrameSize::Variable, rPr.Width(), rPr.Height());
+ aPrtSize.SetWhich(GetPool().GetWhich(FN_GET_PRINT_AREA));
+ aSet.Put(aPrtSize);
+
+ aSet.Put(rMgr.GetAttrSet());
+ aSet.SetParent( rMgr.GetAttrSet().GetParent() );
+
+ // Delete minimum size in columns.
+ SvxBoxInfoItem aBoxInfo(aSet.Get(SID_ATTR_BORDER_INNER));
+ const SvxBoxItem& rBox = aSet.Get(RES_BOX);
+ aBoxInfo.SetMinDist(false);
+ aBoxInfo.SetDefDist(rBox.GetDistance(SvxBoxItemLine::LEFT));
+ aSet.Put(aBoxInfo);
+
+ if (!SwFlyFrameAttrMgr::SingleTableSelected(GetShell()))
+ {
+ SwFormatAnchor aAnchor(RndStdIds::FLY_AT_CHAR);
+ aSet.Put(aAnchor);
+ }
+
+ return aSet;
+}
+
+void SwTextShell::InsertSymbol( SfxRequest& rReq )
+{
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ const SfxStringItem* pItem = nullptr;
+ if( pArgs )
+ pItem = pArgs->GetItemIfSet(SID_CHARMAP, false);
+
+ OUString aChars, aFontName;
+ if ( pItem )
+ {
+ aChars = pItem->GetValue();
+ const SfxStringItem* pFontItem = pArgs->GetItemIfSet( SID_ATTR_SPECIALCHAR, false );
+ if ( pFontItem )
+ aFontName = pFontItem->GetValue();
+ }
+
+ SwWrtShell &rSh = GetShell();
+ SfxItemSetFixed<RES_CHRATR_FONT, RES_CHRATR_FONT,
+ RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONT,
+ RES_CHRATR_CTL_FONT, RES_CHRATR_CTL_FONT> aSet( GetPool() );
+ rSh.GetCurAttr( aSet );
+ SvtScriptType nScript = rSh.GetScriptType();
+
+ std::shared_ptr<SvxFontItem> aFont(std::make_shared<SvxFontItem>(RES_CHRATR_FONT));
+ {
+ SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT, *aSet.GetPool() );
+ aSetItem.GetItemSet().Put( aSet, false );
+ const SfxPoolItem* pI = aSetItem.GetItemOfScript( nScript );
+ if( pI )
+ {
+ aFont.reset(static_cast<SvxFontItem*>(pI->Clone()));
+ }
+ else
+ {
+ TypedWhichId<SvxFontItem> nFontWhich =
+ GetWhichOfScript(
+ RES_CHRATR_FONT,
+ SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() ) );
+ aFont.reset(aSet.Get(nFontWhich).Clone());
+ }
+
+ if (aFontName.isEmpty())
+ aFontName = aFont->GetFamilyName();
+ }
+
+ vcl::Font aNewFont(aFontName, Size(1,1)); // Size only because CTOR.
+ if( aChars.isEmpty() )
+ {
+ // Set selected font as default.
+ SfxAllItemSet aAllSet( rSh.GetAttrPool() );
+ aAllSet.Put( SfxBoolItem( FN_PARAM_1, false ) );
+
+ SwViewOption aOpt(*GetShell().GetViewOptions());
+ const OUString& sSymbolFont = aOpt.GetSymbolFont();
+ if( aFontName.isEmpty() && !sSymbolFont.isEmpty() )
+ aAllSet.Put( SfxStringItem( SID_FONT_NAME, sSymbolFont ) );
+ else
+ aAllSet.Put( SfxStringItem( SID_FONT_NAME, aFont->GetFamilyName() ) );
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ auto xFrame = GetView().GetViewFrame().GetFrame().GetFrameInterface();
+ ScopedVclPtr<SfxAbstractDialog> pDlg(pFact->CreateCharMapDialog(GetView().GetFrameWeld(), aAllSet, xFrame));
+ pDlg->Execute();
+ return;
+ }
+
+ if( aChars.isEmpty() )
+ return;
+
+ rSh.StartAllAction();
+
+ // Delete selected content.
+ SwRewriter aRewriter;
+ aRewriter.AddRule(UndoArg1, SwResId(STR_SPECIALCHAR));
+
+ rSh.StartUndo( SwUndoId::INSERT, &aRewriter );
+ if ( rSh.HasSelection() )
+ {
+ rSh.DelRight();
+ aSet.ClearItem();
+ rSh.GetCurAttr( aSet );
+
+ SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT, *aSet.GetPool() );
+ aSetItem.GetItemSet().Put( aSet, false );
+ const SfxPoolItem* pI = aSetItem.GetItemOfScript( nScript );
+ if( pI )
+ {
+ aFont.reset(static_cast<SvxFontItem*>(pI->Clone()));
+ }
+ else
+ {
+ TypedWhichId<SvxFontItem> nFontWhich =
+ GetWhichOfScript(
+ RES_CHRATR_FONT,
+ SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() ) );
+ aFont.reset(aSet.Get( nFontWhich ).Clone());
+ }
+ }
+
+ // Insert character.
+ rSh.Insert( aChars );
+
+ // #108876# a font attribute has to be set always due to a guessed script type
+ if( !aNewFont.GetFamilyName().isEmpty() )
+ {
+ std::unique_ptr<SvxFontItem> aNewFontItem(aFont->Clone());
+ aNewFontItem->SetFamilyName( aNewFont.GetFamilyName() );
+ aNewFontItem->SetFamily( aNewFont.GetFamilyType());
+ aNewFontItem->SetPitch( aNewFont.GetPitch());
+ aNewFontItem->SetCharSet( aNewFont.GetCharSet() );
+
+ SfxItemSetFixed<RES_CHRATR_FONT, RES_CHRATR_FONT,
+ RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONT,
+ RES_CHRATR_CTL_FONT, RES_CHRATR_CTL_FONT> aRestoreSet( GetPool() );
+
+ nScript = g_pBreakIt->GetAllScriptsOfText( aChars );
+ if( SvtScriptType::LATIN & nScript )
+ {
+ aRestoreSet.Put( aSet.Get( RES_CHRATR_FONT ) );
+ aNewFontItem->SetWhich(RES_CHRATR_FONT);
+ aSet.Put( *aNewFontItem );
+ }
+ if( SvtScriptType::ASIAN & nScript )
+ {
+ aRestoreSet.Put( aSet.Get( RES_CHRATR_CJK_FONT ) );
+ aNewFontItem->SetWhich(RES_CHRATR_CJK_FONT);
+ aSet.Put( *aNewFontItem );
+ }
+ if( SvtScriptType::COMPLEX & nScript )
+ {
+ aRestoreSet.Put( aSet.Get( RES_CHRATR_CTL_FONT ) );
+ aNewFontItem->SetWhich(RES_CHRATR_CTL_FONT);
+ aSet.Put( *aNewFontItem );
+ }
+
+ rSh.SetMark();
+ rSh.ExtendSelection( false, aChars.getLength() );
+ rSh.SetAttrSet( aSet, SetAttrMode::DONTEXPAND | SetAttrMode::NOFORMATATTR );
+ if( !rSh.IsCursorPtAtEnd() )
+ rSh.SwapPam();
+
+ rSh.ClearMark();
+
+ // #i75891#
+ // SETATTR_DONTEXPAND does not work if there are already hard attributes.
+ // Therefore we have to restore the font attributes.
+ rSh.SetMark();
+ rSh.SetAttrSet( aRestoreSet );
+ rSh.ClearMark();
+
+ rSh.UpdateAttr();
+
+ // Why was this done? aFont is not used anymore below, we are not
+ // in a loop and it's a local variable...?
+ // aFont = aNewFontItem;
+ }
+
+ rSh.EndAllAction();
+ rSh.EndUndo();
+
+ if ( !aChars.isEmpty() )
+ {
+ rReq.AppendItem( SfxStringItem( SID_CHARMAP, aChars ) );
+ rReq.AppendItem( SfxStringItem( SID_ATTR_SPECIALCHAR, aNewFont.GetFamilyName() ) );
+ rReq.Done();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/textsh1.cxx b/sw/source/uibase/shells/textsh1.cxx
new file mode 100644
index 0000000000..2bf6c670e4
--- /dev/null
+++ b/sw/source/uibase/shells/textsh1.cxx
@@ -0,0 +1,2822 @@
+/* -*- 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 <config_features.h>
+
+#include <com/sun/star/i18n/WordType.hpp>
+#include <com/sun/star/linguistic2/XThesaurus.hpp>
+
+#include <hintids.hxx>
+#include <cmdid.h>
+#include <comphelper/lok.hxx>
+
+#include <i18nutil/unicode.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <svtools/langtab.hxx>
+#include <svl/numformat.hxx>
+#include <svl/slstitm.hxx>
+#include <svl/stritem.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <svl/whiter.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <vcl/unohelp2.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/request.hxx>
+#include <svl/eitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/tstpitem.hxx>
+#include <editeng/brushitem.hxx>
+#include <editeng/svxacorr.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/ctloptions.hxx>
+#include <IDocumentDrawModelAccess.hxx>
+#include <IDocumentSettingAccess.hxx>
+#include <charfmt.hxx>
+#include <svx/SmartTagItem.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xfillit0.hxx>
+#include <fmtinfmt.hxx>
+#include <wrtsh.hxx>
+#include <wview.hxx>
+#include <swmodule.hxx>
+#include <viewopt.hxx>
+#include <uitool.hxx>
+#include <textsh.hxx>
+#include <IMark.hxx>
+#include <swdtflvr.hxx>
+#include <swundo.hxx>
+#include <reffld.hxx>
+#include <docsh.hxx>
+#include <inputwin.hxx>
+#include <chrdlgmodes.hxx>
+#include <fmtcol.hxx>
+#include <cellatr.hxx>
+#include <edtwin.hxx>
+#include <fldmgr.hxx>
+#include <strings.hrc>
+#include <paratr.hxx>
+#include <vcl/svapp.hxx>
+#include <sfx2/app.hxx>
+#include <breakit.hxx>
+#include <SwSmartTagMgr.hxx>
+#include <editeng/acorrcfg.hxx>
+#include <swabstdlg.hxx>
+#include <sfx2/sfxdlg.hxx>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/linguistic2/ProofreadingResult.hpp>
+#include <com/sun/star/linguistic2/XDictionary.hpp>
+#include <com/sun/star/linguistic2/XSpellAlternatives.hpp>
+#include <editeng/unolingu.hxx>
+#include <doc.hxx>
+#include <drawdoc.hxx>
+#include <view.hxx>
+#include <pam.hxx>
+#include <sfx2/objface.hxx>
+#include <langhelper.hxx>
+#include <uiitems.hxx>
+#include <svx/nbdtmgfact.hxx>
+#include <svx/nbdtmg.hxx>
+#include <SwRewriter.hxx>
+#include <svx/drawitem.hxx>
+#include <numrule.hxx>
+#include <memory>
+#include <xmloff/odffields.hxx>
+#include <bookmark.hxx>
+#include <linguistic/misc.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <comphelper/scopeguard.hxx>
+#include <authfld.hxx>
+#include <config_wasm_strip.h>
+#if HAVE_FEATURE_CURL && !ENABLE_WASM_STRIP_EXTRA
+#include <officecfg/Office/Common.hxx>
+#include <officecfg/Office/Linguistic.hxx>
+#include <svl/visitem.hxx>
+#include <translatelangselect.hxx>
+#endif // HAVE_FEATURE_CURL && ENABLE_WASM_STRIP_EXTRA
+#include <translatehelper.hxx>
+#include <IDocumentContentOperations.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <fmtcntnt.hxx>
+#include <fmtrfmrk.hxx>
+#include <cntfrm.hxx>
+#include <flyfrm.hxx>
+
+using namespace ::com::sun::star;
+using namespace com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace com::sun::star::style;
+using namespace svx::sidebar;
+
+static void sw_CharDialogResult(const SfxItemSet* pSet, SwWrtShell &rWrtSh, std::shared_ptr<SfxItemSet> const & pCoreSet, bool bSel,
+ bool bSelectionPut, bool bApplyToParagraph, SfxRequest *pReq);
+
+static void sw_CharDialog(SwWrtShell& rWrtSh, bool bUseDialog, bool bApplyToParagraph,
+ sal_uInt16 nSlot, const SfxItemSet* pArgs, SfxRequest* pReq)
+{
+ FieldUnit eMetric = ::GetDfltMetric(dynamic_cast<SwWebView*>( &rWrtSh.GetView()) != nullptr );
+ SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)));
+ auto pCoreSet = std::make_shared<SfxItemSetFixed<
+ RES_CHRATR_BEGIN, RES_CHRATR_END - 1,
+ RES_TXTATR_INETFMT, RES_TXTATR_INETFMT,
+ RES_BACKGROUND, RES_SHADOW,
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
+ SID_HTML_MODE, SID_HTML_MODE,
+ SID_ATTR_CHAR_WIDTH_FIT_TO_LINE, SID_ATTR_CHAR_WIDTH_FIT_TO_LINE,
+ FN_PARAM_SELECTION, FN_PARAM_SELECTION>> ( rWrtSh.GetView().GetPool() );
+ rWrtSh.GetCurAttr(*pCoreSet);
+
+ bool bSel = rWrtSh.HasSelection();
+ bool bSelectionPut = false;
+ if(bSel || rWrtSh.IsInWord())
+ {
+ if(!bSel)
+ {
+ rWrtSh.StartAction();
+ rWrtSh.Push();
+ if(!rWrtSh.SelectTextAttr( RES_TXTATR_INETFMT ))
+ rWrtSh.SelWrd();
+ }
+ pCoreSet->Put(SfxStringItem(FN_PARAM_SELECTION, rWrtSh.GetSelText()));
+ bSelectionPut = true;
+ if(!bSel)
+ {
+ rWrtSh.Pop(SwCursorShell::PopMode::DeleteCurrent);
+ rWrtSh.EndAction();
+ }
+ }
+ pCoreSet->Put(SfxUInt16Item(SID_ATTR_CHAR_WIDTH_FIT_TO_LINE, rWrtSh.GetScalingOfSelectedText()));
+
+ ::ConvertAttrCharToGen(*pCoreSet);
+
+ // Setting the BoxInfo
+ ::PrepareBoxInfo(*pCoreSet, rWrtSh);
+
+ pCoreSet->Put(SfxUInt16Item(SID_HTML_MODE, ::GetHtmlMode(rWrtSh.GetView().GetDocShell())));
+ VclPtr<SfxAbstractTabDialog> pDlg;
+ if ( bUseDialog && GetActiveView() )
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ pDlg.reset(pFact->CreateSwCharDlg(rWrtSh.GetView().GetFrameWeld(), rWrtSh.GetView(), *pCoreSet, SwCharDlgMode::Std));
+
+ if (nSlot == FN_INSERT_HYPERLINK)
+ pDlg->SetCurPageId("hyperlink");
+ else if (nSlot == SID_CHAR_DLG_EFFECT)
+ pDlg->SetCurPageId("fonteffects");
+ else if (nSlot == SID_CHAR_DLG_POSITION)
+ pDlg->SetCurPageId("position");
+ else if (nSlot == SID_CHAR_DLG_FOR_PARAGRAPH)
+ pDlg->SetCurPageId("font");
+ else if (pReq)
+ {
+ const SfxStringItem* pItem = (*pReq).GetArg<SfxStringItem>(FN_PARAM_1);
+ if (pItem)
+ pDlg->SetCurPageId(pItem->GetValue());
+ }
+ }
+
+ if (bUseDialog)
+ {
+ std::shared_ptr<SfxRequest> pRequest;
+ if (pReq)
+ {
+ pRequest = std::make_shared<SfxRequest>(*pReq);
+ pReq->Ignore(); // the 'old' request is not relevant any more
+ }
+ pDlg->StartExecuteAsync([pDlg, &rWrtSh, pCoreSet, bSel, bSelectionPut, bApplyToParagraph, pRequest](sal_Int32 nResult){
+ if (nResult == RET_OK)
+ {
+ sw_CharDialogResult(pDlg->GetOutputItemSet(), rWrtSh, pCoreSet, bSel, bSelectionPut,
+ bApplyToParagraph, pRequest.get());
+ }
+ pDlg->disposeOnce();
+ });
+ }
+ else if (pArgs)
+ {
+ sw_CharDialogResult(pArgs, rWrtSh, pCoreSet, bSel, bSelectionPut, bApplyToParagraph, pReq);
+ }
+}
+
+static void sw_CharDialogResult(const SfxItemSet* pSet, SwWrtShell& rWrtSh, std::shared_ptr<SfxItemSet> const & pCoreSet, bool bSel,
+ bool bSelectionPut, bool bApplyToParagraph, SfxRequest* pReq)
+{
+ SfxItemSet aTmpSet( *pSet );
+ ::ConvertAttrGenToChar(aTmpSet, *pCoreSet);
+
+ const bool bWasLocked = rWrtSh.IsViewLocked();
+ if (bApplyToParagraph)
+ {
+ rWrtSh.StartAction();
+ rWrtSh.LockView(true);
+ rWrtSh.Push();
+ SwLangHelper::SelectCurrentPara(rWrtSh);
+ }
+
+ const SfxStringItem* pSelectionItem;
+ bool bInsert = false;
+ sal_Int32 nInsert = 0;
+
+ // The old item is for unknown reasons back in the set again.
+ if( !bSelectionPut && (pSelectionItem = aTmpSet.GetItemIfSet(FN_PARAM_SELECTION, false)) )
+ {
+ OUString sInsert = pSelectionItem->GetValue();
+ bInsert = !sInsert.isEmpty();
+ if(bInsert)
+ {
+ nInsert = sInsert.getLength();
+ rWrtSh.StartAction();
+ rWrtSh.Insert( sInsert );
+ rWrtSh.SetMark();
+ rWrtSh.ExtendSelection(false, sInsert.getLength());
+ SfxRequest aReq(rWrtSh.GetView().GetViewFrame(), FN_INSERT_STRING);
+ aReq.AppendItem( SfxStringItem( FN_INSERT_STRING, sInsert ) );
+ aReq.Done();
+ SfxRequest aReq1(rWrtSh.GetView().GetViewFrame(), FN_CHAR_LEFT);
+ aReq1.AppendItem( SfxInt32Item(FN_PARAM_MOVE_COUNT, nInsert) );
+ aReq1.AppendItem( SfxBoolItem(FN_PARAM_MOVE_SELECTION, true) );
+ aReq1.Done();
+ }
+ }
+ aTmpSet.ClearItem(FN_PARAM_SELECTION);
+
+ SwTextFormatColl* pColl = rWrtSh.GetCurTextFormatColl();
+ if(bSel && rWrtSh.IsSelFullPara() && pColl && pColl->IsAutoUpdateOnDirectFormat())
+ {
+ rWrtSh.AutoUpdatePara(pColl, aTmpSet);
+ }
+ else
+ rWrtSh.SetAttrSet( aTmpSet );
+ if (pReq)
+ pReq->Done(aTmpSet);
+ if(bInsert)
+ {
+ SfxRequest aReq1(rWrtSh.GetView().GetViewFrame(), FN_CHAR_RIGHT);
+ aReq1.AppendItem( SfxInt32Item(FN_PARAM_MOVE_COUNT, nInsert) );
+ aReq1.AppendItem( SfxBoolItem(FN_PARAM_MOVE_SELECTION, false) );
+ aReq1.Done();
+ rWrtSh.SwapPam();
+ rWrtSh.ClearMark();
+ rWrtSh.DontExpandFormat();
+ rWrtSh.EndAction();
+ }
+
+ if (bApplyToParagraph)
+ {
+ rWrtSh.Pop(SwCursorShell::PopMode::DeleteCurrent);
+ rWrtSh.LockView(bWasLocked);
+ rWrtSh.EndAction();
+ }
+}
+
+
+static void sw_ParagraphDialogResult(SfxItemSet* pSet, SwWrtShell &rWrtSh, SfxRequest& rReq, SwPaM* pPaM)
+{
+ if (!pSet)
+ return;
+
+ rReq.Done( *pSet );
+ ::SfxToSwPageDescAttr( rWrtSh, *pSet );
+ // #i56253#
+ // enclose all undos.
+ // Thus, check conditions, if actions will be performed.
+ const bool bUndoNeeded( pSet->Count() ||
+ SfxItemState::SET == pSet->GetItemState(FN_NUMBER_NEWSTART) ||
+ SfxItemState::SET == pSet->GetItemState(FN_NUMBER_NEWSTART_AT) );
+ if ( bUndoNeeded )
+ {
+ rWrtSh.StartUndo( SwUndoId::INSATTR );
+ }
+ if( pSet->Count() )
+ {
+ rWrtSh.StartAction();
+ if ( const SfxStringItem* pDropTextItem = pSet->GetItemIfSet(FN_DROP_TEXT, false) )
+ {
+ if ( !pDropTextItem->GetValue().isEmpty() )
+ rWrtSh.ReplaceDropText(pDropTextItem->GetValue(), pPaM);
+ }
+ rWrtSh.SetAttrSet(*pSet, SetAttrMode::DEFAULT, pPaM);
+ rWrtSh.EndAction();
+ SwTextFormatColl* pColl = rWrtSh.GetPaMTextFormatColl(pPaM);
+ if(pColl && pColl->IsAutoUpdateOnDirectFormat())
+ {
+ rWrtSh.AutoUpdatePara(pColl, *pSet, pPaM);
+ }
+ }
+
+ if( SfxItemState::SET == pSet->GetItemState(FN_NUMBER_NEWSTART) )
+ {
+ //SetNumRuleStart(true) restarts the numbering at the value
+ //that is defined at the starting point of the numbering level
+ //otherwise the SetNodeNumStart() value determines the start
+ //if it's set to something different than USHRT_MAX
+
+ bool bStart = static_cast<const SfxBoolItem&>(pSet->Get(FN_NUMBER_NEWSTART)).GetValue();
+
+ // Default value for restart value has to be USHRT_MAX
+ // in order to indicate that the restart value of the list
+ // style has to be used on restart.
+ sal_uInt16 nNumStart = USHRT_MAX;
+ if( SfxItemState::SET == pSet->GetItemState(FN_NUMBER_NEWSTART_AT) )
+ {
+ nNumStart = pSet->Get(FN_NUMBER_NEWSTART_AT).GetValue();
+ }
+ rWrtSh.SetNumRuleStart(bStart, pPaM);
+ rWrtSh.SetNodeNumStart(nNumStart);
+ }
+ else if( SfxItemState::SET == pSet->GetItemState(FN_NUMBER_NEWSTART_AT) )
+ {
+ rWrtSh.SetNodeNumStart(pSet->Get(FN_NUMBER_NEWSTART_AT).GetValue());
+ rWrtSh.SetNumRuleStart(false, pPaM);
+ }
+ // #i56253#
+ if ( bUndoNeeded )
+ {
+ rWrtSh.EndUndo( SwUndoId::INSATTR );
+ }
+}
+
+namespace {
+
+void InsertBreak(SwWrtShell& rWrtSh,
+ sal_uInt16 nKind,
+ ::std::optional<sal_uInt16> oPageNumber,
+ const OUString& rTemplateName, std::optional<SwLineBreakClear> oClear)
+{
+ switch ( nKind )
+ {
+ case 1 :
+ rWrtSh.InsertLineBreak(oClear);
+ break;
+ case 2 :
+ rWrtSh.InsertColumnBreak(); break;
+ case 3 :
+ {
+ rWrtSh.StartAllAction();
+ if( !rTemplateName.isEmpty() )
+ rWrtSh.InsertPageBreak( &rTemplateName, oPageNumber );
+ else
+ rWrtSh.InsertPageBreak();
+ rWrtSh.EndAllAction();
+ }
+ }
+}
+
+OUString GetLocalURL(const SwWrtShell& rSh)
+{
+ SwField* pField = rSh.GetCurField();
+ if (!pField)
+ {
+ return OUString();
+ }
+
+ if (pField->GetTyp()->Which() != SwFieldIds::TableOfAuthorities)
+ {
+ return OUString();
+ }
+
+ const auto& rAuthorityField = *static_cast<const SwAuthorityField*>(pField);
+ SwAuthEntry* pAuthEntry = rAuthorityField.GetAuthEntry();
+ if (!pAuthEntry)
+ {
+ return OUString();
+ }
+
+ const OUString& rLocalURL = pAuthEntry->GetAuthorField(AUTH_FIELD_LOCAL_URL);
+ return rLocalURL;
+}
+
+void UpdateSections(SfxRequest& rReq, SwWrtShell& rWrtSh)
+{
+ OUString aSectionNamePrefix;
+ const SfxStringItem* pSectionNamePrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ if (pSectionNamePrefix)
+ {
+ aSectionNamePrefix = pSectionNamePrefix->GetValue();
+ }
+
+ uno::Sequence<beans::PropertyValues> aSections;
+ const SfxUnoAnyItem* pSections = rReq.GetArg<SfxUnoAnyItem>(FN_PARAM_2);
+ if (pSections)
+ {
+ pSections->GetValue() >>= aSections;
+ }
+
+ rWrtSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::UPDATE_SECTIONS, nullptr);
+ rWrtSh.StartAction();
+
+ SwDoc* pDoc = rWrtSh.GetDoc();
+ sal_Int32 nSectionIndex = 0;
+ const SwSectionFormats& rFormats = pDoc->GetSections();
+ IDocumentContentOperations& rIDCO = pDoc->getIDocumentContentOperations();
+ for (size_t i = 0; i < rFormats.size(); ++i)
+ {
+ const SwSectionFormat* pFormat = rFormats[i];
+ if (!pFormat->GetName().startsWith(aSectionNamePrefix))
+ {
+ continue;
+ }
+
+ if (nSectionIndex >= aSections.getLength())
+ {
+ break;
+ }
+
+ comphelper::SequenceAsHashMap aMap(aSections[nSectionIndex++]);
+ OUString aSectionName = aMap["RegionName"].get<OUString>();
+ if (aSectionName != pFormat->GetName())
+ {
+ const_cast<SwSectionFormat*>(pFormat)->SetFormatName(aSectionName, /*bBroadcast=*/true);
+ SwSectionData aSectionData(*pFormat->GetSection());
+ aSectionData.SetSectionName(aSectionName);
+ pDoc->UpdateSection(i, aSectionData);
+ }
+
+ const SwFormatContent& rContent = pFormat->GetContent();
+ const SwNodeIndex* pContentNodeIndex = rContent.GetContentIdx();
+ if (pContentNodeIndex)
+ {
+ SwPaM aSectionStart(SwPosition{*pContentNodeIndex});
+ aSectionStart.Move(fnMoveForward, GoInContent);
+ SwPaM* pCursorPos = rWrtSh.GetCursor();
+ *pCursorPos = aSectionStart;
+ rWrtSh.EndOfSection(/*bSelect=*/true);
+ rIDCO.DeleteAndJoin(*pCursorPos);
+ rWrtSh.EndSelect();
+
+ OUString aSectionText = aMap["Content"].get<OUString>();
+ SwTranslateHelper::PasteHTMLToPaM(rWrtSh, pCursorPos, aSectionText.toUtf8());
+ }
+ }
+
+ rWrtSh.EndAction();
+ rWrtSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::UPDATE_SECTIONS, nullptr);
+}
+
+void DeleteSections(SfxRequest& rReq, SwWrtShell& rWrtSh)
+{
+ OUString aSectionNamePrefix;
+ const SfxStringItem* pSectionNamePrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ if (pSectionNamePrefix)
+ {
+ aSectionNamePrefix = pSectionNamePrefix->GetValue();
+ }
+
+ rWrtSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::DELETE_SECTIONS, nullptr);
+ rWrtSh.StartAction();
+ comphelper::ScopeGuard g(
+ [&rWrtSh]
+ {
+ rWrtSh.EndAction();
+ rWrtSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::DELETE_SECTIONS, nullptr);
+ });
+
+ SwDoc* pDoc = rWrtSh.GetDoc();
+ SwSectionFormats& rFormats = pDoc->GetSections();
+ std::vector<SwSectionFormat*> aRemovals;
+ for (size_t i = 0; i < rFormats.size(); ++i)
+ {
+ SwSectionFormat* pFormat = rFormats[i];
+
+ if (!aSectionNamePrefix.isEmpty())
+ {
+ if (!pFormat->GetName().startsWith(aSectionNamePrefix))
+ {
+ continue;
+ }
+ }
+
+ aRemovals.push_back(pFormat);
+ }
+
+ for (const auto& pFormat : aRemovals)
+ {
+ // Just delete the format, not the content of the section.
+ pDoc->DelSectionFormat(pFormat);
+ }
+}
+
+void UpdateBookmarks(SfxRequest& rReq, SwWrtShell& rWrtSh)
+{
+ if (rWrtSh.getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS))
+ {
+ return;
+ }
+
+ OUString aBookmarkNamePrefix;
+ const SfxStringItem* pBookmarkNamePrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ if (pBookmarkNamePrefix)
+ {
+ aBookmarkNamePrefix = pBookmarkNamePrefix->GetValue();
+ }
+
+ uno::Sequence<beans::PropertyValues> aBookmarks;
+ const SfxUnoAnyItem* pBookmarks = rReq.GetArg<SfxUnoAnyItem>(FN_PARAM_2);
+ if (pBookmarks)
+ {
+ pBookmarks->GetValue() >>= aBookmarks;
+ }
+
+ rWrtSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::UPDATE_BOOKMARKS, nullptr);
+ rWrtSh.StartAction();
+
+ IDocumentMarkAccess& rIDMA = *rWrtSh.GetDoc()->getIDocumentMarkAccess();
+ sal_Int32 nBookmarkIndex = 0;
+ bool bSortMarks = false;
+ for (auto it = rIDMA.getBookmarksBegin(); it != rIDMA.getBookmarksEnd(); ++it)
+ {
+ auto pMark = dynamic_cast<sw::mark::Bookmark*>(*it);
+ assert(pMark);
+ if (!pMark->GetName().startsWith(aBookmarkNamePrefix))
+ {
+ continue;
+ }
+
+ if (aBookmarks.getLength() <= nBookmarkIndex)
+ {
+ continue;
+ }
+
+ comphelper::SequenceAsHashMap aMap(aBookmarks[nBookmarkIndex++]);
+ if (aMap["Bookmark"].get<OUString>() != pMark->GetName())
+ {
+ rIDMA.renameMark(pMark, aMap["Bookmark"].get<OUString>());
+ }
+
+ OUString aBookmarkText = aMap["BookmarkText"].get<OUString>();
+
+ // Insert markers to remember where the paste positions are.
+ SwPaM aMarkers(pMark->GetMarkEnd());
+ IDocumentContentOperations& rIDCO = rWrtSh.GetDoc()->getIDocumentContentOperations();
+ bool bSuccess = rIDCO.InsertString(aMarkers, "XY");
+ if (bSuccess)
+ {
+ SwPaM aPasteEnd(pMark->GetMarkEnd());
+ aPasteEnd.Move(fnMoveForward, GoInContent);
+
+ // Paste HTML content.
+ SwPaM* pCursorPos = rWrtSh.GetCursor();
+ *pCursorPos = aPasteEnd;
+ SwTranslateHelper::PasteHTMLToPaM(rWrtSh, pCursorPos, aBookmarkText.toUtf8());
+
+ // Update the bookmark to point to the new content.
+ SwPaM aPasteStart(pMark->GetMarkEnd());
+ aPasteStart.Move(fnMoveForward, GoInContent);
+ SwPaM aStartMarker(pMark->GetMarkStart(), *aPasteStart.GetPoint());
+ SwPaM aEndMarker(*aPasteEnd.GetPoint(), *aPasteEnd.GetPoint());
+ aEndMarker.GetMark()->AdjustContent(1);
+ pMark->SetMarkPos(*aPasteStart.GetPoint());
+ pMark->SetOtherMarkPos(*aPasteEnd.GetPoint());
+ bSortMarks = true;
+
+ // Remove markers. the start marker includes the old content as well.
+ rIDCO.DeleteAndJoin(aStartMarker);
+ rIDCO.DeleteAndJoin(aEndMarker);
+ }
+ }
+ if (bSortMarks)
+ {
+ rIDMA.assureSortedMarkContainers();
+ }
+
+ rWrtSh.EndAction();
+ rWrtSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::UPDATE_BOOKMARKS, nullptr);
+}
+
+void UpdateBookmark(SfxRequest& rReq, SwWrtShell& rWrtSh)
+{
+ if (rWrtSh.getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS))
+ {
+ return;
+ }
+
+ OUString aBookmarkNamePrefix;
+ const SfxStringItem* pBookmarkNamePrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ if (pBookmarkNamePrefix)
+ {
+ aBookmarkNamePrefix = pBookmarkNamePrefix->GetValue();
+ }
+
+ uno::Sequence<beans::PropertyValue> aBookmark;
+ const SfxUnoAnyItem* pBookmarks = rReq.GetArg<SfxUnoAnyItem>(FN_PARAM_2);
+ if (pBookmarks)
+ {
+ pBookmarks->GetValue() >>= aBookmark;
+ }
+
+ IDocumentMarkAccess& rIDMA = *rWrtSh.GetDoc()->getIDocumentMarkAccess();
+ SwPosition& rCursor = *rWrtSh.GetCursor()->GetPoint();
+ auto pBookmark = dynamic_cast<sw::mark::Bookmark*>(rIDMA.getOneInnermostBookmarkFor(rCursor));
+ if (!pBookmark || !pBookmark->GetName().startsWith(aBookmarkNamePrefix))
+ {
+ return;
+ }
+
+ SwRewriter aRewriter;
+ aRewriter.AddRule(UndoArg1, pBookmark->GetName());
+ rWrtSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::UPDATE_BOOKMARK, &aRewriter);
+ rWrtSh.StartAction();
+ comphelper::ScopeGuard g(
+ [&rWrtSh, &aRewriter]
+ {
+ rWrtSh.EndAction();
+ rWrtSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::UPDATE_BOOKMARK, &aRewriter);
+ });
+
+
+ comphelper::SequenceAsHashMap aMap(aBookmark);
+ if (aMap["Bookmark"].get<OUString>() != pBookmark->GetName())
+ {
+ rIDMA.renameMark(pBookmark, aMap["Bookmark"].get<OUString>());
+ }
+
+ // Insert markers to remember where the paste positions are.
+ SwPaM aMarkers(pBookmark->GetMarkEnd());
+ IDocumentContentOperations& rIDCO = rWrtSh.GetDoc()->getIDocumentContentOperations();
+ if (!rIDCO.InsertString(aMarkers, "XY"))
+ {
+ return;
+ }
+
+ SwPaM aPasteEnd(pBookmark->GetMarkEnd());
+ aPasteEnd.Move(fnMoveForward, GoInContent);
+
+ OUString aBookmarkText = aMap["BookmarkText"].get<OUString>();
+
+ // Paste HTML content.
+ SwPaM* pCursorPos = rWrtSh.GetCursor();
+ *pCursorPos = aPasteEnd;
+ SwTranslateHelper::PasteHTMLToPaM(rWrtSh, pCursorPos, aBookmarkText.toUtf8());
+
+ // Update the bookmark to point to the new content.
+ SwPaM aPasteStart(pBookmark->GetMarkEnd());
+ aPasteStart.Move(fnMoveForward, GoInContent);
+ SwPaM aStartMarker(pBookmark->GetMarkStart(), *aPasteStart.GetPoint());
+ SwPaM aEndMarker(*aPasteEnd.GetPoint(), *aPasteEnd.GetPoint());
+ aEndMarker.GetMark()->AdjustContent(1);
+ pBookmark->SetMarkPos(*aPasteStart.GetPoint());
+ pBookmark->SetOtherMarkPos(*aPasteEnd.GetPoint());
+
+ // Remove markers. the start marker includes the old content as well.
+ rIDCO.DeleteAndJoin(aStartMarker);
+ rIDCO.DeleteAndJoin(aEndMarker);
+ rIDMA.assureSortedMarkContainers();
+}
+
+void DeleteBookmarks(SfxRequest& rReq, SwWrtShell& rWrtSh)
+{
+ if (rWrtSh.getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS))
+ {
+ return;
+ }
+
+ OUString aBookmarkNamePrefix;
+ const SfxStringItem* pBookmarkNamePrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ if (pBookmarkNamePrefix)
+ {
+ aBookmarkNamePrefix = pBookmarkNamePrefix->GetValue();
+ }
+
+ rWrtSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::DELETE_BOOKMARKS, nullptr);
+ rWrtSh.StartAction();
+ comphelper::ScopeGuard g(
+ [&rWrtSh]
+ {
+ rWrtSh.EndAction();
+ rWrtSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::DELETE_BOOKMARKS, nullptr);
+ });
+
+ IDocumentMarkAccess* pMarkAccess = rWrtSh.GetDoc()->getIDocumentMarkAccess();
+ std::vector<sw::mark::IMark*> aRemovals;
+ for (auto it = pMarkAccess->getBookmarksBegin(); it != pMarkAccess->getBookmarksEnd(); ++it)
+ {
+ auto pBookmark = dynamic_cast<sw::mark::Bookmark*>(*it);
+ assert(pBookmark);
+
+ if (!aBookmarkNamePrefix.isEmpty())
+ {
+ if (!pBookmark->GetName().startsWith(aBookmarkNamePrefix))
+ {
+ continue;
+ }
+ }
+
+ aRemovals.push_back(pBookmark);
+ }
+
+ for (const auto& pMark : aRemovals)
+ {
+ pMarkAccess->deleteMark(pMark);
+ }
+}
+
+void DeleteFields(SfxRequest& rReq, SwWrtShell& rWrtSh)
+{
+ const SfxStringItem* pTypeName = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ if (!pTypeName || pTypeName->GetValue() != "SetRef")
+ {
+ // This is implemented so far only for reference marks.
+ return;
+ }
+
+ OUString aNamePrefix;
+ const SfxStringItem* pNamePrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_2);
+ if (pNamePrefix)
+ {
+ aNamePrefix = pNamePrefix->GetValue();
+ }
+
+ SwDoc* pDoc = rWrtSh.GetDoc();
+ pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::DELETE_FIELDS, nullptr);
+ rWrtSh.StartAction();
+ comphelper::ScopeGuard g(
+ [&rWrtSh]
+ {
+ rWrtSh.EndAction();
+ rWrtSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::DELETE_FIELDS, nullptr);
+ });
+
+ std::vector<const SwFormatRefMark*> aRemovals;
+ for (sal_uInt16 i = 0; i < pDoc->GetRefMarks(); ++i)
+ {
+ const SwFormatRefMark* pRefMark = pDoc->GetRefMark(i);
+ if (!aNamePrefix.isEmpty())
+ {
+ if (!pRefMark->GetRefName().startsWith(aNamePrefix))
+ {
+ continue;
+ }
+ }
+
+ aRemovals.push_back(pRefMark);
+ }
+
+ for (const auto& pMark : aRemovals)
+ {
+ pDoc->DeleteFormatRefMark(pMark);
+ }
+}
+}
+
+void SwTextShell::Execute(SfxRequest &rReq)
+{
+ bool bUseDialog = true;
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ SwWrtShell& rWrtSh = GetShell();
+ const SfxPoolItem* pItem = nullptr;
+ const sal_uInt16 nSlot = rReq.GetSlot();
+ if(pArgs)
+ pArgs->GetItemState(GetPool().GetWhich(nSlot), false, &pItem);
+ switch( nSlot )
+ {
+ case SID_UNICODE_NOTATION_TOGGLE:
+ {
+ tools::Long nMaxUnits = 256;
+ sal_Int32 nSelLength = rWrtSh.GetSelText().getLength();
+ if( rWrtSh.IsSelection() && !rWrtSh.IsMultiSelection() && (nSelLength < nMaxUnits) )
+ nMaxUnits = nSelLength;
+
+ tools::Long index = 0;
+ ToggleUnicodeCodepoint aToggle;
+ while( nMaxUnits-- && aToggle.AllowMoreInput(rWrtSh.GetChar(true, index-1)) )
+ --index;
+
+ OUString sReplacement = aToggle.ReplacementString();
+ if( !sReplacement.isEmpty() )
+ {
+ if (rWrtSh.HasReadonlySel() && !rWrtSh.CursorInsideInputField())
+ {
+ // Only break if there's something to do; don't nag with the dialog otherwise
+ rWrtSh.InfoReadOnlyDialog(false);
+ break;
+ }
+ SwRewriter aRewriter;
+ aRewriter.AddRule( UndoArg1, aToggle.StringToReplace() );
+ aRewriter.AddRule( UndoArg2, SwResId(STR_YIELDS) );
+ aRewriter.AddRule( UndoArg3, sReplacement );
+ rWrtSh.StartUndo(SwUndoId::REPLACE, &aRewriter);
+ rWrtSh.GetCursor()->Normalize(false);
+
+ rWrtSh.ClearMark();
+ if( rWrtSh.IsInSelect() ) // cancel any in-progress keyboard selection as well
+ rWrtSh.EndSelect();
+
+ for( sal_uInt32 i=aToggle.CharsToDelete(); i > 0; --i )
+ rWrtSh.DelLeft();
+ rWrtSh.Insert2( sReplacement );
+ rWrtSh.EndUndo(SwUndoId::REPLACE, &aRewriter);
+ }
+ }
+ break;
+
+ case SID_LANGUAGE_STATUS:
+ {
+ // get the language
+ OUString aNewLangText;
+ const SfxStringItem* pItem2 = rReq.GetArg<SfxStringItem>(SID_LANGUAGE_STATUS);
+ if (pItem2)
+ aNewLangText = pItem2->GetValue();
+
+ //!! Remember the view frame right now...
+ //!! (call to GetView().GetViewFrame() will break if the
+ //!! SwTextShell got destroyed meanwhile.)
+ SfxViewFrame& rViewFrame = GetView().GetViewFrame();
+
+ if (aNewLangText == "*")
+ {
+ // open the dialog "Tools/Options/Languages and Locales - General"
+ // to set the documents default language
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateVclDialog(GetView().GetFrameWeld(), SID_LANGUAGE_OPTIONS));
+ pDlg->Execute();
+ }
+ else
+ {
+ //!! We have to use StartAction / EndAction bracketing in
+ //!! order to prevent possible destruction of the SwTextShell
+ //!! due to the selection changes coming below.
+ rWrtSh.StartAction();
+ // prevent view from jumping because of (temporary) selection changes
+ rWrtSh.LockView( true );
+
+ // setting the new language...
+ if (!aNewLangText.isEmpty())
+ {
+ static constexpr OUString aSelectionLangPrefix(u"Current_"_ustr);
+ static constexpr OUString aParagraphLangPrefix(u"Paragraph_"_ustr);
+ static constexpr OUString aDocumentLangPrefix(u"Default_"_ustr);
+
+ SfxItemSetFixed
+ <RES_CHRATR_LANGUAGE, RES_CHRATR_LANGUAGE,
+ RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CJK_LANGUAGE,
+ RES_CHRATR_CTL_LANGUAGE, RES_CHRATR_CTL_LANGUAGE> aCoreSet( GetPool() );
+
+ sal_Int32 nPos = 0;
+ bool bForSelection = true;
+ bool bForParagraph = false;
+ if (-1 != (nPos = aNewLangText.indexOf( aSelectionLangPrefix )))
+ {
+ // ... for the current selection
+ aNewLangText = aNewLangText.replaceAt(nPos, aSelectionLangPrefix.getLength(), u"");
+ bForSelection = true;
+ }
+ else if (-1 != (nPos = aNewLangText.indexOf(aParagraphLangPrefix)))
+ {
+ // ... for the current paragraph language
+ aNewLangText = aNewLangText.replaceAt(nPos, aParagraphLangPrefix.getLength(), u"");
+ bForSelection = true;
+ bForParagraph = true;
+ }
+ else if (-1 != (nPos = aNewLangText.indexOf(aDocumentLangPrefix)))
+ {
+ // ... as default document language
+ aNewLangText = aNewLangText.replaceAt(nPos, aDocumentLangPrefix.getLength(), u"");
+ bForSelection = false;
+ }
+
+ if (bForParagraph || !bForSelection)
+ {
+ rWrtSh.Push(); // save selection for later restoration
+ rWrtSh.ClearMark(); // fdo#67796: invalidate table crsr
+ }
+
+ if (bForParagraph)
+ SwLangHelper::SelectCurrentPara( rWrtSh );
+
+ if (!bForSelection) // document language to be changed...
+ {
+ rWrtSh.SelAll();
+ rWrtSh.ExtendedSelectAll();
+ }
+
+ rWrtSh.StartUndo( ( !bForParagraph && !bForSelection ) ? SwUndoId::SETDEFTATTR : SwUndoId::EMPTY );
+ if (aNewLangText == "LANGUAGE_NONE")
+ SwLangHelper::SetLanguage_None( rWrtSh, bForSelection, aCoreSet );
+ else if (aNewLangText == "RESET_LANGUAGES")
+ SwLangHelper::ResetLanguages( rWrtSh );
+ else
+ SwLangHelper::SetLanguage( rWrtSh, aNewLangText, bForSelection, aCoreSet );
+ rWrtSh.EndUndo();
+
+ if (bForParagraph || !bForSelection)
+ {
+ rWrtSh.Pop(SwCursorShell::PopMode::DeleteCurrent); // restore selection...
+ }
+ }
+
+ rWrtSh.LockView( false );
+ rWrtSh.EndAction();
+ }
+
+ // invalidate slot to get the new language displayed
+ rViewFrame.GetBindings().Invalidate( nSlot );
+
+ rReq.Done();
+ break;
+ }
+
+ case SID_THES:
+ {
+ // replace word/selection with text from selected sub menu entry
+ OUString aReplaceText;
+ const SfxStringItem* pItem2 = rReq.GetArg(FN_PARAM_THES_WORD_REPLACE);
+ if (pItem2)
+ aReplaceText = pItem2->GetValue();
+ if (!aReplaceText.isEmpty())
+ {
+ SwView &rView2 = rWrtSh.GetView();
+ const bool bSelection = rWrtSh.HasSelection();
+ const OUString aLookUpText = rView2.GetThesaurusLookUpText( bSelection );
+ rView2.InsertThesaurusSynonym( aReplaceText, aLookUpText, bSelection );
+ }
+ }
+ break;
+
+ case SID_CHARMAP:
+ {
+ InsertSymbol( rReq );
+ }
+ break;
+ case FN_INSERT_FOOTNOTE:
+ case FN_INSERT_ENDNOTE:
+ {
+ OUString aStr;
+ const SfxStringItem* pFont = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ const SfxStringItem* pNameItem = rReq.GetArg<SfxStringItem>(nSlot);
+ if ( pNameItem )
+ aStr = pNameItem->GetValue();
+ bool bFont = pFont && !pFont->GetValue().isEmpty();
+ rWrtSh.StartUndo( SwUndoId::UI_INSERT_FOOTNOTE );
+ rWrtSh.InsertFootnote( aStr, nSlot == FN_INSERT_ENDNOTE, !bFont );
+ if ( bFont )
+ {
+ rWrtSh.Left( SwCursorSkipMode::Chars, true, 1, false );
+ SfxItemSetFixed<RES_CHRATR_FONT, RES_CHRATR_FONT> aSet( rWrtSh.GetAttrPool() );
+ rWrtSh.GetCurAttr( aSet );
+ rWrtSh.SetAttrSet( aSet, SetAttrMode::DONTEXPAND );
+ rWrtSh.ResetSelect(nullptr, false);
+ rWrtSh.EndSelect();
+ rWrtSh.GotoFootnoteText();
+ }
+ rWrtSh.EndUndo( SwUndoId::UI_INSERT_FOOTNOTE );
+ rReq.Done();
+ }
+ break;
+ case FN_INSERT_FOOTNOTE_DLG:
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractInsFootNoteDlg> pDlg(pFact->CreateInsFootNoteDlg(
+ GetView().GetFrameWeld(), rWrtSh));
+ pDlg->SetHelpId(GetStaticInterface()->GetSlot(nSlot)->GetCommand());
+ if ( pDlg->Execute() == RET_OK )
+ {
+ const sal_uInt16 nId = pDlg->IsEndNote() ? FN_INSERT_ENDNOTE : FN_INSERT_FOOTNOTE;
+ SfxRequest aReq(GetView().GetViewFrame(), nId);
+ if ( !pDlg->GetStr().isEmpty() )
+ aReq.AppendItem( SfxStringItem( nId, pDlg->GetStr() ) );
+ if ( !pDlg->GetFontName().isEmpty() )
+ aReq.AppendItem( SfxStringItem( FN_PARAM_1, pDlg->GetFontName() ) );
+ ExecuteSlot( aReq );
+ }
+
+ rReq.Ignore();
+ }
+ break;
+ case FN_FORMAT_FOOTNOTE_DLG:
+ case FN_FORMAT_CURRENT_FOOTNOTE_DLG:
+ {
+ GetView().ExecFormatFootnote();
+ break;
+ }
+ case SID_INSERTDOC:
+ {
+ GetView().ExecuteInsertDoc( rReq, pItem );
+ break;
+ }
+ case FN_FORMAT_RESET:
+ {
+ // #i78856, reset all attributes but not the language attributes
+ // (for this build an array of all relevant attributes and
+ // remove the languages from that)
+ o3tl::sorted_vector<sal_uInt16> aAttribs;
+
+ constexpr std::pair<sal_uInt16, sal_uInt16> aResetableSetRange[] = {
+ // tdf#40496: we don't want to change writing direction, so exclude RES_FRAMEDIR:
+ { RES_FRMATR_BEGIN, RES_FRAMEDIR - 1 },
+ { RES_FRAMEDIR + 1, RES_FRMATR_END - 1 },
+ { RES_CHRATR_BEGIN, RES_CHRATR_LANGUAGE - 1 },
+ { RES_CHRATR_LANGUAGE + 1, RES_CHRATR_CJK_LANGUAGE - 1 },
+ { RES_CHRATR_CJK_LANGUAGE + 1, RES_CHRATR_CTL_LANGUAGE - 1 },
+ { RES_CHRATR_CTL_LANGUAGE + 1, RES_CHRATR_END - 1 },
+ { RES_PARATR_BEGIN, RES_PARATR_END - 1 },
+ { RES_PARATR_LIST_AUTOFMT, RES_PARATR_LIST_AUTOFMT },
+ { RES_TXTATR_UNKNOWN_CONTAINER, RES_TXTATR_UNKNOWN_CONTAINER },
+ { RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END - 1 },
+ };
+ for (const auto& [nBegin, nEnd] : aResetableSetRange)
+ {
+ for (sal_uInt16 i = nBegin; i <= nEnd; ++i)
+ aAttribs.insert( i );
+ }
+ rWrtSh.ResetAttr( aAttribs );
+
+ // also clear the direct formatting flag inside SwTableBox(es)
+ if (SwFEShell* pFEShell = GetView().GetDocShell()->GetFEShell())
+ pFEShell->UpdateTableStyleFormatting(nullptr, true);
+
+ rReq.Done();
+ break;
+ }
+ case FN_INSERT_BREAK_DLG:
+ {
+ if ( pItem )
+ {
+ ::std::optional<sal_uInt16> oPageNumber;
+ std::optional<SwLineBreakClear> oClear;
+ OUString aTemplateName;
+ sal_uInt16 nKind = static_cast<const SfxInt16Item*>(pItem)->GetValue();
+ const SfxStringItem* pTemplate = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ const SfxUInt16Item* pNumber = rReq.GetArg<SfxUInt16Item>(FN_PARAM_2);
+ const SfxBoolItem* pIsNumberFilled = rReq.GetArg<SfxBoolItem>(FN_PARAM_3);
+ if ( pTemplate )
+ aTemplateName = pTemplate->GetValue();
+ if ( pNumber && pIsNumberFilled && pIsNumberFilled->GetValue() )
+ oPageNumber = pNumber->GetValue();
+
+ InsertBreak(rWrtSh, nKind, oPageNumber, aTemplateName, oClear);
+ }
+ else
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+
+ std::shared_ptr<AbstractSwBreakDlg> pAbstractDialog(pFact->CreateSwBreakDlg(GetView().GetFrameWeld(), rWrtSh));
+ std::shared_ptr<weld::DialogController> pDialogController(pAbstractDialog->getDialogController());
+
+ weld::DialogController::runAsync(pDialogController,
+ [pAbstractDialog, &rWrtSh] (sal_Int32 nResult) {
+ if( RET_OK == nResult )
+ {
+ sal_uInt16 nKind = pAbstractDialog->GetKind();
+ OUString aTemplateName = pAbstractDialog->GetTemplateName();
+ ::std::optional<sal_uInt16> oPageNumber = pAbstractDialog->GetPageNumber();
+ std::optional<SwLineBreakClear> oClear = pAbstractDialog->GetClear();
+
+ InsertBreak(rWrtSh, nKind, oPageNumber, aTemplateName, oClear);
+ }
+ });
+ }
+
+ break;
+ }
+ case FN_INSERT_BOOKMARK:
+ {
+ const SfxStringItem* pBookmarkText = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ SwPaM* pCursorPos = rWrtSh.GetCursor();
+ if ( pItem )
+ {
+ rWrtSh.StartAction();
+ OUString sName = static_cast<const SfxStringItem*>(pItem)->GetValue();
+
+ if (pBookmarkText)
+ {
+ OUString aBookmarkText = pBookmarkText->GetValue();
+ // Split node to remember where the start position is.
+ bool bSuccess = rWrtSh.GetDoc()->getIDocumentContentOperations().SplitNode(
+ *pCursorPos->GetPoint(), /*bChkTableStart=*/false);
+ if (bSuccess)
+ {
+ SwPaM aBookmarkPam(*pCursorPos->GetPoint());
+ aBookmarkPam.Move(fnMoveBackward, GoInContent);
+
+ // Paste HTML content.
+ SwTranslateHelper::PasteHTMLToPaM(
+ rWrtSh, pCursorPos, aBookmarkText.toUtf8());
+ if (pCursorPos->GetPoint()->GetContentIndex() == 0)
+ {
+ // The paste created a last empty text node, remove it.
+ SwPaM aPam(*pCursorPos->GetPoint());
+ aPam.SetMark();
+ aPam.Move(fnMoveBackward, GoInContent);
+ rWrtSh.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(aPam);
+ }
+
+ // Undo the above SplitNode().
+ aBookmarkPam.SetMark();
+ aBookmarkPam.Move(fnMoveForward, GoInContent);
+ rWrtSh.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(
+ aBookmarkPam);
+ *aBookmarkPam.GetMark() = *pCursorPos->GetPoint();
+ *pCursorPos = aBookmarkPam;
+ }
+ }
+
+ rWrtSh.SetBookmark( vcl::KeyCode(), sName );
+ if (pBookmarkText)
+ {
+ pCursorPos->DeleteMark();
+ }
+ rWrtSh.EndAction();
+ break;
+ }
+ [[fallthrough]];
+ }
+ case FN_EDIT_BOOKMARK:
+ {
+ ::std::optional<OUString> oName;
+ if (pItem)
+ {
+ oName.emplace(static_cast<const SfxStringItem*>(pItem)->GetValue());
+ }
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSwInsertBookmarkDlg(GetView().GetFrameWeld(), rWrtSh, oName ? &*oName : nullptr));
+ VclAbstractDialog::AsyncContext aContext;
+ aContext.maEndDialogFn = [](sal_Int32){};
+ pDlg->StartExecuteAsync(aContext);
+ }
+
+ break;
+ }
+ case FN_UPDATE_BOOKMARKS:
+ {
+ // This updates all bookmarks in the document that match the conditions specified in
+ // rReq.
+ UpdateBookmarks(rReq, rWrtSh);
+ break;
+ }
+ case FN_UPDATE_BOOKMARK:
+ {
+ // This updates the bookmark under the cursor.
+ UpdateBookmark(rReq, rWrtSh);
+ break;
+ }
+ case FN_DELETE_BOOKMARK:
+ {
+ // This deletes a bookmark with the specified name.
+ if (pItem && !rWrtSh.getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS))
+ {
+ IDocumentMarkAccess* const pMarkAccess = rWrtSh.getIDocumentMarkAccess();
+ pMarkAccess->deleteMark(pMarkAccess->findMark(static_cast<const SfxStringItem*>(pItem)->GetValue()), false);
+ }
+ break;
+ }
+ case FN_DELETE_BOOKMARKS:
+ {
+ // This deletes all bookmarks in the document matching a specified prefix.
+ DeleteBookmarks(rReq, rWrtSh);
+ break;
+ }
+ case FN_DELETE_FIELDS:
+ {
+ // This deletes all fields in the document matching a specified type & prefix.
+ DeleteFields(rReq, rWrtSh);
+ break;
+ }
+ case FN_UPDATE_SECTIONS:
+ {
+ UpdateSections(rReq, rWrtSh);
+ break;
+ }
+ case FN_DELETE_SECTIONS:
+ {
+ // This deletes all sections in the document matching a specified prefix. Note that the
+ // section is deleted, but not its contents.
+ DeleteSections(rReq, rWrtSh);
+ break;
+ }
+ case FN_SET_REMINDER:
+ {
+ // collect and sort navigator reminder names
+ IDocumentMarkAccess* const pMarkAccess = rWrtSh.getIDocumentMarkAccess();
+ std::vector< OUString > vNavMarkNames;
+ for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getAllMarksBegin();
+ ppMark != pMarkAccess->getAllMarksEnd();
+ ++ppMark)
+ {
+ if( IDocumentMarkAccess::GetType(**ppMark) == IDocumentMarkAccess::MarkType::NAVIGATOR_REMINDER )
+ vNavMarkNames.push_back((*ppMark)->GetName());
+ }
+ std::sort(vNavMarkNames.begin(), vNavMarkNames.end());
+
+ // we are maxed out so delete the first one
+ // this assumes that IDocumentMarkAccess generates Names in ascending order
+ if(vNavMarkNames.size() == MAX_MARKS)
+ pMarkAccess->deleteMark(pMarkAccess->findMark(vNavMarkNames[0]), false);
+
+ rWrtSh.SetBookmark(vcl::KeyCode(), OUString(), IDocumentMarkAccess::MarkType::NAVIGATOR_REMINDER);
+ SwView::SetActMark(vNavMarkNames.size() < MAX_MARKS ? vNavMarkNames.size() : MAX_MARKS-1);
+
+ break;
+ }
+ case FN_AUTOFORMAT_REDLINE_APPLY:
+ {
+ SvxSwAutoFormatFlags aFlags(SvxAutoCorrCfg::Get().GetAutoCorrect()->GetSwFlags());
+ // This must always be false for the postprocessing.
+ aFlags.bAFormatByInput = false;
+ aFlags.bWithRedlining = true;
+ rWrtSh.AutoFormat( &aFlags, false );
+ aFlags.bWithRedlining = false;
+
+ SfxViewFrame& rVFrame = GetView().GetViewFrame();
+ if (rVFrame.HasChildWindow(FN_REDLINE_ACCEPT))
+ rVFrame.ToggleChildWindow(FN_REDLINE_ACCEPT);
+
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSwModalRedlineAcceptDlg> xDlg(pFact->CreateSwModalRedlineAcceptDlg(GetView().GetEditWin().GetFrameWeld()));
+
+ xDlg->Execute();
+ rReq.Done();
+ }
+ break;
+
+ case FN_AUTOFORMAT_APPLY:
+ {
+ SvxSwAutoFormatFlags aFlags(SvxAutoCorrCfg::Get().GetAutoCorrect()->GetSwFlags());
+ // This must always be false for the postprocessing.
+ aFlags.bAFormatByInput = false;
+ rWrtSh.AutoFormat( &aFlags, false );
+ rReq.Done();
+ }
+ break;
+ case FN_AUTOFORMAT_AUTO:
+ {
+ SvxAutoCorrCfg& rACfg = SvxAutoCorrCfg::Get();
+ bool bSet = pItem ? static_cast<const SfxBoolItem*>(pItem)->GetValue() : !rACfg.IsAutoFormatByInput();
+ if( bSet != rACfg.IsAutoFormatByInput() )
+ {
+ rACfg.SetAutoFormatByInput( bSet );
+ rACfg.Commit();
+ GetView().GetViewFrame().GetBindings().Invalidate( nSlot );
+ if ( !pItem )
+ rReq.AppendItem( SfxBoolItem( GetPool().GetWhich(nSlot), bSet ) );
+ rReq.Done();
+ }
+ }
+ break;
+ case FN_AUTO_CORRECT:
+ {
+ // At first set to blank as default.
+ rWrtSh.AutoCorrect( *SvxAutoCorrCfg::Get().GetAutoCorrect(), ' ' );
+ rReq.Done();
+ }
+ break;
+ case FN_TABLE_SORT_DIALOG:
+ case FN_SORTING_DLG:
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSwSortingDialog(GetView().GetFrameWeld(), rWrtSh));
+ pDlg->Execute();
+ rReq.Done();
+ }
+ break;
+ case FN_NUMBERING_OUTLINE_DLG:
+ {
+ GetView().ExecNumberingOutline(GetPool());
+ rReq.Done();
+ }
+ break;
+ case FN_CALCULATE:
+ {
+ rtl::Reference<SwTransferable> pTransfer = new SwTransferable( rWrtSh );
+ pTransfer->CalculateAndCopy();
+ rReq.Done();
+ }
+ break;
+ case FN_GOTO_REFERENCE:
+ {
+ SwField *pField = rWrtSh.GetCurField();
+ if(pField && pField->GetTypeId() == SwFieldTypesEnum::GetRef)
+ {
+ rWrtSh.StartAllAction();
+ rWrtSh.SwCursorShell::GotoRefMark( static_cast<SwGetRefField*>(pField)->GetSetRefName(),
+ static_cast<SwGetRefField*>(pField)->GetSubType(),
+ static_cast<SwGetRefField*>(pField)->GetSeqNo(),
+ static_cast<SwGetRefField*>(pField)->GetFlags() );
+ rWrtSh.EndAllAction();
+ rReq.Done();
+ }
+ }
+ break;
+ case FN_EDIT_FORMULA:
+ {
+ const sal_uInt16 nId = SwInputChild::GetChildWindowId();
+ SfxViewFrame& rVFrame = GetView().GetViewFrame();
+ if(pItem)
+ {
+ //if the ChildWindow is active it has to be removed
+ if( rVFrame.HasChildWindow( nId ) )
+ {
+ rVFrame.ToggleChildWindow( nId );
+ rVFrame.GetBindings().InvalidateAll( true );
+ }
+
+ OUString sFormula(static_cast<const SfxStringItem*>(pItem)->GetValue());
+ SwFieldMgr aFieldMgr;
+ rWrtSh.StartAllAction();
+ bool bDelSel = rWrtSh.HasSelection();
+ if( bDelSel )
+ {
+ rWrtSh.StartUndo( SwUndoId::START );
+ rWrtSh.DelRight();
+ }
+ else
+ {
+ rWrtSh.EnterStdMode();
+ }
+
+ if( !bDelSel && aFieldMgr.GetCurField() && SwFieldTypesEnum::Formel == aFieldMgr.GetCurTypeId() )
+ aFieldMgr.UpdateCurField( aFieldMgr.GetCurField()->GetFormat(), OUString(), sFormula );
+ else if( !sFormula.isEmpty() )
+ {
+ if( rWrtSh.IsCursorInTable() )
+ {
+ SfxItemSetFixed<RES_BOXATR_FORMULA, RES_BOXATR_FORMULA> aSet( rWrtSh.GetAttrPool() );
+ aSet.Put( SwTableBoxFormula( sFormula ));
+ rWrtSh.SetTableBoxFormulaAttrs( aSet );
+ rWrtSh.UpdateTable();
+ }
+ else
+ {
+ SvNumberFormatter* pFormatter = rWrtSh.GetNumberFormatter();
+ const sal_uInt32 nSysNumFormat = pFormatter->GetFormatIndex( NF_NUMBER_STANDARD, LANGUAGE_SYSTEM);
+ SwInsertField_Data aData(SwFieldTypesEnum::Formel, nsSwGetSetExpType::GSE_FORMULA, OUString(), sFormula, nSysNumFormat);
+ aFieldMgr.InsertField(aData);
+ }
+ }
+
+ if( bDelSel )
+ rWrtSh.EndUndo( SwUndoId::END );
+ rWrtSh.EndAllAction();
+ rReq.Done();
+ }
+ else
+ {
+ rWrtSh.EndAllTableBoxEdit();
+ rVFrame.ToggleChildWindow( nId );
+ if( !rVFrame.HasChildWindow( nId ) )
+ rVFrame.GetBindings().InvalidateAll( true );
+ rReq.Ignore();
+ }
+ }
+
+ break;
+ case FN_TABLE_UNSET_READ_ONLY:
+ {
+ rWrtSh.UnProtectTables();
+ }
+ break;
+ case SID_EDIT_HYPERLINK:
+ GetView().GetViewFrame().SetChildWindow(SID_HYPERLINK_DIALOG, true);
+ break;
+ case SID_REMOVE_HYPERLINK:
+ {
+ bool bSel = rWrtSh.HasSelection();
+ if(!bSel)
+ {
+ rWrtSh.StartAction();
+ rWrtSh.Push();
+ if(!rWrtSh.SelectTextAttr( RES_TXTATR_INETFMT ))
+ rWrtSh.SelWrd();
+ }
+ //now remove the attribute
+ rWrtSh.ResetAttr({ RES_TXTATR_INETFMT });
+ if(!bSel)
+ {
+ rWrtSh.Pop(SwCursorShell::PopMode::DeleteCurrent);
+ rWrtSh.EndAction();
+ }
+ }
+ break;
+ case SID_ATTR_BRUSH_CHAR :
+ case SID_ATTR_CHAR_SCALEWIDTH :
+ case SID_ATTR_CHAR_ROTATED :
+ case FN_TXTATR_INET :
+ case FN_INSERT_HYPERLINK:
+ {
+ const sal_uInt16 nWhich = GetPool().GetWhich( nSlot );
+ if ( pArgs && pArgs->GetItemState( nWhich ) == SfxItemState::SET )
+ bUseDialog = false;
+ [[fallthrough]];
+ }
+ case SID_CHAR_DLG:
+ case SID_CHAR_DLG_EFFECT:
+ case SID_CHAR_DLG_POSITION:
+ {
+ sw_CharDialog(rWrtSh, bUseDialog, /*ApplyToParagraph*/false, nSlot, pArgs, &rReq);
+ }
+ break;
+ case SID_CHAR_DLG_FOR_PARAGRAPH:
+ {
+ sw_CharDialog(rWrtSh, /*UseDialog*/true, /*ApplyToParagraph*/true, nSlot, pArgs, &rReq);
+ }
+ break;
+ case SID_ATTR_LRSPACE :
+ case SID_ATTR_ULSPACE :
+ case SID_ATTR_BRUSH :
+ case SID_PARA_VERTALIGN :
+ case SID_ATTR_PARA_NUMRULE :
+ case SID_ATTR_PARA_REGISTER :
+ case SID_ATTR_PARA_PAGENUM :
+ case FN_FORMAT_LINENUMBER :
+ case FN_NUMBER_NEWSTART :
+ case FN_NUMBER_NEWSTART_AT :
+ case FN_FORMAT_DROPCAPS :
+ case FN_DROP_TEXT:
+ case SID_ATTR_PARA_LRSPACE:
+ {
+ const sal_uInt16 nWhich = GetPool().GetWhich( nSlot );
+ if ( pArgs && pArgs->GetItemState( nWhich ) == SfxItemState::SET )
+ bUseDialog = false;
+ [[fallthrough]];
+ }
+ case SID_PARA_DLG:
+ {
+ SwPaM* pPaM = nullptr;
+
+ if ( pArgs )
+ {
+ const SwPaMItem* pPaMItem = pArgs->GetItemIfSet( GetPool().GetWhich( FN_PARAM_PAM ), false );
+ if ( pPaMItem )
+ pPaM = pPaMItem->GetValue( );
+ }
+
+ if ( !pPaM )
+ pPaM = rWrtSh.GetCursor();
+
+ FieldUnit eMetric = ::GetDfltMetric( dynamic_cast<SwWebView*>( &GetView()) != nullptr );
+ SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)));
+
+ bool bApplyCharUnit = ::HasCharUnit( dynamic_cast<SwWebView*>( &GetView()) != nullptr );
+ SW_MOD()->PutItem(SfxBoolItem(SID_ATTR_APPLYCHARUNIT, bApplyCharUnit));
+
+ SfxItemSetFixed<
+ RES_PARATR_BEGIN, RES_FRMATR_END - 1,
+ // FillAttribute support:
+ XATTR_FILL_FIRST, XATTR_FILL_LAST,
+ // Includes SID_ATTR_TABSTOP_POS:
+ SID_ATTR_TABSTOP_DEFAULTS, SID_ATTR_TABSTOP_OFFSET,
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
+ SID_ATTR_PARA_MODEL, SID_ATTR_PARA_KEEP,
+ // Items to hand over XPropertyList things like XColorList,
+ // XHatchList, XGradientList, and XBitmapList to the Area
+ // TabPage:
+ SID_COLOR_TABLE, SID_PATTERN_LIST,
+ SID_HTML_MODE, SID_HTML_MODE,
+ SID_ATTR_PARA_PAGENUM, SID_ATTR_PARA_PAGENUM,
+ FN_PARAM_1, FN_PARAM_1,
+ FN_NUMBER_NEWSTART, FN_NUMBER_NEWSTART_AT,
+ FN_DROP_TEXT, FN_DROP_CHAR_STYLE_NAME> aCoreSet( GetPool() );
+
+ // get also the list level indent values merged as LR-SPACE item, if needed.
+ rWrtSh.GetPaMAttr( pPaM, aCoreSet, true );
+
+ // create needed items for XPropertyList entries from the DrawModel so that
+ // the Area TabPage can access them
+ // Do this after GetCurAttr, this resets the ItemSet content again
+ SwDrawModel* pDrawModel = GetView().GetDocShell()->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
+
+ aCoreSet.Put(SvxColorListItem(pDrawModel->GetColorList(), SID_COLOR_TABLE));
+ aCoreSet.Put(SvxGradientListItem(pDrawModel->GetGradientList(), SID_GRADIENT_LIST));
+ aCoreSet.Put(SvxHatchListItem(pDrawModel->GetHatchList(), SID_HATCH_LIST));
+ aCoreSet.Put(SvxBitmapListItem(pDrawModel->GetBitmapList(), SID_BITMAP_LIST));
+ aCoreSet.Put(SvxPatternListItem(pDrawModel->GetPatternList(), SID_PATTERN_LIST));
+ aCoreSet.Put(SfxUInt16Item(SID_HTML_MODE,
+ ::GetHtmlMode(GetView().GetDocShell())));
+
+ // Tabulators: Put DefaultTabs into ItemSet
+ const SvxTabStopItem& rDefTabs =
+ GetPool().GetDefaultItem(RES_PARATR_TABSTOP);
+
+ const sal_uInt16 nDefDist = o3tl::narrowing<sal_uInt16>(::GetTabDist( rDefTabs ));
+ SfxUInt16Item aDefDistItem( SID_ATTR_TABSTOP_DEFAULTS, nDefDist );
+ aCoreSet.Put( aDefDistItem );
+
+ // Current tabulator
+ SfxUInt16Item aTabPos( SID_ATTR_TABSTOP_POS, 0 );
+ aCoreSet.Put( aTabPos );
+
+ // Left border as offset
+ //#i24363# tab stops relative to indent
+ const tools::Long nOff = rWrtSh.getIDocumentSettingAccess().get(DocumentSettingId::TABS_RELATIVE_TO_INDENT)
+ ? aCoreSet.Get(RES_MARGIN_TEXTLEFT).GetTextLeft() : 0;
+ SfxInt32Item aOff( SID_ATTR_TABSTOP_OFFSET, nOff );
+ aCoreSet.Put( aOff );
+
+ // Setting the BoxInfo
+ ::PrepareBoxInfo( aCoreSet, rWrtSh );
+
+ // Current page format
+ ::SwToSfxPageDescAttr( aCoreSet );
+
+ // Properties of numbering
+ if (rWrtSh.GetNumRuleAtCurrCursorPos())
+ {
+ SfxBoolItem aStart( FN_NUMBER_NEWSTART, rWrtSh.IsNumRuleStart( pPaM ) );
+ aCoreSet.Put(aStart);
+ SfxUInt16Item aStartAt( FN_NUMBER_NEWSTART_AT,
+ rWrtSh.GetNodeNumStart( pPaM ) );
+ aCoreSet.Put(aStartAt);
+ }
+ VclPtr<SfxAbstractTabDialog> pDlg;
+
+ if ( bUseDialog && GetActiveView() )
+ {
+ OUString sDefPage;
+ if (pItem)
+ sDefPage = static_cast<const SfxStringItem*>(pItem)->GetValue();
+
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ pDlg.reset(pFact->CreateSwParaDlg(GetView().GetFrameWeld(), GetView(), aCoreSet, false, sDefPage));
+ }
+
+ if ( !bUseDialog )
+ {
+ if ( nSlot == SID_ATTR_PARA_LRSPACE)
+ {
+ SvxLRSpaceItem aParaMargin(static_cast<const SvxLRSpaceItem&>(pArgs->Get(nSlot)));
+ SvxFirstLineIndentItem firstLine(RES_MARGIN_FIRSTLINE);
+ SvxTextLeftMarginItem leftMargin(RES_MARGIN_TEXTLEFT);
+ SvxRightMarginItem rightMargin(RES_MARGIN_RIGHT);
+ firstLine.SetTextFirstLineOffset(aParaMargin.GetTextFirstLineOffset(), aParaMargin.GetPropTextFirstLineOffset());
+ firstLine.SetAutoFirst(aParaMargin.IsAutoFirst());
+ leftMargin.SetTextLeft(aParaMargin.GetTextLeft(), aParaMargin.GetPropLeft());
+ rightMargin.SetRight(aParaMargin.GetRight(), aParaMargin.GetPropRight());
+ aCoreSet.Put(firstLine);
+ aCoreSet.Put(leftMargin);
+ aCoreSet.Put(rightMargin);
+
+ sw_ParagraphDialogResult(&aCoreSet, rWrtSh, rReq, pPaM);
+ }
+ else
+ sw_ParagraphDialogResult(const_cast<SfxItemSet*>(pArgs), rWrtSh, rReq, pPaM);
+ }
+ else if (pDlg)
+ {
+ auto pRequest = std::make_shared<SfxRequest>(rReq);
+ rReq.Ignore(); // the 'old' request is not relevant any more
+
+ auto vCursors = CopyPaMRing(*pPaM); // tdf#134439 make a copy to use at later apply
+ pDlg->StartExecuteAsync([pDlg, &rWrtSh, pDrawModel, pRequest, nDefDist, vCursors](sal_Int32 nResult){
+ if (nResult == RET_OK)
+ {
+ // Apply defaults if necessary.
+ SfxItemSet* pSet = const_cast<SfxItemSet*>(pDlg->GetOutputItemSet());
+ sal_uInt16 nNewDist;
+ const SfxUInt16Item* pDefaultsItem = pSet->GetItemIfSet(SID_ATTR_TABSTOP_DEFAULTS, false);
+ if (pDefaultsItem && nDefDist != (nNewDist = pDefaultsItem->GetValue()) )
+ {
+ SvxTabStopItem aDefTabs( 0, 0, SvxTabAdjust::Default, RES_PARATR_TABSTOP );
+ MakeDefTabs( nNewDist, aDefTabs );
+ rWrtSh.SetDefault( aDefTabs );
+ pSet->ClearItem( SID_ATTR_TABSTOP_DEFAULTS );
+ }
+
+ const SfxPoolItem* pItem2 = nullptr;
+ if (SfxItemState::SET == pSet->GetItemState(FN_PARAM_1, false, &pItem2))
+ {
+ pSet->Put(SfxStringItem(FN_DROP_TEXT, static_cast<const SfxStringItem*>(pItem2)->GetValue()));
+ pSet->ClearItem(FN_PARAM_1);
+ }
+
+ if (const SwFormatDrop* pDropItem = pSet->GetItemIfSet(RES_PARATR_DROP, false))
+ {
+ OUString sCharStyleName;
+ if (pDropItem->GetCharFormat())
+ sCharStyleName = pDropItem->GetCharFormat()->GetName();
+ pSet->Put(SfxStringItem(FN_DROP_CHAR_STYLE_NAME, sCharStyleName));
+ }
+
+ const XFillStyleItem* pFS = pSet->GetItem<XFillStyleItem>(XATTR_FILLSTYLE);
+ bool bSet = pFS && pFS->GetValue() == drawing::FillStyle_GRADIENT;
+ const XFillGradientItem* pTempGradItem
+ = bSet ? pSet->GetItem<XFillGradientItem>(XATTR_FILLGRADIENT) : nullptr;
+ if (pTempGradItem && pTempGradItem->GetName().isEmpty())
+ {
+ // MigrateItemSet guarantees unique gradient names
+ SfxItemSetFixed<XATTR_FILLGRADIENT, XATTR_FILLGRADIENT> aMigrateSet(rWrtSh.GetView().GetPool());
+ aMigrateSet.Put(XFillGradientItem("gradient", pTempGradItem->GetGradientValue()));
+ SdrModel::MigrateItemSet(&aMigrateSet, pSet, pDrawModel);
+ }
+
+ bSet = pFS && pFS->GetValue() == drawing::FillStyle_HATCH;
+ const XFillHatchItem* pTempHatchItem
+ = bSet ? pSet->GetItem<XFillHatchItem>(XATTR_FILLHATCH) : nullptr;
+ if (pTempHatchItem && pTempHatchItem->GetName().isEmpty())
+ {
+ SfxItemSetFixed<XATTR_FILLHATCH, XATTR_FILLHATCH> aMigrateSet(rWrtSh.GetView().GetPool());
+ aMigrateSet.Put(XFillHatchItem("hatch", pTempHatchItem->GetHatchValue()));
+ SdrModel::MigrateItemSet(&aMigrateSet, pSet, pDrawModel);
+ }
+
+ sw_ParagraphDialogResult(pSet, rWrtSh, *pRequest, vCursors->front().get());
+ }
+ pDlg->disposeOnce();
+ });
+ }
+ }
+ break;
+ case FN_NUM_CONTINUE:
+ {
+ OUString sContinuedListId;
+ const SwNumRule* pRule =
+ rWrtSh.SearchNumRule( true, sContinuedListId );
+ // #i86492#
+ // Search also for bullet list
+ if ( !pRule )
+ {
+ pRule = rWrtSh.SearchNumRule( false, sContinuedListId );
+ }
+ if ( pRule )
+ {
+ rWrtSh.SetCurNumRule( *pRule, false, sContinuedListId );
+ }
+ }
+ break;
+
+ case FN_SELECT_PARA:
+ {
+ if ( !rWrtSh.IsSttOfPara() )
+ rWrtSh.SttPara();
+ else
+ rWrtSh.EnterStdMode();
+ rWrtSh.EndPara( true );
+ }
+ break;
+
+ case SID_DEC_INDENT:
+ case SID_INC_INDENT:
+ //According to the requirement, modified the behavior when user
+ //using the indent button on the toolbar. Now if we increase/decrease indent for a
+ //paragraph which has bullet style it will increase/decrease the bullet level.
+ {
+ //If the current paragraph has bullet call the function to
+ //increase or decrease the bullet level.
+ //Why could I know whether a paragraph has bullet or not by checking the below conditions?
+ //Please refer to the "case KEY_TAB:" section in SwEditWin::KeyInput(..) :
+ // if( rSh.GetCurNumRule() && rSh.IsSttOfPara() &&
+ // !rSh.HasReadonlySel() )
+ // eKeyState = KS_NumDown;
+ //Above code demonstrates that when the cursor is at the start of a paragraph which has bullet,
+ //press TAB will increase the bullet level.
+ //So I copied from that ^^
+ if ( rWrtSh.GetNumRuleAtCurrCursorPos() && !rWrtSh.HasReadonlySel() )
+ {
+ rWrtSh.NumUpDown( SID_INC_INDENT == nSlot );
+ }
+ else //execute the original processing functions
+ {
+ //below is copied of the old codes
+ rWrtSh.MoveLeftMargin( SID_INC_INDENT == nSlot, rReq.GetModifier() != KEY_MOD1 );
+ }
+ }
+ rReq.Done();
+ break;
+
+ case FN_DEC_INDENT_OFFSET:
+ case FN_INC_INDENT_OFFSET:
+ rWrtSh.MoveLeftMargin( FN_INC_INDENT_OFFSET == nSlot, rReq.GetModifier() == KEY_MOD1 );
+ rReq.Done();
+ break;
+
+ case SID_ATTR_CHAR_COLOR2:
+ {
+ if (pItem)
+ {
+ auto* pColorItem = static_cast<const SvxColorItem*>(pItem);
+ SwEditWin& rEditWin = GetView().GetEditWin();
+ rEditWin.SetWaterCanTextColor(pColorItem->GetValue());
+ SwApplyTemplate* pApply = rEditWin.GetApplyTemplate();
+
+ // If there is a selection, then set the color on it
+ // otherwise, it'll be the color for the next text to be typed
+ if (!pApply || pApply->nColor != SID_ATTR_CHAR_COLOR_EXT)
+ {
+ rWrtSh.SetAttrItem(SvxColorItem(pColorItem->GetValue(), pColorItem->getComplexColor(), RES_CHRATR_COLOR));
+ }
+
+ rReq.Done();
+ }
+ }
+ break;
+ case SID_ATTR_CHAR_BACK_COLOR:
+ case SID_ATTR_CHAR_COLOR_BACKGROUND: // deprecated
+ case SID_ATTR_CHAR_COLOR_EXT:
+ {
+ Color aColor;
+ model::ComplexColor aComplexColor;
+
+ if (pItem)
+ {
+ auto* pColorItem = static_cast<const SvxColorItem*>(pItem);
+ aColor = pColorItem->GetValue();
+ aComplexColor = pColorItem->getComplexColor();
+ }
+ else
+ aColor = COL_TRANSPARENT;
+
+ SwEditWin& rEdtWin = GetView().GetEditWin();
+ if (nSlot != SID_ATTR_CHAR_COLOR_EXT)
+ rEdtWin.SetWaterCanTextBackColor(aColor);
+ else if (pItem)
+ rEdtWin.SetWaterCanTextColor(aColor);
+
+ SwApplyTemplate* pApply = rEdtWin.GetApplyTemplate();
+ SwApplyTemplate aTempl;
+ if (!pApply && (rWrtSh.HasSelection() || rReq.IsAPI()))
+ {
+ if (nSlot != SID_ATTR_CHAR_COLOR_EXT)
+ {
+ SfxItemSetFixed<RES_CHRATR_BACKGROUND, RES_CHRATR_BACKGROUND> aCoreSet( rWrtSh.GetView().GetPool() );
+
+ rWrtSh.GetCurAttr(aCoreSet);
+
+ // Remove highlight if already set of the same color
+ const SvxBrushItem& rBrushItem = aCoreSet.Get(RES_CHRATR_BACKGROUND);
+ if (aColor == rBrushItem.GetColor())
+ {
+ aComplexColor = model::ComplexColor();
+ aColor = COL_TRANSPARENT;
+ }
+ ApplyCharBackground(aColor, aComplexColor, rWrtSh);
+ }
+ else
+ rWrtSh.SetAttrItem(SvxColorItem(aColor, aComplexColor, RES_CHRATR_COLOR));
+ }
+ else
+ {
+ if(!pApply || pApply->nColor != nSlot)
+ aTempl.nColor = nSlot;
+ rEdtWin.SetApplyTemplate(aTempl);
+ }
+
+ rReq.Done();
+ }
+ break;
+
+ case FN_NUM_BULLET_MOVEDOWN:
+ if (!rWrtSh.IsAddMode())
+ rWrtSh.MoveParagraph();
+ rReq.Done();
+ break;
+
+ case FN_NUM_BULLET_MOVEUP:
+ if (!rWrtSh.IsAddMode())
+ rWrtSh.MoveParagraph(SwNodeOffset(-1));
+ rReq.Done();
+ break;
+ case SID_RUBY_DIALOG:
+ case SID_HYPERLINK_DIALOG:
+ {
+ SfxRequest aReq(nSlot, SfxCallMode::SLOT, SfxGetpApp()->GetPool());
+ GetView().GetViewFrame().ExecuteSlot( aReq);
+ rReq.Ignore();
+ }
+ break;
+ case FN_INSERT_PAGEHEADER:
+ case FN_INSERT_PAGEFOOTER:
+ if(pArgs && pArgs->Count())
+ {
+ OUString sStyleName;
+ if(pItem)
+ sStyleName = static_cast<const SfxStringItem*>(pItem)->GetValue();
+ bool bOn = true;
+ if( SfxItemState::SET == pArgs->GetItemState(FN_PARAM_1, false, &pItem))
+ bOn = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ rWrtSh.ChangeHeaderOrFooter(sStyleName, FN_INSERT_PAGEHEADER == nSlot, bOn, !rReq.IsAPI());
+ rReq.Done();
+ }
+ break;
+ case FN_READONLY_SELECTION_MODE :
+ if(GetView().GetDocShell()->IsReadOnly())
+ {
+ rWrtSh.SetReadonlySelectionOption(
+ !rWrtSh.GetViewOptions()->IsSelectionInReadonly());
+ rWrtSh.ShowCursor();
+ }
+ break;
+ case FN_SELECTION_MODE_DEFAULT:
+ case FN_SELECTION_MODE_BLOCK :
+ {
+ bool bSetBlockMode = !rWrtSh.IsBlockMode();
+ if( pArgs && SfxItemState::SET == pArgs->GetItemState(nSlot, false, &pItem))
+ bSetBlockMode = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ if( ( nSlot == FN_SELECTION_MODE_DEFAULT ) != bSetBlockMode )
+ rWrtSh.EnterBlockMode();
+ else
+ rWrtSh.EnterStdMode();
+ SfxBindings &rBnd = GetView().GetViewFrame().GetBindings();
+ rBnd.Invalidate(FN_STAT_SELMODE);
+ rBnd.Update(FN_STAT_SELMODE);
+ }
+ break;
+ case SID_OPEN_HYPERLINK:
+ case SID_COPY_HYPERLINK_LOCATION:
+ {
+ SfxItemSetFixed<RES_TXTATR_INETFMT, RES_TXTATR_INETFMT> aSet(GetPool());
+ rWrtSh.GetCurAttr(aSet);
+ if(SfxItemState::SET <= aSet.GetItemState( RES_TXTATR_INETFMT ))
+ {
+ const SwFormatINetFormat& rINetFormat = aSet.Get(RES_TXTATR_INETFMT);
+
+ if (nSlot == SID_OPEN_HYPERLINK)
+ {
+ rWrtSh.ClickToINetAttr(rINetFormat);
+ }
+ else if (nSlot == SID_COPY_HYPERLINK_LOCATION)
+ {
+ OUString hyperlinkLocation = rINetFormat.GetValue();
+ ::uno::Reference< datatransfer::clipboard::XClipboard > xClipboard = GetView().GetEditWin().GetClipboard();
+ vcl::unohelper::TextDataObject::CopyStringTo(hyperlinkLocation, xClipboard, SfxViewShell::Current());
+ }
+ }
+ else
+ {
+ SwField* pField = rWrtSh.GetCurField();
+ if (pField && pField->GetTyp()->Which() == SwFieldIds::TableOfAuthorities)
+ {
+ const auto& rAuthorityField = *static_cast<const SwAuthorityField*>(pField);
+ OUString targetURL = "";
+
+ if (auto targetType = rAuthorityField.GetTargetType();
+ targetType == SwAuthorityField::TargetType::UseDisplayURL
+ || targetType == SwAuthorityField::TargetType::UseTargetURL)
+ {
+ // Bibliography entry with URL also provides a hyperlink.
+ targetURL = rAuthorityField.GetAbsoluteURL();
+ }
+
+ if (targetURL.getLength() > 0)
+ {
+ if (nSlot == SID_OPEN_HYPERLINK)
+ {
+ ::LoadURL(rWrtSh, targetURL, LoadUrlFlags::NewView, /*rTargetFrameName=*/OUString());
+ }
+ else if (nSlot == SID_COPY_HYPERLINK_LOCATION)
+ {
+ ::uno::Reference< datatransfer::clipboard::XClipboard > xClipboard = GetView().GetEditWin().GetClipboard();
+ vcl::unohelper::TextDataObject::CopyStringTo(targetURL, xClipboard, SfxViewShell::Current());
+ }
+ }
+ }
+ }
+ }
+ break;
+ case FN_OPEN_LOCAL_URL:
+ {
+ OUString aLocalURL = GetLocalURL(rWrtSh);
+ if (!aLocalURL.isEmpty())
+ {
+ ::LoadURL(rWrtSh, aLocalURL, LoadUrlFlags::NewView, /*rTargetFrameName=*/OUString());
+ }
+ }
+ break;
+ case SID_OPEN_XML_FILTERSETTINGS:
+ {
+ HandleOpenXmlFilterSettings(rReq);
+ }
+ break;
+ case FN_FORMAT_APPLY_HEAD1:
+ {
+ }
+ break;
+ case FN_FORMAT_APPLY_HEAD2:
+ {
+ }
+ break;
+ case FN_FORMAT_APPLY_HEAD3:
+ {
+ }
+ break;
+ case FN_FORMAT_APPLY_DEFAULT:
+ {
+ }
+ break;
+ case FN_FORMAT_APPLY_TEXTBODY:
+ {
+ }
+ break;
+ case FN_WORDCOUNT_DIALOG:
+ {
+ GetView().UpdateWordCount(this, nSlot);
+ }
+ break;
+ case FN_PROTECT_FIELDS:
+ case FN_PROTECT_BOOKMARKS:
+ {
+ IDocumentSettingAccess& rIDSA = rWrtSh.getIDocumentSettingAccess();
+ DocumentSettingId aSettingId = nSlot == FN_PROTECT_FIELDS
+ ? DocumentSettingId::PROTECT_FIELDS
+ : DocumentSettingId::PROTECT_BOOKMARKS;
+ rIDSA.set(aSettingId, !rIDSA.get(aSettingId));
+ // Invalidate so that toggle state gets updated
+ SfxViewFrame& rViewFrame = GetView().GetViewFrame();
+ rViewFrame.GetBindings().Invalidate(nSlot);
+ rViewFrame.GetBindings().Update(nSlot);
+ }
+ break;
+ case SID_FM_CTL_PROPERTIES:
+ {
+ SwPosition aPos(*GetShell().GetCursor()->GetPoint());
+ sw::mark::IFieldmark* pFieldBM = GetShell().getIDocumentMarkAccess()->getInnerFieldmarkFor(aPos);
+ if ( !pFieldBM )
+ {
+ aPos.AdjustContent(-1);
+ pFieldBM = GetShell().getIDocumentMarkAccess()->getInnerFieldmarkFor(aPos);
+ }
+
+ if ( pFieldBM && pFieldBM->GetFieldname() == ODF_FORMDROPDOWN
+ && !(rWrtSh.GetCurrSection() && rWrtSh.GetCurrSection()->IsProtect()) )
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateDropDownFormFieldDialog(rWrtSh.GetView().GetFrameWeld(), pFieldBM));
+ if (pDlg->Execute() == RET_OK)
+ {
+ pFieldBM->Invalidate();
+ rWrtSh.InvalidateWindows( SwRect(rWrtSh.GetView().GetVisArea()) );
+ rWrtSh.UpdateCursor(); // cursor position might be invalid
+ }
+ }
+ else if ( pFieldBM && pFieldBM->GetFieldname() == ODF_FORMDATE )
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ sw::mark::DateFieldmark& rDateField = dynamic_cast<sw::mark::DateFieldmark&>(*pFieldBM);
+ ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateDateFormFieldDialog(rWrtSh.GetView().GetFrameWeld(), &rDateField, *GetView().GetDocShell()->GetDoc()));
+ if (pDlg->Execute() == RET_OK)
+ {
+ rDateField.Invalidate();
+ rWrtSh.InvalidateWindows( SwRect(rWrtSh.GetView().GetVisArea()) );
+ rWrtSh.UpdateCursor(); // cursor position might be invalid
+ }
+ }
+ else
+ {
+ SfxRequest aReq(GetView().GetViewFrame(), SID_FM_CTL_PROPERTIES);
+ aReq.AppendItem( SfxBoolItem( SID_FM_CTL_PROPERTIES, true ) );
+ rWrtSh.GetView().GetFormShell()->Execute( aReq );
+ }
+ }
+ break;
+ case SID_FM_TRANSLATE:
+ {
+#if HAVE_FEATURE_CURL && !ENABLE_WASM_STRIP_EXTRA
+ const SfxPoolItem* pTargetLangStringItem = nullptr;
+ if (pArgs && SfxItemState::SET == pArgs->GetItemState(SID_ATTR_TARGETLANG_STR, false, &pTargetLangStringItem))
+ {
+ std::optional<OUString> oDeeplAPIUrl = officecfg::Office::Linguistic::Translation::Deepl::ApiURL::get();
+ std::optional<OUString> oDeeplKey = officecfg::Office::Linguistic::Translation::Deepl::AuthKey::get();
+ if (!oDeeplAPIUrl || oDeeplAPIUrl->isEmpty() || !oDeeplKey || oDeeplKey->isEmpty())
+ {
+ SAL_WARN("sw.ui", "SID_FM_TRANSLATE: API options are not set");
+ break;
+ }
+ const OString aAPIUrl = OUStringToOString(rtl::Concat2View(*oDeeplAPIUrl + "?tag_handling=html"), RTL_TEXTENCODING_UTF8).trim();
+ const OString aAuthKey = OUStringToOString(*oDeeplKey, RTL_TEXTENCODING_UTF8).trim();
+ OString aTargetLang = OUStringToOString(static_cast<const SfxStringItem*>(pTargetLangStringItem)->GetValue(), RTL_TEXTENCODING_UTF8);
+ SwTranslateHelper::TranslateAPIConfig aConfig({aAPIUrl, aAuthKey, aTargetLang});
+ SwTranslateHelper::TranslateDocument(rWrtSh, aConfig);
+ }
+ else
+ {
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ std::shared_ptr<AbstractSwTranslateLangSelectDlg> pAbstractDialog(pFact->CreateSwTranslateLangSelectDlg(GetView().GetFrameWeld(), rWrtSh));
+ std::shared_ptr<weld::DialogController> pDialogController(pAbstractDialog->getDialogController());
+ weld::DialogController::runAsync(pDialogController, [] (sal_Int32 /*nResult*/) { });
+ }
+#endif // HAVE_FEATURE_CURL && ENABLE_WASM_STRIP_EXTRA
+ }
+ break;
+ case SID_SPELLCHECK_IGNORE:
+ {
+ SwPaM *pPaM = rWrtSh.GetCursor();
+ if (pPaM)
+ SwEditShell::IgnoreGrammarErrorAt( *pPaM );
+ }
+ break;
+ case SID_SPELLCHECK_IGNORE_ALL:
+ {
+ OUString sApplyText;
+ const SfxStringItem* pItem2 = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ if (pItem2)
+ sApplyText = pItem2->GetValue();
+
+ if(sApplyText == "Grammar")
+ {
+ linguistic2::ProofreadingResult aGrammarCheckRes;
+ sal_Int32 nErrorInResult = -1;
+ uno::Sequence< OUString > aSuggestions;
+ sal_Int32 nErrorPosInText = -1;
+ SwRect aToFill;
+ bool bCorrectionRes = rWrtSh.GetGrammarCorrection( aGrammarCheckRes, nErrorPosInText, nErrorInResult, aSuggestions, nullptr, aToFill );
+ if(bCorrectionRes)
+ {
+ try {
+ uno::Reference< linguistic2::XDictionary > xDictionary = LinguMgr::GetIgnoreAllList();
+ aGrammarCheckRes.xProofreader->ignoreRule(
+ aGrammarCheckRes.aErrors[ nErrorInResult ].aRuleIdentifier,
+ aGrammarCheckRes.aLocale );
+ // refresh the layout of the actual paragraph (faster)
+ SwPaM *pPaM = rWrtSh.GetCursor();
+ if (pPaM)
+ SwEditShell::IgnoreGrammarErrorAt( *pPaM );
+ if (xDictionary.is())
+ {
+ // refresh the layout of all paragraphs (workaround to launch a dictionary event)
+ xDictionary->setActive(false);
+ xDictionary->setActive(true);
+ }
+ }
+ catch( const uno::Exception& )
+ {
+ }
+ }
+ }
+ else if (sApplyText == "Spelling")
+ {
+ SwRect aToFill;
+ uno::Reference<linguistic2::XSpellAlternatives> xSpellAlt(rWrtSh.GetCorrection(nullptr, aToFill));
+ if (!xSpellAlt.is())
+ return;
+ uno::Reference< linguistic2::XDictionary > xDictionary = LinguMgr::GetIgnoreAllList();
+ OUString sWord(xSpellAlt->getWord());
+ linguistic::DictionaryError nAddRes = linguistic::AddEntryToDic( xDictionary,
+ sWord, false, OUString() );
+ if (linguistic::DictionaryError::NONE != nAddRes && xDictionary.is() && !xDictionary->getEntry(sWord).is())
+ {
+ SvxDicError(rWrtSh.GetView().GetFrameWeld(), nAddRes);
+ }
+ }
+ }
+ break;
+ case SID_SPELLCHECK_APPLY_SUGGESTION:
+ {
+ OUString sApplyText;
+ const SfxStringItem* pItem2 = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ if (pItem2)
+ sApplyText = pItem2->GetValue();
+
+ static constexpr OUString sSpellingRule(u"Spelling_"_ustr);
+ static constexpr OUString sGrammarRule(u"Grammar_"_ustr);
+
+ bool bGrammar = false;
+ sal_Int32 nPos = 0;
+ uno::Reference< linguistic2::XSpellAlternatives > xSpellAlt;
+ if(-1 != (nPos = sApplyText.indexOf( sGrammarRule )))
+ {
+ sApplyText = sApplyText.replaceAt(nPos, sGrammarRule.getLength(), u"");
+ bGrammar = true;
+ }
+ else if (-1 != (nPos = sApplyText.indexOf( sSpellingRule )))
+ {
+ sApplyText = sApplyText.replaceAt(nPos, sSpellingRule.getLength(), u"");
+ SwRect aToFill;
+ xSpellAlt.set(rWrtSh.GetCorrection(nullptr, aToFill));
+ bGrammar = false;
+ }
+
+ if (!bGrammar && !xSpellAlt.is())
+ return;
+
+ bool bOldIns = rWrtSh.IsInsMode();
+ rWrtSh.SetInsMode();
+
+ OUString aTmp( sApplyText );
+ OUString aOrig( bGrammar ? OUString() : xSpellAlt->getWord() );
+
+ // if original word has a trailing . (likely the end of a sentence)
+ // and the replacement text hasn't, then add it to the replacement
+ if (!aTmp.isEmpty() && !aOrig.isEmpty() &&
+ aOrig.endsWith(".") && /* !IsAlphaNumeric ??*/
+ !aTmp.endsWith("."))
+ {
+ aTmp += ".";
+ }
+
+ SwRewriter aRewriter;
+
+ aRewriter.AddRule(UndoArg1, rWrtSh.GetCursorDescr()
+ // don't show the hidden control character of the comment
+ .replaceAll(OUStringChar(CH_TXTATR_INWORD), "") );
+ aRewriter.AddRule(UndoArg2, SwResId(STR_YIELDS));
+
+ OUString aTmpStr = SwResId(STR_START_QUOTE) +
+ aTmp + SwResId(STR_END_QUOTE);
+ aRewriter.AddRule(UndoArg3, aTmpStr);
+
+ rWrtSh.StartUndo(SwUndoId::UI_REPLACE, &aRewriter);
+ rWrtSh.StartAction();
+
+ // keep comments at the end of the replacement in case spelling correction is
+ // invoked via the context menu. The spell check dialog does the correction in edlingu.cxx.
+ rWrtSh.ReplaceKeepComments(aTmp);
+
+ rWrtSh.EndAction();
+ rWrtSh.EndUndo();
+
+ rWrtSh.SetInsMode( bOldIns );
+ }
+ break;
+ default:
+ OSL_ENSURE(false, "wrong dispatcher");
+ return;
+ }
+}
+
+void SwTextShell::GetState( SfxItemSet &rSet )
+{
+ SwWrtShell &rSh = GetShell();
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ const sal_uInt16 nSlotId = GetPool().GetSlotId(nWhich);
+ switch (nSlotId)
+ {
+ case FN_FORMAT_CURRENT_FOOTNOTE_DLG:
+ if( !rSh.IsCursorInFootnote() )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_LANGUAGE_STATUS:
+ {
+ // the value of used script types
+ OUString aScriptTypesInUse( OUString::number( static_cast<int>(rSh.GetScriptType()) ) );
+
+ // get keyboard language
+ OUString aKeyboardLang;
+ SwEditWin& rEditWin = GetView().GetEditWin();
+ LanguageType nLang = rEditWin.GetInputLanguage();
+ if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
+ aKeyboardLang = SvtLanguageTable::GetLanguageString( nLang );
+
+ // get the language that is in use
+ OUString aCurrentLang = "*";
+ nLang = SwLangHelper::GetCurrentLanguage( rSh );
+ if (nLang != LANGUAGE_DONTKNOW)
+ {
+ aCurrentLang = SvtLanguageTable::GetLanguageString( nLang );
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ if (nLang == LANGUAGE_NONE)
+ {
+ aCurrentLang += ";-";
+ }
+ else
+ {
+ aCurrentLang += ";" + LanguageTag(nLang).getBcp47(false);
+ }
+ }
+ }
+
+ // build sequence for status value
+ uno::Sequence< OUString > aSeq{ aCurrentLang,
+ aScriptTypesInUse,
+ aKeyboardLang,
+ SwLangHelper::GetTextForLanguageGuessing( rSh ) };
+
+ // set sequence as status value
+ SfxStringListItem aItem( SID_LANGUAGE_STATUS );
+ aItem.SetStringList( aSeq );
+ rSet.Put( aItem );
+ }
+ break;
+
+ case SID_THES:
+ {
+ // is there a valid selection to get text from?
+ OUString aText;
+ bool bValid = !rSh.HasSelection() ||
+ (rSh.IsSelOnePara() && !rSh.IsMultiSelection());
+ // prevent context menu from showing when cursor is not in or at the end of a word
+ // (GetCurWord will return the next word if there is none at the current position...)
+ const sal_Int16 nWordType = ::i18n::WordType::DICTIONARY_WORD;
+ bool bWord = rSh.IsInWord( nWordType ) || rSh.IsStartWord( nWordType ) || rSh.IsEndWord( nWordType );
+ if (bValid && bWord)
+ aText = rSh.HasSelection()? rSh.GetSelText() : rSh.GetCurWord();
+
+ LanguageType nLang = rSh.GetCurLang();
+ LanguageTag aLanguageTag( nLang);
+ const lang::Locale& aLocale( aLanguageTag.getLocale());
+
+ // disable "Thesaurus" context menu entry if there is nothing to look up
+ uno::Reference< linguistic2::XThesaurus > xThes( ::GetThesaurus() );
+ if (aText.isEmpty() ||
+ !xThes.is() || nLang == LANGUAGE_NONE || !xThes->hasLocale( aLocale ))
+ rSet.DisableItem( SID_THES );
+ else
+ {
+ // set word and locale to look up as status value
+ OUString aStatusVal = aText + "#" + aLanguageTag.getBcp47();
+ rSet.Put( SfxStringItem( SID_THES, aStatusVal ) );
+ }
+ }
+ break;
+
+ case FN_NUMBER_NEWSTART :
+ if(!rSh.GetNumRuleAtCurrCursorPos())
+ rSet.DisableItem(nWhich);
+ else
+ rSet.Put(SfxBoolItem(FN_NUMBER_NEWSTART,
+ rSh.IsNumRuleStart()));
+ break;
+
+ case FN_EDIT_FORMULA:
+ case SID_CHARMAP:
+ case SID_CHARMAP_CONTROL:
+ {
+ const SelectionType nType = rSh.GetSelectionType();
+ if (!(nType & SelectionType::Text) &&
+ !(nType & SelectionType::Table) &&
+ !(nType & SelectionType::NumberList))
+ {
+ rSet.DisableItem(nWhich);
+ }
+ else if ( nWhich == FN_EDIT_FORMULA
+ && rSh.CursorInsideInputField() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case FN_INSERT_ENDNOTE:
+ case FN_INSERT_FOOTNOTE:
+ case FN_INSERT_FOOTNOTE_DLG:
+ {
+ const FrameTypeFlags nNoType =
+ FrameTypeFlags::FLY_ANY | FrameTypeFlags::HEADER | FrameTypeFlags::FOOTER | FrameTypeFlags::FOOTNOTE;
+ FrameTypeFlags eType = rSh.GetFrameType(nullptr, true);
+ bool bSplitFly = false;
+ if (eType & FrameTypeFlags::FLY_ATCNT)
+ {
+ SwContentFrame* pContentFrame = rSh.GetCurrFrame(/*bCalcFrame=*/false);
+ if (pContentFrame)
+ {
+ SwFlyFrame* pFlyFrame = pContentFrame->FindFlyFrame();
+ bSplitFly = pFlyFrame && pFlyFrame->IsFlySplitAllowed();
+ }
+ }
+ if (eType & nNoType && !bSplitFly)
+ rSet.DisableItem(nWhich);
+
+ if ( rSh.CursorInsideInputField() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case FN_INSERT_HYPERLINK:
+ case SID_INSERTDOC:
+ case FN_INSERT_GLOSSARY:
+ case FN_EXPAND_GLOSSARY:
+ if ( rSh.CursorInsideInputField() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case FN_INSERT_TABLE:
+ if ( rSh.CursorInsideInputField()
+ || rSh.GetTableFormat()
+ || (rSh.GetFrameType(nullptr,true) & FrameTypeFlags::FOOTNOTE) )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case FN_CALCULATE:
+ if ( !rSh.IsSelection() )
+ rSet.DisableItem(nWhich);
+ break;
+ case FN_GOTO_REFERENCE:
+ {
+ SwField *pField = rSh.GetCurField();
+ if ( !pField || (pField->GetTypeId() != SwFieldTypesEnum::GetRef) )
+ rSet.DisableItem(nWhich);
+ }
+ break;
+ case FN_AUTOFORMAT_AUTO:
+ {
+ rSet.Put( SfxBoolItem( nWhich, SvxAutoCorrCfg::Get().IsAutoFormatByInput() ));
+ }
+ break;
+
+ case SID_DEC_INDENT:
+ case SID_INC_INDENT:
+ {
+ //if the paragraph has bullet we'll do the following things:
+ //1: if the bullet level is the first level, disable the decrease-indent button
+ //2: if the bullet level is the last level, disable the increase-indent button
+ if ( rSh.GetNumRuleAtCurrCursorPos() && !rSh.HasReadonlySel() )
+ {
+ const sal_uInt8 nLevel = rSh.GetNumLevel();
+ if ( ( nLevel == ( MAXLEVEL - 1 ) && nWhich == SID_INC_INDENT )
+ || ( nLevel == 0 && nWhich == SID_DEC_INDENT ) )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ else
+ {
+ sal_uInt16 nHtmlMode = ::GetHtmlMode( GetView().GetDocShell() );
+ nHtmlMode &= HTMLMODE_ON | HTMLMODE_SOME_STYLES;
+ if ( ( nHtmlMode == HTMLMODE_ON )
+ || !rSh.IsMoveLeftMargin( SID_INC_INDENT == nWhich ) )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ }
+ break;
+
+ case FN_DEC_INDENT_OFFSET:
+ case FN_INC_INDENT_OFFSET:
+ {
+ sal_uInt16 nHtmlMode = ::GetHtmlMode(GetView().GetDocShell());
+ nHtmlMode &= HTMLMODE_ON|HTMLMODE_SOME_STYLES;
+ if( (nHtmlMode == HTMLMODE_ON) ||
+ !rSh.IsMoveLeftMargin( FN_INC_INDENT_OFFSET == nWhich,
+ false ))
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_ATTR_CHAR_COLOR2:
+ {
+ SfxItemSet aSet( GetPool() );
+ rSh.GetCurAttr( aSet );
+ const SvxColorItem& aColorItem = aSet.Get(RES_CHRATR_COLOR);
+ rSet.Put( aColorItem.CloneSetWhich(SID_ATTR_CHAR_COLOR2) );
+ }
+ break;
+ case SID_ATTR_CHAR_BACK_COLOR:
+ case SID_ATTR_CHAR_COLOR_BACKGROUND:
+ {
+ // Always use the visible background
+ SfxItemSet aSet( GetPool() );
+ rSh.GetCurAttr( aSet );
+ const SvxBrushItem& aBrushItem = aSet.Get(RES_CHRATR_HIGHLIGHT);
+ if( aBrushItem.GetColor() != COL_TRANSPARENT )
+ {
+ rSet.Put(SvxColorItem(aBrushItem.GetColor(), aBrushItem.getComplexColor(), nWhich));
+ }
+ else
+ {
+ const SvxBrushItem& aBrushItem2 = aSet.Get(RES_CHRATR_BACKGROUND);
+ rSet.Put(SvxColorItem(aBrushItem2.GetColor(), aBrushItem2.getComplexColor(), nWhich));
+ }
+ }
+ break;
+ case SID_ATTR_CHAR_COLOR_BACKGROUND_EXT:
+ {
+ SwEditWin& rEdtWin = GetView().GetEditWin();
+ SwApplyTemplate* pApply = rEdtWin.GetApplyTemplate();
+ const sal_uInt32 nColWhich = pApply ? pApply->nColor : 0;
+ const bool bUseTemplate = nColWhich == SID_ATTR_CHAR_BACK_COLOR
+ || nColWhich == SID_ATTR_CHAR_COLOR_BACKGROUND;
+ rSet.Put(SfxBoolItem(nWhich, bUseTemplate));
+ }
+ break;
+ case SID_ATTR_CHAR_COLOR_EXT:
+ {
+ SwEditWin& rEdtWin = GetView().GetEditWin();
+ SwApplyTemplate* pApply = rEdtWin.GetApplyTemplate();
+ rSet.Put(SfxBoolItem(nWhich, pApply && pApply->nColor == nWhich));
+ }
+ break;
+ case FN_SET_REMINDER:
+ case FN_INSERT_BOOKMARK:
+ if( rSh.IsTableMode()
+ || rSh.CursorInsideInputField() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case FN_INSERT_BREAK:
+ if ( rSh.HasReadonlySel()
+ && !rSh.CursorInsideInputField() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case FN_INSERT_BREAK_DLG:
+ case FN_INSERT_COLUMN_BREAK:
+ case FN_INSERT_PAGEBREAK:
+ if( rSh.CursorInsideInputField() || rSh.CursorInsideContentControl() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case FN_INSERT_PAGEHEADER:
+ case FN_INSERT_PAGEFOOTER:
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ bool bState = false;
+ bool bAllState = true;
+ bool bIsPhysical = false;
+
+ OUString aStyleName;
+ std::vector<OUString> aList;
+ static constexpr OUStringLiteral sPhysical(u"IsPhysical");
+ static constexpr OUStringLiteral sDisplay(u"DisplayName");
+ const OUString sHeaderOn(nWhich == FN_INSERT_PAGEHEADER ? OUString("HeaderIsOn") : OUString("FooterIsOn"));
+
+ uno::Reference< XStyleFamiliesSupplier > xSupplier(GetView().GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
+ if (xSupplier.is())
+ {
+ uno::Reference< XNameContainer > xContainer;
+ uno::Reference< XNameAccess > xFamilies = xSupplier->getStyleFamilies();
+ if (xFamilies->getByName("PageStyles") >>= xContainer)
+ {
+ const uno::Sequence< OUString > aSeqNames = xContainer->getElementNames();
+ for (const auto& rName : aSeqNames)
+ {
+ aStyleName = rName;
+ uno::Reference<XPropertySet> xPropSet(xContainer->getByName(aStyleName), uno::UNO_QUERY);
+ if (xPropSet.is() && (xPropSet->getPropertyValue(sPhysical) >>= bIsPhysical) && bIsPhysical)
+ {
+ xPropSet->getPropertyValue(sDisplay) >>= aStyleName;
+ if ((xPropSet->getPropertyValue(sHeaderOn)>>= bState) && bState)
+ aList.push_back(aStyleName);
+ else
+ bState = false;
+
+ // Check if all entries have the same state
+ bAllState &= bState;
+ }
+ else
+ bIsPhysical = false;
+ }
+ }
+ }
+
+ if (bAllState && aList.size() > 1)
+ aList.push_back("_ALL_");
+
+ rSet.Put(SfxStringListItem(nWhich, &aList));
+ }
+ else
+ {
+ rSet.Put( SfxObjectShellItem( nWhich, GetView().GetDocShell() ));
+ }
+ break;
+ case FN_TABLE_SORT_DIALOG:
+ case FN_SORTING_DLG:
+ if(!rSh.HasSelection() ||
+ (FN_TABLE_SORT_DIALOG == nWhich && !rSh.GetTableFormat()))
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_RUBY_DIALOG:
+ {
+ if( !SvtCJKOptions::IsRubyEnabled()
+ || rSh.CursorInsideInputField() )
+ {
+ GetView().GetViewFrame().GetBindings().SetVisibleState( nWhich, false );
+ rSet.DisableItem(nWhich);
+ }
+ else
+ GetView().GetViewFrame().GetBindings().SetVisibleState( nWhich, true );
+ }
+ break;
+
+ case SID_FM_TRANSLATE:
+ {
+#if HAVE_FEATURE_CURL && !ENABLE_WASM_STRIP_EXTRA
+ if (!officecfg::Office::Common::Misc::ExperimentalMode::get()
+ && !comphelper::LibreOfficeKit::isActive())
+ {
+ rSet.Put(SfxVisibilityItem(nWhich, false));
+ break;
+ }
+ std::optional<OUString> oDeeplAPIUrl = officecfg::Office::Linguistic::Translation::Deepl::ApiURL::get();
+ std::optional<OUString> oDeeplKey = officecfg::Office::Linguistic::Translation::Deepl::AuthKey::get();
+ if (!oDeeplAPIUrl || oDeeplAPIUrl->isEmpty() || !oDeeplKey || oDeeplKey->isEmpty())
+ {
+ rSet.DisableItem(nWhich);
+ }
+#endif
+ }
+ break;
+
+ case SID_HYPERLINK_DIALOG:
+ if( GetView().GetDocShell()->IsReadOnly()
+ || ( !GetView().GetViewFrame().HasChildWindow(nWhich)
+ && rSh.HasReadonlySel() )
+ || rSh.CursorInsideInputField() )
+ {
+ rSet.DisableItem(nWhich);
+ }
+ else
+ {
+ rSet.Put(SfxBoolItem( nWhich, nullptr != GetView().GetViewFrame().GetChildWindow( nWhich ) ));
+ }
+ break;
+
+ case SID_EDIT_HYPERLINK:
+ {
+ SfxItemSetFixed<RES_TXTATR_INETFMT, RES_TXTATR_INETFMT> aSet(GetPool());
+ rSh.GetCurAttr(aSet);
+ if(SfxItemState::SET > aSet.GetItemState( RES_TXTATR_INETFMT ) || rSh.HasReadonlySel())
+ {
+ rSet.DisableItem(nWhich);
+ }
+ }
+ break;
+ case SID_REMOVE_HYPERLINK:
+ {
+ SfxItemSetFixed<RES_TXTATR_INETFMT, RES_TXTATR_INETFMT> aSet(GetPool());
+ rSh.GetCurAttr(aSet);
+
+ // If a hyperlink is selected, either alone or along with other text...
+ if ((aSet.GetItemState(RES_TXTATR_INETFMT) < SfxItemState::SET &&
+ aSet.GetItemState(RES_TXTATR_INETFMT) != SfxItemState::DONTCARE) ||
+ rSh.HasReadonlySel())
+ {
+ rSet.DisableItem(nWhich);
+ }
+ }
+ break;
+ case SID_TRANSLITERATE_HALFWIDTH:
+ case SID_TRANSLITERATE_FULLWIDTH:
+ case SID_TRANSLITERATE_HIRAGANA:
+ case SID_TRANSLITERATE_KATAKANA:
+ {
+ if(!SvtCJKOptions::IsChangeCaseMapEnabled())
+ {
+ GetView().GetViewFrame().GetBindings().SetVisibleState( nWhich, false );
+ rSet.DisableItem(nWhich);
+ }
+ else
+ GetView().GetViewFrame().GetBindings().SetVisibleState( nWhich, true );
+ }
+ break;
+ case FN_READONLY_SELECTION_MODE :
+ if(!GetView().GetDocShell()->IsReadOnly())
+ rSet.DisableItem( nWhich );
+ else
+ {
+ rSet.Put(SfxBoolItem(nWhich, rSh.GetViewOptions()->IsSelectionInReadonly()));
+ }
+ break;
+ case FN_SELECTION_MODE_DEFAULT:
+ case FN_SELECTION_MODE_BLOCK :
+ rSet.Put(SfxBoolItem(nWhich, (nWhich == FN_SELECTION_MODE_DEFAULT) != rSh.IsBlockMode()));
+ break;
+ case SID_COPY_HYPERLINK_LOCATION:
+ case SID_OPEN_HYPERLINK:
+ {
+ SfxItemSetFixed<RES_TXTATR_INETFMT, RES_TXTATR_INETFMT> aSet(GetPool());
+ rSh.GetCurAttr(aSet);
+
+ bool bAuthorityFieldURL = false;
+ SwField* pField = rSh.GetCurField();
+ if (pField && pField->GetTyp()->Which() == SwFieldIds::TableOfAuthorities)
+ {
+ const auto& rAuthorityField = *static_cast<const SwAuthorityField*>(pField);
+ if (auto targetType = rAuthorityField.GetTargetType();
+ targetType == SwAuthorityField::TargetType::UseDisplayURL
+ || targetType == SwAuthorityField::TargetType::UseTargetURL)
+ {
+ // Check if the Bibliography entry has a target URL
+ bAuthorityFieldURL = rAuthorityField.GetAbsoluteURL().getLength() > 0;
+ }
+ }
+ if (SfxItemState::SET > aSet.GetItemState(RES_TXTATR_INETFMT, false)
+ && !bAuthorityFieldURL)
+ rSet.DisableItem(nWhich);
+ }
+ break;
+ case FN_OPEN_LOCAL_URL:
+ {
+ if (GetLocalURL(rSh).isEmpty())
+ {
+ rSet.DisableItem(nWhich);
+ }
+ }
+ break;
+ case SID_OPEN_SMARTTAGMENU:
+ {
+ std::vector< OUString > aSmartTagTypes;
+ uno::Sequence< uno::Reference< container::XStringKeyMap > > aStringKeyMaps;
+ uno::Reference<text::XTextRange> xRange;
+
+ rSh.GetSmartTagTerm( aSmartTagTypes, aStringKeyMaps, xRange );
+
+ if ( xRange.is() && !aSmartTagTypes.empty() )
+ {
+ uno::Sequence < uno::Sequence< uno::Reference< smarttags::XSmartTagAction > > > aActionComponentsSequence;
+ uno::Sequence < uno::Sequence< sal_Int32 > > aActionIndicesSequence;
+
+ const SmartTagMgr& rSmartTagMgr = SwSmartTagMgr::Get();
+ rSmartTagMgr.GetActionSequences( aSmartTagTypes,
+ aActionComponentsSequence,
+ aActionIndicesSequence );
+
+ uno::Reference <frame::XController> xController = GetView().GetController();
+ lang::Locale aLocale( SW_BREAKITER()->GetLocale( GetAppLanguageTag() ) );
+ const OUString& aApplicationName( rSmartTagMgr.GetApplicationName() );
+ const OUString aRangeText = xRange->getString();
+
+ const SvxSmartTagItem aItem( SID_OPEN_SMARTTAGMENU,
+ aActionComponentsSequence,
+ aActionIndicesSequence,
+ aStringKeyMaps,
+ xRange,
+ xController,
+ std::move(aLocale),
+ aApplicationName,
+ aRangeText );
+
+ rSet.Put( aItem );
+ }
+ else
+ rSet.DisableItem(nWhich);
+ }
+ break;
+
+ case FN_NUM_NUMBERING_ON:
+ rSet.Put(SfxBoolItem(FN_NUM_NUMBERING_ON,rSh.SelectionHasNumber()));
+ break;
+
+ case FN_NUM_BULLET_ON:
+ rSet.Put(SfxBoolItem(FN_NUM_BULLET_ON,rSh.SelectionHasBullet()));
+ break;
+
+ case FN_NUM_BULLET_OFF:
+ rSet.Put(SfxBoolItem(FN_NUM_BULLET_OFF, !rSh.GetNumRuleAtCurrCursorPos() &&
+ !rSh.GetNumRuleAtCurrentSelection()));
+ break;
+
+ case FN_SVX_SET_OUTLINE:
+ {
+ NBOTypeMgrBase* pOutline = NBOutlineTypeMgrFact::CreateInstance(NBOType::Outline);
+ auto pCurRule = const_cast<SwNumRule*>(rSh.GetNumRuleAtCurrCursorPos());
+ if (pOutline && pCurRule)
+ {
+ SvxNumRule aSvxRule = pCurRule->MakeSvxNumRule();
+ const sal_uInt16 nIndex = pOutline->GetNBOIndexForNumRule(aSvxRule, 0);
+ rSet.Put(SfxBoolItem(FN_SVX_SET_OUTLINE, nIndex < USHRT_MAX));
+ }
+ break;
+ }
+ case FN_BUL_NUM_RULE_INDEX:
+ case FN_NUM_NUM_RULE_INDEX:
+ case FN_OUTLINE_RULE_INDEX:
+ {
+ SwNumRule* pCurRule = const_cast<SwNumRule*>(GetShell().GetNumRuleAtCurrCursorPos());
+ if( pCurRule )
+ {
+ sal_uInt16 nActNumLvl = GetShell().GetNumLevel();
+ if( nActNumLvl < MAXLEVEL )
+ {
+ nActNumLvl = 1<<nActNumLvl;
+ }
+ SvxNumRule aSvxRule = pCurRule->MakeSvxNumRule();
+ if ( GetShell().HasBullet())
+ {
+ rSet.Put(SfxUInt16Item(FN_BUL_NUM_RULE_INDEX, USHRT_MAX));
+ rSet.Put(SfxUInt16Item(FN_NUM_NUM_RULE_INDEX, USHRT_MAX));
+ NBOTypeMgrBase* pBullets = NBOutlineTypeMgrFact::CreateInstance(NBOType::Bullets);
+ if ( pBullets )
+ {
+ const sal_uInt16 nBulIndex = pBullets->GetNBOIndexForNumRule(aSvxRule,nActNumLvl);
+ rSet.Put(SfxUInt16Item(FN_BUL_NUM_RULE_INDEX,nBulIndex));
+ }
+ }else if ( GetShell().HasNumber() )
+ {
+ rSet.Put(SfxUInt16Item(FN_BUL_NUM_RULE_INDEX, USHRT_MAX));
+ rSet.Put(SfxUInt16Item(FN_NUM_NUM_RULE_INDEX, USHRT_MAX));
+ NBOTypeMgrBase* pNumbering = NBOutlineTypeMgrFact::CreateInstance(NBOType::Numbering);
+ if ( pNumbering )
+ {
+ const sal_uInt16 nBulIndex = pNumbering->GetNBOIndexForNumRule(aSvxRule,nActNumLvl);
+ rSet.Put(SfxUInt16Item(FN_NUM_NUM_RULE_INDEX,nBulIndex));
+ }
+ }
+
+ if ( nWhich == FN_OUTLINE_RULE_INDEX )
+ {
+ rSet.Put(SfxUInt16Item(FN_OUTLINE_RULE_INDEX, USHRT_MAX));
+ NBOTypeMgrBase* pOutline = NBOutlineTypeMgrFact::CreateInstance(NBOType::Outline);
+ if ( pOutline )
+ {
+ const sal_uInt16 nIndex = pOutline->GetNBOIndexForNumRule(aSvxRule,nActNumLvl);
+ rSet.Put(SfxUInt16Item(FN_OUTLINE_RULE_INDEX,nIndex));
+ }
+ }
+ }
+ }
+ break;
+ case FN_NUM_CONTINUE:
+ {
+ // #i86492#
+ // Search also for bullet list
+ OUString aDummy;
+ const SwNumRule* pRule =
+ rSh.SearchNumRule( true, aDummy );
+ if ( !pRule )
+ {
+ pRule = rSh.SearchNumRule( false, aDummy );
+ }
+ if ( !pRule )
+ rSet.DisableItem(nWhich);
+ }
+ break;
+ case SID_INSERT_RLM :
+ case SID_INSERT_LRM :
+ {
+ bool bEnabled = SvtCTLOptions::IsCTLFontEnabled();
+ GetView().GetViewFrame().GetBindings().SetVisibleState( nWhich, bEnabled );
+ if(!bEnabled)
+ rSet.DisableItem(nWhich);
+ }
+ break;
+ case SID_FM_CTL_PROPERTIES:
+ {
+ bool bDisable = false;
+
+ // First get the state from the form shell
+ SfxItemSetFixed<SID_FM_CTL_PROPERTIES, SID_FM_CTL_PROPERTIES> aSet(GetShell().GetAttrPool());
+ aSet.Put(SfxBoolItem( SID_FM_CTL_PROPERTIES, true ));
+ GetShell().GetView().GetFormShell()->GetState( aSet );
+
+ if(SfxItemState::DISABLED == aSet.GetItemState(SID_FM_CTL_PROPERTIES))
+ {
+ bDisable = true;
+ }
+
+ // Enable it if we have a valid object other than what form shell knows
+ SwPosition aPos(*GetShell().GetCursor()->GetPoint());
+ sw::mark::IFieldmark* pFieldBM = GetShell().getIDocumentMarkAccess()->getInnerFieldmarkFor(aPos);
+ if ( !pFieldBM && aPos.GetContentIndex() > 0)
+ {
+ aPos.AdjustContent(-1);
+ pFieldBM = GetShell().getIDocumentMarkAccess()->getInnerFieldmarkFor(aPos);
+ }
+ if ( pFieldBM && (pFieldBM->GetFieldname() == ODF_FORMDROPDOWN || pFieldBM->GetFieldname() == ODF_FORMDATE) )
+ {
+ bDisable = false;
+ }
+
+ if(bDisable)
+ rSet.DisableItem(nWhich);
+ }
+ break;
+ case SID_COPY:
+ case SID_CUT:
+ {
+ if (GetObjectShell()->isContentExtractionLocked())
+ rSet.DisableItem(nWhich);
+ break;
+ }
+ case FN_PROTECT_FIELDS:
+ case FN_PROTECT_BOOKMARKS:
+ {
+ DocumentSettingId aSettingId = nWhich == FN_PROTECT_FIELDS
+ ? DocumentSettingId::PROTECT_FIELDS
+ : DocumentSettingId::PROTECT_BOOKMARKS;
+ bool bProtected = rSh.getIDocumentSettingAccess().get(aSettingId);
+ rSet.Put(SfxBoolItem(nWhich, bProtected));
+ }
+ break;
+ case FN_CONTENT_CONTROL_PROPERTIES:
+ {
+ if (!GetShell().CursorInsideContentControl())
+ {
+ rSet.DisableItem(nWhich);
+ }
+ }
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/textsh2.cxx b/sw/source/uibase/shells/textsh2.cxx
new file mode 100644
index 0000000000..8a62f401fe
--- /dev/null
+++ b/sw/source/uibase/shells/textsh2.cxx
@@ -0,0 +1,252 @@
+/* -*- 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 <sfx2/bindings.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svl/stritem.hxx>
+#include <svl/itemset.hxx>
+#include <sfx2/request.hxx>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/sdbc/XDataSource.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <comphelper/types.hxx>
+#include <sfx2/frame.hxx>
+#include <fldmgr.hxx>
+#include <fldbas.hxx>
+#include <dbmgr.hxx>
+#include <svx/dataaccessdescriptor.hxx>
+#include <osl/diagnose.h>
+
+#include <vcl/svapp.hxx>
+
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <swtypes.hxx>
+#include <cmdid.h>
+#include <textsh.hxx>
+#include <swabstdlg.hxx>
+
+using namespace ::svx;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+
+struct DBTextStruct_Impl
+{
+ SwDBData aDBData;
+ Sequence<Any> aSelection;
+ Reference<XResultSet> xCursor;
+ Reference<XConnection> xConnection;
+};
+
+void SwTextShell::ExecDB(SfxRequest const &rReq)
+{
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ SwDBManager* pDBManager = GetShell().GetDBManager();
+ OUString sSourceArg, sCommandArg;
+ sal_Int32 nCommandTypeArg = 0;
+ const SfxUnoAnyItem* pSourceItem = nullptr;
+ const SfxUnoAnyItem* pCommandItem = nullptr;
+ const SfxUnoAnyItem* pCommandTypeItem = nullptr;
+ const SfxUnoAnyItem* pConnectionItem = nullptr;
+
+ // first get the selection of rows to be inserted
+
+ Sequence<Any> aSelection;
+ if(const SfxUnoAnyItem* pSelectionItem = pArgs->GetItemIfSet(FN_DB_DATA_SELECTION_ANY, false))
+ pSelectionItem->GetValue() >>= aSelection;
+
+ // get the data source name
+ pSourceItem = pArgs->GetItemIfSet(FN_DB_DATA_SOURCE_ANY, false);
+ if(pSourceItem)
+ pSourceItem->GetValue() >>= sSourceArg;
+
+ // get the command
+ pCommandItem = pArgs->GetItemIfSet(FN_DB_DATA_COMMAND_ANY, false);
+ if(pCommandItem)
+ pCommandItem->GetValue() >>= sCommandArg;
+
+ // get the command type
+ pCommandTypeItem = pArgs->GetItemIfSet(FN_DB_DATA_COMMAND_TYPE_ANY, false);
+ if(pCommandTypeItem)
+ pCommandTypeItem->GetValue() >>= nCommandTypeArg;
+
+ Reference<XConnection> xConnection;
+ pConnectionItem = pArgs->GetItemIfSet(FN_DB_CONNECTION_ANY, false);
+ if(pConnectionItem)
+ pConnectionItem->GetValue() >>= xConnection;
+ // may be we even get no connection
+ if ( !xConnection.is() )
+ {
+ Reference<XDataSource> xSource;
+ SwView &rSwView = GetView();
+ xConnection = SwDBManager::GetConnection(sSourceArg, xSource, &rSwView);
+ }
+ if(!xConnection.is())
+ return ;
+
+ // get the cursor, we use to travel, may be NULL
+ Reference<XResultSet> xCursor;
+ if ( const SfxUnoAnyItem* pCursorItem = pArgs->GetItemIfSet(FN_DB_DATA_CURSOR_ANY, false) )
+ pCursorItem->GetValue() >>= xCursor;
+
+ switch (rReq.GetSlot())
+ {
+ case FN_QRY_INSERT:
+ {
+ if(pSourceItem && pCommandItem && pCommandTypeItem)
+ {
+ DBTextStruct_Impl* pNew = new DBTextStruct_Impl;
+ pNew->aDBData.sDataSource = sSourceArg;
+ pNew->aDBData.sCommand = sCommandArg;
+ pNew->aDBData.nCommandType = nCommandTypeArg;
+ pNew->aSelection = aSelection;
+ //if the cursor is NULL, it must be created inside InsertDBTextHdl
+ // because it called via a PostUserEvent
+ pNew->xCursor = xCursor;
+ pNew->xConnection = xConnection;
+
+ Application::PostUserEvent( LINK( this, SwBaseShell, InsertDBTextHdl ), pNew );
+ // the pNew will be removed in InsertDBTextHdl !!
+ }
+ }
+ break;
+
+ case FN_QRY_MERGE_FIELD:
+ {
+ // we don't get any cursor, so we must create our own
+ bool bDisposeResultSet = false;
+ if ( !xCursor.is() )
+ {
+ SwView &rSwView = GetView();
+ xCursor = SwDBManager::createCursor(sSourceArg,sCommandArg,nCommandTypeArg,xConnection,&rSwView);
+ bDisposeResultSet = xCursor.is();
+ }
+
+ ODataAccessDescriptor aDescriptor;
+ aDescriptor.setDataSource(sSourceArg);
+ aDescriptor[DataAccessDescriptorProperty::Command] <<= sCommandArg;
+ aDescriptor[DataAccessDescriptorProperty::Cursor] <<= xCursor;
+ aDescriptor[DataAccessDescriptorProperty::Selection] <<= aSelection;
+ aDescriptor[DataAccessDescriptorProperty::CommandType] <<= nCommandTypeArg;
+
+ SwMergeDescriptor aMergeDesc( DBMGR_MERGE, *GetShellPtr(), aDescriptor );
+ pDBManager->Merge(aMergeDesc);
+
+ if ( bDisposeResultSet )
+ ::comphelper::disposeComponent(xCursor);
+ }
+ break;
+
+ case FN_QRY_INSERT_FIELD:
+ {
+ const SfxUnoAnyItem* pColumnItem = pArgs->GetItemIfSet(FN_DB_COLUMN_ANY, false);
+ const SfxUnoAnyItem* pColumnNameItem =
+ pArgs->GetItemIfSet(FN_DB_DATA_COLUMN_NAME_ANY, false);
+
+ OUString sColumnName;
+ if(pColumnNameItem)
+ pColumnNameItem->GetValue() >>= sColumnName;
+ OUString sDBName = sSourceArg + OUStringChar(DB_DELIM)
+ + sCommandArg + OUStringChar(DB_DELIM)
+ + OUString::number(nCommandTypeArg)
+ + OUStringChar(DB_DELIM) + sColumnName;
+
+ SwFieldMgr aFieldMgr(GetShellPtr());
+ SwInsertField_Data aData(SwFieldTypesEnum::Database, 0, sDBName, OUString(), 0);
+ if(pConnectionItem)
+ aData.m_aDBConnection = pConnectionItem->GetValue();
+ if(pColumnItem)
+ aData.m_aDBColumn = pColumnItem->GetValue();
+ aFieldMgr.InsertField(aData);
+ SfxViewFrame& rViewFrame = GetView().GetViewFrame();
+ uno::Reference< XDispatchRecorder > xRecorder =
+ rViewFrame.GetBindings().GetRecorder();
+ if ( xRecorder.is() )
+ {
+ SfxRequest aReq(rViewFrame, FN_INSERT_DBFIELD);
+ aReq.AppendItem( SfxUInt16Item(FN_PARAM_FIELD_TYPE, static_cast<sal_uInt16>(SwFieldTypesEnum::Database)));
+ aReq.AppendItem( SfxStringItem( FN_INSERT_DBFIELD, sDBName ));
+ aReq.AppendItem( SfxStringItem( FN_PARAM_1, sCommandArg ));
+ aReq.AppendItem( SfxStringItem( FN_PARAM_2, sColumnName ));
+ aReq.AppendItem( SfxInt32Item( FN_PARAM_3, nCommandTypeArg));
+ aReq.Done();
+ }
+ }
+ break;
+
+ default:
+ OSL_ENSURE(false, "wrong dispatcher");
+ return;
+ }
+}
+
+IMPL_LINK( SwBaseShell, InsertDBTextHdl, void*, p, void )
+{
+ DBTextStruct_Impl* pDBStruct = static_cast<DBTextStruct_Impl*>(p);
+ if( pDBStruct )
+ {
+ bool bDispose = false;
+ Reference< sdbc::XConnection> xConnection = pDBStruct->xConnection;
+ Reference<XDataSource> xSource = SwDBManager::getDataSourceAsParent(xConnection,pDBStruct->aDBData.sDataSource);
+ // #111987# the connection is disposed and so no parent has been found
+ if(xConnection.is() && !xSource.is())
+ return;
+
+ if ( !xConnection.is() )
+ {
+ SwView &rSwView = GetView();
+ xConnection = SwDBManager::GetConnection(pDBStruct->aDBData.sDataSource, xSource, &rSwView);
+ bDispose = true;
+ }
+
+ Reference< XColumnsSupplier> xColSupp;
+ if(xConnection.is())
+ xColSupp = SwDBManager::GetColumnSupplier(xConnection,
+ pDBStruct->aDBData.sCommand,
+ pDBStruct->aDBData.nCommandType == CommandType::QUERY ?
+ SwDBSelect::QUERY : SwDBSelect::TABLE);
+
+ if( xColSupp.is() )
+ {
+ SwDBData aDBData = pDBStruct->aDBData;
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSwInsertDBColAutoPilot>pDlg (pFact->CreateSwInsertDBColAutoPilot(GetView(),
+ xSource,
+ xColSupp,
+ aDBData));
+ if( RET_OK == pDlg->Execute() )
+ {
+ pDlg->DataToDoc(pDBStruct->aSelection, xSource, xConnection, pDBStruct->xCursor);
+ }
+ }
+ if ( bDispose )
+ ::comphelper::disposeComponent(xConnection);
+ }
+
+ delete pDBStruct;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/translatehelper.cxx b/sw/source/uibase/shells/translatehelper.cxx
new file mode 100644
index 0000000000..eb9bcaedbb
--- /dev/null
+++ b/sw/source/uibase/shells/translatehelper.cxx
@@ -0,0 +1,216 @@
+/* -*- 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 <config_features.h>
+#include <config_wasm_strip.h>
+#include <wrtsh.hxx>
+#include <pam.hxx>
+#include <node.hxx>
+#include <ndtxt.hxx>
+#include <translatehelper.hxx>
+#include <sal/log.hxx>
+#include <rtl/string.h>
+#include <shellio.hxx>
+#include <vcl/scheduler.hxx>
+#include <vcl/svapp.hxx>
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/json_parser.hpp>
+#include <vcl/htmltransferable.hxx>
+#include <vcl/transfer.hxx>
+#include <swdtflvr.hxx>
+#include <linguistic/translate.hxx>
+#include <com/sun/star/task/XStatusIndicator.hpp>
+#include <sfx2/viewfrm.hxx>
+#include <com/sun/star/task/XStatusIndicatorFactory.hpp>
+#include <strings.hrc>
+
+namespace SwTranslateHelper
+{
+OString ExportPaMToHTML(SwPaM* pCursor)
+{
+ SolarMutexGuard gMutex;
+ OString aResult;
+ WriterRef xWrt;
+ GetHTMLWriter(u"NoLineLimit,SkipHeaderFooter,NoPrettyPrint", OUString(), xWrt);
+ if (pCursor != nullptr)
+ {
+ SvMemoryStream aMemoryStream;
+ SwWriter aWriter(aMemoryStream, *pCursor);
+ ErrCodeMsg nError = aWriter.Write(xWrt);
+ if (nError.IsError())
+ {
+ SAL_WARN("sw.ui", "ExportPaMToHTML: failed to export selection to HTML " << nError);
+ return {};
+ }
+ aResult
+ = OString(static_cast<const char*>(aMemoryStream.GetData()), aMemoryStream.GetSize());
+ aResult = aResult.replaceAll("<p"_ostr, "<span"_ostr);
+ aResult = aResult.replaceAll("</p>"_ostr, "</span>"_ostr);
+
+ // HTML has for that <br> and <p> also does new line
+ aResult = aResult.replaceAll("<ul>"_ostr, ""_ostr);
+ aResult = aResult.replaceAll("</ul>"_ostr, ""_ostr);
+ aResult = aResult.replaceAll("<ol>"_ostr, ""_ostr);
+ aResult = aResult.replaceAll("</ol>"_ostr, ""_ostr);
+ aResult = aResult.replaceAll("\n"_ostr, ""_ostr).trim();
+ return aResult;
+ }
+ return {};
+}
+
+void PasteHTMLToPaM(SwWrtShell& rWrtSh, SwPaM* pCursor, const OString& rData)
+{
+ SolarMutexGuard gMutex;
+ rtl::Reference<vcl::unohelper::HtmlTransferable> pHtmlTransferable
+ = new vcl::unohelper::HtmlTransferable(rData);
+ if (pHtmlTransferable.is())
+ {
+ TransferableDataHelper aDataHelper(pHtmlTransferable);
+ if (aDataHelper.GetXTransferable().is()
+ && SwTransferable::IsPasteSpecial(rWrtSh, aDataHelper))
+ {
+ rWrtSh.SetSelection(*pCursor);
+ SwTransferable::Paste(rWrtSh, aDataHelper);
+ rWrtSh.KillSelection(nullptr, false);
+ }
+ }
+}
+
+#if HAVE_FEATURE_CURL && !ENABLE_WASM_STRIP_EXTRA
+void TranslateDocument(SwWrtShell& rWrtSh, const TranslateAPIConfig& rConfig)
+{
+ bool bCancel = false;
+ TranslateDocumentCancellable(rWrtSh, rConfig, bCancel);
+}
+
+void TranslateDocumentCancellable(SwWrtShell& rWrtSh, const TranslateAPIConfig& rConfig,
+ bool& rCancelTranslation)
+{
+ auto m_pCurrentPam = rWrtSh.GetCursor();
+ bool bHasSelection = rWrtSh.HasSelection();
+
+ if (bHasSelection)
+ {
+ // iteration will start top to bottom
+ if (m_pCurrentPam->GetPoint()->nNode > m_pCurrentPam->GetMark()->nNode)
+ m_pCurrentPam->Exchange();
+ }
+
+ auto const& pNodes = rWrtSh.GetNodes();
+ SwPosition aPoint = *m_pCurrentPam->GetPoint();
+ SwPosition aMark = *m_pCurrentPam->GetMark();
+ auto startNode = bHasSelection ? aPoint.nNode.GetIndex() : SwNodeOffset(0);
+ auto endNode = bHasSelection ? aMark.nNode.GetIndex() : pNodes.Count() - 1;
+
+ sal_Int32 nCount(0);
+ sal_Int32 nProgress(0);
+
+ for (SwNodeOffset n(startNode); n <= endNode; ++n)
+ {
+ if (pNodes[n] && pNodes[n]->IsTextNode())
+ {
+ if (pNodes[n]->GetTextNode()->GetText().isEmpty())
+ continue;
+ nCount++;
+ }
+ }
+
+ SfxViewFrame* pFrame = SfxViewFrame::Current();
+ uno::Reference<frame::XFrame> xFrame(pFrame ? pFrame->GetFrame().GetFrameInterface() : nullptr);
+ uno::Reference<task::XStatusIndicatorFactory> xProgressFactory(xFrame, uno::UNO_QUERY);
+ uno::Reference<task::XStatusIndicator> xStatusIndicator;
+
+ if (xProgressFactory.is())
+ {
+ xStatusIndicator = xProgressFactory->createStatusIndicator();
+ }
+
+ if (xStatusIndicator.is())
+ xStatusIndicator->start(SwResId(STR_STATSTR_SWTRANSLATE), nCount);
+
+ for (SwNodeOffset n(startNode); n <= endNode; ++n)
+ {
+ if (rCancelTranslation)
+ break;
+
+ if (n >= rWrtSh.GetNodes().Count())
+ break;
+
+ if (!pNodes[n])
+ break;
+
+ SwNode* pNode = pNodes[n];
+ if (pNode->IsTextNode())
+ {
+ if (pNode->GetTextNode()->GetText().isEmpty())
+ continue;
+
+ auto cursor
+ = Writer::NewUnoCursor(*rWrtSh.GetDoc(), pNode->GetIndex(), pNode->GetIndex());
+
+ // set edges (start, end) for nodes inside the selection.
+ if (bHasSelection)
+ {
+ if (startNode == endNode)
+ {
+ cursor->SetMark();
+ cursor->GetPoint()->nContent = aPoint.nContent;
+ cursor->GetMark()->nContent = aMark.nContent;
+ }
+ else if (n == startNode)
+ {
+ cursor->SetMark();
+ cursor->GetPoint()->nContent = aPoint.nContent;
+ }
+ else if (n == endNode)
+ {
+ cursor->SetMark();
+ cursor->GetMark()->nContent = aMark.nContent;
+ cursor->GetPoint()->nContent = 0;
+ }
+ }
+
+ const auto aOut = SwTranslateHelper::ExportPaMToHTML(cursor.get());
+ const auto aTranslatedOut = linguistic::Translate(
+ rConfig.m_xTargetLanguage, rConfig.m_xAPIUrl, rConfig.m_xAuthKey, aOut);
+ SwTranslateHelper::PasteHTMLToPaM(rWrtSh, cursor.get(), aTranslatedOut);
+
+ if (xStatusIndicator.is() && nCount)
+ xStatusIndicator->setValue((100 * ++nProgress) / nCount);
+
+ Idle aIdle("ProgressBar::SetValue aIdle");
+ aIdle.SetPriority(TaskPriority::POST_PAINT);
+ aIdle.Start();
+
+ rWrtSh.LockView(true);
+ while (aIdle.IsActive() && !Application::IsQuit())
+ {
+ Application::Yield();
+ }
+ rWrtSh.LockView(false);
+ }
+ }
+
+ if (xStatusIndicator.is())
+ xStatusIndicator->end();
+}
+#endif // HAVE_FEATURE_CURL && !ENABLE_WASM_STRIP_EXTRA
+}
diff --git a/sw/source/uibase/shells/txtattr.cxx b/sw/source/uibase/shells/txtattr.cxx
new file mode 100644
index 0000000000..68f4197f54
--- /dev/null
+++ b/sw/source/uibase/shells/txtattr.cxx
@@ -0,0 +1,849 @@
+/* -*- 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 <svl/whiter.hxx>
+#include <svl/stritem.hxx>
+#include <svl/ctloptions.hxx>
+#include <swmodule.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/adjustitem.hxx>
+#include <editeng/lspcitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/escapementitem.hxx>
+#include <editeng/pmdlitem.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/cmapitem.hxx>
+#include <osl/diagnose.h>
+#include <paratr.hxx>
+
+#include <fmtinfmt.hxx>
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <viewopt.hxx>
+#include <uitool.hxx>
+#include <textsh.hxx>
+#include <swundo.hxx>
+#include <fmtcol.hxx>
+
+#include <cmdid.h>
+#include <globals.h>
+#include <SwStyleNameMapper.hxx>
+#include <swabstdlg.hxx>
+#include <memory>
+
+const sal_uInt32 nFontInc = 40; // 2pt
+const sal_uInt32 nFontMaxSz = 19998; // 999.9pt
+
+void SwTextShell::ExecCharAttr(SfxRequest &rReq)
+{
+ SwWrtShell &rSh = GetShell();
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ int eState = STATE_TOGGLE;
+ sal_uInt16 nWhich = rReq.GetSlot();
+
+ if(pArgs )
+ {
+ const SfxPoolItem* pItem;
+ pArgs->GetItemState(nWhich, false, &pItem);
+ eState = static_cast<const SfxBoolItem &>( pArgs->
+ Get( nWhich )).GetValue() ? STATE_ON : STATE_OFF;
+ }
+
+ SfxItemSetFixed<RES_CHRATR_BEGIN, RES_CHRATR_END-1> aSet( GetPool() );
+ if (STATE_TOGGLE == eState)
+ rSh.GetCurAttr( aSet );
+
+ switch ( nWhich )
+ {
+ case FN_SET_SUB_SCRIPT:
+ case FN_SET_SUPER_SCRIPT:
+ {
+ SvxEscapement eEscape = SvxEscapement::Subscript;
+ switch (eState)
+ {
+ case STATE_TOGGLE:
+ {
+ short nTmpEsc = aSet.Get( RES_CHRATR_ESCAPEMENT ).GetEsc();
+ eEscape = nWhich == FN_SET_SUPER_SCRIPT ?
+ SvxEscapement::Superscript:
+ SvxEscapement::Subscript;
+ if( (nWhich == FN_SET_SUB_SCRIPT && nTmpEsc < 0) ||
+ (nWhich == FN_SET_SUPER_SCRIPT && nTmpEsc > 0) )
+ eEscape = SvxEscapement::Off;
+
+ SfxBindings& rBind = GetView().GetViewFrame().GetBindings();
+ if( nWhich == FN_SET_SUB_SCRIPT )
+ rBind.SetState( SfxBoolItem( FN_SET_SUPER_SCRIPT,
+ false ) );
+ else
+ rBind.SetState( SfxBoolItem( FN_SET_SUB_SCRIPT,
+ false ) );
+
+ }
+ break;
+ case STATE_ON:
+ eEscape = nWhich == FN_SET_SUPER_SCRIPT ?
+ SvxEscapement::Superscript:
+ SvxEscapement::Subscript;
+ break;
+ case STATE_OFF:
+ eEscape = SvxEscapement::Off;
+ break;
+ }
+ SvxEscapementItem aEscape( eEscape, RES_CHRATR_ESCAPEMENT );
+ rSh.SetAttrItem( aEscape );
+ rReq.AppendItem( aEscape );
+ rReq.Done();
+ }
+ break;
+
+ case FN_SET_SMALL_CAPS:
+ {
+ SvxCaseMap eCaseMap = SvxCaseMap::SmallCaps;
+ switch (eState)
+ {
+ case STATE_TOGGLE:
+ {
+ SvxCaseMap eTmpCaseMap = aSet.Get(RES_CHRATR_CASEMAP).GetCaseMap();
+ if (eTmpCaseMap == SvxCaseMap::SmallCaps)
+ eCaseMap = SvxCaseMap::NotMapped;
+ }
+ break;
+ case STATE_ON:
+ // Nothing to do, already set.
+ break;
+ case STATE_OFF:
+ eCaseMap = SvxCaseMap::NotMapped;
+ break;
+ }
+ SvxCaseMapItem aCaseMap(eCaseMap, RES_CHRATR_CASEMAP);
+ rSh.SetAttrItem(aCaseMap);
+ rReq.AppendItem(aCaseMap);
+ rReq.Done();
+ }
+ break;
+
+ case FN_UPDATE_STYLE_BY_EXAMPLE:
+ rSh.QuickUpdateStyle();
+ rReq.Done();
+ break;
+
+ case SID_ULINE_VAL_NONE:
+ {
+ SvxUnderlineItem aUnderline(LINESTYLE_NONE, RES_CHRATR_UNDERLINE );
+ rSh.SetAttrItem( aUnderline );
+ rReq.AppendItem( aUnderline );
+ rReq.Done();
+ break;
+ }
+
+ case SID_ULINE_VAL_SINGLE:
+ case SID_ULINE_VAL_DOUBLE:
+ case SID_ULINE_VAL_DOTTED:
+ {
+ FontLineStyle eOld = aSet.Get(RES_CHRATR_UNDERLINE).GetLineStyle();
+ FontLineStyle eNew = eOld;
+
+ switch (nWhich)
+ {
+ case SID_ULINE_VAL_SINGLE:
+ eNew = ( eOld == LINESTYLE_SINGLE ) ? LINESTYLE_NONE : LINESTYLE_SINGLE;
+ break;
+ case SID_ULINE_VAL_DOUBLE:
+ eNew = ( eOld == LINESTYLE_DOUBLE ) ? LINESTYLE_NONE : LINESTYLE_DOUBLE;
+ break;
+ case SID_ULINE_VAL_DOTTED:
+ eNew = ( eOld == LINESTYLE_DOTTED ) ? LINESTYLE_NONE : LINESTYLE_DOTTED;
+ break;
+ }
+
+ SvxUnderlineItem aUnderline(eNew, RES_CHRATR_UNDERLINE );
+ rSh.SetAttrItem( aUnderline );
+ rReq.AppendItem( aUnderline );
+ rReq.Done();
+ }
+ break;
+ case FN_REMOVE_DIRECT_CHAR_FORMATS:
+ if( !rSh.HasReadonlySel() && rSh.IsEndPara())
+ rSh.DontExpandFormat();
+ break;
+ default:
+ OSL_FAIL("wrong dispatcher");
+ return;
+ }
+}
+
+void SwTextShell::ExecCharAttrArgs(SfxRequest &rReq)
+{
+ sal_uInt16 nSlot = rReq.GetSlot();
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ bool bArgs = pArgs != nullptr && pArgs->Count() > 0;
+ SwWrtShell& rWrtSh = GetShell();
+ SwTextFormatColl* pColl = nullptr;
+
+ // Is only set if the whole paragraph is selected and AutoUpdateFormat is set.
+ if (rWrtSh.HasSelection() && rWrtSh.IsSelFullPara())
+ {
+ pColl = rWrtSh.GetCurTextFormatColl();
+ if ( pColl && !pColl->IsAutoUpdateOnDirectFormat() )
+ pColl = nullptr;
+ }
+ SfxItemPool& rPool = GetPool();
+ sal_uInt16 nWhich = rPool.GetWhich( nSlot );
+ switch (nSlot)
+ {
+ case FN_TXTATR_INET:
+ // Special treatment of the PoolId of the SwFormatInetFormat
+ if(bArgs)
+ {
+ const SfxPoolItem& rItem = pArgs->Get( nWhich );
+
+ SwFormatINetFormat aINetFormat( static_cast<const SwFormatINetFormat&>(rItem) );
+ if ( USHRT_MAX == aINetFormat.GetVisitedFormatId() )
+ {
+ OSL_ENSURE( false, "<SwTextShell::ExecCharAttrArgs(..)> - unexpected visited character format ID at hyperlink attribute" );
+ aINetFormat.SetVisitedFormatAndId(
+ aINetFormat.GetVisitedFormat(),
+ SwStyleNameMapper::GetPoolIdFromUIName( aINetFormat.GetVisitedFormat(), SwGetPoolIdFromName::ChrFmt ) );
+ }
+ if ( USHRT_MAX == aINetFormat.GetINetFormatId() )
+ {
+ OSL_ENSURE( false, "<SwTextShell::ExecCharAttrArgs(..)> - unexpected unvisited character format ID at hyperlink attribute" );
+ aINetFormat.SetINetFormatAndId(
+ aINetFormat.GetINetFormat(),
+ SwStyleNameMapper::GetPoolIdFromUIName( aINetFormat.GetINetFormat(), SwGetPoolIdFromName::ChrFmt ) );
+ }
+
+ if ( pColl )
+ pColl->SetFormatAttr( aINetFormat );
+ else
+ rWrtSh.SetAttrItem( aINetFormat );
+ rReq.Done();
+ }
+ break;
+
+ case FN_GROW_FONT_SIZE:
+ case FN_SHRINK_FONT_SIZE:
+ {
+ SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONTHEIGHT, rPool );
+ rWrtSh.GetCurAttr( aSetItem.GetItemSet() );
+ SfxItemSet aAttrSet( rPool, aSetItem.GetItemSet().GetRanges() );
+
+ SvtScriptType nScriptTypes = rWrtSh.GetScriptType();
+ const SvxFontHeightItem* pSize( static_cast<const SvxFontHeightItem*>(
+ aSetItem.GetItemOfScript( nScriptTypes ) ) );
+ std::vector<std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM> >> vItems;
+ // simple case where selected text has one size and
+ // (tdf#124919) selection is not multiple table cells
+ if (pSize && !rWrtSh.IsTableMode())
+ {
+ // must create new one, otherwise document is without pam
+ SwPaM* pPaM = rWrtSh.GetCursor();
+ vItems.emplace_back( pSize, std::make_unique<SwPaM>( *(pPaM->GetMark()), *(pPaM->GetPoint())) );
+ }
+ else
+ vItems = rWrtSh.GetItemWithPaM( RES_CHRATR_FONTSIZE );
+
+ rWrtSh.StartUndo( SwUndoId::INSATTR );
+ for( std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM> >& iPair : vItems )
+ {
+ std::unique_ptr<SwPaM> pPaM = std::move(iPair.second);
+ const SfxPoolItem* pItem = iPair.first;
+ aSetItem.GetItemSet().ClearItem();
+ rWrtSh.GetPaMAttr( pPaM.get(), aSetItem.GetItemSet() );
+ aAttrSet.SetRanges( aSetItem.GetItemSet().GetRanges() );
+
+ pSize = static_cast<const SvxFontHeightItem*>( pItem );
+ if (pSize)
+ {
+ SvxFontHeightItem aSize(*pSize);
+
+ sal_uInt32 nSize = aSize.GetHeight();
+
+ if ( nSlot == FN_GROW_FONT_SIZE && ( nSize += nFontInc ) > nFontMaxSz )
+ nSize = nFontMaxSz;
+ else if ( nSlot == FN_SHRINK_FONT_SIZE && ( nSize -= nFontInc ) < nFontInc )
+ nSize = nFontInc;
+
+ aSize.SetHeight( nSize );
+ aSetItem.PutItemForScriptType( nScriptTypes, aSize );
+ aAttrSet.Put( aSetItem.GetItemSet() );
+ if( pColl )
+ pColl->SetFormatAttr( aAttrSet );
+ else
+ rWrtSh.SetAttrSet( aAttrSet, SetAttrMode::DEFAULT, pPaM.get() );
+ }
+ }
+ rWrtSh.EndUndo( SwUndoId::INSATTR );
+ rReq.Done();
+ }
+ break;
+
+ default:
+ OSL_FAIL("wrong dispatcher");
+ return;
+ }
+}
+
+void SwTextShell::ExecParaAttr(SfxRequest &rReq)
+{
+ SvxAdjust eAdjst;
+ sal_uInt16 ePropL;
+ const SfxItemSet* pArgs = rReq.GetArgs();
+
+ // Get both attributes immediately isn't more expensive!!
+ SfxItemSetFixed
+ <RES_PARATR_LINESPACING, RES_PARATR_ADJUST,
+ RES_FRAMEDIR, RES_FRAMEDIR> aSet( GetPool() );
+
+ sal_uInt16 nSlot = rReq.GetSlot();
+ switch (nSlot)
+ {
+ case SID_ATTR_PARA_ADJUST:
+ {
+ if( pArgs && SfxItemState::SET == pArgs->GetItemState(RES_PARATR_ADJUST) )
+ {
+ const SvxAdjustItem& rAdj = pArgs->Get(RES_PARATR_ADJUST);
+ SvxAdjustItem aAdj( rAdj.GetAdjust(), RES_PARATR_ADJUST );
+ if ( rAdj.GetAdjust() == SvxAdjust::Block )
+ {
+ aAdj.SetLastBlock( rAdj.GetLastBlock() );
+ aAdj.SetOneWord( rAdj.GetOneWord() );
+ }
+
+ aSet.Put(aAdj);
+ }
+ }
+ break;
+ case SID_ATTR_PARA_ADJUST_LEFT: eAdjst = SvxAdjust::Left; goto SET_ADJUST;
+ case SID_ATTR_PARA_ADJUST_RIGHT: eAdjst = SvxAdjust::Right; goto SET_ADJUST;
+ case SID_ATTR_PARA_ADJUST_CENTER: eAdjst = SvxAdjust::Center; goto SET_ADJUST;
+ case SID_ATTR_PARA_ADJUST_BLOCK: eAdjst = SvxAdjust::Block; goto SET_ADJUST;
+SET_ADJUST:
+ {
+ aSet.Put(SvxAdjustItem(eAdjst,RES_PARATR_ADJUST));
+ rReq.AppendItem( SfxBoolItem( GetPool().GetWhich(nSlot), true ) );
+ }
+ break;
+
+ case SID_ATTR_PARA_LINESPACE:
+ if(pArgs && SfxItemState::SET == pArgs->GetItemState( GetPool().GetWhich(nSlot) ))
+ {
+ SvxLineSpacingItem aLineSpace = static_cast<const SvxLineSpacingItem&>( pArgs->Get(
+ GetPool().GetWhich(nSlot)));
+ aSet.Put( aLineSpace );
+ }
+ break;
+ case SID_ATTR_PARA_LINESPACE_10: ePropL = 100; goto SET_LINESPACE;
+ case SID_ATTR_PARA_LINESPACE_15: ePropL = 150; goto SET_LINESPACE;
+ case SID_ATTR_PARA_LINESPACE_115: ePropL = 115; goto SET_LINESPACE;
+ case SID_ATTR_PARA_LINESPACE_20: ePropL = 200; goto SET_LINESPACE;
+
+SET_LINESPACE:
+ {
+
+ SvxLineSpacingItem aLineSpacing(ePropL, RES_PARATR_LINESPACING );
+ aLineSpacing.SetLineSpaceRule( SvxLineSpaceRule::Auto );
+ if( 100 == ePropL )
+ aLineSpacing.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off );
+ else
+ aLineSpacing.SetPropLineSpace(ePropL);
+ aSet.Put( aLineSpacing );
+ }
+ break;
+
+ case SID_ATTR_PARA_LEFT_TO_RIGHT :
+ case SID_ATTR_PARA_RIGHT_TO_LEFT :
+ {
+ SfxItemSetFixed<RES_PARATR_ADJUST, RES_PARATR_ADJUST> aAdjustSet( GetPool() );
+ GetShell().GetCurAttr(aAdjustSet);
+ bool bChgAdjust = false;
+ SfxItemState eAdjustState = aAdjustSet.GetItemState(RES_PARATR_ADJUST, false);
+ if(eAdjustState >= SfxItemState::DEFAULT)
+ {
+ SvxAdjust eAdjust =
+ aAdjustSet.Get(RES_PARATR_ADJUST).GetAdjust();
+ bChgAdjust = (SvxAdjust::Left == eAdjust && SID_ATTR_PARA_RIGHT_TO_LEFT == nSlot) ||
+ (SvxAdjust::Right == eAdjust && SID_ATTR_PARA_LEFT_TO_RIGHT == nSlot);
+ }
+ else
+ bChgAdjust = true;
+
+ SvxFrameDirection eFrameDirection =
+ (SID_ATTR_PARA_LEFT_TO_RIGHT == nSlot) ?
+ SvxFrameDirection::Horizontal_LR_TB : SvxFrameDirection::Horizontal_RL_TB;
+ aSet.Put( SvxFrameDirectionItem( eFrameDirection, RES_FRAMEDIR ) );
+
+ if (bChgAdjust)
+ {
+ SvxAdjust eAdjust = (SID_ATTR_PARA_LEFT_TO_RIGHT == nSlot) ?
+ SvxAdjust::Left : SvxAdjust::Right;
+ SvxAdjustItem aAdjust( eAdjust, RES_PARATR_ADJUST );
+ aSet.Put( aAdjust );
+ aAdjust.SetWhich(SID_ATTR_PARA_ADJUST);
+ GetView().GetViewFrame().GetBindings().SetState( aAdjust );
+ // Toggle numbering alignment
+ const SwNumRule* pCurRule = GetShell().GetNumRuleAtCurrCursorPos();
+ if( pCurRule )
+ {
+ SvxNumRule aRule = pCurRule->MakeSvxNumRule();
+
+ for(sal_uInt16 i = 0; i < aRule.GetLevelCount(); i++)
+ {
+ SvxNumberFormat aFormat(aRule.GetLevel(i));
+ if(SvxAdjust::Left == aFormat.GetNumAdjust())
+ aFormat.SetNumAdjust( SvxAdjust::Right );
+
+ else if(SvxAdjust::Right == aFormat.GetNumAdjust())
+ aFormat.SetNumAdjust( SvxAdjust::Left );
+
+ aRule.SetLevel(i, aFormat, aRule.Get(i) != nullptr);
+ }
+ SwNumRule aSetRule( pCurRule->GetName(),
+ pCurRule->Get( 0 ).GetPositionAndSpaceMode() );
+ aSetRule.SetSvxRule( aRule, GetShell().GetDoc());
+ aSetRule.SetAutoRule( true );
+ // no start or continuation of a list - list style is only changed
+ GetShell().SetCurNumRule( aSetRule, false );
+ }
+ }
+ }
+ break;
+
+ default:
+ OSL_FAIL("wrong dispatcher");
+ return;
+ }
+ SwWrtShell& rWrtSh = GetShell();
+ SwTextFormatColl* pColl = rWrtSh.GetCurTextFormatColl();
+ if(pColl && pColl->IsAutoUpdateOnDirectFormat())
+ {
+ rWrtSh.AutoUpdatePara(pColl, aSet);
+ }
+ else
+ rWrtSh.SetAttrSet( aSet, SetAttrMode::DEFAULT, nullptr, true);
+ rReq.Done();
+}
+
+void SwTextShell::ExecParaAttrArgs(SfxRequest &rReq)
+{
+ SwWrtShell &rSh = GetShell();
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ const SfxPoolItem *pItem = nullptr;
+
+ sal_uInt16 nSlot = rReq.GetSlot();
+ if(pArgs)
+ pArgs->GetItemState(GetPool().GetWhich(nSlot), false, &pItem);
+ switch ( nSlot )
+ {
+ case FN_DROP_CHAR_STYLE_NAME:
+ if( pItem )
+ {
+ OUString sCharStyleName = static_cast<const SfxStringItem*>(pItem)->GetValue();
+ SfxItemSetFixed<RES_PARATR_DROP, RES_PARATR_DROP> aSet(GetPool());
+ rSh.GetCurAttr(aSet);
+ SwFormatDrop aDropItem(aSet.Get(RES_PARATR_DROP));
+ SwCharFormat* pFormat = nullptr;
+ if(!sCharStyleName.isEmpty())
+ pFormat = rSh.FindCharFormatByName( sCharStyleName );
+ aDropItem.SetCharFormat( pFormat );
+ aSet.Put(aDropItem);
+ rSh.SetAttrSet(aSet);
+ }
+ break;
+ case FN_FORMAT_DROPCAPS:
+ {
+ if(pItem)
+ {
+ rSh.SetAttrItem(*pItem);
+ rReq.Done();
+ }
+ else
+ {
+ SfxItemSetFixed<RES_PARATR_DROP, RES_PARATR_DROP,
+ HINT_END, HINT_END> aSet(GetPool());
+ rSh.GetCurAttr(aSet);
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ ScopedVclPtr<SfxAbstractDialog> pDlg(pFact->CreateSwDropCapsDialog(GetView().GetFrameWeld(), aSet));
+ if (pDlg->Execute() == RET_OK)
+ {
+ rSh.StartAction();
+ rSh.StartUndo( SwUndoId::START );
+ if ( const SfxStringItem* pHintItem = aSet.GetItemIfSet(HINT_END,false) )
+ {
+ if ( !pHintItem->GetValue().isEmpty() )
+ rSh.ReplaceDropText(pHintItem->GetValue());
+ }
+ rSh.SetAttrSet(*pDlg->GetOutputItemSet());
+ rSh.EndUndo( SwUndoId::END );
+ rSh.EndAction();
+ rReq.Done(*pDlg->GetOutputItemSet());
+ }
+ }
+ }
+ break;
+ case SID_ATTR_PARA_PAGEBREAK:
+ if(pItem)
+ {
+ rSh.SetAttrItem( *pItem );
+ rReq.Done();
+ }
+ break;
+ case SID_ATTR_PARA_MODEL:
+ {
+ if(pItem)
+ {
+ SfxItemSetFixed<RES_PAGEDESC, RES_PAGEDESC,
+ SID_ATTR_PARA_MODEL, SID_ATTR_PARA_MODEL> aCoreSet( GetPool() );
+ aCoreSet.Put(*pItem);
+ SfxToSwPageDescAttr( rSh, aCoreSet);
+ rSh.SetAttrSet(aCoreSet);
+ rReq.Done();
+ }
+ }
+ break;
+
+ default:
+ OSL_FAIL("wrong dispatcher");
+ return;
+ }
+}
+
+void SwTextShell::GetAttrState(SfxItemSet &rSet)
+{
+ SwWrtShell &rSh = GetShell();
+ SfxItemPool& rPool = GetPool();
+ SfxItemSet aCoreSet(rPool, aTextFormatCollSetRange);
+ // Request *all* text attributes from the core.
+ // fdo#78737: this is called from SvxRuler, which requires the list indents!
+ rSh.GetCurAttr(aCoreSet, /* bMergeIndentValuesOfNumRule = */ true);
+
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nSlot = aIter.FirstWhich();
+ bool bFlag = false;
+ SfxBoolItem aFlagItem;
+ const SfxPoolItem* pItem = nullptr;
+ SvxAdjust eAdjust = SvxAdjust::Left;
+ bool bAdjustGood = false;
+ SfxItemState eState = aCoreSet.GetItemState(RES_PARATR_ADJUST, false, &pItem);
+
+ if( SfxItemState::DEFAULT == eState )
+ pItem = &rPool.GetDefaultItem(RES_PARATR_ADJUST);
+ if( SfxItemState::DEFAULT <= eState )
+ {
+ eAdjust = static_cast<const SvxAdjustItem* >( pItem)->GetAdjust();
+ bAdjustGood = true;
+ }
+
+ short nEsc = 0;
+ eState = aCoreSet.GetItemState(RES_CHRATR_ESCAPEMENT, false, &pItem);
+ if( SfxItemState::DEFAULT == eState )
+ pItem = &rPool.GetDefaultItem(RES_CHRATR_ESCAPEMENT);
+ if( eState >= SfxItemState::DEFAULT )
+ nEsc = static_cast<const SvxEscapementItem* >(pItem)->GetEsc();
+
+ sal_uInt16 nLineSpace = 0;
+ eState = aCoreSet.GetItemState(RES_PARATR_LINESPACING, false, &pItem);
+ if( SfxItemState::DEFAULT == eState )
+ pItem = &rPool.GetDefaultItem(RES_PARATR_LINESPACING);
+ if( SfxItemState::DEFAULT <= eState &&
+ static_cast<const SvxLineSpacingItem* >(pItem)->GetLineSpaceRule() == SvxLineSpaceRule::Auto )
+ {
+ if(SvxInterLineSpaceRule::Off ==
+ static_cast<const SvxLineSpacingItem* >(pItem)->GetInterLineSpaceRule())
+ nLineSpace = 100;
+ else
+ nLineSpace = static_cast<const SvxLineSpacingItem* >(pItem)->GetPropLineSpace();
+ }
+
+ SvxCaseMap eCaseMap = SvxCaseMap::NotMapped;
+ eState = aCoreSet.GetItemState(RES_CHRATR_CASEMAP, false, &pItem);
+ if (eState == SfxItemState::DEFAULT)
+ pItem = &rPool.GetDefaultItem(RES_CHRATR_CASEMAP);
+ if (eState >= SfxItemState::DEFAULT)
+ eCaseMap = static_cast<const SvxCaseMapItem*>(pItem)->GetCaseMap();
+
+ while (nSlot)
+ {
+ switch(nSlot)
+ {
+ case FN_SET_SUPER_SCRIPT:
+ bFlag = 0 < nEsc;
+ break;
+ case FN_SET_SUB_SCRIPT:
+ bFlag = 0 > nEsc;
+ break;
+ case FN_SET_SMALL_CAPS:
+ bFlag = eCaseMap == SvxCaseMap::SmallCaps;
+ break;
+ case SID_ATTR_PARA_ADJUST_LEFT:
+ if (!bAdjustGood)
+ {
+ rSet.InvalidateItem( nSlot );
+ nSlot = 0;
+ }
+ else
+ bFlag = SvxAdjust::Left == eAdjust;
+ break;
+ case SID_ATTR_PARA_ADJUST_RIGHT:
+ if (!bAdjustGood)
+ {
+ rSet.InvalidateItem( nSlot );
+ nSlot = 0;
+ }
+ else
+ bFlag = SvxAdjust::Right == eAdjust;
+ break;
+ case SID_ATTR_PARA_ADJUST_CENTER:
+ if (!bAdjustGood)
+ {
+ rSet.InvalidateItem( nSlot );
+ nSlot = 0;
+ }
+ else
+ bFlag = SvxAdjust::Center == eAdjust;
+ break;
+ case SID_ATTR_PARA_ADJUST_BLOCK:
+ {
+ if (!bAdjustGood)
+ {
+ rSet.InvalidateItem( nSlot );
+ nSlot = 0;
+ }
+ else
+ {
+ bFlag = SvxAdjust::Block == eAdjust;
+ sal_uInt16 nHtmlMode = GetHtmlMode(rSh.GetView().GetDocShell());
+ if((nHtmlMode & HTMLMODE_ON) && !(nHtmlMode & HTMLMODE_FULL_STYLES ))
+ {
+ rSet.DisableItem( nSlot );
+ nSlot = 0;
+ }
+ }
+ }
+ break;
+ case SID_ATTR_PARA_LINESPACE_10:
+ bFlag = nLineSpace == 100;
+ break;
+ case SID_ATTR_PARA_LINESPACE_115:
+ bFlag = nLineSpace == 115;
+ break;
+ case SID_ATTR_PARA_LINESPACE_15:
+ bFlag = nLineSpace == 150;
+ break;
+ case SID_ATTR_PARA_LINESPACE_20:
+ bFlag = nLineSpace == 200;
+ break;
+ case FN_GROW_FONT_SIZE:
+ case FN_SHRINK_FONT_SIZE:
+ {
+ SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONTHEIGHT,
+ *rSet.GetPool() );
+ aSetItem.GetItemSet().Put( aCoreSet, false );
+ const SvxFontHeightItem* pSize( static_cast<const SvxFontHeightItem*>(
+ aSetItem.GetItemOfScript( rSh.GetScriptType() ) ) );
+
+ if( pSize ) // selection is of one size
+ {
+ sal_uInt32 nSize = pSize->GetHeight();
+ if( nSize == nFontMaxSz )
+ rSet.DisableItem( FN_GROW_FONT_SIZE );
+ else if( nSize == nFontInc )
+ rSet.DisableItem( FN_SHRINK_FONT_SIZE );
+ }
+ else
+ {
+ std::vector<std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM> >>
+ vFontHeight = rSh.GetItemWithPaM( RES_CHRATR_FONTSIZE );
+ for ( const std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM>>& aIt : vFontHeight )
+ {
+ if (!aIt.first)
+ {
+ rSet.DisableItem(FN_GROW_FONT_SIZE);
+ rSet.DisableItem(FN_SHRINK_FONT_SIZE);
+ break;
+ }
+ pSize = static_cast<const SvxFontHeightItem*>( aIt.first );
+ sal_uInt32 nSize = pSize->GetHeight();
+ if( nSize == nFontMaxSz )
+ rSet.DisableItem( FN_GROW_FONT_SIZE );
+ else if( nSize == nFontInc )
+ rSet.DisableItem( FN_SHRINK_FONT_SIZE );
+ }
+ }
+ nSlot = 0;
+ }
+ break;
+ case SID_ULINE_VAL_NONE:
+ case SID_ULINE_VAL_SINGLE:
+ case SID_ULINE_VAL_DOUBLE:
+ case SID_ULINE_VAL_DOTTED:
+ {
+ eState = aCoreSet.GetItemState(RES_CHRATR_UNDERLINE);
+ if( eState >= SfxItemState::DEFAULT )
+ {
+ FontLineStyle eLineStyle = aCoreSet.Get(RES_CHRATR_UNDERLINE).GetLineStyle();
+
+ switch (nSlot)
+ {
+ case SID_ULINE_VAL_NONE:
+ rSet.Put(SfxBoolItem(nSlot, eLineStyle == LINESTYLE_NONE));
+ break;
+ case SID_ULINE_VAL_SINGLE:
+ rSet.Put(SfxBoolItem(nSlot, eLineStyle == LINESTYLE_SINGLE));
+ break;
+ case SID_ULINE_VAL_DOUBLE:
+ rSet.Put(SfxBoolItem(nSlot, eLineStyle == LINESTYLE_DOUBLE));
+ break;
+ case SID_ULINE_VAL_DOTTED:
+ rSet.Put(SfxBoolItem(nSlot, eLineStyle == LINESTYLE_DOTTED));
+ break;
+ }
+ }
+ else
+ rSet.InvalidateItem(nSlot);
+ nSlot = 0;
+ }
+ break;
+ case SID_ATTR_PARA_ADJUST:
+ if (!bAdjustGood)
+ rSet.InvalidateItem( nSlot );
+ else
+ rSet.Put(SvxAdjustItem(eAdjust, SID_ATTR_PARA_ADJUST ));
+ nSlot = 0;
+ break;
+ case SID_ATTR_PARA_LRSPACE:
+ case SID_ATTR_PARA_LEFTSPACE:
+ case SID_ATTR_PARA_RIGHTSPACE:
+ case SID_ATTR_PARA_FIRSTLINESPACE:
+ {
+ eState = aCoreSet.GetItemState(RES_MARGIN_FIRSTLINE);
+ eState = std::min(aCoreSet.GetItemState(RES_MARGIN_TEXTLEFT), eState);
+ eState = std::min(aCoreSet.GetItemState(RES_MARGIN_RIGHT), eState);
+ if( eState >= SfxItemState::DEFAULT )
+ {
+ SvxLRSpaceItem aLR(RES_LR_SPACE);
+ SvxFirstLineIndentItem const& rFirstLine(aCoreSet.Get(RES_MARGIN_FIRSTLINE));
+ SvxTextLeftMarginItem const& rLeftMargin(aCoreSet.Get(RES_MARGIN_TEXTLEFT));
+ SvxRightMarginItem const& rRightMargin(aCoreSet.Get(RES_MARGIN_RIGHT));
+ aLR.SetTextFirstLineOffset(rFirstLine.GetTextFirstLineOffset(), rFirstLine.GetPropTextFirstLineOffset());
+ aLR.SetAutoFirst(rFirstLine.IsAutoFirst());
+ aLR.SetTextLeft(rLeftMargin.GetTextLeft(), rLeftMargin.GetPropLeft());
+ aLR.SetRight(rRightMargin.GetRight(), rRightMargin.GetPropRight());
+ aLR.SetWhich(nSlot);
+ rSet.Put(aLR);
+ }
+ else
+ rSet.InvalidateItem(nSlot);
+ nSlot = 0;
+ }
+ break;
+
+ case SID_ATTR_PARA_LEFT_TO_RIGHT :
+ case SID_ATTR_PARA_RIGHT_TO_LEFT :
+ {
+ if ( !SvtCTLOptions::IsCTLFontEnabled() )
+ {
+ rSet.DisableItem( nSlot );
+ nSlot = 0;
+ }
+ else
+ {
+ // is the item set?
+ sal_uInt16 nHtmlMode = GetHtmlMode(rSh.GetView().GetDocShell());
+ if((!(nHtmlMode & HTMLMODE_ON) || (0 != (nHtmlMode & HTMLMODE_SOME_STYLES))) &&
+ aCoreSet.GetItemState( RES_FRAMEDIR, false ) >= SfxItemState::DEFAULT)
+ {
+ SvxFrameDirection eFrameDir =
+ aCoreSet.Get(RES_FRAMEDIR).GetValue();
+ if (SvxFrameDirection::Environment == eFrameDir)
+ {
+ eFrameDir = rSh.IsInRightToLeftText() ?
+ SvxFrameDirection::Horizontal_RL_TB : SvxFrameDirection::Horizontal_LR_TB;
+ }
+ bFlag = (SID_ATTR_PARA_LEFT_TO_RIGHT == nSlot &&
+ SvxFrameDirection::Horizontal_LR_TB == eFrameDir) ||
+ (SID_ATTR_PARA_RIGHT_TO_LEFT == nSlot &&
+ SvxFrameDirection::Horizontal_RL_TB == eFrameDir);
+ }
+ else
+ {
+ rSet.InvalidateItem(nSlot);
+ nSlot = 0;
+ }
+ }
+ }
+ break;
+
+ case SID_ATTR_CHAR_LANGUAGE:
+ case SID_ATTR_CHAR_KERNING:
+ case RES_PARATR_DROP:
+ {
+ rSet.Put(aCoreSet.Get( GetPool().GetWhich(nSlot)));
+ nSlot = 0;
+ }
+ break;
+ case SID_ATTR_PARA_MODEL:
+ {
+ SfxItemSetFixed
+ <RES_PAGEDESC,RES_PAGEDESC,
+ SID_ATTR_PARA_MODEL,SID_ATTR_PARA_MODEL> aTemp(GetPool());
+ aTemp.Put(aCoreSet);
+ ::SwToSfxPageDescAttr(aTemp);
+ rSet.Put(aTemp.Get(SID_ATTR_PARA_MODEL));
+ nSlot = 0;
+ }
+ break;
+ case RES_TXTATR_INETFMT:
+ {
+ SfxItemSetFixed<RES_TXTATR_INETFMT, RES_TXTATR_INETFMT> aSet(GetPool());
+ rSh.GetCurAttr(aSet);
+ const SfxPoolItem& rItem = aSet.Get(RES_TXTATR_INETFMT);
+ rSet.Put(rItem);
+ nSlot = 0;
+ }
+ break;
+
+ default:
+ // Do nothing
+ nSlot = 0;
+ break;
+
+ }
+ if( nSlot )
+ {
+ aFlagItem.SetWhich( nSlot );
+ aFlagItem.SetValue( bFlag );
+ rSet.Put( aFlagItem );
+ }
+ nSlot = aIter.NextWhich();
+ }
+
+ rSet.Put(aCoreSet,false);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/txtcrsr.cxx b/sw/source/uibase/shells/txtcrsr.cxx
new file mode 100644
index 0000000000..6dc161cb1e
--- /dev/null
+++ b/sw/source/uibase/shells/txtcrsr.cxx
@@ -0,0 +1,464 @@
+/* -*- 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 <sfx2/request.hxx>
+#include <svl/eitem.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/bindings.hxx>
+#include <osl/diagnose.h>
+
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <textsh.hxx>
+#include <edtwin.hxx>
+#include <doc.hxx>
+#include <docsh.hxx>
+
+#include <cmdid.h>
+#include <globals.hrc>
+
+#include <svx/svdouno.hxx>
+#include <svx/fmshell.hxx>
+#include <svx/sdrobjectfilter.hxx>
+
+using namespace ::com::sun::star;
+
+void SwTextShell::ExecBasicMove(SfxRequest &rReq)
+{
+ SwWrtShell &rSh = GetShell();
+ GetView().GetEditWin().FlushInBuffer();
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ bool bSelect = false;
+ sal_Int32 nCount = 1;
+ if(pArgs)
+ {
+ if(const SfxInt32Item* pCountItem = pArgs->GetItemIfSet(FN_PARAM_MOVE_COUNT))
+ nCount = pCountItem->GetValue();
+ if(const SfxBoolItem* pSelectionItem = pArgs->GetItemIfSet(FN_PARAM_MOVE_SELECTION))
+ bSelect = pSelectionItem->GetValue();
+ }
+ switch(rReq.GetSlot())
+ {
+ case FN_CHAR_LEFT_SEL:
+ rReq.SetSlot( FN_CHAR_LEFT );
+ bSelect = true;
+ break;
+ case FN_CHAR_RIGHT_SEL:
+ rReq.SetSlot( FN_CHAR_RIGHT );
+ bSelect = true;
+ break;
+ case FN_LINE_UP_SEL:
+ rReq.SetSlot( FN_LINE_UP );
+ bSelect = true;
+ break;
+ case FN_LINE_DOWN_SEL:
+ rReq.SetSlot( FN_LINE_DOWN );
+ bSelect = true;
+ break;
+ }
+
+ uno::Reference< frame::XDispatchRecorder > xRecorder =
+ GetView().GetViewFrame().GetBindings().GetRecorder();
+ if ( xRecorder.is() )
+ {
+ rReq.AppendItem( SfxInt32Item(FN_PARAM_MOVE_COUNT, nCount) );
+ rReq.AppendItem( SfxBoolItem(FN_PARAM_MOVE_SELECTION, bSelect) );
+ }
+ const sal_uInt16 nSlot = rReq.GetSlot();
+ rReq.Done();
+ // Get EditWin before calling the move functions (shell change may occur!)
+ SwEditWin& rTmpEditWin = GetView().GetEditWin();
+ for( sal_Int32 i = 0; i < nCount; i++ )
+ {
+ switch(nSlot)
+ {
+ case FN_CHAR_LEFT:
+ rSh.Left( SwCursorSkipMode::Cells, bSelect, 1, false, true );
+ break;
+ case FN_CHAR_RIGHT:
+ rSh.Right( SwCursorSkipMode::Cells, bSelect, 1, false, true );
+ break;
+ case FN_LINE_UP:
+ rSh.Up( bSelect );
+ break;
+ case FN_LINE_DOWN:
+ rSh.Down( bSelect );
+ break;
+ default:
+ OSL_FAIL("wrong Dispatcher");
+ return;
+ }
+ }
+
+ //#i42732# - notify the edit window that from now on we do not use the input language
+ rTmpEditWin.SetUseInputLanguage( false );
+}
+
+void SwTextShell::ExecMove(SfxRequest &rReq)
+{
+ SwWrtShell &rSh = GetShell();
+ rSh.addCurrentPosition();
+ SwEditWin& rTmpEditWin = GetView().GetEditWin();
+ rTmpEditWin.FlushInBuffer();
+
+ bool bRet = false;
+ switch ( rReq.GetSlot() )
+ {
+ case FN_START_OF_LINE_SEL:
+ bRet = rSh.LeftMargin( true, false );
+ break;
+ case FN_START_OF_LINE:
+ bRet = rSh.LeftMargin( false, false );
+ break;
+ case FN_END_OF_LINE_SEL:
+ bRet = rSh.RightMargin( true, false );
+ break;
+ case FN_END_OF_LINE:
+ bRet = rSh.RightMargin( false, false );
+ break;
+ case FN_START_OF_DOCUMENT_SEL:
+ bRet = rSh.StartOfSection( true );
+ break;
+ case FN_START_OF_DOCUMENT:
+ bRet = rSh.StartOfSection();
+ break;
+ case FN_END_OF_DOCUMENT_SEL:
+ bRet = rSh.EndOfSection( true );
+ break;
+ case FN_END_OF_DOCUMENT:
+ bRet = rSh.EndOfSection();
+ break;
+ case FN_SELECT_WORD:
+ bRet = rSh.SelNearestWrd();
+ break;
+ case FN_SELECT_SENTENCE:
+ rSh.SelSentence( nullptr );
+ bRet = true;
+ break;
+ case SID_SELECTALL:
+ rSh.SelAll();
+ bRet = true;
+ break;
+ default:
+ OSL_FAIL("wrong dispatcher");
+ return;
+ }
+
+ if ( bRet )
+ rReq.Done();
+ else
+ rReq.Ignore();
+
+ //#i42732# - notify the edit window that from now on we do not use the input language
+ rTmpEditWin.SetUseInputLanguage( false );
+}
+
+void SwTextShell::ExecMovePage(SfxRequest &rReq)
+{
+ SwWrtShell &rSh = GetShell();
+ rSh.addCurrentPosition();
+ GetView().GetEditWin().FlushInBuffer();
+
+ switch( rReq.GetSlot() )
+ {
+ case FN_START_OF_NEXT_PAGE_SEL :
+ rSh.SttNxtPg( true );
+ break;
+ case FN_START_OF_NEXT_PAGE:
+ rSh.SttNxtPg();
+ break;
+ case FN_END_OF_NEXT_PAGE_SEL:
+ rSh.EndNxtPg( true );
+ break;
+ case FN_END_OF_NEXT_PAGE:
+ rSh.EndNxtPg();
+ break;
+ case FN_START_OF_PREV_PAGE_SEL:
+ rSh.SttPrvPg( true );
+ break;
+ case FN_START_OF_PREV_PAGE:
+ rSh.SttPrvPg();
+ break;
+ case FN_END_OF_PREV_PAGE_SEL:
+ rSh.EndPrvPg( true );
+ break;
+ case FN_END_OF_PREV_PAGE:
+ rSh.EndPrvPg();
+ break;
+ case FN_START_OF_PAGE_SEL:
+ rSh.SttPg( true );
+ break;
+ case FN_START_OF_PAGE:
+ rSh.SttPg();
+ break;
+ case FN_END_OF_PAGE_SEL:
+ rSh.EndPg( true );
+ break;
+ case FN_END_OF_PAGE:
+ rSh.EndPg();
+ break;
+ default:
+ OSL_FAIL("wrong dispatcher");
+ return;
+ }
+ rReq.Done();
+}
+
+void SwTextShell::ExecMoveCol(SfxRequest &rReq)
+{
+ SwWrtShell &rSh = GetShell();
+ rSh.addCurrentPosition();
+ switch ( rReq.GetSlot() )
+ {
+ case FN_START_OF_COLUMN:
+ rSh.StartOfColumn();
+ break;
+ case FN_END_OF_COLUMN:
+ rSh.EndOfColumn();
+ break;
+ case FN_START_OF_NEXT_COLUMN:
+ rSh.StartOfNextColumn() ;
+ break;
+ case FN_END_OF_NEXT_COLUMN:
+ rSh.EndOfNextColumn();
+ break;
+ case FN_START_OF_PREV_COLUMN:
+ rSh.StartOfPrevColumn();
+ break;
+ case FN_END_OF_PREV_COLUMN:
+ rSh.EndOfPrevColumn();
+ break;
+ default:
+ OSL_FAIL("wrong dispatcher");
+ return;
+ }
+ rReq.Done();
+}
+
+void SwTextShell::ExecMoveLingu(SfxRequest &rReq)
+{
+ SwWrtShell &rSh = GetShell();
+ rSh.addCurrentPosition();
+ GetView().GetEditWin().FlushInBuffer();
+
+ switch ( rReq.GetSlot() )
+ {
+ case FN_NEXT_WORD_SEL:
+ rSh.NxtWrd( true );
+ break;
+ case FN_NEXT_WORD:
+ rSh.NxtWrd();
+ break;
+ case FN_START_OF_PARA_SEL:
+ rSh.SttPara( true );
+ break;
+ case FN_START_OF_PARA:
+ rSh.SttPara();
+ break;
+ case FN_END_OF_PARA_SEL:
+ rSh.EndPara( true );
+ break;
+ case FN_END_OF_PARA:
+ rSh.EndPara();
+ break;
+ case FN_PREV_WORD_SEL:
+ rSh.PrvWrd( true );
+ break;
+ case FN_PREV_WORD:
+ rSh.PrvWrd();
+ break;
+ case FN_NEXT_SENT_SEL:
+ rSh.FwdSentence( true );
+ break;
+ case FN_NEXT_SENT:
+ rSh.FwdSentence();
+ break;
+ case FN_PREV_SENT_SEL:
+ rSh.BwdSentence( true );
+ break;
+ case FN_PREV_SENT:
+ rSh.BwdSentence();
+ break;
+ case FN_NEXT_PARA:
+ rSh.FwdPara();
+ break;
+ case FN_PREV_PARA:
+ rSh.BwdPara();
+ break;
+ default:
+ OSL_FAIL("wrong dispatcher");
+ return;
+ }
+ rReq.Done();
+}
+
+void SwTextShell::ExecMoveMisc(SfxRequest &rReq)
+{
+ SwWrtShell &rSh = GetShell();
+ rSh.addCurrentPosition();
+ const sal_uInt16 nSlot = rReq.GetSlot();
+ bool bSetRetVal = true, bRet = true;
+ switch ( nSlot )
+ {
+ case SID_FM_TOGGLECONTROLFOCUS:
+ {
+ const SwDoc* pDoc = rSh.GetDoc();
+ const SwDocShell* pDocShell = pDoc ? pDoc->GetDocShell() : nullptr;
+ const SwView* pView = pDocShell ? pDocShell->GetView() : nullptr;
+ const FmFormShell* pFormShell = pView ? pView->GetFormShell() : nullptr;
+ SdrView* pDrawView = pView ? pView->GetDrawView() : nullptr;
+ vcl::Window* pWindow = pView ? pView->GetWrtShell().GetWin() : nullptr;
+
+ OSL_ENSURE( pFormShell && pDrawView && pWindow, "SwXTextView::ExecMoveMisc: no chance!" );
+ if ( !pFormShell || !pDrawView || !pWindow )
+ break;
+
+ std::unique_ptr< svx::ISdrObjectFilter > pFilter( FmFormShell::CreateFocusableControlFilter(
+ *pDrawView, *pWindow->GetOutDev() ) );
+ if (!pFilter)
+ break;
+
+ const SdrObject* pNearestControl = rSh.GetBestObject( true, GotoObjFlags::DrawControl, false, pFilter.get() );
+ if ( !pNearestControl )
+ break;
+
+ const SdrUnoObj* pUnoObject = dynamic_cast< const SdrUnoObj* >( pNearestControl );
+ OSL_ENSURE( pUnoObject, "SwTextShell::ExecMoveMisc: GetBestObject returned nonsense!" );
+ if ( !pUnoObject )
+ break;
+
+ pFormShell->ToggleControlFocus( *pUnoObject, *pDrawView, *pWindow->GetOutDev() );
+ }
+ break;
+ case FN_CNTNT_TO_NEXT_FRAME:
+ bRet = rSh.GotoObj(true, GotoObjFlags::Any);
+ if(bRet)
+ {
+ rSh.HideCursor();
+ rSh.EnterSelFrameMode();
+ }
+ break;
+ case FN_NEXT_FOOTNOTE:
+ rSh.MoveCursor();
+ bRet = rSh.GotoNextFootnoteAnchor();
+ break;
+ case FN_PREV_FOOTNOTE:
+ rSh.MoveCursor();
+ bRet = rSh.GotoPrevFootnoteAnchor();
+ break;
+ case FN_TO_HEADER:
+ rSh.MoveCursor();
+ if ( FrameTypeFlags::HEADER & rSh.GetFrameType(nullptr,false) )
+ rSh.SttPg();
+ else
+ {
+ bool bMoved = rSh.GotoHeaderText();
+ if ( !bMoved )
+ rSh.SttPg();
+ }
+ bSetRetVal = false;
+ break;
+ case FN_TO_FOOTER:
+ rSh.MoveCursor();
+ if ( FrameTypeFlags::FOOTER & rSh.GetFrameType(nullptr,false) )
+ rSh.EndPg();
+ else
+ {
+ bool bMoved = rSh.GotoFooterText();
+ if ( !bMoved )
+ rSh.EndPg();
+ }
+ bSetRetVal = false;
+ break;
+ case FN_FOOTNOTE_TO_ANCHOR:
+ rSh.MoveCursor();
+ if ( FrameTypeFlags::FOOTNOTE & rSh.GetFrameType(nullptr,false) )
+ rSh.GotoFootnoteAnchor();
+ else
+ rSh.GotoFootnoteText();
+ bSetRetVal = false;
+ break;
+ case FN_TO_FOOTNOTE_AREA :
+ rSh.GotoFootnoteText();
+ break;
+ case FN_PREV_TABLE:
+ bRet = rSh.MoveTable( GotoPrevTable, fnTableStart);
+ break;
+ case FN_NEXT_TABLE:
+ bRet = rSh.MoveTable(GotoNextTable, fnTableStart);
+ break;
+ case FN_GOTO_NEXT_REGION :
+ bRet = rSh.MoveRegion(GotoNextRegion, fnRegionStart);
+ break;
+ case FN_GOTO_PREV_REGION :
+ bRet = rSh.MoveRegion(GotoPrevRegion, fnRegionStart);
+ break;
+ case FN_NEXT_TOXMARK:
+ bRet = rSh.GotoNxtPrvTOXMark();
+ break;
+ case FN_PREV_TOXMARK:
+ bRet = rSh.GotoNxtPrvTOXMark( false );
+ break;
+ case FN_NEXT_TBLFML:
+ bRet = rSh.GotoNxtPrvTableFormula();
+ break;
+ case FN_PREV_TBLFML:
+ bRet = rSh.GotoNxtPrvTableFormula( false );
+ break;
+ case FN_NEXT_TBLFML_ERR:
+ bRet = rSh.GotoNxtPrvTableFormula( true, true );
+ break;
+ case FN_PREV_TBLFML_ERR:
+ bRet = rSh.GotoNxtPrvTableFormula( false, true );
+ break;
+ default:
+ OSL_FAIL("wrong dispatcher");
+ return;
+ }
+
+ if( bSetRetVal )
+ rReq.SetReturnValue(SfxBoolItem( nSlot, bRet ));
+ rReq.Done();
+
+ bool bInHeader = true;
+ if ( rSh.IsInHeaderFooter( &bInHeader ) )
+ {
+ if ( !bInHeader )
+ {
+ rSh.SetShowHeaderFooterSeparator( FrameControlType::Footer, true );
+ rSh.SetShowHeaderFooterSeparator( FrameControlType::Header, false );
+ }
+ else
+ {
+ rSh.SetShowHeaderFooterSeparator( FrameControlType::Header, true );
+ rSh.SetShowHeaderFooterSeparator( FrameControlType::Footer, false );
+ }
+
+ // Force repaint
+ rSh.GetWin()->Invalidate();
+ }
+ if ( rSh.IsInHeaderFooter() != rSh.IsHeaderFooterEdit() )
+ rSh.ToggleHeaderFooterEdit();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/txtnum.cxx b/sw/source/uibase/shells/txtnum.cxx
new file mode 100644
index 0000000000..e769b7f463
--- /dev/null
+++ b/sw/source/uibase/shells/txtnum.cxx
@@ -0,0 +1,330 @@
+/* -*- 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 <sfx2/request.hxx>
+#include <svl/eitem.hxx>
+#include <svl/stritem.hxx>
+#include <editeng/numitem.hxx>
+#include <editeng/brushitem.hxx>
+#include <osl/diagnose.h>
+#include <numrule.hxx>
+
+#include <cmdid.h>
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <viewopt.hxx>
+#include <wdocsh.hxx>
+#include <poolfmt.hxx>
+#include <textsh.hxx>
+#include <swabstdlg.hxx>
+#include <SwStyleNameMapper.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <svx/nbdtmg.hxx>
+#include <svx/nbdtmgfact.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/bindings.hxx>
+#include <memory>
+
+void SwTextShell::ExecEnterNum(SfxRequest &rReq)
+{
+ //Because the record before any shell exchange.
+ switch(rReq.GetSlot())
+ {
+ case FN_NUM_NUMBERING_ON:
+ {
+ GetShell().StartAllAction();
+ const SfxBoolItem* pItem = rReq.GetArg<SfxBoolItem>(FN_PARAM_1);
+ bool bMode = !GetShell().SelectionHasNumber(); // #i29560#
+ if ( pItem )
+ bMode = pItem->GetValue();
+ else
+ rReq.AppendItem( SfxBoolItem( FN_PARAM_1, bMode ) );
+
+ if ( bMode != (GetShell().SelectionHasNumber()) ) // #i29560#
+ {
+ rReq.Done();
+ if( bMode )
+ GetShell().NumOn();
+ else
+ GetShell().NumOrBulletOff(); // #i29560#
+ }
+ bool bNewResult = GetShell().SelectionHasNumber();
+ if (bNewResult!=bMode) {
+ SfxBindings& rBindings = GetView().GetViewFrame().GetBindings();
+ SfxBoolItem aItem(FN_NUM_NUMBERING_ON,!bNewResult);
+ rBindings.SetState(aItem);
+ SfxBoolItem aNewItem(FN_NUM_NUMBERING_ON,bNewResult);
+ rBindings.SetState(aNewItem);
+ }
+ GetShell().EndAllAction();
+ }
+ break;
+ case FN_NUM_BULLET_ON:
+ {
+ GetShell().StartAllAction();
+ const SfxBoolItem* pItem = rReq.GetArg<SfxBoolItem>(FN_PARAM_1);
+ bool bMode = !GetShell().SelectionHasBullet(); // #i29560#
+ if ( pItem )
+ bMode = pItem->GetValue();
+ else
+ rReq.AppendItem( SfxBoolItem( FN_PARAM_1, bMode ) );
+
+ if ( bMode != (GetShell().SelectionHasBullet()) ) // #i29560#
+ {
+ rReq.Done();
+ if( bMode )
+ GetShell().BulletOn();
+ else
+ GetShell().NumOrBulletOff(); // #i29560#
+ }
+ bool bNewResult = GetShell().SelectionHasBullet();
+ if (bNewResult!=bMode) {
+ SfxBindings& rBindings = GetView().GetViewFrame().GetBindings();
+ SfxBoolItem aItem(FN_NUM_BULLET_ON,!bNewResult);
+ rBindings.SetState(aItem);
+ SfxBoolItem aNewItem(FN_NUM_BULLET_ON,bNewResult);
+ rBindings.SetState(aNewItem);
+ }
+ GetShell().EndAllAction();
+ }
+ break;
+
+ case FN_NUM_BULLET_OFF:
+ {
+ GetShell().StartAllAction();
+ SfxRequest aReq(GetView().GetViewFrame(), FN_NUM_BULLET_ON);
+ aReq.AppendItem(SfxBoolItem(FN_PARAM_1, false));
+ aReq.Done();
+ GetShell().NumOrBulletOff();
+ GetShell().DelNumRules();
+ GetShell().EndAllAction();
+ }
+ break;
+
+ case FN_NUMBER_BULLETS:
+ case SID_OUTLINE_BULLET:
+ {
+ SfxItemSetFixed<SID_HTML_MODE, SID_HTML_MODE,
+ SID_ATTR_NUMBERING_RULE, SID_PARAM_CUR_NUM_LEVEL> aSet( GetPool() );
+ SwDocShell* pDocSh = GetView().GetDocShell();
+ const bool bHtml = dynamic_cast<SwWebDocShell*>( pDocSh ) != nullptr;
+ const SwNumRule* pNumRuleAtCurrentSelection = GetShell().GetNumRuleAtCurrentSelection();
+ if ( pNumRuleAtCurrentSelection != nullptr )
+ {
+ SvxNumRule aRule = pNumRuleAtCurrentSelection->MakeSvxNumRule();
+
+ //convert type of linked bitmaps from SVX_NUM_BITMAP to (SVX_NUM_BITMAP|LINK_TOKEN)
+ for ( sal_uInt16 i = 0; i < aRule.GetLevelCount(); i++ )
+ {
+ SvxNumberFormat aFormat( aRule.GetLevel( i ) );
+ if ( SVX_NUM_BITMAP == aFormat.GetNumberingType() )
+ {
+ const SvxBrushItem* pBrush = aFormat.GetBrush();
+ if(pBrush && !pBrush->GetGraphicLink().isEmpty())
+ aFormat.SetNumberingType(SvxNumType(SVX_NUM_BITMAP|LINK_TOKEN));
+ aRule.SetLevel(i, aFormat, aRule.Get(i) != nullptr);
+ }
+ }
+ if(bHtml)
+ aRule.SetFeatureFlag(SvxNumRuleFlags::ENABLE_EMBEDDED_BMP, false);
+
+ aSet.Put(SvxNumBulletItem(aRule));
+ OSL_ENSURE( GetShell().GetNumLevel() < MAXLEVEL,
+ "<SwTextShell::ExecEnterNum()> - numbered node without valid list level. Serious defect." );
+ sal_uInt16 nLevel = GetShell().GetNumLevel();
+ if( nLevel < MAXLEVEL )
+ {
+ nLevel = 1 << nLevel;
+ aSet.Put( SfxUInt16Item( SID_PARAM_CUR_NUM_LEVEL, nLevel ) );
+ }
+ }
+ else
+ {
+ SwNumRule aRule( GetShell().GetUniqueNumRuleName(),
+ // #i89178#
+ numfunc::GetDefaultPositionAndSpaceMode() );
+ SvxNumRule aSvxRule = aRule.MakeSvxNumRule();
+ const bool bRightToLeft = GetShell().IsInRightToLeftText();
+
+ if ( bHtml || bRightToLeft )
+ {
+ for ( sal_uInt8 n = 0; n < MAXLEVEL; ++n )
+ {
+ SvxNumberFormat aFormat( aSvxRule.GetLevel( n ) );
+ if ( n && bHtml )
+ {
+ // 1/2" for HTML
+ aFormat.SetAbsLSpace(n * 720);
+ }
+ // #i38904# Default alignment for
+ // numbering/bullet should be rtl in rtl paragraph:
+ if ( bRightToLeft )
+ {
+ aFormat.SetNumAdjust( SvxAdjust::Right );
+ }
+ aSvxRule.SetLevel( n, aFormat, false );
+ }
+ aSvxRule.SetFeatureFlag(SvxNumRuleFlags::ENABLE_EMBEDDED_BMP, false);
+ }
+ aSet.Put( SvxNumBulletItem( std::move(aSvxRule) ) );
+ }
+
+ aSet.Put( SfxBoolItem( SID_PARAM_NUM_PRESET,false ));
+
+ // Before the dialogue of the HTML mode will be dropped at the Docshell.
+ pDocSh->PutItem(SfxUInt16Item(SID_HTML_MODE, ::GetHtmlMode(pDocSh)));
+
+ SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
+ weld::Window *pParent = rReq.GetFrameWeld();
+ VclPtr<AbstractNumBulletDialog> pDlg(pFact->CreateSvxNumBulletTabDialog(pParent, aSet, GetShell()));
+ const SfxStringItem* pPageItem = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ if ( pPageItem )
+ pDlg->SetCurPageId( pPageItem->GetValue() );
+
+ auto pRequest = std::make_shared<SfxRequest>(rReq);
+ rReq.Ignore(); // the 'old' request is not relevant any more
+
+ pDlg->StartExecuteAsync([pDlg, pNumRuleAtCurrentSelection, pRequest, this](sal_Int32 nResult){
+ if (RET_OK == nResult)
+ {
+ const SvxNumBulletItem* pBulletItem = pDlg->GetOutputItemSet()->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false);
+ if (pBulletItem)
+ {
+ pRequest->AppendItem(*pBulletItem);
+ pRequest->Done();
+ SvxNumRule& rSetRule = const_cast<SvxNumRule&>(pBulletItem->GetNumRule());
+ rSetRule.UnLinkGraphics();
+ SwNumRule aSetRule(pNumRuleAtCurrentSelection != nullptr
+ ? pNumRuleAtCurrentSelection->GetName()
+ : GetShell().GetUniqueNumRuleName(),
+ numfunc::GetDefaultPositionAndSpaceMode());
+ aSetRule.SetSvxRule(rSetRule, GetShell().GetDoc());
+ aSetRule.SetAutoRule(true);
+ // No start of new list, if an existing list style is edited.
+ // Otherwise start a new list.
+ const bool bCreateList = (pNumRuleAtCurrentSelection == nullptr);
+ GetShell().SetCurNumRule(aSetRule, bCreateList);
+ }
+ // If the Dialog was leaved with OK but nothing was chosen then the
+ // numbering must be at least activated, if it is not already.
+ else if (pNumRuleAtCurrentSelection == nullptr
+ && (pBulletItem = pDlg->GetInputItemSet()->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false)))
+ {
+ pRequest->AppendItem(*pBulletItem);
+ pRequest->Done();
+ const SvxNumRule& rSetRule = pBulletItem->GetNumRule();
+ SwNumRule aSetRule(
+ GetShell().GetUniqueNumRuleName(),
+ numfunc::GetDefaultPositionAndSpaceMode());
+ aSetRule.SetSvxRule(rSetRule, GetShell().GetDoc());
+ aSetRule.SetAutoRule(true);
+ // start new list
+ GetShell().SetCurNumRule(aSetRule, true);
+ }
+ }
+ else if (RET_USER == nResult)
+ GetShell().DelNumRules();
+ pDlg->disposeOnce();
+ });
+ }
+ break;
+
+ default:
+ OSL_FAIL("wrong dispatcher");
+ return;
+ }
+}
+
+
+void SwTextShell::ExecSetNumber(SfxRequest const &rReq)
+{
+ const sal_uInt16 nSlot = rReq.GetSlot();
+ switch ( nSlot )
+ {
+ case FN_SVX_SET_NUMBER:
+ case FN_SVX_SET_BULLET:
+ case FN_SVX_SET_OUTLINE:
+ {
+ const SfxUInt16Item* pItem = rReq.GetArg<SfxUInt16Item>(nSlot);
+ if ( pItem != nullptr )
+ {
+ const sal_uInt16 nChosenItemIdx = pItem->GetValue();
+ svx::sidebar::NBOType nNBOType = svx::sidebar::NBOType::Bullets;
+ if ( nSlot == FN_SVX_SET_NUMBER )
+ nNBOType = svx::sidebar::NBOType::Numbering;
+ else if ( nSlot == FN_SVX_SET_OUTLINE )
+ nNBOType = svx::sidebar::NBOType::Outline;
+
+ svx::sidebar::NBOTypeMgrBase* pNBOTypeMgr = svx::sidebar::NBOutlineTypeMgrFact::CreateInstance( nNBOType );
+
+ if ( pNBOTypeMgr != nullptr )
+ {
+ const SwNumRule* pNumRuleAtCurrentSelection = GetShell().GetNumRuleAtCurrentSelection();
+ sal_uInt16 nActNumLvl = USHRT_MAX;
+ if ( pNumRuleAtCurrentSelection != nullptr )
+ {
+ const sal_uInt16 nLevel = GetShell().GetNumLevel();
+ if ( nLevel < MAXLEVEL )
+ {
+ nActNumLvl = 1 << nLevel;
+ }
+ }
+ SwNumRule aNewNumRule(
+ pNumRuleAtCurrentSelection != nullptr ? pNumRuleAtCurrentSelection->GetName() : GetShell().GetUniqueNumRuleName(),
+ numfunc::GetDefaultPositionAndSpaceMode() );
+ SvxNumRule aNewSvxNumRule = pNumRuleAtCurrentSelection != nullptr
+ ? pNumRuleAtCurrentSelection->MakeSvxNumRule()
+ : aNewNumRule.MakeSvxNumRule();
+
+ OUString aNumCharFormat, aBulletCharFormat;
+ SwStyleNameMapper::FillUIName( RES_POOLCHR_NUM_LEVEL, aNumCharFormat );
+ SwStyleNameMapper::FillUIName( RES_POOLCHR_BULLET_LEVEL, aBulletCharFormat );
+
+ SfxAllItemSet aSet( GetPool() );
+ aSet.Put( SfxStringItem( SID_NUM_CHAR_FMT, aNumCharFormat ) );
+ aSet.Put( SfxStringItem( SID_BULLET_CHAR_FMT, aBulletCharFormat ) );
+ aSet.Put( SvxNumBulletItem( aNewSvxNumRule, SID_ATTR_NUMBERING_RULE ) );
+
+ pNBOTypeMgr->SetItems( &aSet );
+ pNBOTypeMgr->ApplyNumRule( aNewSvxNumRule, nChosenItemIdx - 1, nActNumLvl );
+
+ aNewNumRule.SetSvxRule( aNewSvxNumRule, GetShell().GetDoc() );
+ aNewNumRule.SetAutoRule( true );
+ const bool bCreateNewList = ( pNumRuleAtCurrentSelection == nullptr );
+ GetShell().SetCurNumRule( aNewNumRule, bCreateNewList );
+ }
+ }
+ else if (nSlot == FN_SVX_SET_OUTLINE)
+ {
+ // no outline provided: launch dialog to request a specific outline
+ SfxBindings& rBindings = GetView().GetViewFrame().GetBindings();
+ const SfxStringItem aPage(FN_PARAM_1, "outlinenum");
+ const SfxPoolItem* aItems[] = { &aPage, nullptr };
+ rBindings.Execute(SID_OUTLINE_BULLET, aItems);
+ }
+ }
+ break;
+
+ default:
+ OSL_ENSURE(false, "wrong Dispatcher");
+ return;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */