diff options
Diffstat (limited to 'sw/source/uibase/shells')
29 files changed, 22380 insertions, 0 deletions
diff --git a/sw/source/uibase/shells/annotsh.cxx b/sw/source/uibase/shells/annotsh.cxx new file mode 100644 index 000000000..1ba67da00 --- /dev/null +++ b/sw/source/uibase/shells/annotsh.cxx @@ -0,0 +1,1856 @@ +/* -*- 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/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 (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(OUStringToOString(pItem->GetValue(), RTL_TEXTENCODING_UTF8)); + } + + 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 SfxPoolItem* pState = m_rView.GetSlotState(nWhich); + if (pState) + rSet.Put(SfxBoolItem(nWhich, static_cast<const SfxBoolItem*>(pState)->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 : + { + SvtCTLOptions aCTLOptions; + bool bEnabled = aCTLOptions.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()->IsProtected()) && + ( (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: + { + const SfxPoolItem &rItem = m_rView.GetWrtShell().GetDoc()->GetDefault( + GetWhichOfScript( RES_CHRATR_LANGUAGE, + SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage())) ); + LanguageType nLang = static_cast<const SvxLanguageItem &>( + 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 *pSfxViewFrame = m_rView.GetViewFrame(); + SwWrtShell &rSh = m_rView.GetWrtShell(); + + while( nWhich ) + { + switch ( nWhich ) + { + case SID_UNDO: + { + sal_uInt16 nCount = pUndoManager ? pUndoManager->GetUndoActionCount() : 0; + if ( nCount ) + pSfxViewFrame->GetSlotState( nWhich, pSfxViewFrame->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 ) + pSfxViewFrame->GetSlotState( nWhich, pSfxViewFrame->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: + { + pSfxViewFrame->GetSlotState( nWhich, pSfxViewFrame->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 000000000..7f422172e --- /dev/null +++ b/sw/source/uibase/shells/basesh.cxx @@ -0,0 +1,3187 @@ +/* -*- 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 <IDocumentSettingAccess.hxx> +#include <IDocumentUndoRedo.hxx> +#include <swabstdlg.hxx> +#include <modcfg.hxx> +#include <svx/fmshell.hxx> +#include <SwRewriter.hxx> +#include <GraphicSizeCheck.hxx> +#include <svx/galleryitem.hxx> +#include <sfx2/devtools/DevelopmentToolChildWindow.hxx> +#include <com/sun/star/gallery/GalleryItemType.hpp> +#include <memory> + +#include <svx/unobrushitemhelper.hxx> +#include <comphelper/scopeguard.hxx> +#include <comphelper/lok.hxx> +#include <osl/diagnose.h> + +#include <svx/svxdlg.hxx> + +#include <shellres.hxx> +#include <UndoTable.hxx> + +#include <ndtxt.hxx> +#include <UndoManager.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> +#include <svx/AccessibilityCheckDialog.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()->GetNode()); + 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()->GetNode()); + 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( CRSR_SKIP_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* pViewFrame = pView->GetViewFrame(); + uno::Reference< frame::XDispatchRecorder > xRecorder = + pViewFrame->GetBindings().GetRecorder(); + if(xRecorder.is()) { + SfxRequest aReq( pViewFrame, 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* pViewFrame = pView->GetViewFrame(); + uno::Reference< frame::XDispatchRecorder > xRecorder = + pViewFrame->GetBindings().GetRecorder(); + if(xRecorder.is()) { + SfxRequest aReq( pViewFrame, 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()); + + 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 *const pViewFrame( 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(); + + 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(); + 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)) ); + } + else if (nUndoId == SwUndoId::INSFMTATTR) + { + rWrtShell.GetDoc()->GetDocShell()->GetStyleSheetPool()->Broadcast(SfxHint(SfxHintId::StyleSheetModified)); + } + + if (pViewFrame) { pViewFrame->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(); + } +} + +// 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: + { + 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_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* pViewFrame = GetView().GetViewFrame(); + if( SfxRequest::HasMacroRecorder(pViewFrame) ) + { + SfxRequest aReq( pViewFrame, 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* pVFrame = GetView().GetViewFrame(); + pVFrame->ToggleChildWindow( nId ); + pVFrame->GetBindings().Invalidate( SID_IMAP ); + + if ( pVFrame->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* pVFrame = GetView().GetViewFrame(); + pVFrame->ToggleChildWindow( nId ); + pVFrame->GetBindings().Invalidate( SID_CONTOUR_DLG ); + + SelectionType nSel = rSh.GetSelectionType(); + if ( pVFrame->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, rSh.GetPhyPageNum()); + 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* pVFrame = 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 = pVFrame->HasChildWindow(nId) ? + pVFrame->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 = pVFrame->HasChildWindow(nId) ? + pVFrame->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 + pVFrame->GetBindings().SetState( aBool ); + } + } + m_aGrfUpdateSlots.clear(); +} + +void SwBaseShell::GetState( SfxItemSet &rSet ) +{ + SwWrtShell &rSh = GetShell(); + SfxViewFrame* pVFrame = 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 = pVFrame->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 && pVFrame->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; + } + 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->IsAutoUpdateFormat() ) + { + 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(), 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: + { + const SfxPoolItem* pColorStringItem = nullptr; + bool bIsTransparent = false; + + aBrushItem->SetGraphicPos(GPOS_NONE); + + sal_uInt16 nSlotId = (nSlot == SID_BACKGROUND_COLOR) ? SID_BACKGROUND_COLOR : SID_TABLE_CELL_BACKGROUND_COLOR; + if (pArgs && SfxItemState::SET == pArgs->GetItemState(SID_ATTR_COLOR_STR, false, &pColorStringItem)) + { + OUString sColor = static_cast<const SfxStringItem*>(pColorStringItem)->GetValue(); + if (sColor == "transparent") + { + bIsTransparent = true; + } + else + { + Color aColor(ColorTransparency, sColor.toInt32(16)); + + aBrushItem->SetColor(aColor); + + SvxColorItem aNewColorItem(nSlotId); + aNewColorItem.SetValue(aColor); + + GetView().GetViewFrame()->GetBindings().SetState(aNewColorItem); + } + } + else if (pArgs) + { + const SvxColorItem& rNewColorItem = static_cast<const SvxColorItem&>(pArgs->Get(nSlotId)); + const Color& rNewColor = rNewColorItem.GetValue(); + aBrushItem->SetColor(rNewColor); + 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->IsAutoUpdateFormat()) + { + rSh.AutoUpdateFrame(pFormat, aCoreSet); + } + else + { + rSh.SetFlyFrameAttr(aCoreSet); + } + } + else + { + SwTextFormatColl* pColl = rSh.GetCurTextFormatColl(); + + if(pColl && pColl->IsAutoUpdateFormat()) + { + 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: + { + 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(); + + OString 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_DLG: + if (pItem) + sPageId = OUStringToOString(static_cast<const SfxStringItem*>(pItem)->GetValue(), RTL_TEXTENCODING_UTF8); + 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_ACCESSIBILITY_CHECK: + { + sw::AccessibilityCheck aCheck(rSh.GetDoc()); + aCheck.check(); + std::shared_ptr<svx::AccessibilityCheckDialog> aDialog = std::make_shared<svx::AccessibilityCheckDialog>(pMDI, aCheck.getIssueCollection()); + weld::DialogController::runAsync(aDialog, [](int){}); + } + break; + + case SID_GRAPHIC_SIZE_CHECK: + { + sw::GraphicSizeCheckGUIResult aResult(rSh.GetDoc()); + svx::GenericCheckDialog aDialog(pMDI, aResult); + aDialog.run(); + } + 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()->SetName( 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 000000000..73bbc88ac --- /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 000000000..dd60a34b4 --- /dev/null +++ b/sw/source/uibase/shells/drawdlg.cxx @@ -0,0 +1,397 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <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* pDoc = pView->GetModel(); + bool bChanged = pDoc->IsChanged(); + pDoc->SetChanged(false); + + SfxItemSet aNewAttr( pDoc->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, + pDoc, + true, + false)); + + pDlg->StartExecuteAsync([bChanged, bHasMarked, pDoc, pDlg, pSh, pView, this]( + sal_Int32 nResult){ + pDoc->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 (pDoc->IsChanged()) + GetShell().SetModified(); + else if (bChanged) + pDoc->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, + pDoc, + pObj, + bHasMarked)); + + pDlg->StartExecuteAsync([bChanged, bHasMarked, pDoc, pDlg, pSh, pView, this]( + sal_Int32 nResult){ + pDoc->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 (pDoc->IsChanged()) + GetShell().SetModified(); + else if (bChanged) + pDoc->SetChanged(); + + pDlg->disposeOnce(); + }); + } + break; + + default: + break; + } + + if (pDoc->IsChanged()) + GetShell().SetModified(); + else if (bChanged) + pDoc->SetChanged(); +} + +namespace +{ + void lcl_convertStringArguments(sal_uInt16 nSlot, const std::unique_ptr<SfxItemSet>& pArgs) + { + Color aColor; + const SfxPoolItem* pItem = nullptr; + + if (SfxItemState::SET == pArgs->GetItemState(SID_ATTR_COLOR_STR, false, &pItem)) + { + OUString sColor = static_cast<const SfxStringItem*>(pItem)->GetValue(); + + if (sColor == "transparent") + aColor = COL_TRANSPARENT; + else + aColor = Color(ColorTransparency, sColor.toInt32(16)); + + switch (nSlot) + { + case SID_ATTR_LINE_COLOR: + { + XLineColorItem aLineColorItem(OUString(), aColor); + pArgs->Put(aLineColorItem); + break; + } + + case SID_ATTR_FILL_COLOR: + { + XFillColorItem aFillColorItem(OUString(), aColor); + pArgs->Put(aFillColorItem); + break; + } + } + } + else 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)) + { + XGradient aGradient = XGradient::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(rReq.GetSlot(), 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, Quadratic, Square. + // 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; + + XGradient 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 000000000..5286c85b3 --- /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)) + { + SdrGrafObj* pNewGrafObj(pSdrGrafObj->CloneSdrObject(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); + + // set in all cases - the Clone() will have copied an existing link (!) + pNewGrafObj->SetGraphicLink( + bAsLink ? aDlg.GetPath() : OUString()); + + pResult = pNewGrafObj; + } + 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(), 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* pVFrame = GetView().GetViewFrame(); + if (pArgs) + { + pVFrame->SetChildWindow(SvxFontWorkChildWindow::GetChildWindowId(), + static_cast<const SfxBoolItem&>((pArgs->Get(SID_FONTWORK))).GetValue()); + } + else + pVFrame->ToggleChildWindow( SvxFontWorkChildWindow::GetChildWindowId() ); + pVFrame->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 = dynamic_cast< const SdrTextObj* >(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 000000000..7c16bde0a --- /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 000000000..766ca0ae8 --- /dev/null +++ b/sw/source/uibase/shells/drwbassh.cxx @@ -0,0 +1,1230 @@ +/* -*- 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; + + 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 + } + } + 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()) + { + pDlg->GetName(aName); + pSelected->SetName(aName); + pSh->SetModified(); + } + } + + 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()); + + SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); + ScopedVclPtr<AbstractSvxObjectTitleDescDialog> pDlg(pFact->CreateSvxObjectTitleDescDialog(GetView().GetFrameWeld(), + aTitle, aDescription)); + + if(RET_OK == pDlg->Execute()) + { + pDlg->GetTitle(aTitle); + pDlg->GetDescription(aDescription); + + pSelected->SetTitle(aTitle); + pSelected->SetDescription(aDescription); + + 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 SwPosition* pContentPos = nullptr; + SdrView* pSdrView = pSh->GetDrawView(); + const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); + if( rMarkList.GetMarkCount() == 1 ) + { + SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); + SwFrameFormat* pFrameFormat = FindFrameFormat( pObj ); + pContentPos = pFrameFormat->GetAnchor().GetContentAnchor(); + } + + pSh->CalcBoundRect( aBoundRect, eAnchorType, + rValidation.nHRelOrient, + rValidation.nVRelOrient, + pContentPos, + 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 000000000..c84ee7bd9 --- /dev/null +++ b/sw/source/uibase/shells/drwtxtex.cxx @@ -0,0 +1,1275 @@ +/* -*- 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; + +namespace +{ + void lcl_convertStringArguments(sal_uInt16 nSlot, SfxItemSet& rArgs) + { + Color aColor; + OUString sColor; + const SfxStringItem* pItem = rArgs.GetItemIfSet(SID_ATTR_COLOR_STR, false); + if (!pItem) + return; + + sColor = pItem->GetValue(); + + if (sColor == "transparent") + aColor = COL_TRANSPARENT; + else + aColor = Color(ColorTransparency, sColor.toInt32(16)); + + switch (nSlot) + { + case SID_ATTR_CHAR_COLOR: + { + SvxColorItem aColorItem(aColor, EE_CHAR_COLOR); + rArgs.Put(aColorItem); + break; + } + + case SID_ATTR_CHAR_BACK_COLOR: + { + SvxColorItem pBackgroundItem(aColor, EE_CHAR_BKGCOLOR); + rArgs.Put(pBackgroundItem); + break; + } + } + } +} + +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(OUStringToOString(pItem->GetValue(), RTL_TEXTENCODING_UTF8)); + } + + 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 SvxFieldData* pField = pOLV->GetFieldAtCursor(); + if (const SvxURLField* pURLField = dynamic_cast<const SvxURLField*>(pField)) + { + SfxStringItem aUrl(SID_FILE_NAME, pURLField->GetURL()); + SfxStringItem aTarget(SID_TARGETNAME, pURLField->GetTargetFrame()); + SfxBoolItem aNewView(SID_OPEN_NEW_VIEW, false); + SfxBoolItem aBrowsing(SID_BROWSE, true); + GetView().GetViewFrame()->GetDispatcher()->ExecuteList( + SID_OPENDOC, SfxCallMode::SYNCHRON, { &aUrl, &aTarget, &aNewView, &aBrowsing }); + } + } + break; + + case SID_COPY_HYPERLINK_LOCATION: + { + const SvxFieldData* pField = pOLV->GetFieldAtCursor(); + 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) + { + lcl_convertStringArguments(nSlot, *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 + const SfxPoolItem& rItem = GetShell().GetDoc()->GetDefault(GetWhichOfScript( + RES_CHRATR_LANGUAGE, + SvtLanguageOptions::GetI18NScriptTypeOfLanguage(GetAppLanguage()))); + LanguageType nLang = static_cast<const SvxLanguageItem&>(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: + { + SvtCTLOptions aCTLOptions; + bool bEnabled = aCTLOptions.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)) + 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 SfxPoolItem* pState = m_rView.GetSlotState(nWhich); + if (pState) + rSet.Put(SfxBoolItem(nWhich, static_cast<const SfxBoolItem*>(pState)->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()); + + 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(); + } + + 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(); + } + + 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 ); + + 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 ); + + 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 000000000..776cd31c0 --- /dev/null +++ b/sw/source/uibase/shells/drwtxtsh.cxx @@ -0,0 +1,848 @@ +/* -*- 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 <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* pVFrame = GetView().GetViewFrame(); + if ( rReq.GetArgs() ) + { + pVFrame->SetChildWindow(SvxFontWorkChildWindow::GetChildWindowId(), + static_cast<const SfxBoolItem&>( (rReq.GetArgs()-> + Get(SID_FONTWORK))).GetValue()); + } + else + pVFrame->ToggleChildWindow(SvxFontWorkChildWindow::GetChildWindowId()); + + pVFrame->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 = dynamic_cast< const SdrTextObj* >(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 *pSfxViewFrame = GetView().GetViewFrame(); + pSfxViewFrame->ExecuteSlot(rReq, pSfxViewFrame->GetInterface()); + } +} + +// State of undo + +void SwDrawTextShell::StateUndo(SfxItemSet &rSet) +{ + if ( !IsTextEdit() ) + return; + + SfxViewFrame *pSfxViewFrame = 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()); + pSfxViewFrame->GetSlotState(nWhich, pSfxViewFrame->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 000000000..15a9a0df6 --- /dev/null +++ b/sw/source/uibase/shells/frmsh.cxx @@ -0,0 +1,1454 @@ +/* -*- 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->IsAutoUpdateFormat()) + { + 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; + } + 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() ) ) ); + + OString sDefPage; + const SfxStringItem* pDlgItem; + if(pArgs && (pDlgItem = pArgs->GetItemIfSet(FN_FORMAT_FRAME_DLG, false))) + sDefPage = OUStringToOString(pDlgItem->GetValue(), RTL_TEXTENCODING_UTF8); + + 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->IsAutoUpdateFormat()) + { + 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()); + + SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); + ScopedVclPtr<AbstractSvxObjectTitleDescDialog> pDlg( + pFact->CreateSvxObjectTitleDescDialog(GetView().GetFrameWeld(), + aTitle, aDescription )); + + if ( pDlg->Execute() == RET_OK ) + { + pDlg->GetDescription(aDescription); + pDlg->GetTitle(aTitle); + + rSh.SetObjDescription(aDescription); + rSh.SetObjTitle(aTitle); + } + } + } + break; + default: + assert(!"wrong dispatcher"); + return; + } + if ( bUpdateMgr ) + { + SwFrameFormat* pFormat = rSh.GetSelectedFrameFormat(); + if ( bCopyToFormat && pFormat && pFormat->IsAutoUpdateFormat() ) + { + 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 (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() ) + const_cast<SvxBorderLine*>(aBoxItem->GetTop())->SetColor( rNewColor ); + if ( aBoxItem->GetBottom() ) + const_cast<SvxBorderLine*>(aBoxItem->GetBottom())->SetColor( rNewColor ); + if ( aBoxItem->GetLeft() ) + const_cast<SvxBorderLine*>(aBoxItem->GetLeft())->SetColor( rNewColor ); + if ( aBoxItem->GetRight() ) + const_cast<SvxBorderLine*>(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->IsAutoUpdateFormat()) + { + 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* pDoc = rSh.GetDrawView()->GetModel(); + SfxItemSet aNewAttr(pDoc->GetItemPool()); + + // get attributes from FlyFrame + rSh.GetFlyFrameAttr(aNewAttr); + + SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); + VclPtr<AbstractSvxAreaTabDialog> pDlg(pFact->CreateSvxAreaTabDialog( + GetView().GetFrameWeld(), + &aNewAttr, + pDoc, + 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 000000000..86dde1851 --- /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 OUStringLiteral TOOLBOX_NAME = u"colorbar"; + +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(), 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->IsAutoUpdateFormat()) + { + 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 000000000..f00a10755 --- /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; } + } + + 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 000000000..0de6c4863 --- /dev/null +++ b/sw/source/uibase/shells/langhelper.cxx @@ -0,0 +1,574 @@ +/* -*- 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; + SfxItemSet aEditAttr(pOLV->GetAttribs()); + ESelection aSelection = pOLV->GetSelection(); + EditView & rEditView = pOLV->GetEditView(); + EditEngine * pEditEngine = rEditView.GetEditEngine(); + + // 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 *pViewFrame = rView.GetViewFrame(); + + if (aNewLangText == "*" ) + { + // open the dialog "Tools/Options/Language Settings - Language" + 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 const OUStringLiteral aSelectionLangPrefix(u"Current_"); + static const OUStringLiteral aParagraphLangPrefix(u"Paragraph_"); + static const OUStringLiteral aDocumentLangPrefix(u"Default_"); + + 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 ); + + // ugly hack, as it seems that EditView/EditEngine does not update their spellchecking marks + // when setting a new language attribute + if (bForSelection) + { + const SwViewOption* pVOpt = rView.GetWrtShellPtr()->GetViewOptions(); + EEControlBits nCntrl = pEditEngine->GetControlWord(); + // turn off + nCntrl &= ~EEControlBits::ONLINESPELLING; + pEditEngine->SetControlWord(nCntrl); + + //turn back on + if (pVOpt->IsOnlineSpell()) + nCntrl |= EEControlBits::ONLINESPELLING; + else + nCntrl &= ~EEControlBits::ONLINESPELLING; + pEditEngine->SetControlWord(nCntrl); + + pEditEngine->CompleteOnlineSpelling(); + rEditView.Invalidate(); + } + + 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 + pViewFrame->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 + sal_uInt16 nLangWhichId = 0; + bool bIsSingleScriptType = true; + switch (SvtLanguageOptions::GetScriptTypeOfLanguage( nLang )) + { + case SvtScriptType::LATIN : nLangWhichId = pEditEngine ? sal_uInt16(EE_CHAR_LANGUAGE) : sal_uInt16(RES_CHRATR_LANGUAGE); break; + case SvtScriptType::ASIAN : nLangWhichId = pEditEngine ? sal_uInt16(EE_CHAR_LANGUAGE_CJK) : sal_uInt16(RES_CHRATR_CJK_LANGUAGE); break; + case SvtScriptType::COMPLEX : nLangWhichId = pEditEngine ? sal_uInt16(EE_CHAR_LANGUAGE_CTL) : sal_uInt16(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 ) ); + + //Resolves: fdo#35282 Clear the language from all Text Styles, and + //fallback to default document language + const SwTextFormatColls *pColls = rWrtSh.GetDoc()->GetTextFormatColls(); + for(size_t i = 0, nCount = pColls->size(); i < nCount; ++i) + { + SwTextFormatColl &rTextColl = *(*pColls)[ i ]; + rTextColl.ResetFormatAttr(nLangWhichId); + } + //Resolves: fdo#35282 Clear the language from all Character Styles, + //and fallback to default document language + const SwCharFormats *pCharFormats = rWrtSh.GetDoc()->GetCharFormats(); + for(size_t i = 0, nCount = pCharFormats->size(); i < nCount; ++i) + { + SwCharFormat &rCharFormat = *(*pCharFormats)[ i ]; + rCharFormat.ResetFormatAttr(nLangWhichId); + } + + // #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 ); + } + + // 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 ); + } + 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, sal_uInt16 nLangWhichId ) + { + SfxItemSet aSet( rSh.GetAttrPool(), nLangWhichId, nLangWhichId ); + rSh.GetCurAttr( aSet ); + + return GetLanguage(aSet,nLangWhichId); + } + + LanguageType GetLanguage( SfxItemSet const & aSet, sal_uInt16 nLangWhichId ) + { + + LanguageType nLang = LANGUAGE_SYSTEM; + + const SfxPoolItem *pItem = nullptr; + SfxItemState nState = aSet.GetItemState( nLangWhichId, true, &pItem ); + if (nState > SfxItemState::DEFAULT && pItem) + { + // the item is set and can be used + nLang = dynamic_cast<const SvxLanguageItem&>(*pItem).GetLanguage(); + } + else if (nState == SfxItemState::DEFAULT) + { + // since the attribute is not set: retrieve the default value + nLang = dynamic_cast<const SvxLanguageItem&>(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 + sal_uInt16 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 sal_uInt16 aScriptTypes[3] = + { + RES_CHRATR_LANGUAGE, + RES_CHRATR_CJK_LANGUAGE, + RES_CHRATR_CTL_LANGUAGE + }; + nCurrentLang = LANGUAGE_NONE; + for (sal_uInt16 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 + sal_uInt16 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 sal_uInt16 aScriptTypes[3] = + { + EE_CHAR_LANGUAGE, + EE_CHAR_LANGUAGE_CJK, + EE_CHAR_LANGUAGE_CTL + }; + nCurrentLang = LANGUAGE_NONE; + for (sal_uInt16 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->GetNode().GetTextNode(); + if (pNode) + { + aText = pNode->GetText(); + if (!aText.isEmpty()) + { + sal_Int32 nEnd = pCursor->GetPoint()->nContent.GetIndex(); + // 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 000000000..cbf3008c5 --- /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 * pFrame = GetView().GetViewFrame(); + + rReq.Done(); + rSh.NumUpDown( nSlot == FN_NUM_BULLET_DOWN ); + pFrame->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 000000000..fb106cc2e --- /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 000000000..6f864ec7c --- /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 000000000..acddd3eb6 --- /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 inChartContext(const SwView& rViewShell) +{ + SidebarController* pSidebar = SidebarController::GetSidebarControllerForView(&rViewShell); + if (pSidebar) + return pSidebar->hasChartContextCurrently(); + + 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(!inChartContext(GetView())) + SwFrameShell::Activate(bMDI); + else + { + // Avoid context changes for chart during activation / deactivation. + const bool bIsContextBroadcasterEnabled (SfxShell::SetContextBroadcasterEnabled(false)); + + SwFrameShell::Activate(bMDI); + + SfxShell::SetContextBroadcasterEnabled(bIsContextBroadcasterEnabled); + } +} + +void SwOleShell::Deactivate(bool bMDI) +{ + if(!inChartContext(GetView())) + SwFrameShell::Deactivate(bMDI); + else + { + // Avoid context changes for chart 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 000000000..3aa3469db --- /dev/null +++ b/sw/source/uibase/shells/slotadd.cxx @@ -0,0 +1,133 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <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 <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 000000000..1073bf9b0 --- /dev/null +++ b/sw/source/uibase/shells/tabsh.cxx @@ -0,0 +1,1654 @@ +/* -*- 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/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 <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.StartsWithTable() && 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_BoxesInDeletedRows(SwWrtShell &rSh, const SwSelBoxes& rBoxes) +{ + // cursor and selection are there only in deleted rows in Show Changes mode + if ( rSh.GetLayout()->IsHideRedlines() ) + return false; + + // not selected or all selected rows are deleted + bool bRet = true; + SwRedlineTable::size_type nRedlinePos = 0; + if ( rBoxes.empty() ) + bRet = rSh.GetCursor()->GetNode().GetTableBox()->GetUpper()->IsDeleted(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->IsDeleted(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()->nNode.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(OUStringToOString(static_cast<const SfxStringItem *>(pItem)->GetValue(), RTL_TEXTENCODING_UTF8)); + + 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(); + SfxItemSetFixed<SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_INFO> + aCoreSet( GetPool() ); + + SfxItemSetFixed<RES_BOXATR_FORMAT, RES_BOXATR_FORMAT, + RES_BOXATR_VALUE, RES_BOXATR_VALUE> + aBoxSet( *aCoreSet.GetPool() ); + rSh.GetTableBoxFormulaAttrs( aBoxSet ); + + SfxItemState eState = aBoxSet.GetItemState(RES_BOXATR_FORMAT); + if(eState == SfxItemState::DEFAULT) + { + aCoreSet.Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE, + pFormatter->GetFormatIndex(NF_TEXT, LANGUAGE_SYSTEM))); + } + else + aCoreSet.Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE, + aBoxSet.Get( + RES_BOXATR_FORMAT ).GetValue() )); + + OUString sCurText( rSh.GetTableBoxText() ); + aCoreSet.Put( SvxNumberInfoItem( pFormatter, + aBoxSet.Get( + RES_BOXATR_VALUE).GetValue(), + sCurText, SID_ATTR_NUMBERFORMAT_INFO )); + + SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); + ScopedVclPtr<SfxAbstractDialog> pDlg(pFact->CreateNumFormatDialog(GetView().GetFrameWeld(), aCoreSet)); + + if (RET_OK == pDlg->Execute()) + { + const SvxNumberInfoItem* pNumberFormatItem + = GetView().GetDocShell()->GetItem( SID_ATTR_NUMBERFORMAT_INFO ); + + if( pNumberFormatItem ) + { + for ( sal_uInt32 key : pNumberFormatItem->GetDelFormats() ) + pNumberFormatItem->GetNumberFormatter()->DeleteEntry( key ); + } + + const SfxUInt32Item* pNumberFormatValueItem = + pDlg->GetOutputItemSet()->GetItemIfSet( + SID_ATTR_NUMBERFORMAT_VALUE, false); + if( pNumberFormatValueItem ) + { + SfxItemSetFixed<RES_BOXATR_FORMAT, RES_BOXATR_FORMAT> + aBoxFormatSet( *aCoreSet.GetPool() ); + aBoxFormatSet.Put( SwTableBoxNumFormat( + pNumberFormatValueItem->GetValue() )); + rSh.SetTableBoxFormulaAttrs( aBoxFormatSet ); + + } + } + } + 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 sal_uInt16 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* pVFrame = GetView().GetViewFrame(); + if( pVFrame ) + pVFrame->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(); + ScopedVclPtr<AbstractSplitTableDialog> pDlg(pFact->CreateSplitTableDialog(GetView().GetFrameWeld(), rSh)); + pDlg->Execute(); + rReq.AppendItem( SfxUInt16Item( FN_PARAM_1, static_cast<sal_uInt16>(pDlg->GetSplitMode()) ) ); + bCallDone = true; + } + 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* pVFrame = GetView().GetViewFrame(); + pVFrame->GetDispatcher()->Execute(FN_EDIT_FORMULA, SfxCallMode::SYNCHRON); + const sal_uInt16 nId = SwInputChild::GetChildWindowId(); + SwInputChild* pChildWin = static_cast<SwInputChild*>(pVFrame-> + 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_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_BoxesInDeletedRows( 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).getStr()); + } + } + 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).getStr()); + } + + 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 000000000..881468c5d --- /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 000000000..6f9e3aadb --- /dev/null +++ b/sw/source/uibase/shells/textfld.cxx @@ -0,0 +1,1123 @@ +/* -*- 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 <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 <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 <xmloff/odffields.hxx> +#include <IDocumentContentOperations.hxx> +#include <IDocumentRedlineAccess.hxx> +#include <IDocumentUndoRedo.hxx> +#include <svl/zforlist.hxx> +#include <svl/zformat.hxx> +#include <IMark.hxx> +#include <officecfg/Office/Compatibility.hxx> +#include <ndtxt.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()) + { + 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_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(), true)))) + { + 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; + + 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()); + 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]; + } + 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* pVFrame = GetView().GetViewFrame(); + pVFrame->ToggleChildWindow(FN_INSERT_FIELD); + bRes = pVFrame->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* pVFrame = GetView().GetViewFrame(); + if (!pVFrame->HasChildWindow(FN_INSERT_FIELD)) + pVFrame->ToggleChildWindow(FN_INSERT_FIELD); // Show dialog + + // Switch Fielddlg at a new TabPage + sal_uInt16 nId = SwFieldDlgWrapper::GetChildWindowId(); + SwFieldDlgWrapper *pWrp = static_cast<SwFieldDlgWrapper*>(pVFrame->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); + } + } + } + } + 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 : + { + nInsertType = SwFieldTypesEnum::Date; + bIsText = false; + // use long date format for Hungarian + SwPaM* pCursorPos = rSh.GetCursor(); + if( pCursorPos ) + { + LanguageType nLang = pCursorPos->GetPoint()->nNode.GetNode().GetTextNode()->GetLang(pCursorPos->GetPoint()->nContent.GetIndex()); + if (nLang == LANGUAGE_HUNGARIAN) + nInsertFormat = rSh.GetNumberFormatter()->GetFormatIndex(NF_DATE_SYSTEM_LONG, nLang); + } + goto FIELD_INSERT; + } + case FN_INSERT_FLD_TIME : + nInsertType = SwFieldTypesEnum::Time; + 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: + { + 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"; + bool bSuccess = rSh.GetDoc()->getIDocumentContentOperations().InsertString(*pCursorPos, vEnSpaces); + if(bSuccess) + { + IDocumentMarkAccess* pMarksAccess = rSh.GetDoc()->getIDocumentMarkAccess(); + SwPaM aFieldPam(pCursorPos->GetPoint()->nNode, pCursorPos->GetPoint()->nContent.GetIndex() - vEnSpaces.getLength(), + pCursorPos->GetPoint()->nNode, pCursorPos->GetPoint()->nContent.GetIndex()); + pMarksAccess->makeFieldBookmark(aFieldPam, OUString(), ODF_FORMTEXT, + aFieldPam.Start()); + } + } + + 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()->nNode, pCursorPos->GetPoint()->nContent.GetIndex() - ODF_FORMFIELD_DEFAULT_LENGTH, + pCursorPos->GetPoint()->nNode, pCursorPos->GetPoint()->nContent.GetIndex()); + 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; + 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_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* pVFrame = GetView().GetViewFrame(); + //#i5788# prevent closing of the field dialog while a modal dialog ( Input field dialog ) is active + if(!pVFrame->IsInModalMode() && + pVFrame->KnowsChildWindow(FN_INSERT_FIELD) && !pVFrame->HasChildWindow(FN_INSERT_FIELD_DATA_ONLY) ) + rSet.Put(SfxBoolItem( FN_INSERT_FIELD, pVFrame->HasChildWindow(nWhich))); + else + rSet.DisableItem(FN_INSERT_FIELD); + } + } + break; + + case FN_INSERT_REF_FIELD: + { + SfxViewFrame* pVFrame = GetView().GetViewFrame(); + if ( !pVFrame->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 Allow disabling comment insertion on footnote/endnote for better OOXML interoperability + else if ( rSh.IsCursorInFootnote() && !officecfg::Office::Compatibility::View::AllowCommentsInFootnotes::get() ) + { + 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()->getFieldmarkFor(aCursorPos); + if ((!pFieldBM || pFieldBM->GetFieldname() != ODF_FORMTEXT) + && aCursorPos.nContent.GetIndex() > 0) + { + SwPosition aPos(aCursorPos); + --aPos.nContent; + pFieldBM = GetShell().getIDocumentMarkAccess()->getFieldmarkFor(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(); + 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(); + 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 000000000..d229964d2 --- /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 000000000..590b9fa82 --- /dev/null +++ b/sw/source/uibase/shells/textidx.cxx @@ -0,0 +1,235 @@ +/* -*- 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> + +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* pVFrame = GetView().GetViewFrame(); + + switch( nSlot ) + { + case FN_EDIT_AUTH_ENTRY_DLG : + { + SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); + ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSwAutoMarkDialog(GetView().GetFrameWeld(), GetShell())); + pDlg->Execute(); + } + break; + case FN_INSERT_AUTH_ENTRY_DLG: + { + // no BASIC support + pVFrame->ToggleChildWindow(FN_INSERT_AUTH_ENTRY_DLG); + Invalidate(rReq.GetSlot()); + } + break; + case FN_INSERT_IDX_ENTRY_DLG: + { + pVFrame->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* pVFrame = GetView().GetViewFrame(); + SwInsertIdxMarkWrapper *pIdxMrk = static_cast<SwInsertIdxMarkWrapper*>( + pVFrame->GetChildWindow(FN_INSERT_IDX_ENTRY_DLG)); + + SfxChildWindow* pAuthMark = pVFrame->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 ); + 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( rSh.HasSelection() || 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 000000000..522b8ddbf --- /dev/null +++ b/sw/source/uibase/shells/textsh.cxx @@ -0,0 +1,1083 @@ +/* -*- 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> + +using namespace ::com::sun::star; + +#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> + +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 ) ) + { + 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_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 ); + 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(); + 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(); + 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(); + ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateFrameTabDialog("FrameDialog", + GetView().GetViewFrame(), + GetView().GetFrameWeld(), + aSet)); + if(pDlg->Execute() == RET_OK && pDlg->GetOutputItemSet()) + { + //local variable necessary at least after call of .AutoCaption() because this could be deleted at this point + SwWrtShell& rShell = GetShell(); + rShell.LockPaint(); + rShell.StartAllAction(); + rShell.StartUndo(SwUndoId::INSERT); + + const SfxItemSet* pOutSet = pDlg->GetOutputItemSet(); + aMgr.SetAttrSet(*pOutSet); + + // At first delete the selection at the ClickToEditField. + if( rShell.IsInClickToEdit() ) + rShell.DelRight(); + + aMgr.InsertFlyFrame(); + + uno::Reference< frame::XDispatchRecorder > xRecorder = + GetView().GetViewFrame()->GetBindings().GetRecorder(); + if ( xRecorder.is() ) + { + //FN_INSERT_FRAME + sal_uInt16 nAnchor = static_cast<sal_uInt16>(aMgr.GetAnchor()); + rReq.AppendItem(SfxUInt16Item(nSlot, nAnchor)); + rReq.AppendItem(SfxPointItem(FN_PARAM_1, rShell.GetObjAbsPos())); + rReq.AppendItem(SvxSizeItem(FN_PARAM_2, rShell.GetObjSize())); + rReq.Done(); + } + + GetView().AutoCaption(FRAME_CAP); + + { + SwRewriter aRewriter; + + aRewriter.AddRule(UndoArg1, SwResId(STR_FRAME)); + + rShell.EndUndo(SwUndoId::INSERT, &aRewriter); + } + rShell.EndAllAction(); + rShell.UnlockPaint(); + } + } + 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(); + + bool bCursorInHidden = false; + if( !rSh.HasMark() ) + { + rSh.Push(); + bCursorInHidden = rSh.SelectHiddenRange(); + rSh.Pop(); + } + + 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); + + 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 000000000..e28877c91 --- /dev/null +++ b/sw/source/uibase/shells/textsh1.cxx @@ -0,0 +1,2260 @@ +/* -*- 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/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 <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 <authfld.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, SfxRequest *pReq); + +static void sw_CharDialog(SwWrtShell &rWrtSh, bool bUseDialog, 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, + XATTR_FILLSTYLE, XATTR_FILLCOLOR, + 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(OUStringToOString(pItem->GetValue(), RTL_TEXTENCODING_UTF8)); + } + } + + 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, pRequest](sal_Int32 nResult){ + if (nResult == RET_OK) + { + sw_CharDialogResult(pDlg->GetOutputItemSet(), rWrtSh, pCoreSet, bSel, bSelectionPut, pRequest.get()); + } + pDlg->disposeOnce(); + }); + } + else if (pArgs) + { + sw_CharDialogResult(pArgs, rWrtSh, pCoreSet, bSel, bSelectionPut, pReq); + } +} + +static void sw_CharDialogResult(const SfxItemSet* pSet, SwWrtShell &rWrtSh, std::shared_ptr<SfxItemSet> const & pCoreSet, bool bSel, bool bSelectionPut, SfxRequest *pReq) +{ + SfxItemSet aTmpSet( *pSet ); + ::ConvertAttrGenToChar(aTmpSet, *pCoreSet); + + 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->IsAutoUpdateFormat()) + { + 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(); + } + +} + +static short lcl_AskRedlineFlags(weld::Window *pWin) +{ + std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pWin, "modules/swriter/ui/queryredlinedialog.ui")); + std::unique_ptr<weld::MessageDialog> xQBox(xBuilder->weld_message_dialog("QueryRedlineDialog")); + return xQBox->run(); +} + +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->IsAutoUpdateFormat()) + { + 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 = static_cast<const SfxUInt16Item&>(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(static_cast<const SfxUInt16Item&>(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 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 + auto xInfo(std::make_unique<weld::GenericDialogController>( + rWrtSh.GetView().GetFrameWeld(), "modules/swriter/ui/inforeadonlydialog.ui", + "InfoReadonlyDialog")); + xInfo->run(); + 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 *pViewFrame = GetView().GetViewFrame(); + + if (aNewLangText == "*") + { + // open the dialog "Tools/Options/Language Settings - Language" + // 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 const OUStringLiteral aSelectionLangPrefix(u"Current_"); + static const OUStringLiteral aParagraphLangPrefix(u"Paragraph_"); + static const OUStringLiteral aDocumentLangPrefix(u"Default_"); + + 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 + pViewFrame->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( CRSR_SKIP_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_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: + { + if ( pItem ) + { + OUString sName = static_cast<const SfxStringItem*>(pItem)->GetValue(); + rWrtSh.SetBookmark( vcl::KeyCode(), sName ); + } + else + { + SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); + ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSwInsertBookmarkDlg(GetView().GetFrameWeld(), rWrtSh)); + VclAbstractDialog::AsyncContext aContext; + aContext.maEndDialogFn = [](sal_Int32){}; + pDlg->StartExecuteAsync(aContext); + } + + break; + } + case FN_DELETE_BOOKMARK: + { + 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_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 ); + aFlags.bWithRedlining = false; + + SfxViewFrame* pVFrame = GetView().GetViewFrame(); + if (pVFrame->HasChildWindow(FN_REDLINE_ACCEPT)) + pVFrame->ToggleChildWindow(FN_REDLINE_ACCEPT); + + SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); + ScopedVclPtr<AbstractSwModalRedlineAcceptDlg> xDlg(pFact->CreateSwModalRedlineAcceptDlg(GetView().GetEditWin().GetFrameWeld())); + + switch (lcl_AskRedlineFlags(GetView().GetFrameWeld())) + { + case RET_OK: + { + xDlg->AcceptAll(true); + SfxRequest aReq( pVFrame, FN_AUTOFORMAT_APPLY ); + aReq.Done(); + rReq.Ignore(); + break; + } + + case RET_CANCEL: + xDlg->AcceptAll(false); + rReq.Ignore(); + break; + + case 102: + xDlg->Execute(); + rReq.Done(); + break; + } + } + 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 ); + 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() ); + rWrtSh.EndAllAction(); + rReq.Done(); + } + } + break; + case FN_EDIT_FORMULA: + { + const sal_uInt16 nId = SwInputChild::GetChildWindowId(); + SfxViewFrame* pVFrame = GetView().GetViewFrame(); + if(pItem) + { + //if the ChildWindow is active it has to be removed + if( pVFrame->HasChildWindow( nId ) ) + { + pVFrame->ToggleChildWindow( nId ); + pVFrame->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(); + pVFrame->ToggleChildWindow( nId ); + if( !pVFrame->HasChildWindow( nId ) ) + pVFrame->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, nSlot, pArgs, &rReq ); + } + break; + case SID_CHAR_DLG_FOR_PARAGRAPH: + { + rWrtSh.Push(); //save current cursor + SwLangHelper::SelectCurrentPara( rWrtSh ); + sw_CharDialog( rWrtSh, bUseDialog, nSlot, pArgs, &rReq ); + rWrtSh.Pop(SwCursorShell::PopMode::DeleteCurrent); // restore old cursor + } + 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_LR_SPACE ).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() ) + { + OString sDefPage; + if (pItem) + sDefPage = OUStringToOString(static_cast<const SfxStringItem*>(pItem)->GetValue(), RTL_TEXTENCODING_UTF8); + + 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))); + aParaMargin.SetWhich( RES_LR_SPACE); + aCoreSet.Put(aParaMargin); + + 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 XFillGradientItem* pTempGradItem = pSet->GetItem<XFillGradientItem>(XATTR_FILLGRADIENT); + 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); + } + + const XFillHatchItem* pTempHatchItem = pSet->GetItem<XFillHatchItem>(XATTR_FILLHATCH); + 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: + { + Color aSet; + const SfxStringItem* pColorStringItem = nullptr; + bool bHasItem = false; + + if(pItem) + { + aSet = static_cast<const SvxColorItem*>(pItem)->GetValue(); + bHasItem = true; + } + else if (pArgs && (pColorStringItem = pArgs->GetItemIfSet(SID_ATTR_COLOR_STR, false))) + { + OUString sColor = pColorStringItem->GetValue(); + aSet = Color(ColorTransparency, sColor.toInt32(16)); + bHasItem = true; + } + + if (bHasItem) + { + SwEditWin& rEditWin = GetView().GetEditWin(); + rEditWin.SetWaterCanTextColor(aSet); + 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 (aSet, RES_CHRATR_COLOR)); + } + + rReq.Done(); + } + } + break; + case SID_ATTR_CHAR_COLOR_BACKGROUND: + case SID_ATTR_CHAR_COLOR_BACKGROUND_EXT: + case SID_ATTR_CHAR_COLOR_EXT: + { + Color aSet; + const SfxStringItem* pColorStringItem = nullptr; + + if (pArgs && (pColorStringItem = pArgs->GetItemIfSet(SID_ATTR_COLOR_STR, false))) + { + OUString sColor = pColorStringItem->GetValue(); + if (sColor == "transparent") + aSet = COL_TRANSPARENT; + else + aSet = Color(ColorTransparency, sColor.toInt32(16)); + } + else if (pItem) + aSet = static_cast<const SvxColorItem*>(pItem)->GetValue(); + else + aSet = COL_TRANSPARENT; + + SwEditWin& rEdtWin = GetView().GetEditWin(); + if (nSlot != SID_ATTR_CHAR_COLOR_EXT) + rEdtWin.SetWaterCanTextBackColor(aSet); + else if (pItem) + rEdtWin.SetWaterCanTextColor(aSet); + + 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 ( aSet == rBrushItem.GetColor() ) + aSet = COL_TRANSPARENT; + + ApplyCharBackground(aSet, rWrtSh); + } + else + rWrtSh.SetAttrItem( + SvxColorItem(aSet, RES_CHRATR_COLOR) ); + } + else if (nSlot == SID_ATTR_CHAR_COLOR_BACKGROUND) + { + if (!pApply || pApply->nColor != SID_ATTR_CHAR_COLOR_BACKGROUND_EXT) + { + aTempl.nColor = SID_ATTR_CHAR_COLOR_BACKGROUND_EXT; + rEdtWin.SetApplyTemplate(aTempl); + } + } + 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 = dynamic_cast<const SwFormatINetFormat&>( aSet.Get(RES_TXTATR_INETFMT) ); + 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 + rWrtSh.ClickToINetAttr(rINetFormat); + } + else + { + SwField* pField = rWrtSh.GetCurField(); + if (pField && pField->GetTyp()->Which() == SwFieldIds::TableOfAuthorities) + { + const auto& rAuthorityField = *static_cast<const SwAuthorityField*>(pField); + if (rAuthorityField.HasURL()) + { + // Bibliography entry with URL also provides a hyperlink. + const OUString& rURL + = rAuthorityField.GetAuthEntry()->GetAuthorField(AUTH_FIELD_URL); + ::LoadURL(rWrtSh, rURL, LoadUrlFlags::NewView, /*rTargetFrameName=*/OUString()); + } + } + } + } + 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* pViewFrame = GetView().GetViewFrame(); + pViewFrame->GetBindings().Invalidate(nSlot); + pViewFrame->GetBindings().Update(nSlot); + } + break; + case SID_FM_CTL_PROPERTIES: + { + SwPosition aPos(*GetShell().GetCursor()->GetPoint()); + sw::mark::IFieldmark* pFieldBM = GetShell().getIDocumentMarkAccess()->getFieldmarkFor(aPos); + if ( !pFieldBM ) + { + --aPos.nContent; + pFieldBM = GetShell().getIDocumentMarkAccess()->getFieldmarkFor(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_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 const OUStringLiteral sSpellingRule(u"Spelling_"); + static const OUStringLiteral sGrammarRule(u"Grammar_"); + + 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()); + 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(); + + rWrtSh.Replace(aTmp, false); + + 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 ) + { + switch ( nWhich ) + { + 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_EMOJI_CONTROL: + 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; + if ( rSh.GetFrameType(nullptr,true) & nNoType ) + 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_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(), nWhich) ); + } + else + { + const SvxBrushItem& aBrushItem2 = aSet.Get(RES_CHRATR_BACKGROUND); + rSet.Put( SvxColorItem(aBrushItem2.GetColor(), nWhich) ); + } + } + break; + case SID_ATTR_CHAR_COLOR_BACKGROUND_EXT: + 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 const OUStringLiteral sPhysical(u"IsPhysical"); + static const 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_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: + case SID_COPY_HYPERLINK_LOCATION: + { + 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_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) + { + // Bibliography entry with URL also provides a hyperlink. + const auto& rAuthorityField = *static_cast<const SwAuthorityField*>(pField); + bAuthorityFieldURL = rAuthorityField.HasURL(); + } + 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(); + const 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, + 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.SelectionHasBullet() && + !rSh.SelectionHasNumber()))); + 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 : + { + SvtCTLOptions aCTLOptions; + bool bEnabled = aCTLOptions.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()->getFieldmarkFor(aPos); + if ( !pFieldBM && aPos.nContent.GetIndex() > 0) + { + --aPos.nContent; + pFieldBM = GetShell().getIDocumentMarkAccess()->getFieldmarkFor(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 000000000..582a7d9a5 --- /dev/null +++ b/sw/source/uibase/shells/textsh2.cxx @@ -0,0 +1,253 @@ +/* -*- 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* pViewFrame = GetView().GetViewFrame(); + uno::Reference< XDispatchRecorder > xRecorder = + pViewFrame->GetBindings().GetRecorder(); + if ( xRecorder.is() ) + { + SfxRequest aReq( pViewFrame, 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() ) + { + Reference <XResultSet> xResSet = pDBStruct->xCursor; + pDlg->DataToDoc( pDBStruct->aSelection, xSource, xConnection, xResSet); + } + } + if ( bDispose ) + ::comphelper::disposeComponent(xConnection); + } + + delete pDBStruct; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/uibase/shells/txtattr.cxx b/sw/source/uibase/shells/txtattr.cxx new file mode 100644 index 000000000..b42dcdc8a --- /dev/null +++ b/sw/source/uibase/shells/txtattr.cxx @@ -0,0 +1,844 @@ +/* -*- 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 ); + if(eEscape == SvxEscapement::Superscript) + aEscape.GetEsc() = DFLT_ESC_AUTO_SUPER; + else if(eEscape == SvxEscapement::Subscript) + aEscape.GetEsc() = DFLT_ESC_AUTO_SUB; + 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->IsAutoUpdateFormat() ) + 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->IsAutoUpdateFormat()) + { + 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_LR_SPACE); + if( eState >= SfxItemState::DEFAULT ) + { + SvxLRSpaceItem aLR = aCoreSet.Get( RES_LR_SPACE ); + 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 ( !SW_MOD()->GetCTLOptions().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 000000000..f8ec0d7a6 --- /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( CRSR_SKIP_CELLS, bSelect, 1, false, true ); + break; + case FN_CHAR_RIGHT: + rSh.Right( CRSR_SKIP_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 000000000..34a95d13e --- /dev/null +++ b/sw/source/uibase/shells/txtnum.cxx @@ -0,0 +1,322 @@ +/* -*- 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<SfxAbstractTabDialog> pDlg(pFact->CreateSvxNumBulletTabDialog(pParent, &aSet, GetShell())); + const SfxStringItem* pPageItem = rReq.GetArg<SfxStringItem>(FN_PARAM_1); + if ( pPageItem ) + pDlg->SetCurPageId( OUStringToOString( pPageItem->GetValue(), RTL_TEXTENCODING_UTF8 ) ); + + auto pRequest = std::make_shared<SfxRequest>(rReq); + rReq.Ignore(); // the 'old' request is not relevant any more + + pDlg->StartExecuteAsync([aSet, 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 = aSet.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 ); + } + } + } + break; + + default: + OSL_ENSURE(false, "wrong Dispatcher"); + return; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |