diff options
Diffstat (limited to 'sw/source/uibase/shells')
30 files changed, 4767 insertions, 2063 deletions
diff --git a/sw/source/uibase/shells/annotsh.cxx b/sw/source/uibase/shells/annotsh.cxx index cce25927afbc..d6f018e98ac6 100644 --- a/sw/source/uibase/shells/annotsh.cxx +++ b/sw/source/uibase/shells/annotsh.cxx @@ -31,7 +31,9 @@ #include <sfx2/objface.hxx> #include <sfx2/viewfrm.hxx> #include <sfx2/bindings.hxx> +#include <sfx2/dispatch.hxx> #include <sfx2/request.hxx> +#include <editeng/editund2.hxx> #include <editeng/eeitem.hxx> #include <editeng/flstitem.hxx> #include <editeng/spltitem.hxx> @@ -84,6 +86,7 @@ #include <svl/itempool.hxx> #include <editeng/outliner.hxx> #include <editeng/editview.hxx> +#include <osl/diagnose.h> #include <svl/languageoptions.hxx> @@ -125,19 +128,21 @@ SfxItemPool* SwAnnotationShell::GetAnnotationPool(SwView const & rV) } SwAnnotationShell::SwAnnotationShell( SwView& r ) - : rView(r) + : m_rView(r) { - SetPool(SwAnnotationShell::GetAnnotationPool(rView)); + 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 = rView.GetPostItMgr(); + SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr(); if ( !pPostItMgr || !pPostItMgr->HasActiveSidebarWin() ) { @@ -150,7 +155,7 @@ SfxUndoManager* SwAnnotationShell::GetUndoManager() void SwAnnotationShell::Exec( SfxRequest &rReq ) { //TODO: clean this up!!!! - SwPostItMgr* pPostItMgr = rView.GetPostItMgr(); + SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr(); if ( !pPostItMgr || !pPostItMgr->HasActiveSidebarWin() ) return; @@ -158,8 +163,8 @@ void SwAnnotationShell::Exec( SfxRequest &rReq ) SfxItemSet aEditAttr(pOLV->GetAttribs()); SfxItemSet aNewAttr(*aEditAttr.GetPool(), aEditAttr.GetRanges()); - sal_uInt16 nSlot = rReq.GetSlot(); - sal_uInt16 nWhich = GetPool().GetWhich(nSlot); + const sal_uInt16 nSlot = rReq.GetSlot(); + const sal_uInt16 nWhich = GetPool().GetWhichIDFromSlotID(nSlot); const SfxItemSet *pNewAttrs = rReq.GetArgs(); sal_uInt16 nEEWhich = 0; switch (nSlot) @@ -201,7 +206,7 @@ void SwAnnotationShell::Exec( SfxRequest &rReq ) case SID_ATTR_PARA_LINESPACE: { SvxLineSpacingItem aParaMargin = static_cast<const SvxLineSpacingItem&>(pNewAttrs->Get( - GetPool().GetWhich(nSlot))); + GetPool().GetWhichIDFromSlotID(nSlot))); aParaMargin.SetWhich( EE_PARA_SBL ); aNewAttr.Put(aParaMargin); @@ -211,7 +216,7 @@ void SwAnnotationShell::Exec( SfxRequest &rReq ) case SID_ATTR_PARA_ULSPACE: { SvxULSpaceItem aULSpace = static_cast<const SvxULSpaceItem&>(pNewAttrs->Get( - GetPool().GetWhich(nSlot))); + GetPool().GetWhichIDFromSlotID(nSlot))); aULSpace.SetWhich( EE_PARA_ULSPACE ); aNewAttr.Put( aULSpace ); rReq.Done(); @@ -220,8 +225,9 @@ void SwAnnotationShell::Exec( SfxRequest &rReq ) case FN_GROW_FONT_SIZE: case FN_SHRINK_FONT_SIZE: { - const SvxFontListItem* pFontListItem = static_cast< const SvxFontListItem* > - ( SfxObjectShell::Current()->GetItem( SID_ATTR_CHAR_FONTLIST ) ); + 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 ); } @@ -296,6 +302,13 @@ void SwAnnotationShell::Exec( SfxRequest &rReq ) 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); @@ -383,7 +396,7 @@ void SwAnnotationShell::Exec( SfxRequest &rReq ) case FN_INSERT_NNBSP: case SID_INSERT_RLM : case SID_INSERT_LRM : - case SID_INSERT_ZWNBSP : + case SID_INSERT_WJ : case SID_INSERT_ZWSP: { sal_Unicode cIns = 0; @@ -396,7 +409,7 @@ void SwAnnotationShell::Exec( SfxRequest &rReq ) 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_ZWNBSP: cIns = CHAR_ZWNBSP; break; + case SID_INSERT_WJ: cIns = CHAR_WJ; break; } pOLV->InsertText( OUString(cIns)); rReq.Done(); @@ -413,18 +426,18 @@ void SwAnnotationShell::Exec( SfxRequest &rReq ) const SfxPoolItem* pItem = nullptr; if (pNewAttrs) pNewAttrs->GetItemState(nSlot, false, &pItem ); - if (pPostItMgr->GetActiveSidebarWin()->GetLayoutStatus()!=SwPostItHelper::DELETED) + if (pItem && pPostItMgr->GetActiveSidebarWin()->GetLayoutStatus()!=SwPostItHelper::DELETED) pOLV->InsertText(static_cast<const SfxStringItem *>(pItem)->GetValue()); break; } case FN_FORMAT_FOOTNOTE_DLG: { - rView.ExecFormatFootnote(); + m_rView.ExecFormatFootnote(); break; } case FN_NUMBERING_OUTLINE_DLG: { - rView.ExecNumberingOutline(GetPool()); + m_rView.ExecNumberingOutline(GetPool()); rReq.Done(); } break; @@ -435,10 +448,11 @@ void SwAnnotationShell::Exec( SfxRequest &rReq ) break; case FN_WORDCOUNT_DIALOG: { - rView.UpdateWordCount(this, nSlot); + 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(); @@ -451,7 +465,7 @@ void SwAnnotationShell::Exec( SfxRequest &rReq ) FieldUnit eMetric = ::GetDfltMetric(dynamic_cast<SwWebView*>( pView) != nullptr ); SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, eMetric)); */ - SfxItemSet aDlgAttr(GetPool(), svl::Items<XATTR_FILLSTYLE, XATTR_FILLCOLOR, EE_ITEMS_START, EE_ITEMS_END>{}); + 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. @@ -459,24 +473,35 @@ void SwAnnotationShell::Exec( SfxRequest &rReq ) aDlgAttr.Put( SvxKerningItem(0, RES_CHRATR_KERNING) ); SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); - ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateSwCharDlg(rView.GetFrameWeld(), rView, aDlgAttr, SwCharDlgMode::Ann)); + VclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateSwCharDlg(m_rView.GetFrameWeld(), m_rView, aDlgAttr, SwCharDlgMode::Ann)); if (nSlot == SID_CHAR_DLG_EFFECT) { pDlg->SetCurPageId("fonteffects"); } - else if (pItem) + if (nSlot == SID_CHAR_DLG_POSITION) { - pDlg->SetCurPageId(OUStringToOString(pItem->GetValue(), RTL_TEXTENCODING_UTF8)); + pDlg->SetCurPageId("position"); } - - sal_uInt16 nRet = pDlg->Execute(); - if(RET_OK == nRet ) + else if (pItem) { - rReq.Done( *( pDlg->GetOutputItemSet() ) ); - aNewAttr.Put(*pDlg->GetOutputItemSet()); + pDlg->SetCurPageId(pItem->GetValue()); } - if(RET_OK != nRet) - return ; + + auto xRequest = std::make_shared<SfxRequest>(rReq); + rReq.Ignore(); // the 'old' request is not relevant any more + pDlg->StartExecuteAsync( + [this, pDlg, xRequest=std::move(xRequest), nEEWhich, aNewAttr2=aNewAttr, pOLV] (sal_Int32 nResult) mutable ->void + { + if (nResult == RET_OK) + { + xRequest->Done( *( pDlg->GetOutputItemSet() ) ); + aNewAttr2.Put(*pDlg->GetOutputItemSet()); + ExecPost(*xRequest, nEEWhich, aNewAttr2, pOLV); + } + pDlg->disposeOnce(); + } + ); + return; } else aNewAttr.Put(*pArgs); @@ -493,11 +518,10 @@ void SwAnnotationShell::Exec( SfxRequest &rReq ) FieldUnit eMetric = ::GetDfltMetric(dynamic_cast<SwWebView*>( pView) != nullptr ); SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, eMetric)); */ - SfxItemSet aDlgAttr( - GetPool(), - svl::Items< + SfxItemSetFixed< EE_ITEMS_START, EE_ITEMS_END, - SID_ATTR_PARA_HYPHENZONE, SID_ATTR_PARA_WIDOWS>{}); + SID_ATTR_PARA_HYPHENZONE, SID_ATTR_PARA_WIDOWS> + aDlgAttr( GetPool() ); aDlgAttr.Put(aEditAttr); @@ -508,7 +532,7 @@ void SwAnnotationShell::Exec( SfxRequest &rReq ) aDlgAttr.Put( SvxOrphansItem( 0, RES_PARATR_ORPHANS ) ); SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); - ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateSwParaDlg(rView.GetFrameWeld(), rView, aDlgAttr, true)); + ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateSwParaDlg(m_rView.GetFrameWeld(), m_rView, aDlgAttr, true)); sal_uInt16 nRet = pDlg->Execute(); if(RET_OK == nRet) { @@ -525,7 +549,7 @@ void SwAnnotationShell::Exec( SfxRequest &rReq ) case SID_AUTOSPELL_CHECK: { - rView.ExecuteSlot(rReq); + m_rView.ExecuteSlot(rReq); break; } case SID_ATTR_PARA_LEFT_TO_RIGHT: @@ -539,15 +563,14 @@ void SwAnnotationShell::Exec( SfxRequest &rReq ) if( !static_cast<const SfxBoolItem*>(pPoolItem)->GetValue() ) bLeftToRight = !bLeftToRight; } - SfxItemSet aAttr( - *aNewAttr.GetPool(), - svl::Items< + SfxItemSetFixed< EE_PARA_WRITINGDIR, EE_PARA_WRITINGDIR, - EE_PARA_JUST, EE_PARA_JUST>{}); + EE_PARA_JUST, EE_PARA_JUST> + aAttr( *aNewAttr.GetPool() ); SvxAdjust nAdjust = SvxAdjust::Left; - if( SfxItemState::SET == aEditAttr.GetItemState(EE_PARA_JUST, true, &pPoolItem ) ) - nAdjust = static_cast<const SvxAdjustItem*>(pPoolItem)->GetAdjust(); + if( const SvxAdjustItem* pAdjustItem = aEditAttr.GetItemIfSet(EE_PARA_JUST ) ) + nAdjust = pAdjustItem->GetAdjust(); if( bLeftToRight ) { @@ -566,19 +589,36 @@ void SwAnnotationShell::Exec( SfxRequest &rReq ) } } + ExecPost(rReq, nEEWhich, aNewAttr, pOLV ); +} + +void SwAnnotationShell::ExecPost( SfxRequest& rReq, sal_uInt16 nEEWhich, SfxItemSet& rNewAttr, OutlinerView* pOLV ) +{ + const SfxItemSet *pNewAttrs = rReq.GetArgs(); + const sal_uInt16 nSlot = rReq.GetSlot(); + const sal_uInt16 nWhich = GetPool().GetWhichIDFromSlotID(nSlot); + if(nEEWhich && pNewAttrs) { - aNewAttr.Put(pNewAttrs->Get(nWhich).CloneSetWhich(nEEWhich)); + rNewAttr.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); + if (tools::Rectangle() != aOutRect && rNewAttr.Count()) + pOLV->SetAttribs(rNewAttr); - rView.GetViewFrame()->GetBindings().InvalidateAll(false); + m_rView.GetViewFrame().GetBindings().InvalidateAll(false); if ( pOLV->GetOutliner()->IsModified() ) - rView.GetWrtShell().SetModified(); - + m_rView.GetWrtShell().SetModified(); } void SwAnnotationShell::GetState(SfxItemSet& rSet) @@ -588,7 +628,7 @@ void SwAnnotationShell::GetState(SfxItemSet& rSet) //SID_ATTR_PARA_ADJUST //SID_ATTR_PARA_ADJUST_BLOCK - SwPostItMgr* pPostItMgr = rView.GetPostItMgr(); + SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr(); if ( !pPostItMgr || !pPostItMgr->HasActiveSidebarWin() ) return; @@ -725,8 +765,7 @@ void SwAnnotationShell::GetState(SfxItemSet& rSet) else if (nWhich==SID_ATTR_PARA_ADJUST_BLOCK) eAdjust = SvxAdjust::Block; - const SfxPoolItem *pAdjust = nullptr; - aEditAttr.GetItemState( EE_PARA_JUST, false, &pAdjust); + const SvxAdjustItem *pAdjust = aEditAttr.GetItemIfSet( EE_PARA_JUST, false ); if( !pAdjust || IsInvalidItem( pAdjust )) { @@ -734,7 +773,7 @@ void SwAnnotationShell::GetState(SfxItemSet& rSet) } else { - if ( eAdjust == static_cast<const SvxAdjustItem*>(pAdjust)->GetAdjust()) + if ( eAdjust == pAdjust->GetAdjust()) rSet.Put( SfxBoolItem( nWhich, true )); else rSet.InvalidateItem( nWhich ); @@ -742,19 +781,21 @@ void SwAnnotationShell::GetState(SfxItemSet& rSet) 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 SfxPoolItem *pLSpace = nullptr; - aEditAttr.GetItemState( EE_PARA_SBL, false, &pLSpace ); + const SvxLineSpacingItem *pLSpace = aEditAttr.GetItemIfSet( EE_PARA_SBL, false ); if( !pLSpace || IsInvalidItem( pLSpace )) { @@ -762,18 +803,21 @@ void SwAnnotationShell::GetState(SfxItemSet& rSet) } else { - if( nLSpace == static_cast<const SvxLineSpacingItem*>(pLSpace)->GetPropLineSpace() ) + if( nLSpace == pLSpace->GetPropLineSpace() ) rSet.Put( SfxBoolItem( nWhich, true )); else - rSet.InvalidateItem( nWhich ); + { + // tdf#114631 - disable non selected line spacing + rSet.Put(SfxBoolItem(nWhich, false)); + } } break; } case SID_AUTOSPELL_CHECK: { - const SfxPoolItem* pState = rView.GetSlotState(nWhich); - if (pState) - rSet.Put(SfxBoolItem(nWhich, static_cast<const SfxBoolItem*>(pState)->GetValue())); + const SfxPoolItemHolder aResult(m_rView.GetSlotState(nWhich)); + if (aResult) + rSet.Put(SfxBoolItem(nWhich, static_cast<const SfxBoolItem*>(aResult.getItem())->GetValue())); else rSet.DisableItem( nWhich ); break; @@ -781,7 +825,7 @@ void SwAnnotationShell::GetState(SfxItemSet& rSet) case SID_ATTR_PARA_LEFT_TO_RIGHT: case SID_ATTR_PARA_RIGHT_TO_LEFT: { - if ( !SvtLanguageOptions().IsCTLFontEnabled() ) + if ( !SvtCTLOptions::IsCTLFontEnabled() ) rSet.DisableItem( nWhich ); else { @@ -814,9 +858,8 @@ void SwAnnotationShell::GetState(SfxItemSet& rSet) case SID_INSERT_RLM : case SID_INSERT_LRM : { - SvtCTLOptions aCTLOptions; - bool bEnabled = aCTLOptions.IsCTLFontEnabled(); - rView.GetViewFrame()->GetBindings().SetVisibleState( nWhich, bEnabled ); + bool bEnabled = SvtCTLOptions::IsCTLFontEnabled(); + m_rView.GetViewFrame().GetBindings().SetVisibleState( nWhich, bEnabled ); if(!bEnabled) rSet.DisableItem(nWhich); } @@ -832,7 +875,7 @@ void SwAnnotationShell::GetState(SfxItemSet& rSet) if(nEEWhich == EE_CHAR_KERNING) { SfxItemState eState = aEditAttr.GetItemState( EE_CHAR_KERNING ); - if ( eState == SfxItemState::DONTCARE ) + if ( eState == SfxItemState::INVALID ) { rSet.InvalidateItem(EE_CHAR_KERNING); } @@ -848,17 +891,17 @@ void SwAnnotationShell::GetState(SfxItemSet& rSet) void SwAnnotationShell::ExecSearch(SfxRequest& rReq) { - rView.ExecSearch(rReq); + m_rView.ExecSearch(rReq); } void SwAnnotationShell::StateSearch(SfxItemSet &rSet) { - rView.StateSearch(rSet); + m_rView.StateSearch(rSet); } void SwAnnotationShell::ExecClpbrd(SfxRequest const &rReq) { - SwPostItMgr* pPostItMgr = rView.GetPostItMgr(); + SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr(); if ( !pPostItMgr || !pPostItMgr->HasActiveSidebarWin() ) return; @@ -889,13 +932,13 @@ void SwAnnotationShell::ExecClpbrd(SfxRequest const &rReq) if (pPostItMgr->GetActiveSidebarWin()->GetLayoutStatus()!=SwPostItHelper::DELETED) { SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); - ScopedVclPtr<SfxAbstractPasteDialog> pDlg(pFact->CreatePasteDialog(rView.GetEditWin().GetFrameWeld())); + 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( &rView.GetEditWin() ) ); + TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( &m_rView.GetEditWin() ) ); SotClipboardFormatId nFormat = pDlg->GetFormat( aDataHelper.GetTransferable() ); @@ -934,12 +977,12 @@ void SwAnnotationShell::ExecClpbrd(SfxRequest const &rReq) void SwAnnotationShell::StateClpbrd(SfxItemSet &rSet) { - SwPostItMgr* pPostItMgr = rView.GetPostItMgr(); + SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr(); if ( !pPostItMgr || !pPostItMgr->HasActiveSidebarWin() ) return; OutlinerView* pOLV = pPostItMgr->GetActiveSidebarWin()->GetOutlinerView(); - TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( &rView.GetEditWin() ) ); + 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); @@ -1020,7 +1063,7 @@ void SwAnnotationShell::StateStatusLine(SfxItemSet &rSet) void SwAnnotationShell::StateInsert(SfxItemSet &rSet) { - SwPostItMgr* pPostItMgr = rView.GetPostItMgr(); + SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr(); if ( !pPostItMgr || !pPostItMgr->HasActiveSidebarWin() ) return; @@ -1055,7 +1098,7 @@ void SwAnnotationShell::StateInsert(SfxItemSet &rSet) aHLinkItem.SetName(comphelper::string::stripEnd(sSel, ' ')); } - sal_uInt16 nHtmlMode = ::GetHtmlMode(rView.GetDocShell()); + sal_uInt16 nHtmlMode = ::GetHtmlMode(m_rView.GetDocShell()); aHLinkItem.SetInsertMode(static_cast<SvxLinkInsertMode>(aHLinkItem.GetInsertMode() | ((nHtmlMode & HTMLMODE_ON) != 0 ? HLINK_HTMLMODE : 0))); @@ -1073,7 +1116,7 @@ void SwAnnotationShell::StateInsert(SfxItemSet &rSet) void SwAnnotationShell::NoteExec(SfxRequest const &rReq) { - SwPostItMgr* pPostItMgr = rView.GetPostItMgr(); + SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr(); if ( !pPostItMgr ) return; @@ -1093,7 +1136,7 @@ void SwAnnotationShell::NoteExec(SfxRequest const &rReq) pPostItMgr->Delete(); break; case FN_FORMAT_ALL_NOTES: - pPostItMgr->ExecuteFormatAllDialog(rView); + pPostItMgr->ExecuteFormatAllDialog(m_rView); break; case FN_DELETE_NOTE_AUTHOR: { @@ -1122,7 +1165,7 @@ void SwAnnotationShell::NoteExec(SfxRequest const &rReq) void SwAnnotationShell::GetNoteState(SfxItemSet &rSet) { - SwPostItMgr* pPostItMgr = rView.GetPostItMgr(); + SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr(); SfxWhichIter aIter(rSet); sal_uInt16 nWhich = aIter.FirstWhich(); while(nWhich) @@ -1219,7 +1262,7 @@ void SwAnnotationShell::GetNoteState(SfxItemSet &rSet) if (pPostItMgr && pPostItMgr->HasActiveSidebarWin()) { - if ( (pPostItMgr->GetActiveSidebarWin()->IsProtected()) && + if ( (pPostItMgr->GetActiveSidebarWin()->IsReadOnlyOrProtected()) && ( (nSlotId==FN_DELETE_COMMENT) || (nSlotId==FN_REPLY) ) ) rSet.DisableItem( nWhich ); } @@ -1229,13 +1272,13 @@ void SwAnnotationShell::GetNoteState(SfxItemSet &rSet) void SwAnnotationShell::ExecLingu(SfxRequest &rReq) { - SwPostItMgr* pPostItMgr = rView.GetPostItMgr(); + SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr(); if ( !pPostItMgr || !pPostItMgr->HasActiveSidebarWin() ) return; OutlinerView* pOLV = pPostItMgr->GetActiveSidebarWin()->GetOutlinerView(); sal_uInt16 nSlot = rReq.GetSlot(); - SwWrtShell &rSh = rView.GetWrtShell(); + SwWrtShell &rSh = m_rView.GetWrtShell(); bool bRestoreSelection = false; ESelection aOldSelection; @@ -1249,13 +1292,13 @@ void SwAnnotationShell::ExecLingu(SfxRequest &rReq) pOLV->GetEditView().SelectCurrentWord(); } - bRestoreSelection = SwLangHelper::SetLanguageStatus(pOLV,rReq,rView,rSh); + bRestoreSelection = SwLangHelper::SetLanguageStatus(pOLV,rReq,m_rView,rSh); break; } case SID_THES: { OUString aReplaceText; - const SfxStringItem* pItem2 = rReq.GetArg<SfxStringItem>(SID_THES); + const SfxStringItem* pItem2 = rReq.GetArg(FN_PARAM_THES_WORD_REPLACE); if (pItem2) aReplaceText = pItem2->GetValue(); if (!aReplaceText.isEmpty()) @@ -1264,12 +1307,12 @@ void SwAnnotationShell::ExecLingu(SfxRequest &rReq) } case SID_THESAURUS: { - pOLV->StartThesaurus(); + pOLV->StartThesaurus(rReq.GetFrameWeld()); break; } case SID_HANGUL_HANJA_CONVERSION: - pOLV->StartTextConversion( LANGUAGE_KOREAN, LANGUAGE_KOREAN, nullptr, - i18n::TextConversionOption::CHARACTER_BY_CHARACTER, true, false ); + pOLV->StartTextConversion(rReq.GetFrameWeld(), LANGUAGE_KOREAN, LANGUAGE_KOREAN, nullptr, + i18n::TextConversionOption::CHARACTER_BY_CHARACTER, true, false); break; case SID_CHINESE_CONVERSION: @@ -1328,7 +1371,7 @@ void SwAnnotationShell::ExecLingu(SfxRequest &rReq) vcl::Font aTargetFont = OutputDevice::GetDefaultFont( DefaultFontType::CJK_TEXT, nTargetLang, GetDefaultFontFlags::OnlyOne ); - pOLV->StartTextConversion( nSourceLang, nTargetLang, &aTargetFont, nOptions, false, false ); + pOLV->StartTextConversion(rReq.GetFrameWeld(), nSourceLang, nTargetLang, &aTargetFont, nOptions, false, false); } } Reference< lang::XComponent > xComponent( xDialog, UNO_QUERY ); @@ -1349,7 +1392,7 @@ void SwAnnotationShell::ExecLingu(SfxRequest &rReq) void SwAnnotationShell::GetLinguState(SfxItemSet &rSet) { - SwPostItMgr* pPostItMgr = rView.GetPostItMgr(); + SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr(); if ( !pPostItMgr || !pPostItMgr->HasActiveSidebarWin() ) return; @@ -1385,11 +1428,10 @@ void SwAnnotationShell::GetLinguState(SfxItemSet &rSet) // disable "Thesaurus" if the language is not supported case SID_THESAURUS: { - const SfxPoolItem &rItem = rView.GetWrtShell().GetDoc()->GetDefault( - GetWhichOfScript( RES_CHRATR_LANGUAGE, - SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage())) ); - LanguageType nLang = static_cast<const SvxLanguageItem &>( - rItem).GetLanguage(); + TypedWhichId<SvxLanguageItem> nLangWhich = GetWhichOfScript( RES_CHRATR_LANGUAGE, + SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() ) ); + const SvxLanguageItem &rItem = m_rView.GetWrtShell().GetDoc()->GetDefault(nLangWhich); + LanguageType nLang = rItem.GetLanguage(); uno::Reference< linguistic2::XThesaurus > xThes( ::GetThesaurus() ); if (!xThes.is() || nLang == LANGUAGE_NONE || !xThes->hasLocale( LanguageTag::convertToLocale( nLang ) )) @@ -1399,13 +1441,13 @@ void SwAnnotationShell::GetLinguState(SfxItemSet &rSet) case SID_HANGUL_HANJA_CONVERSION: case SID_CHINESE_CONVERSION: { - if (!SvtCJKOptions().IsAnyEnabled()) + if (!SvtCJKOptions::IsAnyEnabled()) { - rView.GetViewFrame()->GetBindings().SetVisibleState( nWhich, false ); + m_rView.GetViewFrame().GetBindings().SetVisibleState( nWhich, false ); rSet.DisableItem(nWhich); } else - rView.GetViewFrame()->GetBindings().SetVisibleState( nWhich, true ); + m_rView.GetViewFrame().GetBindings().SetVisibleState( nWhich, true ); } break; } @@ -1419,7 +1461,7 @@ void SwAnnotationShell::GetLinguState(SfxItemSet &rSet) void SwAnnotationShell::ExecTransliteration(SfxRequest const &rReq) { - SwPostItMgr* pPostItMgr = rView.GetPostItMgr(); + SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr(); if (!pPostItMgr || !pPostItMgr->HasActiveSidebarWin()) return; @@ -1473,7 +1515,7 @@ void SwAnnotationShell::ExecRotateTransliteration( SfxRequest const & rReq ) if( rReq.GetSlot() != SID_TRANSLITERATE_ROTATE_CASE ) return; - SwPostItMgr* pPostItMgr = rView.GetPostItMgr(); + SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr(); if (!pPostItMgr || !pPostItMgr->HasActiveSidebarWin()) return; @@ -1489,11 +1531,15 @@ void SwAnnotationShell::ExecUndo(SfxRequest &rReq) { const SfxItemSet* pArgs = rReq.GetArgs(); SfxUndoManager* pUndoManager = GetUndoManager(); - SwWrtShell &rSh = rView.GetWrtShell(); + SwWrtShell &rSh = m_rView.GetWrtShell(); SwUndoId nUndoId(SwUndoId::EMPTY); - tools::Long aOldHeight = rView.GetPostItMgr()->HasActiveSidebarWin() - ? rView.GetPostItMgr()->GetActiveSidebarWin()->GetPostItTextHeight() + // 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(); @@ -1566,15 +1612,15 @@ void SwAnnotationShell::ExecUndo(SfxRequest &rReq) } } - rView.GetViewFrame()->GetBindings().InvalidateAll(false); + rBindings.InvalidateAll(false); - if (rView.GetPostItMgr()->HasActiveSidebarWin()) - rView.GetPostItMgr()->GetActiveSidebarWin()->ResizeIfNecessary(aOldHeight,rView.GetPostItMgr()->GetActiveSidebarWin()->GetPostItTextHeight()); + if (pPostItMgr->HasActiveSidebarWin()) + pPostItMgr->GetActiveSidebarWin()->ResizeIfNecessary(aOldHeight, pPostItMgr->GetActiveSidebarWin()->GetPostItTextHeight()); } void SwAnnotationShell::StateUndo(SfxItemSet &rSet) { - SwPostItMgr* pPostItMgr = rView.GetPostItMgr(); + SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr(); if ( !pPostItMgr || !pPostItMgr->HasActiveSidebarWin() ) return; @@ -1582,8 +1628,8 @@ void SwAnnotationShell::StateUndo(SfxItemSet &rSet) SwUndoId nUndoId(SwUndoId::EMPTY); sal_uInt16 nWhich = aIter.FirstWhich(); SfxUndoManager* pUndoManager = GetUndoManager(); - SfxViewFrame *pSfxViewFrame = rView.GetViewFrame(); - SwWrtShell &rSh = rView.GetWrtShell(); + SfxViewFrame& rSfxViewFrame = m_rView.GetViewFrame(); + SwWrtShell &rSh = m_rView.GetWrtShell(); while( nWhich ) { @@ -1593,7 +1639,7 @@ void SwAnnotationShell::StateUndo(SfxItemSet &rSet) { sal_uInt16 nCount = pUndoManager ? pUndoManager->GetUndoActionCount() : 0; if ( nCount ) - pSfxViewFrame->GetSlotState( nWhich, pSfxViewFrame->GetInterface(), &rSet ); + rSfxViewFrame.GetSlotState( nWhich, rSfxViewFrame.GetInterface(), &rSet ); else if (rSh.GetLastUndoInfo(nullptr, &nUndoId)) { rSet.Put( SfxStringItem( nWhich, rSh.GetDoString(SwWrtShell::UNDO)) ); @@ -1610,7 +1656,7 @@ void SwAnnotationShell::StateUndo(SfxItemSet &rSet) { sal_uInt16 nCount = pUndoManager ? pUndoManager->GetRedoActionCount() : 0; if ( nCount ) - pSfxViewFrame->GetSlotState( nWhich, pSfxViewFrame->GetInterface(), &rSet ); + rSfxViewFrame.GetSlotState( nWhich, rSfxViewFrame.GetInterface(), &rSet ); else if (rSh.GetFirstRedoInfo(nullptr, &nUndoId)) { rSet.Put(SfxStringItem( nWhich, rSh.GetDoString(SwWrtShell::REDO)) ); @@ -1646,7 +1692,7 @@ void SwAnnotationShell::StateUndo(SfxItemSet &rSet) if( nCount ) { for( sal_uInt16 n = 0; n < nCount; ++n ) - sList.append( (pUndoManager->*fnGetComment)( n, SfxUndoManager::TopLevel ) ).append("\n"); + sList.append( (pUndoManager->*fnGetComment)( n, SfxUndoManager::TopLevel ) + "\n"); } SfxStringListItem aItem( nWhich ); @@ -1672,7 +1718,7 @@ void SwAnnotationShell::StateUndo(SfxItemSet &rSet) default: { - pSfxViewFrame->GetSlotState( nWhich, pSfxViewFrame->GetInterface(), &rSet ); + rSfxViewFrame.GetSlotState( nWhich, rSfxViewFrame.GetInterface(), &rSet ); break; } @@ -1698,26 +1744,24 @@ void SwAnnotationShell::StateDisableItems( SfxItemSet &rSet ) void SwAnnotationShell::InsertSymbol(SfxRequest& rReq) { - SwPostItMgr* pPostItMgr = rView.GetPostItMgr(); + SwPostItMgr* pPostItMgr = m_rView.GetPostItMgr(); if ( !pPostItMgr || !pPostItMgr->HasActiveSidebarWin() ) return; OutlinerView* pOLV = pPostItMgr->GetActiveSidebarWin()->GetOutlinerView(); const SfxItemSet *pArgs = rReq.GetArgs(); - const SfxPoolItem* pItem = nullptr; + const SfxStringItem* pCharMapItem = nullptr; if( pArgs ) - pArgs->GetItemState(GetPool().GetWhich(SID_CHARMAP), false, &pItem); + pCharMapItem = pArgs->GetItemIfSet(SID_CHARMAP, false); OUString sSym; OUString sFontName; - if ( pItem ) + if ( pCharMapItem ) { - sSym = static_cast<const SfxStringItem*>(pItem)->GetValue(); - const SfxPoolItem* pFtItem = nullptr; - pArgs->GetItemState( GetPool().GetWhich(SID_ATTR_SPECIALCHAR), false, &pFtItem); - - if (const SfxStringItem* pFontItem = dynamic_cast<const SfxStringItem*>(pFtItem)) + sSym = pCharMapItem->GetValue(); + const SfxStringItem* pFontItem = pArgs->GetItemIfSet( SID_ATTR_SPECIALCHAR, false); + if (pFontItem) sFontName = pFontItem->GetValue(); } @@ -1734,9 +1778,11 @@ void SwAnnotationShell::InsertSymbol(SfxRequest& rReq) } else { - aSetDlgFont.reset(static_cast<SvxFontItem*>(aSet.Get( GetWhichOfScript( + TypedWhichId<SvxFontItem> nFontWhich = + GetWhichOfScript( SID_ATTR_CHAR_FONT, - SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() ) )).Clone())); + SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() ) ); + aSetDlgFont.reset(aSet.Get(nFontWhich).Clone()); } if (sFontName.isEmpty()) @@ -1751,7 +1797,7 @@ void SwAnnotationShell::InsertSymbol(SfxRequest& rReq) SfxAllItemSet aAllSet( GetPool() ); aAllSet.Put( SfxBoolItem( FN_PARAM_1, false ) ); - SwViewOption aOpt(*rView.GetWrtShell().GetViewOptions()); + SwViewOption aOpt(*m_rView.GetWrtShell().GetViewOptions()); const OUString& sSymbolFont = aOpt.GetSymbolFont(); if( !sSymbolFont.isEmpty() ) aAllSet.Put( SfxStringItem( SID_FONT_NAME, sSymbolFont ) ); @@ -1759,23 +1805,27 @@ void SwAnnotationShell::InsertSymbol(SfxRequest& rReq) aAllSet.Put( SfxStringItem( SID_FONT_NAME, aSetDlgFont->GetFamilyName() ) ); // If character is selected then it can be shown. - auto xFrame = rView.GetViewFrame()->GetFrame().GetFrameInterface(); - ScopedVclPtr<SfxAbstractDialog> pDlg(pFact->CreateCharMapDialog(rView.GetFrameWeld(), aAllSet, xFrame)); - pDlg->Execute(); + auto xFrame = m_rView.GetViewFrame().GetFrame().GetFrameInterface(); + VclPtr<SfxAbstractDialog> pDlg(pFact->CreateCharMapDialog(m_rView.GetFrameWeld(), aAllSet, xFrame)); + pDlg->StartExecuteAsync( + [pDlg] (sal_Int32 /*nResult*/)->void + { + pDlg->disposeOnce(); + } + ); return; } // do not flicker pOLV->HideCursor(); Outliner * pOutliner = pOLV->GetOutliner(); - pOutliner->SetUpdateMode(false); + pOutliner->SetUpdateLayout(false); SfxItemSet aOldSet( pOLV->GetAttribs() ); - SfxItemSet aFontSet( - *aOldSet.GetPool(), - svl::Items< + SfxItemSetFixed< EE_CHAR_FONTINFO, EE_CHAR_FONTINFO, - EE_CHAR_FONTINFO_CJK, EE_CHAR_FONTINFO_CTL>{}); + EE_CHAR_FONTINFO_CJK, EE_CHAR_FONTINFO_CTL> + aFontSet( *aOldSet.GetPool() ); aFontSet.Set( aOldSet ); // Insert string @@ -1812,10 +1862,10 @@ void SwAnnotationShell::InsertSymbol(SfxRequest& rReq) pOLV->SetAttribs( aFontSet ); // From now on show it again - pOutliner->SetUpdateMode(true); + pOutliner->SetUpdateLayout(true); pOLV->ShowCursor(); - rReq.AppendItem( SfxStringItem( GetPool().GetWhich(SID_CHARMAP), sSym ) ); + rReq.AppendItem( SfxStringItem( SID_CHARMAP, sSym ) ); if(!aFont.GetFamilyName().isEmpty()) rReq.AppendItem( SfxStringItem( SID_ATTR_SPECIALCHAR, aFont.GetFamilyName() ) ); rReq.Done(); diff --git a/sw/source/uibase/shells/basesh.cxx b/sw/source/uibase/shells/basesh.cxx index 71f93a40d421..cf36bcd7e076 100644 --- a/sw/source/uibase/shells/basesh.cxx +++ b/sw/source/uibase/shells/basesh.cxx @@ -18,10 +18,12 @@ */ #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> @@ -78,27 +80,43 @@ #include <strings.hrc> #include <unotxdoc.hxx> #include <doc.hxx> +#include <drawdoc.hxx> #include <IDocumentSettingAccess.hxx> +#include <IDocumentDrawModelAccess.hxx> #include <IDocumentUndoRedo.hxx> +#include <ThemeColorChanger.hxx> #include <swabstdlg.hxx> #include <modcfg.hxx> #include <svx/fmshell.hxx> #include <SwRewriter.hxx> +#include <GraphicSizeCheck.hxx> #include <svx/galleryitem.hxx> -#include <svx/devtools/DevelopmentToolChildWindow.hxx> +#include <sfx2/devtools/DevelopmentToolChildWindow.hxx> #include <com/sun/star/gallery/GalleryItemType.hpp> +#include <com/sun/star/beans/PropertyValues.hpp> #include <memory> + #include <svx/unobrushitemhelper.hxx> +#include <svx/dialog/ThemeDialog.hxx> #include <comphelper/scopeguard.hxx> #include <comphelper/lok.hxx> +#include <LibreOfficeKit/LibreOfficeKitEnums.h> +#include <osl/diagnose.h> #include <svx/svxdlg.hxx> +#include <comphelper/sequenceashashmap.hxx> #include <shellres.hxx> #include <UndoTable.hxx> -FlyMode SwBaseShell::eFrameMode = FLY_DRAG_END; +#include <ndtxt.hxx> +#include <UndoManager.hxx> +#include <fmtrfmrk.hxx> +#include <txtrfmrk.hxx> +#include <translatehelper.hxx> + +FlyMode SwBaseShell::s_eFrameMode = FLY_DRAG_END; // These variables keep the state of Gallery (slot SID_GALLERY_BG_BRUSH) // detected by GetGalleryState() for the subsequent ExecuteGallery() call. @@ -119,19 +137,18 @@ static sal_uInt8 nFooterPos; #include <swslots.hxx> #include <AccessibilityCheck.hxx> -#include <svx/AccessibilityCheckDialog.hxx> namespace { SvxContourDlg* GetContourDlg(SwView const &rView) { - SfxChildWindow *pWnd = rView.GetViewFrame()->GetChildWindow(SvxContourDlgChildWindow::GetChildWindowId()); + 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()); + SfxChildWindow* pWnd = rView.GetViewFrame().GetChildWindow(SvxIMapDlgChildWindow::GetChildWindowId()); return pWnd ? static_cast<SvxIMapDlg*>(pWnd->GetController().get()) : nullptr; } } @@ -139,7 +156,6 @@ namespace 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) @@ -156,14 +172,14 @@ static void lcl_UpdateIMapDlg( SwWrtShell& rSh ) GraphicType nGrfType = aGrf.GetType(); void* pEditObj = GraphicType::NONE != nGrfType && GraphicType::Default != nGrfType ? rSh.GetIMapInventor() : nullptr; - std::unique_ptr<TargetList> pList(new TargetList); - SfxFrame::GetDefaultTargetList(*pList); + TargetList aList; + SfxFrame::GetDefaultTargetList(aList); - SfxItemSet aSet( rSh.GetAttrPool(), svl::Items<RES_URL, RES_URL>{} ); + SfxItemSetFixed<RES_URL, RES_URL> aSet( rSh.GetAttrPool() ); rSh.GetFlyFrameAttr( aSet ); const SwFormatURL &rURL = aSet.Get( RES_URL ); SvxIMapDlgChildWindow::UpdateIMapDlg( - aGrf, rURL.GetMap(), pList.get(), pEditObj ); + aGrf, rURL.GetMap(), &aList, pEditObj ); } static bool lcl_UpdateContourDlg( SwWrtShell &rSh, SelectionType nSel ) @@ -194,15 +210,60 @@ void SwBaseShell::ExecDelete(SfxRequest &rReq) switch(rReq.GetSlot()) { case SID_DELETE: + if (rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton()) + { + // Disallow if the cursor is at the end of a paragraph and the document model + // node at this position is an outline node with folded content or the next node + // is an outline node with folded content. + if (rSh.IsEndPara()) + { + SwNodeIndex aIdx(rSh.GetCursor()->GetPointNode()); + if (aIdx.GetNode().IsTextNode()) + { + bool bVisible = true; + aIdx.GetNode().GetTextNode()->GetAttrOutlineContentVisible(bVisible); + if (!bVisible) + break; + ++aIdx; + if (aIdx.GetNode().IsTextNode()) + { + bVisible = true; + aIdx.GetNode().GetTextNode()->GetAttrOutlineContentVisible(bVisible); + if (!bVisible) + break; + } + } + } + } rSh.DelRight(); break; case FN_BACKSPACE: - + if (rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton()) + { + // Disallow if the cursor is at the start of a paragraph and the document model + // node at this position is an outline node with folded content or the previous + // node is a content node without a layout frame. + if (rSh.IsSttPara()) + { + SwNodeIndex aIdx(rSh.GetCursor()->GetPointNode()); + if (aIdx.GetNode().IsTextNode()) + { + bool bVisible = true; + aIdx.GetNode().GetTextNode()->GetAttrOutlineContentVisible(bVisible); + if (!bVisible) + break; + --aIdx; + if (aIdx.GetNode().IsContentNode() && + !aIdx.GetNode().GetContentNode()->getLayoutFrame(rSh.GetLayout())) + break; + } + } + } if( rSh.IsNoNum() ) { rSh.SttCursorMove(); - bool bLeft = rSh.Left( CRSR_SKIP_CHARS, true, 1, false ); + bool bLeft = rSh.Left( SwCursorSkipMode::Chars, true, 1, false ); if( bLeft ) { rSh.DelLeft(); @@ -245,7 +306,7 @@ void SwBaseShell::ExecClpbrd(SfxRequest &rReq) { case SID_CUT: case SID_COPY: - rView.GetEditWin().FlushInBuffer(); + m_rView.GetEditWin().FlushInBuffer(); if ( rSh.HasSelection() ) { rtl::Reference<SwTransferable> pTransfer = new SwTransferable( rSh ); @@ -290,7 +351,7 @@ void SwBaseShell::ExecClpbrd(SfxRequest &rReq) { // Temporary variables, because the shell could already be // destroyed after the paste. - SwView* pView = &rView; + SwView* pView = &m_rView; RndStdIds nAnchorType = RndStdIds::FLY_AT_PARA; const SfxUInt16Item* pAnchorType = rReq.GetArg<SfxUInt16Item>(FN_PARAM_1); @@ -305,6 +366,9 @@ void SwBaseShell::ExecClpbrd(SfxRequest &rReq) 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; @@ -325,7 +389,7 @@ void SwBaseShell::ExecClpbrd(SfxRequest &rReq) { // Temporary variables, because the shell could already be // destroyed after the paste. - SwView* pView = &rView; + SwView* pView = &m_rView; SwTransferable::PasteFormat( rSh, aDataHelper, static_cast<SotClipboardFormatId>(static_cast<const SfxUInt32Item*>(pFormat)->GetValue()) ); @@ -336,6 +400,9 @@ void SwBaseShell::ExecClpbrd(SfxRequest &rReq) if( rSh.IsFrameSelected() || rSh.IsObjSelected()) rSh.EnterSelFrameMode(); pView->AttrChangedNotify(nullptr); + + // Fold pasted outlines that have outline content visible attribute false + MakeAllOutlineContentTemporarilyVisible a(rSh.GetDoc()); } } } @@ -350,16 +417,16 @@ void SwBaseShell::ExecClpbrd(SfxRequest &rReq) { // Temporary variables, because the shell could already be // destroyed after the paste. - SwView* pView = &rView; + SwView* pView = &m_rView; rReq.Ignore(); bIgnore = true; if(SwTransferable::PasteUnformatted( rSh, aDataHelper )) { - SfxViewFrame* pViewFrame = pView->GetViewFrame(); + SfxViewFrame& rViewFrame = pView->GetViewFrame(); uno::Reference< frame::XDispatchRecorder > xRecorder = - pViewFrame->GetBindings().GetRecorder(); + rViewFrame.GetBindings().GetRecorder(); if(xRecorder.is()) { - SfxRequest aReq( pViewFrame, SID_CLIPBOARD_FORMAT_ITEMS ); + SfxRequest aReq(rViewFrame, SID_CLIPBOARD_FORMAT_ITEMS); aReq.AppendItem( SfxUInt32Item( SID_CLIPBOARD_FORMAT_ITEMS, static_cast<sal_uInt32>(SotClipboardFormatId::STRING) ) ); aReq.Done(); } @@ -368,6 +435,9 @@ void SwBaseShell::ExecClpbrd(SfxRequest &rReq) 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; @@ -376,7 +446,7 @@ void SwBaseShell::ExecClpbrd(SfxRequest &rReq) case SID_PASTE_SPECIAL: { - std::shared_ptr<TransferableDataHelper> aDataHelper = + std::shared_ptr<const TransferableDataHelper> aDataHelper = std::make_shared<TransferableDataHelper>(TransferableDataHelper::CreateFromSystemClipboard( &rSh.GetView().GetEditWin())); if( aDataHelper->GetXTransferable().is() @@ -394,38 +464,43 @@ void SwBaseShell::ExecClpbrd(SfxRequest &rReq) 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 = &rView; - bool bRet = false; - SotClipboardFormatId nFormatId = pDlg->GetFormatOnly(); + 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( 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 (bRet) + { + SfxViewFrame& rViewFrame = pView->GetViewFrame(); + uno::Reference< frame::XDispatchRecorder > xRecorder = + rViewFrame.GetBindings().GetRecorder(); + if(xRecorder.is()) { + SfxRequest aReq(rViewFrame, SID_CLIPBOARD_FORMAT_ITEMS); + aReq.AppendItem( SfxUInt32Item( SID_CLIPBOARD_FORMAT_ITEMS, static_cast<sal_uInt32>(nFormatId) ) ); + aReq.Done(); + } + } - if (rSh.IsFrameSelected() || rSh.IsObjSelected()) - rSh.EnterSelFrameMode(); - pView->AttrChangedNotify(nullptr); - } + if (rSh.IsFrameSelected() || rSh.IsObjSelected()) + rSh.EnterSelFrameMode(); + pView->AttrChangedNotify(nullptr); - pDlg->disposeOnce(); + // Fold pasted outlines that have outline content visible attribute false + MakeAllOutlineContentTemporarilyVisible a(rSh.GetDoc()); + } - }); + pDlg->disposeOnce(); + } + ); } else return; @@ -508,7 +583,7 @@ void SwBaseShell::StateClpbrd(SfxItemSet &rSet) TransferableDataHelper::CreateFromSystemClipboard( &rSh.GetView().GetEditWin()) ); - SvxClipboardFormatItem aFormatItem( nWhich ); + SvxClipboardFormatItem aFormatItem( SID_CLIPBOARD_FORMAT_ITEMS ); SwTransferable::FillClipFormatItem( rSh, aDataHelper, aFormatItem ); rSet.Put( aFormatItem ); } @@ -522,6 +597,8 @@ void SwBaseShell::StateClpbrd(SfxItemSet &rSet) void SwBaseShell::ExecUndo(SfxRequest &rReq) { + MakeAllOutlineContentTemporarilyVisible a(GetShell().GetDoc(), true); + SwWrtShell &rWrtShell = GetShell(); SwUndoId nUndoId(SwUndoId::EMPTY); @@ -534,11 +611,12 @@ void SwBaseShell::ExecUndo(SfxRequest &rReq) // Repair mode: allow undo/redo of all undo actions, even if access would // be limited based on the view shell ID. bool bRepair = false; - if (pArgs && pArgs->GetItemState(SID_REPAIRPACKAGE, false, &pItem) == SfxItemState::SET) - bRepair = static_cast<const SfxBoolItem*>(pItem)->GetValue(); + 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() ); + SfxViewFrame& rViewFrame( GetView().GetViewFrame() ); IDocumentUndoRedo& rUndoRedo = rWrtShell.GetIDocumentUndoRedo(); bool bWasRepair = rUndoRedo.DoesRepair(); @@ -554,10 +632,35 @@ void SwBaseShell::ExecUndo(SfxRequest &rReq) if (rUndoRedo.GetLastUndoInfo(nullptr, &nUndoId, &rWrtShell.GetView())) { for (SwViewShell& rShell : rWrtShell.GetRingContainer()) - rShell.LockPaint(); - rWrtShell.Do( SwWrtShell::UNDO, nCnt ); + rShell.LockPaint(LockPaintReason::Undo); + + sal_uInt16 nUndoOffset = 0; + if (comphelper::LibreOfficeKit::isActive() && !bRepair && nCnt == 1) + { + sw::UndoManager& rManager = rWrtShell.GetDoc()->GetUndoManager(); + const SfxUndoAction* pAction = rManager.GetUndoAction(); + SwView& rView = rWrtShell.GetView(); + ViewShellId nViewShellId = rView.GetViewShellId(); + sal_uInt16 nOffset = 0; + if (pAction->GetViewShellId() != nViewShellId + && rManager.IsViewUndoActionIndependent(&rView, nOffset)) + { + // Execute the undo with an offset: don't undo the top action, but an + // earlier one, since it's independent and that belongs to our view. + nUndoOffset += nOffset; + } + } + + rWrtShell.Do(SwWrtShell::UNDO, nCnt, nUndoOffset); + for (SwViewShell& rShell : rWrtShell.GetRingContainer()) rShell.UnlockPaint(); + + // tdf#141613 FIXME: Disable redoing header/footer changes for now. + // The proper solution would be to write a SwUndoHeaderFooter class + // to represent the addition of a header or footer to the current page. + if (nUndoId == SwUndoId::HEADER_FOOTER) + rUndoRedo.ClearRedo(); } break; @@ -565,7 +668,7 @@ void SwBaseShell::ExecUndo(SfxRequest &rReq) if (rUndoRedo.GetFirstRedoInfo(nullptr, &nUndoId, &rWrtShell.GetView())) { for (SwViewShell& rShell : rWrtShell.GetRingContainer()) - rShell.LockPaint(); + rShell.LockPaint(LockPaintReason::Redo); rWrtShell.Do( SwWrtShell::REDO, nCnt ); for (SwViewShell& rShell : rWrtShell.GetRingContainer()) rShell.UnlockPaint(); @@ -583,12 +686,8 @@ void SwBaseShell::ExecUndo(SfxRequest &rReq) { 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); } + rViewFrame.GetBindings().InvalidateAll(false); } // State of undo @@ -673,6 +772,141 @@ void SwBaseShell::StateUndo(SfxItemSet &rSet) } } +namespace +{ +/// Searches for the specified field type and field name prefix and update the matching fields to +/// have the provided new name and content. +bool UpdateFieldContents(SfxRequest& rReq, SwWrtShell& rWrtSh) +{ + const SfxStringItem* pTypeName = rReq.GetArg<SfxStringItem>(FN_PARAM_1); + if (!pTypeName || pTypeName->GetValue() != "SetRef") + { + // This is implemented so far only for reference marks. + return false; + } + + const SfxStringItem* pNamePrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_2); + if (!pNamePrefix) + { + return false; + } + const OUString& rNamePrefix = pNamePrefix->GetValue(); + + const SfxUnoAnyItem* pFields = rReq.GetArg<SfxUnoAnyItem>(FN_PARAM_3); + if (!pFields) + { + return false; + } + uno::Sequence<beans::PropertyValues> aFields; + pFields->GetValue() >>= aFields; + + SwDoc* pDoc = rWrtSh.GetDoc(); + pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::UPDATE_FIELDS, nullptr); + rWrtSh.StartAction(); + + std::vector<const SwFormatRefMark*> aRefMarks; + + for (sal_uInt16 i = 0; i < pDoc->GetRefMarks(); ++i) + { + aRefMarks.push_back(pDoc->GetRefMark(i)); + } + + std::sort(aRefMarks.begin(), aRefMarks.end(), + [](const SwFormatRefMark* pMark1, const SwFormatRefMark* pMark2) -> bool { + const SwTextRefMark* pTextRefMark1 = pMark1->GetTextRefMark(); + const SwTextRefMark* pTextRefMark2 = pMark2->GetTextRefMark(); + SwPosition aPos1(pTextRefMark1->GetTextNode(), pTextRefMark1->GetStart()); + SwPosition aPos2(pTextRefMark2->GetTextNode(), pTextRefMark2->GetStart()); + return aPos1 < aPos2; + }); + + sal_uInt16 nFieldIndex = 0; + for (auto& pIntermediateRefMark : aRefMarks) + { + auto pRefMark = const_cast<SwFormatRefMark*>(pIntermediateRefMark); + if (!pRefMark->GetRefName().startsWith(rNamePrefix)) + { + continue; + } + + if (nFieldIndex >= aFields.getLength()) + { + break; + } + comphelper::SequenceAsHashMap aMap(aFields[nFieldIndex++]); + pRefMark->GetRefName() = aMap["Name"].get<OUString>(); + + auto pTextRefMark = const_cast<SwTextRefMark*>(pRefMark->GetTextRefMark()); + pTextRefMark->UpdateFieldContent(pDoc, rWrtSh, aMap["Content"].get<OUString>()); + } + + rWrtSh.EndAction(); + pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::UPDATE_FIELDS, nullptr); + return true; +} + +/// Searches for the specified field type and field name prefix under cursor and update the matching +/// field to have the provided new name and content. +void UpdateFieldContent(SfxRequest& rReq, SwWrtShell& rWrtSh) +{ + const SfxStringItem* pTypeName = rReq.GetArg<SfxStringItem>(FN_PARAM_1); + if (!pTypeName || pTypeName->GetValue() != "SetRef") + { + // This is implemented so far only for reference marks. + return; + } + + const SfxStringItem* pNamePrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_2); + if (!pNamePrefix) + { + return; + } + const OUString& rNamePrefix = pNamePrefix->GetValue(); + + const SfxUnoAnyItem* pField = rReq.GetArg<SfxUnoAnyItem>(FN_PARAM_3); + if (!pField) + { + return; + } + uno::Sequence<beans::PropertyValue> aField; + pField->GetValue() >>= aField; + + SwPosition& rCursor = *rWrtSh.GetCursor()->GetPoint(); + SwTextNode* pTextNode = rCursor.GetNode().GetTextNode(); + std::vector<SwTextAttr*> aAttrs + = pTextNode->GetTextAttrsAt(rCursor.GetContentIndex(), RES_TXTATR_REFMARK); + if (aAttrs.empty()) + { + return; + } + + auto& rRefmark = const_cast<SwFormatRefMark&>(aAttrs[0]->GetRefMark()); + if (!rRefmark.GetRefName().startsWith(rNamePrefix)) + { + return; + } + + SwDoc* pDoc = rWrtSh.GetDoc(); + SwRewriter aRewriter; + aRewriter.AddRule(UndoArg1, rRefmark.GetRefName()); + pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::UPDATE_FIELD, &aRewriter); + rWrtSh.StartAction(); + comphelper::ScopeGuard g( + [&rWrtSh, &aRewriter] + { + rWrtSh.EndAction(); + rWrtSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::UPDATE_FIELD, &aRewriter); + }); + + comphelper::SequenceAsHashMap aMap(aField); + rRefmark.GetRefName() = aMap["Name"].get<OUString>(); + + OUString aContent = aMap["Content"].get<OUString>(); + auto pTextRefMark = const_cast<SwTextRefMark*>(rRefmark.GetTextRefMark()); + pTextRefMark->UpdateFieldContent(pDoc, rWrtSh, aContent); +} +} + // Evaluate respectively dispatching the slot Id void SwBaseShell::Execute(SfxRequest &rReq) @@ -688,13 +922,20 @@ void SwBaseShell::Execute(SfxRequest &rReq) case FN_REPAGINATE: { Reference < XModel > xModel = GetView().GetDocShell()->GetModel(); - auto pDoc = comphelper::getUnoTunnelImplementation<SwXTextDocument>(xModel); + auto pDoc = comphelper::getFromUnoTunnel<SwXTextDocument>(xModel); pDoc->NotifyRefreshListeners(); rSh.CalcLayout(); } break; case FN_UPDATE_FIELDS: { + if (UpdateFieldContents(rReq, rSh)) + { + // Parameters indicated that the name / content of fields has to be updated to + // the provided values, don't do an actual fields update. + break; + } + rSh.UpdateDocStat(); rSh.EndAllTableBoxEdit(); rSh.SwViewShell::UpdateFields(true); @@ -708,9 +949,14 @@ void SwBaseShell::Execute(SfxRequest &rReq) } } break; + case FN_UPDATE_FIELD: + { + UpdateFieldContent(rReq, rSh); + } + break; case FN_UPDATE_CHARTS: { - SwWait aWait( *rView.GetDocShell(), true ); + SwWait aWait( *m_rView.GetDocShell(), true ); rSh.UpdateAllCharts(); } break; @@ -729,11 +975,12 @@ void SwBaseShell::Execute(SfxRequest &rReq) rSh.GetLinkManager().UpdateAllLinks( false, true, nullptr ); rSh.EndAllAction(); } - SfxDispatcher &rDis = *rTempView.GetViewFrame()->GetDispatcher(); + 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; @@ -773,7 +1020,7 @@ void SwBaseShell::Execute(SfxRequest &rReq) bool bRet = rSh.MoveFieldType( pFieldType, nSlot == FN_GOTO_NEXT_MARK ); SwField* pCurField = bRet ? rSh.GetCurField() : nullptr; if (pCurField) - rSh.ClickToField(*pCurField); + rSh.ClickToField(*pCurField, /*bExecHyperlinks=*/false); rReq.SetReturnValue(SfxBoolItem( nSlot, bRet)); } } @@ -818,7 +1065,7 @@ void SwBaseShell::Execute(SfxRequest &rReq) if ( (!rSh.IsSelFrameMode() || nSelType & SelectionType::Graphic) && nGalleryItemType == css::gallery::GalleryItemType::GRAPHIC ) { - SwWait aWait( *rView.GetDocShell(), true ); + SwWait aWait( *m_rView.GetDocShell(), true ); OUString aGrfName, aFltName; const Graphic aGrf( pGalleryItem->GetGraphic() ); @@ -826,7 +1073,7 @@ void SwBaseShell::Execute(SfxRequest &rReq) if ( nSelType & SelectionType::Graphic ) rSh.ReRead( aGrfName, aFltName, &aGrf ); else - rSh.Insert( aGrfName, aFltName, aGrf ); + rSh.InsertGraphic( aGrfName, aFltName, aGrf ); GetView().GetEditWin().GrabFocus(); } @@ -834,7 +1081,7 @@ void SwBaseShell::Execute(SfxRequest &rReq) nGalleryItemType == css::gallery::GalleryItemType::MEDIA ) { const SfxStringItem aMediaURLItem( SID_INSERT_AVMEDIA, pGalleryItem->GetURL() ); - GetView().GetViewFrame()->GetDispatcher()->ExecuteList( + GetView().GetViewFrame().GetDispatcher()->ExecuteList( SID_INSERT_AVMEDIA, SfxCallMode::SYNCHRON, { &aMediaURLItem }); } @@ -868,7 +1115,7 @@ void SwBaseShell::Execute(SfxRequest &rReq) rSh.ChgPageDesc(nCurIdx, aPageDesc); } else - GetView().GetViewFrame()->GetDispatcher()->Execute(FN_FORMAT_PAGE_COLUMN_DLG); + GetView().GetViewFrame().GetDispatcher()->Execute(FN_FORMAT_PAGE_COLUMN_DLG); } break; case FN_CONVERT_TABLE_TO_TEXT: @@ -917,7 +1164,7 @@ void SwBaseShell::Execute(SfxRequest &rReq) // RepeatHeaderLines if(SfxItemState::SET == pArgs->GetItemState( FN_PARAM_4, true, &pItem)) aInsTableOpts.mnRowsToRepeat = - static_cast<sal_uInt16>(static_cast< const SfxInt16Item* >(pItem)->GetValue()); + 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()) @@ -941,13 +1188,13 @@ void SwBaseShell::Execute(SfxRequest &rReq) if( cDelim ) { //Shell change! - SwView& rSaveView = rView; + SwView& rSaveView = m_rView; bool bInserted = false; //recording: - SfxViewFrame* pViewFrame = GetView().GetViewFrame(); - if( SfxRequest::HasMacroRecorder(pViewFrame) ) + SfxViewFrame& rViewFrame = GetView().GetViewFrame(); + if (SfxRequest::HasMacroRecorder(rViewFrame)) { - SfxRequest aReq( pViewFrame, nSlot); + SfxRequest aReq(rViewFrame, nSlot); aReq.AppendItem( SfxStringItem( FN_PARAM_1, OUString(cDelim) )); if(bToTable) { @@ -1030,11 +1277,11 @@ void SwBaseShell::Execute(SfxRequest &rReq) { sal_uInt16 nId = SvxIMapDlgChildWindow::GetChildWindowId(); - SfxViewFrame* pVFrame = GetView().GetViewFrame(); - pVFrame->ToggleChildWindow( nId ); - pVFrame->GetBindings().Invalidate( SID_IMAP ); + SfxViewFrame& rVFrame = GetView().GetViewFrame(); + rVFrame.ToggleChildWindow( nId ); + rVFrame.GetBindings().Invalidate( SID_IMAP ); - if ( pVFrame->HasChildWindow( nId ) && rSh.IsFrameSelected() ) + if ( rVFrame.HasChildWindow( nId ) && rSh.IsFrameSelected() ) lcl_UpdateIMapDlg( rSh ); } break; @@ -1046,7 +1293,7 @@ void SwBaseShell::Execute(SfxRequest &rReq) if ( rSh.IsFrameSelected() && pDlg->GetEditingObject() == rSh.GetIMapInventor() ) { - SfxItemSet aSet( rSh.GetAttrPool(), svl::Items<RES_URL, RES_URL>{} ); + SfxItemSetFixed<RES_URL, RES_URL> aSet( rSh.GetAttrPool() ); rSh.GetFlyFrameAttr( aSet ); SwFormatURL aURL( aSet.Get( RES_URL ) ); aURL.SetMap( &pDlg->GetImageMap() ); @@ -1065,18 +1312,24 @@ void SwBaseShell::Execute(SfxRequest &rReq) 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 ); + SfxViewFrame& rVFrame = GetView().GetViewFrame(); + rVFrame.ToggleChildWindow( nId ); + rVFrame.GetBindings().Invalidate( SID_CONTOUR_DLG ); SelectionType nSel = rSh.GetSelectionType(); - if ( pVFrame->HasChildWindow( nId ) && + if ( rVFrame.HasChildWindow( nId ) && (nSel & (SelectionType::Graphic|SelectionType::Ole)) ) { lcl_UpdateContourDlg( rSh, nSel ); @@ -1093,7 +1346,7 @@ void SwBaseShell::Execute(SfxRequest &rReq) if (pDlg && pDlg->GetEditingObject() == rSh.GetIMapInventor()) { rSh.StartAction(); - SfxItemSet aSet( rSh.GetAttrPool(), svl::Items<RES_SURROUND, RES_SURROUND>{}); + SfxItemSetFixed<RES_SURROUND, RES_SURROUND> aSet( rSh.GetAttrPool() ); rSh.GetFlyFrameAttr( aSet ); SwFormatSurround aSur( aSet.Get( RES_SURROUND ) ); if ( !aSur.IsContour() ) @@ -1140,7 +1393,7 @@ void SwBaseShell::Execute(SfxRequest &rReq) rSh.ChgAnchor(eSet); else if (rSh.IsFrameSelected()) { - SwFormatAnchor aAnc(eSet, rSh.GetPhyPageNum()); + SwFormatAnchor aAnc(eSet, eSet == RndStdIds::FLY_AT_PAGE ? rSh.GetPhyPageNum() : 0); SfxItemSet aSet(SwFEShell::makeItemSetFromFormatAnchor(GetPool(), aAnc)); rSh.SetFlyFrameAttr(aSet); } @@ -1155,7 +1408,7 @@ void SwBaseShell::Execute(SfxRequest &rReq) sal_uInt16 nHtmlMode = ::GetHtmlMode(GetView().GetDocShell()); if( nHtmlMode ) { - SfxItemSet aSet(GetPool(), svl::Items<RES_SURROUND, RES_HORI_ORIENT>{}); + SfxItemSetFixed<RES_SURROUND, RES_HORI_ORIENT> aSet(GetPool()); rSh.GetFlyFrameAttr(aSet); const SwFormatSurround& rSurround = aSet.Get(RES_SURROUND); @@ -1213,7 +1466,7 @@ void SwBaseShell::Execute(SfxRequest &rReq) } rSh.EndUndo(); - GetView().GetViewFrame()->GetBindings().Invalidate( SID_ANCHOR_MENU ); + GetView().GetViewFrame().GetBindings().Invalidate( SID_ANCHOR_MENU ); } break; @@ -1251,7 +1504,7 @@ void SwBaseShell::Execute(SfxRequest &rReq) // set from design mode OSL_ENSURE( GetView().GetFormShell() != nullptr, "form shell?" ); - SfxRequest aReq( GetView().GetViewFrame(), SID_FM_DESIGN_MODE ); + SfxRequest aReq(GetView().GetViewFrame(), SID_FM_DESIGN_MODE); aReq.AppendItem( SfxBoolItem( SID_FM_DESIGN_MODE, bDesignMode ) ); GetView().GetFormShell()->Execute( aReq ); aReq.Done(); @@ -1273,7 +1526,7 @@ void SwBaseShell::Execute(SfxRequest &rReq) return; pItem = nullptr; - pArgs->GetItemState(GetPool().GetWhich(nSlot), false, &pItem); + pArgs->GetItemState(GetPool().GetWhichIDFromSlotID(nSlot), false, &pItem); if(!pItem) return; @@ -1284,7 +1537,7 @@ void SwBaseShell::Execute(SfxRequest &rReq) case RES_SHADOW: { rSh.StartAllAction(); - // Tabele cell(s) selected? + // Table cell(s) selected? if ( rSh.IsTableMode() ) { SwFrameFormat *pFormat = rSh.GetTableFormat(); @@ -1316,7 +1569,7 @@ void SwBaseShell::Execute(SfxRequest &rReq) case SID_ATTR_BORDER_OUTER: { - // Tabele cell(s) selected? + // Table cell(s) selected? if ( rSh.IsTableMode() ) { // Set border attributes Get/SetTabBorders() @@ -1350,12 +1603,12 @@ IMPL_LINK_NOARG(SwBaseShell, GraphicArrivedHdl, SwCursorShell&, void) if (CNT_GRF != rSh.SwEditShell::GetCntType()) return; GraphicType const nGrfType(rSh.GetGraphicType()); - if (GraphicType::NONE == nGrfType || aGrfUpdateSlots.empty()) + 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 : aGrfUpdateSlots ) + SfxViewFrame& rVFrame = GetView().GetViewFrame(); + for( const auto nSlot : m_aGrfUpdateSlots ) { bool bSetState = false; bool bState = false; @@ -1365,8 +1618,8 @@ IMPL_LINK_NOARG(SwBaseShell, GraphicArrivedHdl, SwCursorShell&, void) case SID_IMAP_EXEC: { sal_uInt16 nId = SvxIMapDlgChildWindow::GetChildWindowId(); - SfxChildWindow *pChildWindow = pVFrame->HasChildWindow(nId) ? - pVFrame->GetChildWindow(nId) : nullptr; + SfxChildWindow *pChildWindow = rVFrame.HasChildWindow(nId) ? + rVFrame.GetChildWindow(nId) : nullptr; SvxIMapDlg *pDlg = pChildWindow ? static_cast<SvxIMapDlg*>(pChildWindow->GetController().get()) : nullptr; @@ -1387,8 +1640,8 @@ IMPL_LINK_NOARG(SwBaseShell, GraphicArrivedHdl, SwCursorShell&, void) if( !bProtect ) { sal_uInt16 nId = SvxContourDlgChildWindow::GetChildWindowId(); - SfxChildWindow *pChildWindow = pVFrame->HasChildWindow(nId) ? - pVFrame->GetChildWindow(nId) : nullptr; + SfxChildWindow *pChildWindow = rVFrame.HasChildWindow(nId) ? + rVFrame.GetChildWindow(nId) : nullptr; SvxIMapDlg *pDlg = pChildWindow ? static_cast<SvxIMapDlg*>(pChildWindow->GetController().get()) : nullptr; if( pDlg && pDlg->GetEditingObject() != @@ -1403,7 +1656,7 @@ IMPL_LINK_NOARG(SwBaseShell, GraphicArrivedHdl, SwCursorShell&, void) case FN_FRAME_WRAP_CONTOUR: if( !bProtect ) { - SfxItemSet aSet(GetPool(), svl::Items<RES_SURROUND, RES_SURROUND>{}); + SfxItemSetFixed<RES_SURROUND, RES_SURROUND> aSet(GetPool()); rSh.GetFlyFrameAttr(aSet); const SwFormatSurround& rWrap = aSet.Get(RES_SURROUND); bSetState = true; @@ -1430,22 +1683,22 @@ IMPL_LINK_NOARG(SwBaseShell, GraphicArrivedHdl, SwCursorShell&, void) if( bSetState ) { SfxBoolItem aBool( nSlot, bState ); - if( pGetStateSet ) - pGetStateSet->Put( aBool ); + if( m_pGetStateSet ) + m_pGetStateSet->Put( aBool ); else - pVFrame->GetBindings().SetState( aBool ); + rVFrame.GetBindings().SetState( aBool ); } } - aGrfUpdateSlots.clear(); + m_aGrfUpdateSlots.clear(); } void SwBaseShell::GetState( SfxItemSet &rSet ) { SwWrtShell &rSh = GetShell(); - SfxViewFrame* pVFrame = GetView().GetViewFrame(); + SfxViewFrame& rVFrame = GetView().GetViewFrame(); SfxWhichIter aIter( rSet ); sal_uInt16 nWhich = aIter.FirstWhich(); - pGetStateSet = &rSet; + m_pGetStateSet = &rSet; while ( nWhich ) { switch ( nWhich ) @@ -1510,8 +1763,7 @@ void SwBaseShell::GetState( SfxItemSet &rSet ) break; case RES_SHADOW: { - SfxItemSet aSet( rSh.GetAttrPool(), - svl::Items<RES_SHADOW, RES_SHADOW>{} ); + SfxItemSetFixed<RES_SHADOW, RES_SHADOW> aSet( rSh.GetAttrPool()); // Table cell(s) selected? if ( rSh.IsTableMode() ) @@ -1544,7 +1796,7 @@ void SwBaseShell::GetState( SfxItemSet &rSet ) else { const sal_uInt16 nId = SvxIMapDlgChildWindow::GetChildWindowId(); - const bool bHas = pVFrame->HasChildWindow( nId ); + const bool bHas = rVFrame.HasChildWindow( nId ); const bool bFrameSel = rSh.IsFrameSelected(); const bool bIsGraphicSelection = rSh.GetSelectionType() == SelectionType::Graphic; @@ -1586,7 +1838,7 @@ void SwBaseShell::GetState( SfxItemSet &rSet ) if( !rSh.IsFrameSelected()) bDisable = true; sal_uInt16 nId = SvxIMapDlgChildWindow::GetChildWindowId(); - if(!bDisable && pVFrame->HasChildWindow( nId )) + if(!bDisable && rVFrame.HasChildWindow( nId )) { if(rSh.GetSelectionType() == SelectionType::Graphic && rSh.IsLinkedGrfSwapOut()) @@ -1624,7 +1876,7 @@ void SwBaseShell::GetState( SfxItemSet &rSet ) else { sal_uInt16 nId = SvxContourDlgChildWindow::GetChildWindowId(); - bool bHas = GetView().GetViewFrame()->HasChildWindow( nId ); + bool bHas = GetView().GetViewFrame().HasChildWindow( nId ); SelectionType nSel = rSh.GetSelectionType(); bool bOk(nSel & (SelectionType::Graphic|SelectionType::Ole)); @@ -1671,7 +1923,7 @@ void SwBaseShell::GetState( SfxItemSet &rSet ) if( !(nSel & (SelectionType::Graphic|SelectionType::Ole)) ) bDisable = true; sal_uInt16 nId = SvxContourDlgChildWindow::GetChildWindowId(); - if( !bDisable && GetView().GetViewFrame()->HasChildWindow( nId )) + if( !bDisable && GetView().GetViewFrame().HasChildWindow( nId )) { SvxContourDlg *pDlg = GetContourDlg(GetView()); if (pDlg && pDlg->GetEditingObject() != rSh.GetIMapInventor()) @@ -1693,7 +1945,7 @@ void SwBaseShell::GetState( SfxItemSet &rSet ) if( !bParentCntProt && (bObj || rSh.IsFrameSelected())) { - SfxItemSet aSet(GetPool(), svl::Items<RES_ANCHOR, RES_ANCHOR>{}); + SfxItemSetFixed<RES_ANCHOR, RES_ANCHOR> aSet(GetPool()); if(bObj) rSh.GetObjAttr(aSet); else @@ -1718,8 +1970,7 @@ void SwBaseShell::GetState( SfxItemSet &rSet ) if (comphelper::LibreOfficeKit::isActive()) { - if (nWhich == FN_TOOL_ANCHOR_PAGE || nWhich == FN_TOOL_ANCHOR_PARAGRAPH - || nWhich == FN_TOOL_ANCHOR_FRAME) + if (nWhich == FN_TOOL_ANCHOR_PAGE || nWhich == FN_TOOL_ANCHOR_FRAME) { rSet.DisableItem(nWhich); } @@ -1745,7 +1996,7 @@ void SwBaseShell::GetState( SfxItemSet &rSet ) if( !bParentCntProt && (bObj || rSh.IsFrameSelected())) { - SfxItemSet aSet(GetPool(), svl::Items<RES_OPAQUE, RES_ANCHOR>{}); + SfxItemSetFixed<RES_OPAQUE, RES_ANCHOR> aSet(GetPool()); RndStdIds nAnchorType; if(bObj) { @@ -1806,7 +2057,7 @@ void SwBaseShell::GetState( SfxItemSet &rSet ) break; case FN_FRAME_WRAP_CONTOUR: bDisable |= bHtmlMode; - //no contour available whenn no wrap or wrap through is set + //no contour available when no wrap or wrap through is set bDisable |= (nSurround == css::text::WrapTextMode_NONE || nSurround == css::text::WrapTextMode_THROUGH); if( !bDisable ) { @@ -1869,10 +2120,36 @@ void SwBaseShell::GetState( SfxItemSet &rSet ) else rSet.Put( SfxVisibilityItem( nWhich, false ) ); break; + case SID_GRAPHIC_SIZE_CHECK: + { + sal_Int32 nDPI = rSh.GetDoc()->getIDocumentSettingAccess().getImagePreferredDPI(); + if (nDPI <= 0) + rSet.DisableItem(nWhich); + } + break; + case SID_THEME_DIALOG: + { + bool bDisable = true; + auto* pDocument = rSh.GetDoc(); + auto* pDocumentShell = pDocument->GetDocShell(); + if (pDocumentShell) + { + SdrModel* pModel = pDocument->getIDocumentDrawModelAccess().GetDrawModel(); + if (pModel) + { + auto const& pTheme = pModel->getTheme(); + if (pTheme) + bDisable = false; + } + } + if (bDisable) + rSet.DisableItem(nWhich); + } + break; } nWhich = aIter.NextWhich(); } - pGetStateSet = nullptr; + m_pGetStateSet = nullptr; } // Disable the slots with this status method @@ -1921,7 +2198,7 @@ void SwBaseShell::SetWrapMode( sal_uInt16 nSlot ) if( !bObj && !rSh.IsFrameSelected()) return; - SfxItemSet aSet(GetPool(), svl::Items<RES_OPAQUE, RES_SURROUND>{}); + SfxItemSetFixed<RES_OPAQUE, RES_SURROUND> aSet(GetPool()); if(bObj) rSh.GetObjAttr(aSet); else @@ -2025,8 +2302,8 @@ void SwBaseShell::SetWrapMode( sal_uInt16 nSlot ) void SwBaseShell::SetFrameMode(FlyMode eMode, SwWrtShell *pSh ) { - eFrameMode = eMode; - SfxBindings &rBnd = pSh->GetView().GetViewFrame()->GetBindings(); + s_eFrameMode = eMode; + SfxBindings &rBnd = pSh->GetView().GetViewFrame().GetBindings(); if( eMode == FLY_DRAG || pSh->IsFrameSelected() || pSh->IsObjSelected() ) { @@ -2047,10 +2324,10 @@ void SwBaseShell::SetFrameMode(FlyMode eMode, SwWrtShell *pSh ) SwBaseShell::SwBaseShell(SwView& rVw) : SfxShell( &rVw ), - rView(rVw), - pGetStateSet(nullptr) + m_rView(rVw), + m_pGetStateSet(nullptr) { - SwWrtShell& rWrtSh = rView.GetWrtShell(); + SwWrtShell& rWrtSh = m_rView.GetWrtShell(); SetPool(&rWrtSh.GetAttrPool()); SetName("Base"); @@ -2059,29 +2336,30 @@ SwBaseShell::SwBaseShell(SwView& rVw) : SwBaseShell::~SwBaseShell() { - if( rView.GetCurShell() == this ) - rView.ResetSubShell(); + if( m_rView.GetCurShell() == this ) + m_rView.ResetSubShell(); Link<SwCursorShell&,void> aTmp( LINK( this, SwBaseShell, GraphicArrivedHdl)); - if( aTmp == rView.GetWrtShell().GetGrfArrivedLnk() ) - rView.GetWrtShell().SetGrfArrivedLnk( Link<SwCursorShell&,void>() ); + 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; - sal_uInt16 nSlot = rReq.GetSlot(); SfxItemPool& rPool = rSh.GetAttrPool(); - sal_uInt16 nWhich = rPool.GetWhich( nSlot ); + sal_uInt16 nWhich = rPool.GetWhichIDFromSlotID( nSlot ); SvtScriptType nScripts = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX; - SfxItemSet aHeightSet( GetPool(), svl::Items<RES_CHRATR_FONTSIZE, RES_CHRATR_FONTSIZE, - RES_CHRATR_CJK_FONTSIZE, RES_CHRATR_CJK_FONTSIZE, - RES_CHRATR_CTL_FONTSIZE, RES_CHRATR_CTL_FONTSIZE>{}); + 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 ) { @@ -2123,9 +2401,10 @@ void SwBaseShell::ExecTextCtrl( SfxRequest& rReq ) sal_uInt32 nHeight = static_cast< const SvxFontHeightItem& >(pArgs->Get( nWhich )).GetHeight(); SwStdFontConfig* pStdFont = SW_MOD()->GetStdFontConfig(); - SfxItemSet aLangSet( GetPool(), svl::Items<RES_CHRATR_LANGUAGE, RES_CHRATR_LANGUAGE, - RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CJK_LANGUAGE, - RES_CHRATR_CTL_LANGUAGE, RES_CHRATR_CTL_LANGUAGE>{}); + 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 = @@ -2173,7 +2452,7 @@ void SwBaseShell::ExecTextCtrl( SfxRequest& rReq ) ( rSh.HasSelection() && rSh.IsSelFullPara() ) ) { SwTextFormatColl * pColl = rSh.GetCurTextFormatColl(); - if ( pColl && pColl->IsAutoUpdateFormat() ) + if ( pColl && pColl->IsAutoUpdateOnDirectFormat() ) { rSh.AutoUpdatePara( pColl, *pArgs ); bAuto = true; @@ -2187,7 +2466,14 @@ void SwBaseShell::ExecTextCtrl( SfxRequest& rReq ) } } else - GetView().GetViewFrame()->GetDispatcher()->Execute( SID_CHAR_DLG ); + { + 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(); } @@ -2201,7 +2487,7 @@ void SwBaseShell::GetTextFontCtrlState( SfxItemSet& rSet ) { SwWrtShell &rSh = GetShell(); bool bFirst = true; - std::unique_ptr<SfxItemSet> pFntCoreSet; + std::optional<SfxItemSet> pFntCoreSet; SvtScriptType nScriptType = SvtScriptType::LATIN; SfxWhichIter aIter( rSet ); sal_uInt16 nWhich = aIter.FirstWhich(); @@ -2216,8 +2502,8 @@ void SwBaseShell::GetTextFontCtrlState( SfxItemSet& rSet ) { if( !pFntCoreSet ) { - pFntCoreSet.reset(new SfxItemSet( *rSet.GetPool(), - svl::Items<RES_CHRATR_BEGIN, RES_CHRATR_END-1>{} )); + 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 @@ -2293,7 +2579,7 @@ void SwBaseShell::GetBckColState(SfxItemSet &rSet) else { // Adapt to new DrawingLayer FillStyle; use a parent which has XFILL_NONE set - SfxItemSet aCoreSet(GetPool(), svl::Items<XATTR_FILL_FIRST, XATTR_FILL_LAST>{}); + SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aCoreSet(GetPool()); aCoreSet.SetParent(&GetView().GetDocShell()->GetDoc()->GetDfltFrameFormat()->GetAttrSet()); @@ -2316,7 +2602,7 @@ void SwBaseShell::GetBckColState(SfxItemSet &rSet) case SID_BACKGROUND_COLOR: case SID_TABLE_CELL_BACKGROUND_COLOR: { - SvxColorItem aColorItem(aBrushItem->GetColor(), nWhich); + SvxColorItem aColorItem(aBrushItem->GetColor(), aBrushItem->getComplexColor(), nWhich); rSet.Put(aColorItem); break; } @@ -2357,7 +2643,7 @@ void SwBaseShell::ExecBckCol(SfxRequest& rReq) else { // Adapt to new DrawingLayer FillStyle; use a parent which has XFILL_NONE set - SfxItemSet aCoreSet(GetPool(), svl::Items<XATTR_FILL_FIRST, XATTR_FILL_LAST>{}); + SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aCoreSet(GetPool()); aCoreSet.SetParent(&GetView().GetDocShell()->GetDoc()->GetDfltFrameFormat()->GetAttrSet()); @@ -2378,37 +2664,17 @@ void SwBaseShell::ExecBckCol(SfxRequest& rReq) 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) + 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); + aBrushItem->SetColor(rNewColorItem.GetValue()); + aBrushItem->setComplexColor(rNewColorItem.getComplexColor()); + GetView().GetViewFrame().GetBindings().SetState(rNewColorItem); } else { @@ -2427,7 +2693,7 @@ void SwBaseShell::ExecBckCol(SfxRequest& rReq) 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())); + aBrushItem.reset(static_cast<SvxBrushItem*>(pArgs->Get(GetPool().GetWhichIDFromSlotID(nSlot)).Clone())); break; } default: @@ -2445,7 +2711,7 @@ void SwBaseShell::ExecBckCol(SfxRequest& rReq) else { // Adapt to new DrawingLayer FillStyle; use a parent which has XFILL_NONE set - SfxItemSet aCoreSet(GetPool(), svl::Items<XATTR_FILL_FIRST, XATTR_FILL_LAST>{}); + SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aCoreSet(GetPool()); aCoreSet.SetParent(&GetView().GetDocShell()->GetDoc()->GetDfltFrameFormat()->GetAttrSet()); setSvxBrushItemAsFillAttributesToTargetSet(*aBrushItem, aCoreSet); @@ -2455,7 +2721,7 @@ void SwBaseShell::ExecBckCol(SfxRequest& rReq) // Template autoupdate SwFrameFormat* pFormat = rSh.GetSelectedFrameFormat(); - if(pFormat && pFormat->IsAutoUpdateFormat()) + if(pFormat && pFormat->IsAutoUpdateOnDirectFormat()) { rSh.AutoUpdateFrame(pFormat, aCoreSet); } @@ -2468,7 +2734,7 @@ void SwBaseShell::ExecBckCol(SfxRequest& rReq) { SwTextFormatColl* pColl = rSh.GetCurTextFormatColl(); - if(pColl && pColl->IsAutoUpdateFormat()) + if(pColl && pColl->IsAutoUpdateOnDirectFormat()) { rSh.AutoUpdatePara(pColl, aCoreSet); } @@ -2485,14 +2751,13 @@ void SwBaseShell::ExecBckCol(SfxRequest& rReq) void SwBaseShell::GetBorderState(SfxItemSet &rSet) { SwWrtShell &rSh = GetShell(); - // Tabele cell(s) selected? + // Table cell(s) selected? bool bPrepare = true; bool bTableMode = rSh.IsTableMode(); if ( bTableMode ) { - SfxItemSet aCoreSet( GetPool(), - svl::Items<RES_BOX, RES_BOX, - SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER>{} ); + 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 ); @@ -2526,7 +2791,7 @@ void SwBaseShell::ExecDlg(SfxRequest &rReq) const SfxItemSet* pOutSet = nullptr; bool bDone = false; if(pArgs) - pArgs->GetItemState( GetPool().GetWhich(nSlot), false, &pItem ); + pArgs->GetItemState( GetPool().GetWhichIDFromSlotID(nSlot), false, &pItem ); switch ( nSlot ) { @@ -2542,6 +2807,7 @@ void SwBaseShell::ExecDlg(SfxRequest &rReq) case FN_FORMAT_PAGE_DLG: case FN_FORMAT_PAGE_COLUMN_DLG: case FN_FORMAT_PAGE_SETTING_DLG: + case FN_FORMAT_PAGE_AREA_DLG: { if( !bBackground ) { @@ -2551,7 +2817,7 @@ void SwBaseShell::ExecDlg(SfxRequest &rReq) // for example disable header SwView& rTempView = GetView(); - OString sPageId; + OUString sPageId; switch (nSlot) { case FN_FORMAT_PAGE_COLUMN_DLG: @@ -2560,12 +2826,15 @@ void SwBaseShell::ExecDlg(SfxRequest &rReq) case FN_FORMAT_PAGE_SETTING_DLG: sPageId = "page"; break; + case FN_FORMAT_PAGE_AREA_DLG: + sPageId = "area"; + break; case FN_FORMAT_PAGE_DLG: if (pItem) - sPageId = OUStringToOString(static_cast<const SfxStringItem*>(pItem)->GetValue(), RTL_TEXTENCODING_UTF8); + sPageId = static_cast<const SfxStringItem*>(pItem)->GetValue(); break; } - rTempView.GetDocShell()->FormatPage(rPageDesc.GetName(), sPageId, rSh, &rReq); + rTempView.GetDocShell()->FormatPage(rReq.GetFrameWeld(), rPageDesc.GetName(), sPageId, rSh, &rReq); rTempView.InvalidateRulerPos(); bDone = true; // FormatPage() takes care of calling Done() @@ -2574,9 +2843,8 @@ void SwBaseShell::ExecDlg(SfxRequest &rReq) break; case FN_FORMAT_BORDER_DLG: { - SfxItemSet aSet( rSh.GetAttrPool(), - svl::Items<RES_BOX , RES_SHADOW, - SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER>{} ); + 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() ) @@ -2630,9 +2898,8 @@ void SwBaseShell::ExecDlg(SfxRequest &rReq) break; case FN_FORMAT_BACKGROUND_DLG: { - SfxItemSet aSet( rSh.GetAttrPool(), - svl::Items<RES_BACKGROUND, RES_BACKGROUND, - XATTR_FILL_FIRST, XATTR_FILL_LAST>{} ); + SfxItemSetFixed<RES_BACKGROUND, RES_BACKGROUND, + XATTR_FILL_FIRST, XATTR_FILL_LAST> aSet( rSh.GetAttrPool() ); ScopedVclPtr<SfxAbstractDialog> pDlg; SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); @@ -2641,10 +2908,11 @@ void SwBaseShell::ExecDlg(SfxRequest &rReq) if ( rSh.IsTableMode() ) { // Get background attributes of the table and put it in the set - std::unique_ptr<SvxBrushItem> aBrush; + // 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( *aBrush ); + aSet.Put( std::move(aBrush) ); if ( pDlg->Execute() == RET_OK ) { @@ -2683,14 +2951,42 @@ void SwBaseShell::ExecDlg(SfxRequest &rReq) } } break; - case SID_ACCESSIBILITY_CHECK: + + case SID_GRAPHIC_SIZE_CHECK: { - sw::AccessibilityCheck aCheck(rSh.GetDoc()); - aCheck.check(); - svx::AccessibilityCheckDialog aDialog(pMDI, aCheck.getIssueCollection()); + sw::GraphicSizeCheckGUIResult aResult(rSh.GetDoc()); + svx::GenericCheckDialog aDialog(pMDI, aResult); aDialog.run(); } break; + + case SID_THEME_DIALOG: + { + auto* pDocument = rSh.GetDoc(); + auto* pDocumentShell = pDocument->GetDocShell(); + if (pDocumentShell) + { + SdrModel* pModel = pDocument->getIDocumentDrawModelAccess().GetDrawModel(); + auto const& pTheme = pModel->getTheme(); + if (pTheme) + { + std::shared_ptr<svx::IThemeColorChanger> xChanger(new sw::ThemeColorChanger(pDocumentShell)); + auto pDialog = std::make_shared<svx::ThemeDialog>(pMDI, pTheme.get()); + weld::DialogController::runAsync(pDialog, [pDialog, xChanger=std::move(xChanger)](sal_uInt32 nResult) { + if (RET_OK != nResult) + return; + + auto pColorSet = pDialog->getCurrentColorSet(); + if (pColorSet) + { + xChanger->apply(pColorSet); + } + }); + } + } + } + break; + default:OSL_FAIL("wrong Dispatcher (basesh.cxx)"); } if(!bDone) @@ -2699,12 +2995,12 @@ void SwBaseShell::ExecDlg(SfxRequest &rReq) SwWrtShell& SwBaseShell::GetShell() { - return rView.GetWrtShell(); + return m_rView.GetWrtShell(); } SwWrtShell* SwBaseShell::GetShellPtr() { - return rView.GetWrtShellPtr(); + return m_rView.GetWrtShellPtr(); } static void EndUndo(SwWrtShell& rSh) @@ -2740,7 +3036,7 @@ static void InsertTableImpl(SwWrtShell& rSh, rSh.MoveTable( GotoPrevTable, fnTableStart ); if( !aTableName.isEmpty() && !rSh.GetTableStyle( aTableName ) ) - rSh.GetTableFormat()->SetName( aTableName ); + rSh.GetTableFormat()->SetFormatName( aTableName ); if( pTAFormat != nullptr && !aAutoName.isEmpty() && aAutoName != SwViewShell::GetShellRes()->aStrNone ) @@ -3002,7 +3298,7 @@ void SwBaseShell::ExecuteGallery(SfxRequest &rReq) rSh.SetBoxBackground( aBrush ); else if ( nPos == nFramePos || nPos == nGraphicPos || nPos == nOlePos ) { - SfxItemSet aCoreSet(GetPool(), svl::Items<RES_BACKGROUND, RES_BACKGROUND>{}); + SfxItemSetFixed<RES_BACKGROUND, RES_BACKGROUND> aCoreSet(GetPool()); aCoreSet.Put( aBrush ); rSh.SetFlyFrameAttr( aCoreSet ); } @@ -3038,12 +3334,19 @@ void SwBaseShell::ExecField( SfxRequest const & rReq ) sal_uInt16 nSlot = rReq.GetSlot(); switch( nSlot ) { -#if HAVE_FEATURE_DBCONNECTIVITY +#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS case FN_CHANGE_DBFIELD: { SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); - ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSwChangeDBDlg(GetView())); - pDlg->Execute(); + VclPtr<AbstractChangeDbDialog> pDlg(pFact->CreateSwChangeDBDlg(GetView())); + pDlg->StartExecuteAsync( + [pDlg] (sal_Int32 nResult)->void + { + if (nResult == RET_OK) + pDlg->UpdateFields(); + pDlg->disposeOnce(); + } + ); } break; #endif @@ -3052,4 +3355,16 @@ void SwBaseShell::ExecField( SfxRequest const & rReq ) } } +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 index 73bbc88acbc8..2c4510fd7aa0 100644 --- a/sw/source/uibase/shells/beziersh.cxx +++ b/sw/source/uibase/shells/beziersh.cxx @@ -65,8 +65,8 @@ void SwBezierShell::Execute(SfxRequest const &rReq) SdrView* pSdrView = pSh->GetDrawView(); const SfxItemSet *pArgs = rReq.GetArgs(); sal_uInt16 nSlotId = rReq.GetSlot(); - bool bChanged = pSdrView->GetModel()->IsChanged(); - pSdrView->GetModel()->SetChanged(false); + bool bChanged = pSdrView->GetModel().IsChanged(); + pSdrView->GetModel().SetChanged(false); const SfxPoolItem* pItem; if(pArgs) pArgs->GetItemState(nSlotId, false, &pItem); @@ -78,7 +78,7 @@ void SwBezierShell::Execute(SfxRequest const &rReq) if (pSh->IsObjSelected()) { if (pSdrView->HasMarkedPoints()) - pSh->GetView().GetViewFrame()->GetDispatcher()->Execute(SID_BEZIER_DELETE); + pSh->GetView().GetViewFrame().GetDispatcher()->Execute(SID_BEZIER_DELETE); else { pSh->DelSelectedObj(); @@ -121,7 +121,7 @@ void SwBezierShell::Execute(SfxRequest const &rReq) SID_BEZIER_MOVE, 0 }; - GetView().GetViewFrame()->GetBindings().Invalidate(aInva); + GetView().GetViewFrame().GetBindings().Invalidate(aInva); } break; @@ -182,7 +182,7 @@ void SwBezierShell::Execute(SfxRequest const &rReq) SID_BEZIER_SYMMTR, 0 }; - GetView().GetViewFrame()->GetBindings().Invalidate(aInva); + GetView().GetViewFrame().GetBindings().Invalidate(aInva); } break; } @@ -208,10 +208,10 @@ void SwBezierShell::Execute(SfxRequest const &rReq) break; } - if (pSdrView->GetModel()->IsChanged()) + if (pSdrView->GetModel().IsChanged()) GetShell().SetModified(); else if (bChanged) - pSdrView->GetModel()->SetChanged(); + pSdrView->GetModel().SetChanged(); } void SwBezierShell::GetState(SfxItemSet &rSet) diff --git a/sw/source/uibase/shells/drawdlg.cxx b/sw/source/uibase/shells/drawdlg.cxx index 47b4064642e0..b778ea9b806e 100644 --- a/sw/source/uibase/shells/drawdlg.cxx +++ b/sw/source/uibase/shells/drawdlg.cxx @@ -41,17 +41,15 @@ #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); + SdrModel& rModel = pView->GetModel(); + bool bChanged = rModel.IsChanged(); + rModel.SetChanged(false); - SfxItemSet aNewAttr( pDoc->GetItemPool() ); + SfxItemSet aNewAttr(rModel.GetItemPool()); pView->GetAttributes( aNewAttr ); GetView().NoRotate(); @@ -61,26 +59,32 @@ void SwDrawShell::ExecDrawDlg(SfxRequest& rReq) 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()) + VclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateTextTabDialog(rReq.GetFrameWeld(), &aNewAttr, pView)); + auto xRequest = std::make_shared<SfxRequest>(rReq); + rReq.Ignore(); // the 'old' request is not relevant any more + pDlg->StartExecuteAsync( + [pDlg, xRequest=std::move(xRequest), pView, pSh] (sal_Int32 nResult)->void { - pSh->StartAction(); - pView->SetAttributes(*pDlg->GetOutputItemSet()); - auto vMarkedObjs = pView->GetMarkedObjects(); - for (auto pObj : vMarkedObjs) + if (nResult == RET_OK) { - // If the shape has textframe, set its params as well. - if (SwTextBoxHelper::hasTextFrame(pObj)) - SwTextBoxHelper::updateTextBoxMargin(pObj); + 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); + } + xRequest->Done(*(pDlg->GetOutputItemSet())); + pSh->EndAction(); + } } - rReq.Done(*(pDlg->GetOutputItemSet())); - pSh->EndAction(); + pDlg->disposeOnce(); } - } + ); } break; @@ -110,11 +114,14 @@ void SwDrawShell::ExecDrawDlg(SfxRequest& rReq) SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); VclPtr<AbstractSvxAreaTabDialog> pDlg(pFact->CreateSvxAreaTabDialog(rReq.GetFrameWeld(), &aNewAttr, - pDoc, - true)); + &rModel, + true, + false)); - pDlg->StartExecuteAsync([bChanged, bHasMarked, pDoc, pDlg, pSh, pView, this]( + pDlg->StartExecuteAsync([bChanged, bHasMarked, &rModel, pDlg, pSh, pView, this]( sal_Int32 nResult){ + rModel.SetChanged(false); + if (nResult == RET_OK) { pSh->StartAction(); @@ -132,7 +139,7 @@ void SwDrawShell::ExecDrawDlg(SfxRequest& rReq) SID_ATTR_FILL_FLOATTRANSPARENCE, 0 }; - SfxBindings &rBnd = GetView().GetViewFrame()->GetBindings(); + SfxBindings &rBnd = GetView().GetViewFrame().GetBindings(); rBnd.Invalidate(aInval); rBnd.Update(SID_ATTR_FILL_STYLE); rBnd.Update(SID_ATTR_FILL_COLOR); @@ -140,10 +147,10 @@ void SwDrawShell::ExecDrawDlg(SfxRequest& rReq) rBnd.Update(SID_ATTR_FILL_FLOATTRANSPARENCE); } - if (pDoc->IsChanged()) + if (rModel.IsChanged()) GetShell().SetModified(); else if (bChanged) - pDoc->SetChanged(); + rModel.SetChanged(); pDlg->disposeOnce(); }); @@ -162,12 +169,14 @@ void SwDrawShell::ExecDrawDlg(SfxRequest& rReq) SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); VclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateSvxLineTabDialog(rReq.GetFrameWeld(), &aNewAttr, - pDoc, + &rModel, pObj, bHasMarked)); - pDlg->StartExecuteAsync([bChanged, bHasMarked, pDoc, pDlg, pSh, pView, this]( + pDlg->StartExecuteAsync([bChanged, bHasMarked, &rModel, pDlg, pSh, pView, this]( sal_Int32 nResult){ + rModel.SetChanged(false); + if (nResult == RET_OK) { pSh->StartAction(); @@ -191,13 +200,13 @@ void SwDrawShell::ExecDrawDlg(SfxRequest& rReq) 0 }; - GetView().GetViewFrame()->GetBindings().Invalidate(aInval); + GetView().GetViewFrame().GetBindings().Invalidate(aInval); } - if (pDoc->IsChanged()) + if (rModel.IsChanged()) GetShell().SetModified(); else if (bChanged) - pDoc->SetChanged(); + rModel.SetChanged(); pDlg->disposeOnce(); }); @@ -208,49 +217,19 @@ void SwDrawShell::ExecDrawDlg(SfxRequest& rReq) break; } - if (pDoc->IsChanged()) + if (rModel.IsChanged()) GetShell().SetModified(); - else - if (bChanged) - pDoc->SetChanged(); + else if (bChanged) + rModel.SetChanged(); } namespace { - void lcl_convertStringArguments(sal_uInt16 nSlot, const std::unique_ptr<SfxItemSet>& pArgs) + void lcl_convertStringArguments(const std::unique_ptr<SfxItemSet>& pArgs) { - Color aColor; - const SfxPoolItem* pItem = nullptr; - - if (SfxItemState::SET == pArgs->GetItemState(SID_ATTR_COLOR_STR, false, &pItem)) + if (const SvxDoubleItem* pWidthItem = pArgs->GetItemIfSet(SID_ATTR_LINE_WIDTH_ARG, false)) { - 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 (SfxItemState::SET == pArgs->GetItemState(SID_ATTR_LINE_WIDTH_ARG, false, &pItem)) - { - double fValue = static_cast<const SvxDoubleItem*>(pItem)->GetValue(); + double fValue = pWidthItem->GetValue(); // FIXME: different units... int nPow = 100; int nValue = fValue * nPow; @@ -258,15 +237,11 @@ namespace XLineWidthItem aItem(nValue); pArgs->Put(aItem); } - if (SfxItemState::SET == pArgs->GetItemState(SID_FILL_GRADIENT_JSON, false, &pItem)) + if (const SfxStringItem* pJSON = pArgs->GetItemIfSet(SID_FILL_GRADIENT_JSON, false)) { - const SfxStringItem* pJSON = static_cast<const SfxStringItem*>(pItem); - if (pJSON) - { - XGradient aGradient = XGradient::fromJSON(pJSON->GetValue()); - XFillGradientItem aItem(aGradient); - pArgs->Put(aItem); - } + basegfx::BGradient aGradient = basegfx::BGradient::fromJSON(pJSON->GetValue()); + XFillGradientItem aItem(aGradient); + pArgs->Put(aItem); } } } @@ -276,8 +251,8 @@ 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); + bool bChanged = pView->GetModel().IsChanged(); + pView->GetModel().SetChanged(false); GetView().NoRotate(); @@ -286,7 +261,7 @@ void SwDrawShell::ExecDrawAttrArgs(SfxRequest const & rReq) if(pView->AreObjectsMarked()) { std::unique_ptr<SfxItemSet> pNewArgs = pArgs->Clone(); - lcl_convertStringArguments(rReq.GetSlot(), pNewArgs); + lcl_convertStringArguments(pNewArgs); pView->SetAttrToMarked(*pNewArgs, false); } else @@ -294,7 +269,7 @@ void SwDrawShell::ExecDrawAttrArgs(SfxRequest const & rReq) } else { - SfxDispatcher* pDis = pSh->GetView().GetViewFrame()->GetDispatcher(); + SfxDispatcher* pDis = pSh->GetView().GetViewFrame().GetDispatcher(); switch (rReq.GetSlot()) { case SID_ATTR_FILL_STYLE: @@ -317,16 +292,16 @@ void SwDrawShell::ExecDrawAttrArgs(SfxRequest const & rReq) break; } } - if (pView->GetModel()->IsChanged()) + if (pView->GetModel().IsChanged()) GetShell().SetModified(); else if (bChanged) - pView->GetModel()->SetChanged(); + pView->GetModel().SetChanged(); } static void lcl_unifyFillTransparencyItems(const SfxItemSet& rSet) { - // Transparent fill options are None, Solid, Linear, Axial, Radial, Elliptical, Quadratic, Square. + // Transparent fill options are None, Solid, Linear, Axial, Radial, Elliptical, Square, Rectangular. // But this is represented across two items namely XFillTransparenceItem (for None and Solid) // and XFillFloatTransparenceItem (for the rest). To simplify the representation in LOKit case let's // use XFillFloatTransparenceItem to carry the information of XFillTransparenceItem when gradients @@ -348,7 +323,7 @@ static void lcl_unifyFillTransparencyItems(const SfxItemSet& rSet) if (!pFillTranspItem) return; - XGradient aTmpGradient = pFillFloatTranspItem->GetGradientValue(); + basegfx::BGradient aTmpGradient = pFillFloatTranspItem->GetGradientValue(); sal_uInt16 nTranspPercent = pFillTranspItem->GetValue(); // Encode transparency percentage as intensity sal_uInt16 nIntensity = 100 - std::min<sal_uInt16> @@ -368,7 +343,24 @@ void SwDrawShell::GetDrawAttrState(SfxItemSet& rSet) if( !bDisable ) { - pSdrView->GetAttributes( rSet ); + 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); } diff --git a/sw/source/uibase/shells/drawsh.cxx b/sw/source/uibase/shells/drawsh.cxx index 09b6bdbb3a0d..23c4dd61872d 100644 --- a/sw/source/uibase/shells/drawsh.cxx +++ b/sw/source/uibase/shells/drawsh.cxx @@ -42,6 +42,7 @@ #include <svx/svdundo.hxx> #include <svx/xbtmpit.hxx> #include <svx/sdasitm.hxx> +#include <osl/diagnose.h> #include <swundo.hxx> #include <wrtsh.hxx> @@ -132,29 +133,29 @@ void SwDrawShell::InsertPictureFromFile(SdrObject& rObject) if (SdrGrafObj* pSdrGrafObj = dynamic_cast<SdrGrafObj*>(&rObject)) { - SdrGrafObj* pNewGrafObj(pSdrGrafObj->CloneSdrObject(pSdrGrafObj->getSdrModelFromSdrObject())); + rtl::Reference<SdrGrafObj> pNewGrafObj = SdrObject::Clone(*pSdrGrafObj, pSdrGrafObj->getSdrModelFromSdrObject()); pNewGrafObj->SetGraphic(aGraphic); // #i123922# for handling MasterObject and virtual ones correctly, SW // wants us to call ReplaceObject at the page, but that also // triggers the same assertion (I tried it), so stay at the view method - pSdrView->ReplaceObjectAtView(&rObject, *pSdrView->GetSdrPageView(), pNewGrafObj); + pSdrView->ReplaceObjectAtView(&rObject, *pSdrView->GetSdrPageView(), pNewGrafObj.get()); // set in all cases - the Clone() will have copied an existing link (!) pNewGrafObj->SetGraphicLink( bAsLink ? aDlg.GetPath() : OUString()); - pResult = pNewGrafObj; + pResult = pNewGrafObj.get(); } else // if(rObject.IsClosedObj() && !dynamic_cast< SdrOle2Obj* >(&rObject)) { pSdrView->AddUndo(std::make_unique<SdrUndoAttrObj>(rObject)); - SfxItemSet aSet(pSdrView->GetModel()->GetItemPool(), svl::Items<XATTR_FILLSTYLE, XATTR_FILLBITMAP>{}); + SfxItemSetFixed<XATTR_FILLSTYLE, XATTR_FILLBITMAP> aSet(pSdrView->GetModel().GetItemPool()); aSet.Put(XFillStyleItem(drawing::FillStyle_BITMAP)); - aSet.Put(XFillBitmapItem(OUString(), aGraphic)); + aSet.Put(XFillBitmapItem(OUString(), std::move(aGraphic))); rObject.SetMergedItemSetAndBroadcast(aSet); } @@ -172,11 +173,11 @@ void SwDrawShell::Execute(SfxRequest &rReq) SwWrtShell &rSh = GetShell(); SdrView *pSdrView = rSh.GetDrawView(); const SfxItemSet *pArgs = rReq.GetArgs(); - SfxBindings &rBnd = GetView().GetViewFrame()->GetBindings(); + SfxBindings &rBnd = GetView().GetViewFrame().GetBindings(); sal_uInt16 nSlotId = rReq.GetSlot(); - bool bChanged = pSdrView->GetModel()->IsChanged(); + bool bChanged = pSdrView->GetModel().IsChanged(); - pSdrView->GetModel()->SetChanged(false); + pSdrView->GetModel().SetChanged(false); const SfxPoolItem* pItem; if(pArgs) @@ -197,7 +198,35 @@ void SwDrawShell::Execute(SfxRequest &rReq) 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()) { @@ -262,15 +291,15 @@ void SwDrawShell::Execute(SfxRequest &rReq) { 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(); + SfxViewFrame& rVFrame = GetView().GetViewFrame(); if (pArgs) { - pVFrame->SetChildWindow(SvxFontWorkChildWindow::GetChildWindowId(), + rVFrame.SetChildWindow(SvxFontWorkChildWindow::GetChildWindowId(), static_cast<const SfxBoolItem&>((pArgs->Get(SID_FONTWORK))).GetValue()); } else - pVFrame->ToggleChildWindow( SvxFontWorkChildWindow::GetChildWindowId() ); - pVFrame->GetBindings().Invalidate(SID_FONTWORK); + rVFrame.ToggleChildWindow( SvxFontWorkChildWindow::GetChildWindowId() ); + rVFrame.GetBindings().Invalidate(SID_FONTWORK); } break; case FN_FORMAT_FOOTNOTE_DLG: @@ -348,7 +377,7 @@ void SwDrawShell::Execute(SfxRequest &rReq) { SwFrameFormat* pFrameFormat = ::FindFrameFormat(pObj); if (pFrameFormat) - SwTextBoxHelper::create(pFrameFormat, pObj->HasText()); + SwTextBoxHelper::create(pFrameFormat, pObj, pObj->HasText()); } break; } @@ -358,7 +387,7 @@ void SwDrawShell::Execute(SfxRequest &rReq) { SwFrameFormat* pFrameFormat = ::FindFrameFormat(pObj); if (pFrameFormat) - SwTextBoxHelper::destroy(pFrameFormat); + SwTextBoxHelper::destroy(pFrameFormat, pObj); } break; } @@ -366,10 +395,10 @@ void SwDrawShell::Execute(SfxRequest &rReq) OSL_ENSURE(false, "wrong dispatcher"); return; } - if (pSdrView->GetModel()->IsChanged()) + if (pSdrView->GetModel().IsChanged()) rSh.SetModified(); else if (bChanged) - pSdrView->GetModel()->SetChanged(); + pSdrView->GetModel().SetChanged(); } void SwDrawShell::GetState(SfxItemSet& rSet) @@ -450,7 +479,7 @@ void SwDrawShell::GetState(SfxItemSet& rSet) else { const sal_uInt16 nId = SvxFontWorkChildWindow::GetChildWindowId(); - rSet.Put(SfxBoolItem( nWhich , GetView().GetViewFrame()->HasChildWindow(nId))); + rSet.Put(SfxBoolItem( nWhich , GetView().GetViewFrame().HasChildWindow(nId))); } } break; @@ -474,7 +503,7 @@ void SwDrawShell::GetState(SfxItemSet& rSet) { 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)) + if (pFrameFormat && pFrameFormat->Which() == RES_DRAWFRMFMT && !SwTextBoxHelper::isTextBox(pFrameFormat, RES_DRAWFRMFMT, pObj)) { if (SdrObjCustomShape* pCustomShape = dynamic_cast<SdrObjCustomShape*>( pObj) ) { @@ -497,7 +526,7 @@ void SwDrawShell::GetState(SfxItemSet& rSet) { SwFrameFormat* pFrameFormat = ::FindFrameFormat(pObj); // Allow removing a TextBox only in case it has one. - if (pFrameFormat && SwTextBoxHelper::isTextBox(pFrameFormat, RES_DRAWFRMFMT)) + if (pFrameFormat && SwTextBoxHelper::isTextBox(pFrameFormat, RES_DRAWFRMFMT, pObj)) bDisable = false; } @@ -517,7 +546,15 @@ SwDrawShell::SwDrawShell(SwView &_rView) : { SetName("Draw"); - SfxShell::SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::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 @@ -526,8 +563,8 @@ void SwDrawShell::ExecFormText(SfxRequest const & rReq) { SwWrtShell &rSh = GetShell(); SdrView* pDrView = rSh.GetDrawView(); - bool bChanged = pDrView->GetModel()->IsChanged(); - pDrView->GetModel()->SetChanged(false); + bool bChanged = pDrView->GetModel().IsChanged(); + pDrView->GetModel().SetChanged(false); const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList(); @@ -543,11 +580,11 @@ void SwDrawShell::ExecFormText(SfxRequest const & rReq) pDrView->SetAttributes(rSet); } - if (pDrView->GetModel()->IsChanged()) + if (pDrView->GetModel().IsChanged()) rSh.SetModified(); else if (bChanged) - pDrView->GetModel()->SetChanged(); + pDrView->GetModel().SetChanged(); } //Return status values for FontWork @@ -562,7 +599,7 @@ void SwDrawShell::GetFormTextState(SfxItemSet& rSet) if ( rMarkList.GetMarkCount() == 1 ) pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); - const SdrTextObj* pTextObj = dynamic_cast< const SdrTextObj* >(pObj); + const SdrTextObj* pTextObj = DynCastSdrTextObj(pObj); const bool bDeactivate( !pObj || !pTextObj || diff --git a/sw/source/uibase/shells/drformsh.cxx b/sw/source/uibase/shells/drformsh.cxx index 2e2f5fd5210b..fcf2eab803d1 100644 --- a/sw/source/uibase/shells/drformsh.cxx +++ b/sw/source/uibase/shells/drformsh.cxx @@ -31,6 +31,7 @@ #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> @@ -86,10 +87,10 @@ void SwDrawFormShell::Execute(SfxRequest const &rReq) { //remove object -> results in destruction of this! SwView& rTempView = GetView(); - rTempView.GetViewFrame()->GetDispatcher()->Execute(SID_DELETE, SfxCallMode::SYNCHRON ); + rTempView.GetViewFrame().GetDispatcher()->Execute(SID_DELETE, SfxCallMode::SYNCHRON ); rTempView.StopShellTimer(); //issue a new command to insert the link - rTempView.GetViewFrame()->GetDispatcher()->ExecuteList( + rTempView.GetViewFrame().GetDispatcher()->ExecuteList( SID_HYPERLINK_SETLINK, SfxCallMode::ASYNCHRON, { &rHLinkItem }); } diff --git a/sw/source/uibase/shells/drwbassh.cxx b/sw/source/uibase/shells/drwbassh.cxx index f901f32cc15d..39d5882c9666 100644 --- a/sw/source/uibase/shells/drwbassh.cxx +++ b/sw/source/uibase/shells/drwbassh.cxx @@ -27,6 +27,8 @@ #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> @@ -46,16 +48,22 @@ #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::uno; SFX_IMPL_SUPERCLASS_INTERFACE(SwDrawBaseShell, SwBaseShell) @@ -74,7 +82,7 @@ SwDrawBaseShell::SwDrawBaseShell(SwView &_rView) rWin.SetBezierMode(SID_BEZIER_MOVE); if ( !_rView.GetDrawFuncPtr() ) - _rView.GetEditWin().StdDrawMode( OBJ_NONE, true ); + _rView.GetEditWin().StdDrawMode( SdrObjKind::NONE, true ); SwTransferable::CreateSelection( GetShell() ); } @@ -86,14 +94,14 @@ SwDrawBaseShell::~SwDrawBaseShell() SwTransferable::ClearSelection( GetShell() ); } -void SwDrawBaseShell::Execute(SfxRequest const &rReq) +void SwDrawBaseShell::Execute(SfxRequest& 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); + bool bChanged = pSdrView->GetModel().IsChanged(); + pSdrView->GetModel().SetChanged(false); const SfxPoolItem* pItem = nullptr; if(pArgs) pArgs->GetItemState(nSlotId, false, &pItem); @@ -102,7 +110,7 @@ void SwDrawBaseShell::Execute(SfxRequest const &rReq) bool bTopParam = true, bBottomParam = true; bool bDone = false; - SfxBindings& rBind = GetView().GetViewFrame()->GetBindings(); + SfxBindings& rBind = GetView().GetViewFrame().GetBindings(); switch (nSlotId) { @@ -115,40 +123,47 @@ void SwDrawBaseShell::Execute(SfxRequest const &rReq) const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); if( rMarkList.GetMark(0) != nullptr ) { - SfxItemSet aSet( - GetPool(), - svl::Items< + 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>{}); + 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, sal_uInt8(pSh->GetLayerId()))); + 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 SfxPoolItem* pWrapItem; - const SfxItemSet* pOutSet = pDlg->GetOutputItemSet(); - if(SfxItemState::SET == pOutSet->GetItemState(FN_DRAW_WRAP_DLG, false, &pWrapItem)) + auto xRequest = std::make_shared<SfxRequest>(rReq); + rReq.Ignore(); // the 'old' request is not relevant any more + SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); + VclPtr<SfxAbstractDialog> pDlg(pFact->CreateSwWrapDlg(GetView().GetFrameWeld(), aSet, pSh)); + pDlg->StartExecuteAsync( + [pDlg, pSh, xRequest=std::move(xRequest)] (sal_Int32 nResult)->void { - short nLayer = static_cast<const SfxInt16Item*>(pWrapItem)->GetValue(); - if (nLayer == 1) - pSh->SelectionToHeaven(); - else - pSh->SelectionToHell(); - } + if (nResult == 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); - } + pSh->SetObjAttr(*pOutSet); + } + pDlg->disposeOnce(); + xRequest->Done(); + } + ); } } } @@ -176,7 +191,7 @@ void SwDrawBaseShell::Execute(SfxRequest const &rReq) if ( pSh->IsFlyInFly() ) nAllowedAnchors |= SvxAnchorIds::Fly; - if (pObj->GetObjIdentifier() == OBJ_CAPTION ) + if (pObj->GetObjIdentifier() == SdrObjKind::Caption ) bCaption = true; if (bCaption) @@ -197,7 +212,7 @@ void SwDrawBaseShell::Execute(SfxRequest const &rReq) } SfxItemSet aNewAttr(pSdrView->GetGeoAttrFromMarked()); - const sal_uInt16* pRange = pDlg->GetInputRanges( *aNewAttr.GetPool() ); + 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)) ); @@ -235,6 +250,8 @@ void SwDrawBaseShell::Execute(SfxRequest const &rReq) 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)); @@ -257,74 +274,69 @@ void SwDrawBaseShell::Execute(SfxRequest const &rReq) SfxItemState::SET != pOutSet->GetItemState( SID_ATTR_TRANSFORM_POS_Y, false ); - SfxItemSet aFrameAttrSet(GetPool(), svl::Items<RES_FRMATR_BEGIN, RES_FRMATR_END - 1>{}); + SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END - 1> aFrameAttrSet(GetPool()); bool bSingleSelection = rMarkList.GetMarkCount() == 1; - const SfxPoolItem* pAnchorItem; - if(SfxItemState::SET == pOutSet->GetItemState( - SID_ATTR_TRANSFORM_ANCHOR, false, &pAnchorItem)) + if(const SfxInt16Item* pAnchorItem = pOutSet->GetItemIfSet( + SID_ATTR_TRANSFORM_ANCHOR, false)) { if(!bSingleSelection) - pSh->ChgAnchor(static_cast<RndStdIds>(static_cast<const SfxInt16Item*>(pAnchorItem) + pSh->ChgAnchor(static_cast<RndStdIds>(pAnchorItem ->GetValue()), false, bPosCorr ); else { SwFormatAnchor aAnchor(pFrameFormat->GetAnchor()); - aAnchor.SetType(static_cast<RndStdIds>(static_cast<const SfxInt16Item*>(pAnchorItem)->GetValue())); + aAnchor.SetType(static_cast<RndStdIds>(pAnchorItem->GetValue())); aFrameAttrSet.Put( aAnchor ); } } - const SfxPoolItem* pHoriOrient = nullptr; - const SfxPoolItem* pHoriRelation = nullptr; - const SfxPoolItem* pHoriPosition = nullptr; - const SfxPoolItem* pHoriMirror = nullptr; - pOutSet->GetItemState(SID_ATTR_TRANSFORM_HORI_ORIENT, false, &pHoriOrient); - pOutSet->GetItemState(SID_ATTR_TRANSFORM_HORI_RELATION, false, &pHoriRelation); - pOutSet->GetItemState(SID_ATTR_TRANSFORM_HORI_POSITION, false, &pHoriPosition); - pOutSet->GetItemState(SID_ATTR_TRANSFORM_HORI_MIRROR, false, &pHoriMirror); + 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( - static_cast<const SfxInt16Item*>(pHoriOrient)->GetValue()); + aHOrientFinal.SetHoriOrient(pHoriOrient->GetValue()); if(pHoriRelation) - aHOrientFinal.SetRelationOrient( - static_cast<const SfxInt16Item*>(pHoriRelation)->GetValue()); + aHOrientFinal.SetRelationOrient(pHoriRelation->GetValue()); if(pHoriPosition) - aHOrientFinal.SetPos( static_cast<const SfxInt32Item*>(pHoriPosition)->GetValue()); + aHOrientFinal.SetPos( pHoriPosition->GetValue()); if(pHoriMirror) - aHOrientFinal.SetPosToggle( static_cast<const SfxBoolItem*>(pHoriMirror)->GetValue()); + aHOrientFinal.SetPosToggle( pHoriMirror->GetValue()); aFrameAttrSet.Put(aHOrientFinal); } - const SfxPoolItem* pVertOrient = nullptr; - const SfxPoolItem* pVertRelation = nullptr; - const SfxPoolItem* pVertPosition = nullptr; - pOutSet->GetItemState(SID_ATTR_TRANSFORM_VERT_ORIENT, false, &pVertOrient); - pOutSet->GetItemState(SID_ATTR_TRANSFORM_VERT_RELATION, false, &pVertRelation); - pOutSet->GetItemState(SID_ATTR_TRANSFORM_VERT_POSITION, false, &pVertPosition); + 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( - static_cast<const SfxInt16Item*>(pVertOrient)->GetValue()); + aVOrientFinal.SetVertOrient(pVertOrient->GetValue()); if(pVertRelation) - aVOrientFinal.SetRelationOrient( - static_cast<const SfxInt16Item*>(pVertRelation)->GetValue()); + aVOrientFinal.SetRelationOrient(pVertRelation->GetValue()); if(pVertPosition) - aVOrientFinal.SetPos( static_cast<const SfxInt32Item*>(pVertPosition)->GetValue()); + aVOrientFinal.SetPos( pVertPosition->GetValue()); aFrameAttrSet.Put( aVOrientFinal ); } - const SfxPoolItem* pFollowItem = nullptr; - pOutSet->GetItemState(RES_FOLLOW_TEXT_FLOW, false, &pFollowItem); + 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); + GetView().GetViewFrame().GetBindings().InvalidateAll(false); // #i30451# pSh->EndUndo( SwUndoId::INSFMTATTR ); @@ -332,10 +344,10 @@ void SwDrawBaseShell::Execute(SfxRequest const &rReq) pSh->EndAllAction(); } - if (pSdrView->GetModel()->IsChanged()) + if (pSdrView->GetModel().IsChanged()) pSh->SetModified(); else if (bChanged) - pSdrView->GetModel()->SetChanged(); + pSdrView->GetModel().SetChanged(); pDlg->disposeOnce(); }); @@ -370,6 +382,8 @@ void SwDrawBaseShell::Execute(SfxRequest const &rReq) { bDone = true; + const Point aPt = pSh->GetObjRect().TopLeft(); // tdf#150589 + if( GetView().IsDrawRotate() ) { pSh->SetDragMode( SdrDragMode::Move ); @@ -395,8 +409,10 @@ void SwDrawBaseShell::Execute(SfxRequest const &rReq) if (pSh->IsSelFrameMode()) { pSh->LeaveSelFrameMode(); - // #105852# FME + // #105852# FME <- perhaps fixed by tdf#150589 + static_cast<SwEditShell*>(pSh)->SetCursor(aPt); } + } break; @@ -409,7 +425,7 @@ void SwDrawBaseShell::Execute(SfxRequest const &rReq) break; case SID_UNGROUP: - if (pSh->IsGroupSelected() && pSh->IsUnGroupAllowed()) + if (pSh->IsGroupSelected(true) && pSh->IsUnGroupAllowed()) { pSh->UnGroupSelection(); rBind.Invalidate(SID_GROUP); @@ -417,7 +433,7 @@ void SwDrawBaseShell::Execute(SfxRequest const &rReq) break; case SID_ENTER_GROUP: - if (pSh->IsGroupSelected()) + if (pSh->IsGroupSelected(false)) { pSdrView->EnterMarkedGroup(); rBind.InvalidateAll(false); @@ -433,6 +449,42 @@ void SwDrawBaseShell::Execute(SfxRequest const &rReq) } 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(); + VclPtr<VclAbstractDialog> pDlg = pFact->CreateDiagramDialog( + GetView().GetFrameWeld(), + *static_cast<SdrObjGroup*>(pObj)); + pDlg->StartExecuteAsync( + [pDlg] (sal_Int32 /*nResult*/)->void + { + pDlg->disposeOnce(); + } + ); + } + } + } + } + break; + case SID_OBJECT_ALIGN_LEFT: case SID_OBJECT_ALIGN_CENTER: case SID_OBJECT_ALIGN_RIGHT: @@ -547,19 +599,32 @@ void SwDrawBaseShell::Execute(SfxRequest const &rReq) // #i68101# SdrObject* pSelected = pSdrView->GetMarkedObjectByIndex(0); OSL_ENSURE(pSelected, "DrawViewShell::FuTemp03: nMarkCount, but no object (!)"); - OUString aName(pSelected->GetName()); + OUString aOrigName(pSelected->GetName()); SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); - ScopedVclPtr<AbstractSvxObjectNameDialog> pDlg(pFact->CreateSvxObjectNameDialog(GetView().GetFrameWeld(), aName)); + VclPtr<AbstractSvxObjectNameDialog> pDlg(pFact->CreateSvxObjectNameDialog(GetView().GetFrameWeld(), aOrigName)); pDlg->SetCheckNameHdl(LINK(this, SwDrawBaseShell, CheckGroupShapeNameHdl)); - if(RET_OK == pDlg->Execute()) - { - pDlg->GetName(aName); - pSelected->SetName(aName); - pSh->SetModified(); - } + pDlg->StartExecuteAsync( + [pDlg, pSelected, pSh, aOrigName] (sal_Int32 nResult)->void + { + if (nResult == RET_OK) + { + OUString aNewName = pDlg->GetName(); + pSelected->SetName(aNewName); + pSh->SetModified(); + + // update accessibility sidebar object name if we modify the object name on the navigator bar + if (!aNewName.isEmpty() && aOrigName != aNewName) + { + if (SwNode* pSwNode = FindFrameFormat(pSelected)->GetAnchor().GetAnchorNode()) + pSwNode->resetAndQueueAccessibilityCheck(true); + } + } + pDlg->disposeOnce(); + } + ); } break; @@ -576,23 +641,74 @@ void SwDrawBaseShell::Execute(SfxRequest const &rReq) OSL_ENSURE(pSelected, "DrawViewShell::FuTemp03: nMarkCount, but no object (!)"); OUString aTitle(pSelected->GetTitle()); OUString aDescription(pSelected->GetDescription()); + bool isDecorative(pSelected->IsDecorative()); SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); - ScopedVclPtr<AbstractSvxObjectTitleDescDialog> pDlg(pFact->CreateSvxObjectTitleDescDialog(GetView().GetFrameWeld(), - aTitle, aDescription)); + VclPtr<AbstractSvxObjectTitleDescDialog> pDlg(pFact->CreateSvxObjectTitleDescDialog(GetView().GetFrameWeld(), + aTitle, aDescription, isDecorative)); - if(RET_OK == pDlg->Execute()) - { - pDlg->GetTitle(aTitle); - pDlg->GetDescription(aDescription); + pDlg->StartExecuteAsync( + [pDlg, pSelected, pSh] (sal_Int32 nResult)->void + { + if (nResult == RET_OK) + { + pSelected->SetTitle(pDlg->GetTitle()); + pSelected->SetDescription(pDlg->GetDescription()); + pSelected->SetDecorative(pDlg->IsDecorative()); - pSelected->SetTitle(aTitle); - pSelected->SetDescription(aDescription); + pSh->SetModified(); + } + pDlg->disposeOnce(); + } + ); + } - 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; } @@ -604,10 +720,10 @@ void SwDrawBaseShell::Execute(SfxRequest const &rReq) { if(nSlotId >= SID_OBJECT_ALIGN_LEFT && nSlotId <= SID_OBJECT_ALIGN_DOWN) rBind.Invalidate(SID_ATTR_LONG_LRSPACE); - if (pSdrView->GetModel()->IsChanged()) + if (pSdrView->GetModel().IsChanged()) pSh->SetModified(); else if (bChanged) - pSdrView->GetModel()->SetChanged(); + pSdrView->GetModel().SetChanged(); } } @@ -621,8 +737,7 @@ IMPL_LINK( SwDrawBaseShell, CheckGroupShapeNameHdl, AbstractSvxObjectNameDialog& OSL_ENSURE(rMarkList.GetMarkCount() == 1, "wrong draw selection"); SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); const OUString sCurrentName = pObj->GetName(); - OUString sNewName; - rNameDialog.GetName(sNewName); + OUString sNewName = rNameDialog.GetName(); bool bRet = false; if (sNewName.isEmpty() || sCurrentName == sNewName) bRet = true; @@ -675,11 +790,11 @@ void SwDrawBaseShell::GetState(SfxItemSet& rSet) rSet.DisableItem( nWhich ); break; case SID_UNGROUP: - if ( !rSh.IsGroupSelected() || bProtected || !rSh.IsUnGroupAllowed() ) + if ( !rSh.IsGroupSelected(true) || bProtected || !rSh.IsUnGroupAllowed() ) rSet.DisableItem( nWhich ); break; case SID_ENTER_GROUP: - if ( !rSh.IsGroupSelected() ) + if ( !rSh.IsGroupSelected(false) ) rSet.DisableItem( nWhich ); break; case SID_LEAVE_GROUP: @@ -740,8 +855,12 @@ void SwDrawBaseShell::GetState(SfxItemSet& rSet) 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 (pFrameFormat) + { + SwFormatHoriOrient aHOrient( + pFrameFormat->GetFormatAttr(RES_HORI_ORIENT)); + rSet.Put(SfxBoolItem(nWhich, aHOrient.GetHoriOrient() == nHoriOrient)); + } } if (bVert && !bDisableThis && rMarkList.GetMarkCount() == 1) @@ -764,8 +883,12 @@ void SwDrawBaseShell::GetState(SfxItemSet& rSet) SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); SwFrameFormat* pFrameFormat = FindFrameFormat(pObj); - SwFormatVertOrient aVOrient(pFrameFormat->GetFormatAttr(RES_VERT_ORIENT)); - rSet.Put(SfxBoolItem(nWhich, aVOrient.GetVertOrient() == nVertOrient)); + if (pFrameFormat) + { + SwFormatVertOrient aVOrient( + pFrameFormat->GetFormatAttr(RES_VERT_ORIENT)); + rSet.Put(SfxBoolItem(nWhich, aVOrient.GetVertOrient() == nVertOrient)); + } } } break; @@ -790,6 +913,90 @@ void SwDrawBaseShell::GetState(SfxItemSet& rSet) } } 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(); } @@ -841,18 +1048,18 @@ void SwDrawBaseShell::DisableState( SfxItemSet& rSet ) for (size_t i = 0; i < nMarkCount && i < 50; ++i) { SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj(); - sal_uInt16 nObjType = pObj->GetObjIdentifier(); + SdrObjKind nObjType = pObj->GetObjIdentifier(); - if ( nObjType != OBJ_MEASURE ) + if ( nObjType != SdrObjKind::Measure ) bShowMeasure = false; // If marked object is 2D, disable format area command. - if ( nObjType == OBJ_PLIN || - nObjType == OBJ_LINE || - nObjType == OBJ_PATHLINE || - nObjType == OBJ_FREELINE || - nObjType == OBJ_EDGE || - nObjType == OBJ_CARC || + if ( nObjType == SdrObjKind::PolyLine || + nObjType == SdrObjKind::Line || + nObjType == SdrObjKind::PathLine || + nObjType == SdrObjKind::FreehandLine || + nObjType == SdrObjKind::Edge || + nObjType == SdrObjKind::CircleArc || bShowMeasure ) bShowArea = false; @@ -883,20 +1090,20 @@ IMPL_LINK(SwDrawBaseShell, ValidatePosition, SvxSwFrameValidation&, rValidation, // 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; + const SwFormatAnchor* pAnchor = nullptr; SdrView* pSdrView = pSh->GetDrawView(); const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); if( rMarkList.GetMarkCount() == 1 ) { SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); SwFrameFormat* pFrameFormat = FindFrameFormat( pObj ); - pContentPos = pFrameFormat->GetAnchor().GetContentAnchor(); + pAnchor = &pFrameFormat->GetAnchor(); } pSh->CalcBoundRect( aBoundRect, eAnchorType, rValidation.nHRelOrient, rValidation.nVRelOrient, - pContentPos, + pAnchor, rValidation.bFollowTextFlow, rValidation.bMirror, nullptr, &rValidation.aPercentSize); diff --git a/sw/source/uibase/shells/drwtxtex.cxx b/sw/source/uibase/shells/drwtxtex.cxx index 7bec3a0f82d4..9600c1a83e1c 100644 --- a/sw/source/uibase/shells/drwtxtex.cxx +++ b/sw/source/uibase/shells/drwtxtex.cxx @@ -63,6 +63,7 @@ #include <editeng/editview.hxx> #include <vcl/unohelp2.hxx> #include <editeng/hyphenzoneitem.hxx> +#include <osl/diagnose.h> #include <cmdid.h> #include <doc.hxx> @@ -78,57 +79,19 @@ #include <wview.hxx> #include <swabstdlg.hxx> -#include <memory> using namespace ::com::sun::star; -namespace -{ - void lcl_convertStringArguments(sal_uInt16 nSlot, const std::unique_ptr<SfxItemSet>& pArgs) - { - Color aColor; - OUString sColor; - const SfxPoolItem* pItem = nullptr; - - if (SfxItemState::SET != pArgs->GetItemState(SID_ATTR_COLOR_STR, false, &pItem)) - return; - - 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_CHAR_COLOR: - { - SvxColorItem aColorItem(aColor, EE_CHAR_COLOR); - pArgs->Put(aColorItem); - break; - } - - case SID_ATTR_CHAR_BACK_COLOR: - { - SvxBackgroundColorItem pBackgroundItem(aColor, EE_CHAR_BKGCOLOR); - pArgs->Put(pBackgroundItem); - break; - } - } - } -} - void SwDrawTextShell::Execute( SfxRequest &rReq ) { SwWrtShell &rSh = GetShell(); - OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView(); + 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); + const sal_uInt16 nWhich = GetPool().GetWhichIDFromSlotID(nSlot); std::unique_ptr<SfxItemSet> pNewAttrs(rReq.GetArgs() ? rReq.GetArgs()->Clone() : nullptr); bool bRestoreSelection = false; @@ -152,7 +115,7 @@ void SwDrawTextShell::Execute( SfxRequest &rReq ) case SID_THES: { OUString aReplaceText; - const SfxStringItem* pItem2 = rReq.GetArg<SfxStringItem>(SID_THES); + const SfxStringItem* pItem2 = rReq.GetArg(FN_PARAM_THES_WORD_REPLACE); if (pItem2) aReplaceText = pItem2->GetValue(); if (!aReplaceText.isEmpty()) @@ -190,7 +153,7 @@ void SwDrawTextShell::Execute( SfxRequest &rReq ) { if ( pNewAttrs ) { - const SvxTextLineItem& rTextLineItem = static_cast< const SvxTextLineItem& >( pNewAttrs->Get( pNewAttrs->GetPool()->GetWhich(nSlot) ) ); + const SvxTextLineItem& rTextLineItem = static_cast< const SvxTextLineItem& >( pNewAttrs->Get( pNewAttrs->GetPool()->GetWhichIDFromSlotID(nSlot) ) ); aNewAttr.Put( SvxUnderlineItem( rTextLineItem.GetLineStyle(), EE_CHAR_UNDERLINE ) ); } else @@ -256,18 +219,20 @@ void SwDrawTextShell::Execute( SfxRequest &rReq ) } break; case SID_ATTR_PARA_LINESPACE: + if (pNewAttrs) { SvxLineSpacingItem aLineSpace = static_cast<const SvxLineSpacingItem&>(pNewAttrs->Get( - GetPool().GetWhich(nSlot))); + GetPool().GetWhichIDFromSlotID(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))); + GetPool().GetWhichIDFromSlotID(nSlot))); aULSpace.SetWhich( EE_PARA_ULSPACE ); aNewAttr.Put( aULSpace ); rReq.Done(); @@ -304,6 +269,13 @@ void SwDrawTextShell::Execute( SfxRequest &rReq ) 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); @@ -345,6 +317,7 @@ void SwDrawTextShell::Execute( SfxRequest &rReq ) break; case SID_CHAR_DLG_EFFECT: + case SID_CHAR_DLG_POSITION: case SID_CHAR_DLG: case SID_CHAR_DLG_FOR_PARAGRAPH: { @@ -365,7 +338,7 @@ void SwDrawTextShell::Execute( SfxRequest &rReq ) SwView* pView = &GetView(); FieldUnit eMetric = ::GetDfltMetric(dynamic_cast<SwWebView*>( pView) != nullptr ); SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)) ); - SfxItemSet aDlgAttr(GetPool(), svl::Items<XATTR_FILLSTYLE, XATTR_FILLCOLOR, EE_ITEMS_START, EE_ITEMS_END>{}); + 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. @@ -373,28 +346,39 @@ void SwDrawTextShell::Execute( SfxRequest &rReq ) aDlgAttr.Put( SvxKerningItem(0, RES_CHRATR_KERNING) ); SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); - ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateSwCharDlg(pView->GetFrameWeld(), *pView, aDlgAttr, SwCharDlgMode::Draw)); + VclPtr<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)); + pDlg->SetCurPageId(pItem->GetValue()); } - sal_uInt16 nRet = pDlg->Execute(); - if(RET_OK == nRet ) - { - rReq.Done( *( pDlg->GetOutputItemSet() ) ); - aNewAttr.Put(*pDlg->GetOutputItemSet()); - } - if(RET_OK != nRet) - return ; + auto xRequest = std::make_shared<SfxRequest>(rReq); + rReq.Ignore(); // the 'old' request is not relevant any more + pDlg->StartExecuteAsync( + [this, pDlg, xRequest=std::move(xRequest), nEEWhich, aNewAttr2=aNewAttr, pOLV, bRestoreSelection, aOldSelection] (sal_Int32 nResult) mutable ->void + { + if (nResult == RET_OK) + { + xRequest->Done( *( pDlg->GetOutputItemSet() ) ); + aNewAttr2.Put(*pDlg->GetOutputItemSet()); + ExecutePost(*xRequest, nEEWhich, aNewAttr2, pOLV, bRestoreSelection, aOldSelection); + } + pDlg->disposeOnce(); + } + ); + return; } else aNewAttr.Put(*pArgs); @@ -430,11 +414,9 @@ void SwDrawTextShell::Execute( SfxRequest &rReq ) SwView* pView = &GetView(); FieldUnit eMetric = ::GetDfltMetric(dynamic_cast<SwWebView*>( pView) != nullptr ); SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)) ); - SfxItemSet aDlgAttr( - GetPool(), - svl::Items< + SfxItemSetFixed< EE_ITEMS_START, EE_ITEMS_END, - SID_ATTR_PARA_HYPHENZONE, SID_ATTR_PARA_WIDOWS>{}); + SID_ATTR_PARA_HYPHENZONE, SID_ATTR_PARA_WIDOWS> aDlgAttr( GetPool() ); aDlgAttr.Put(aEditAttr); @@ -463,7 +445,7 @@ void SwDrawTextShell::Execute( SfxRequest &rReq ) { //!! JP 16.03.2001: why?? pSdrView = rSh.GetDrawView(); //!! JP 16.03.2001: why?? pOutliner = pSdrView->GetTextEditOutliner(); - SdrOutliner * pOutliner = pSdrView->GetTextEditOutliner(); + SdrOutliner * pOutliner = m_pSdrView->GetTextEditOutliner(); EEControlBits nCtrl = pOutliner->GetControlWord(); bool bSet = static_cast<const SfxBoolItem&>(rReq.GetArgs()->Get( @@ -474,7 +456,7 @@ void SwDrawTextShell::Execute( SfxRequest &rReq ) nCtrl &= ~EEControlBits::ONLINESPELLING; pOutliner->SetControlWord(nCtrl); - rView.ExecuteSlot(rReq); + m_rView.ExecuteSlot(rReq); } break; case SID_HYPERLINK_SETLINK: @@ -507,7 +489,7 @@ void SwDrawTextShell::Execute( SfxRequest &rReq ) { // Ensure the field is selected first pOLV->SelectFieldAtCursor(); - GetView().GetViewFrame()->GetDispatcher()->Execute(SID_HYPERLINK_DIALOG); + GetView().GetViewFrame().GetDispatcher()->Execute(SID_HYPERLINK_DIALOG); } break; @@ -519,22 +501,22 @@ void SwDrawTextShell::Execute( SfxRequest &rReq ) case SID_OPEN_HYPERLINK: { - const SvxFieldData* pField = pOLV->GetFieldAtCursor(); + const SvxFieldItem* pFieldItem + = pOLV->GetFieldAtSelection(/*AlsoCheckBeforeCursor=*/true); + const SvxFieldData* pField = pFieldItem ? pFieldItem->GetField() : nullptr; 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 }); + ::LoadURL(GetShell(), pURLField->GetURL(), LoadUrlFlags::NONE, + pURLField->GetTargetFrame()); } } break; case SID_COPY_HYPERLINK_LOCATION: { - const SvxFieldData* pField = pOLV->GetFieldAtCursor(); + const SvxFieldItem* pFieldItem + = pOLV->GetFieldAtSelection(/*AlsoCheckBeforeCursor=*/true); + const SvxFieldData* pField = pFieldItem ? pFieldItem->GetField() : nullptr; if (const SvxURLField* pURLField = dynamic_cast<const SvxURLField*>(pField)) { uno::Reference<datatransfer::clipboard::XClipboard> xClipboard @@ -548,15 +530,14 @@ void SwDrawTextShell::Execute( SfxRequest &rReq ) case SID_TEXTDIRECTION_TOP_TO_BOTTOM: // Shell switch! { - SdrObject* pTmpObj = pSdrView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(); - SdrPageView* pTmpPV = pSdrView->GetSdrPageView(); - SdrView* pTmpView = pSdrView; + SdrObject* pTmpObj = m_pSdrView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(); + SdrPageView* pTmpPV = m_pSdrView->GetSdrPageView(); + SdrView* pTmpView = m_pSdrView; - pSdrView->SdrEndTextEdit(true); + m_pSdrView->SdrEndTextEdit(true); - SfxItemSet aAttr( *aNewAttr.GetPool(), - svl::Items<SDRATTR_TEXTDIRECTION, - SDRATTR_TEXTDIRECTION>{} ); + SfxItemSetFixed<SDRATTR_TEXTDIRECTION, + SDRATTR_TEXTDIRECTION> aAttr( *aNewAttr.GetPool() ); aAttr.Put( SvxWritingModeItem( nSlot == SID_TEXTDIRECTION_LEFT_TO_RIGHT ? @@ -572,11 +553,11 @@ void SwDrawTextShell::Execute( SfxRequest &rReq ) case SID_ATTR_PARA_LEFT_TO_RIGHT: case SID_ATTR_PARA_RIGHT_TO_LEFT: { - SdrObject* pTmpObj = pSdrView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(); - SdrPageView* pTmpPV = pSdrView->GetSdrPageView(); - SdrView* pTmpView = pSdrView; + SdrObject* pTmpObj = m_pSdrView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(); + SdrPageView* pTmpPV = m_pSdrView->GetSdrPageView(); + SdrView* pTmpView = m_pSdrView; - pSdrView->SdrEndTextEdit(true); + m_pSdrView->SdrEndTextEdit(true); bool bLeftToRight = nSlot == SID_ATTR_PARA_LEFT_TO_RIGHT; const SfxPoolItem* pPoolItem; @@ -585,15 +566,13 @@ void SwDrawTextShell::Execute( SfxRequest &rReq ) if( !static_cast<const SfxBoolItem*>(pPoolItem)->GetValue() ) bLeftToRight = !bLeftToRight; } - SfxItemSet aAttr( - *aNewAttr.GetPool(), - svl::Items< + SfxItemSetFixed< EE_PARA_WRITINGDIR, EE_PARA_WRITINGDIR, - EE_PARA_JUST, EE_PARA_JUST>{}); + EE_PARA_JUST, EE_PARA_JUST> aAttr( *aNewAttr.GetPool() ); SvxAdjust nAdjust = SvxAdjust::Left; - if( SfxItemState::SET == aEditAttr.GetItemState(EE_PARA_JUST, true, &pPoolItem ) ) - nAdjust = static_cast<const SvxAdjustItem*>(pPoolItem)->GetAdjust(); + if( const SvxAdjustItem* pAdjustItem = aEditAttr.GetItemIfSet(EE_PARA_JUST) ) + nAdjust = pAdjustItem->GetAdjust(); if( bLeftToRight ) { @@ -616,8 +595,9 @@ void SwDrawTextShell::Execute( SfxRequest &rReq ) case FN_GROW_FONT_SIZE: case FN_SHRINK_FONT_SIZE: { + const SfxObjectShell* pObjSh = SfxObjectShell::Current(); const SvxFontListItem* pFontListItem = static_cast< const SvxFontListItem* > - ( SfxObjectShell::Current()->GetItem( SID_ATTR_CHAR_FONTLIST ) ); + (pObjSh ? pObjSh->GetItem(SID_ATTR_CHAR_FONTLIST) : nullptr); const FontList* pFontList = pFontListItem ? pFontListItem->GetFontList() : nullptr; pOLV->GetEditView().ChangeFontSize( nSlot == FN_GROW_FONT_SIZE, pFontList ); } @@ -627,16 +607,35 @@ void SwDrawTextShell::Execute( SfxRequest &rReq ) assert(false && "wrong dispatcher"); return; } + + ExecutePost(rReq, nEEWhich, aNewAttr, pOLV, bRestoreSelection, aOldSelection); +} + +void SwDrawTextShell::ExecutePost( SfxRequest& rReq, sal_uInt16 nEEWhich, SfxItemSet& rNewAttr, + OutlinerView* pOLV, bool bRestoreSelection, const ESelection& rOldSelection ) +{ + SwWrtShell &rSh = GetShell(); + const SfxItemSet *pNewAttrs = rReq.GetArgs(); + const sal_uInt16 nSlot = rReq.GetSlot(); + const sal_uInt16 nWhich = GetPool().GetWhichIDFromSlotID(nSlot); + if (nEEWhich && pNewAttrs) { - lcl_convertStringArguments(nSlot, pNewAttrs); - - aNewAttr.Put(pNewAttrs->Get(nWhich).CloneSetWhich(nEEWhich)); + rNewAttr.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); + SetAttrToMarked(rNewAttr); - GetView().GetViewFrame()->GetBindings().InvalidateAll(false); + GetView().GetViewFrame().GetBindings().InvalidateAll(false); if (IsTextEdit() && pOLV->GetOutliner()->IsModified()) rSh.SetModified(); @@ -644,7 +643,7 @@ void SwDrawTextShell::Execute( SfxRequest &rReq ) if (bRestoreSelection) { // restore selection - pOLV->GetEditView().SetSelection( aOldSelection ); + pOLV->GetEditView().SetSelection( rOldSelection ); } } @@ -653,12 +652,14 @@ void SwDrawTextShell::GetState(SfxItemSet& rSet) if (!IsTextEdit()) // Otherwise sometimes crash! return; - OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView(); + OutlinerView* pOLV = m_pSdrView->GetTextEditOutlinerView(); SfxWhichIter aIter(rSet); sal_uInt16 nWhich = aIter.FirstWhich(); SfxItemSet aEditAttr(pOLV->GetAttribs()); - const SfxPoolItem *pAdjust = nullptr, *pLSpace = nullptr, *pEscItem = nullptr; + const SvxAdjustItem *pAdjust = nullptr; + const SvxLineSpacingItem *pLSpace = nullptr; + const SfxPoolItem *pEscItem = nullptr; SvxAdjust eAdjust; int nLSpace; SvxEscapement nEsc; @@ -710,7 +711,7 @@ void SwDrawTextShell::GetState(SfxItemSet& rSet) ASK_ADJUST: { if (!pAdjust) - aEditAttr.GetItemState(EE_PARA_JUST, false, &pAdjust); + pAdjust = aEditAttr.GetItemIfSet(EE_PARA_JUST, false); if (!pAdjust || IsInvalidItem(pAdjust)) { @@ -718,7 +719,7 @@ void SwDrawTextShell::GetState(SfxItemSet& rSet) nSlotId = 0; } else - bFlag = eAdjust == static_cast<const SvxAdjustItem*>(pAdjust)->GetAdjust(); + bFlag = eAdjust == pAdjust->GetAdjust(); } break; @@ -788,6 +789,9 @@ void SwDrawTextShell::GetState(SfxItemSet& rSet) 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; @@ -797,7 +801,7 @@ void SwDrawTextShell::GetState(SfxItemSet& rSet) ASK_LINESPACE: { if (!pLSpace) - aEditAttr.GetItemState(EE_PARA_SBL, false, &pLSpace); + pLSpace = aEditAttr.GetItemIfSet(EE_PARA_SBL, false); if (!pLSpace || IsInvalidItem(pLSpace)) { @@ -805,10 +809,14 @@ void SwDrawTextShell::GetState(SfxItemSet& rSet) nSlotId = 0; } else if (nLSpace - == static_cast<const SvxLineSpacingItem*>(pLSpace)->GetPropLineSpace()) + == pLSpace->GetPropLineSpace()) bFlag = true; else + { + // tdf#114631 - disable non selected line spacing + rSet.Put(SfxBoolItem(nWhich, false)); nSlotId = 0; + } } break; @@ -833,10 +841,11 @@ void SwDrawTextShell::GetState(SfxItemSet& rSet) case SID_THESAURUS: { // disable "Thesaurus" if the language is not supported - const SfxPoolItem& rItem = GetShell().GetDoc()->GetDefault(GetWhichOfScript( + TypedWhichId<SvxLanguageItem> nLangWhich = GetWhichOfScript( RES_CHRATR_LANGUAGE, - SvtLanguageOptions::GetI18NScriptTypeOfLanguage(GetAppLanguage()))); - LanguageType nLang = static_cast<const SvxLanguageItem&>(rItem).GetLanguage(); + SvtLanguageOptions::GetI18NScriptTypeOfLanguage(GetAppLanguage())); + const SvxLanguageItem& rItem = GetShell().GetDoc()->GetDefault(nLangWhich); + LanguageType nLang = rItem.GetLanguage(); uno::Reference<linguistic2::XThesaurus> xThes(::GetThesaurus()); if (!xThes.is() || nLang == LANGUAGE_NONE @@ -848,26 +857,26 @@ void SwDrawTextShell::GetState(SfxItemSet& rSet) case SID_HANGUL_HANJA_CONVERSION: case SID_CHINESE_CONVERSION: { - if (!SvtCJKOptions().IsAnyEnabled()) + if (!SvtCJKOptions::IsAnyEnabled()) { - GetView().GetViewFrame()->GetBindings().SetVisibleState(nWhich, false); + GetView().GetViewFrame().GetBindings().SetVisibleState(nWhich, false); rSet.DisableItem(nWhich); } else - GetView().GetViewFrame()->GetBindings().SetVisibleState(nWhich, true); + GetView().GetViewFrame().GetBindings().SetVisibleState(nWhich, true); } break; case SID_TEXTDIRECTION_LEFT_TO_RIGHT: case SID_TEXTDIRECTION_TOP_TO_BOTTOM: - if (!SvtLanguageOptions().IsVerticalTextEnabled()) + if (!SvtCJKOptions::IsVerticalTextEnabled()) { rSet.DisableItem(nSlotId); nSlotId = 0; } else { - SdrOutliner* pOutliner = pSdrView->GetTextEditOutliner(); + SdrOutliner* pOutliner = m_pSdrView->GetTextEditOutliner(); if (pOutliner) bFlag = pOutliner->IsVertical() == (SID_TEXTDIRECTION_TOP_TO_BOTTOM == nSlotId); @@ -889,14 +898,14 @@ void SwDrawTextShell::GetState(SfxItemSet& rSet) case SID_ATTR_PARA_LEFT_TO_RIGHT: case SID_ATTR_PARA_RIGHT_TO_LEFT: { - if (!SvtLanguageOptions().IsCTLFontEnabled()) + if (!SvtCTLOptions::IsCTLFontEnabled()) { rSet.DisableItem(nWhich); nSlotId = 0; } else { - SdrOutliner* pOutliner = pSdrView->GetTextEditOutliner(); + SdrOutliner* pOutliner = m_pSdrView->GetTextEditOutliner(); if (pOutliner && pOutliner->IsVertical()) { rSet.DisableItem(nWhich); @@ -925,22 +934,20 @@ void SwDrawTextShell::GetState(SfxItemSet& rSet) case SID_TRANSLITERATE_HIRAGANA: case SID_TRANSLITERATE_KATAKANA: { - SvtCJKOptions aCJKOptions; - if (!aCJKOptions.IsChangeCaseMapEnabled()) + if (!SvtCJKOptions::IsChangeCaseMapEnabled()) { rSet.DisableItem(nWhich); - GetView().GetViewFrame()->GetBindings().SetVisibleState(nWhich, false); + GetView().GetViewFrame().GetBindings().SetVisibleState(nWhich, false); } else - GetView().GetViewFrame()->GetBindings().SetVisibleState(nWhich, true); + 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); + bool bEnabled = SvtCTLOptions::IsCTLFontEnabled(); + GetView().GetViewFrame().GetBindings().SetVisibleState(nWhich, bEnabled); if (!bEnabled) rSet.DisableItem(nWhich); } @@ -950,8 +957,9 @@ void SwDrawTextShell::GetState(SfxItemSet& rSet) case SID_OPEN_HYPERLINK: case SID_COPY_HYPERLINK_LOCATION: { - if (!URLFieldHelper::IsCursorAtURLField(pOLV)) + if (!URLFieldHelper::IsCursorAtURLField(pOLV, /*AlsoCheckBeforeCursor=*/true)) rSet.DisableItem(nWhich); + nSlotId = 0; } break; default: @@ -959,7 +967,7 @@ void SwDrawTextShell::GetState(SfxItemSet& rSet) break; } - if (nSlotId && bFlag) + if (nSlotId) rSet.Put(SfxBoolItem(nWhich, bFlag)); nWhich = aIter.NextWhich(); @@ -971,7 +979,7 @@ void SwDrawTextShell::GetDrawTextCtrlState(SfxItemSet& rSet) if (!IsTextEdit()) // Otherwise crash! return; - OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView(); + OutlinerView* pOLV = m_pSdrView->GetTextEditOutlinerView(); SfxItemSet aEditAttr(pOLV->GetAttribs()); SfxWhichIter aIter(rSet); @@ -1011,9 +1019,9 @@ void SwDrawTextShell::GetDrawTextCtrlState(SfxItemSet& rSet) case SID_ATTR_CHAR_STRIKEOUT: nEEWhich = EE_CHAR_STRIKEOUT;break; case SID_AUTOSPELL_CHECK: { - const SfxPoolItem* pState = rView.GetSlotState(nWhich); - if (pState) - rSet.Put(SfxBoolItem(nWhich, static_cast<const SfxBoolItem*>(pState)->GetValue())); + const SfxPoolItemHolder aResult(m_rView.GetSlotState(nWhich)); + if (aResult) + rSet.Put(SfxBoolItem(nWhich, static_cast<const SfxBoolItem*>(aResult.getItem())->GetValue())); else rSet.DisableItem( nWhich ); break; @@ -1060,7 +1068,7 @@ void SwDrawTextShell::ExecClpbrd(SfxRequest const &rReq) if (!IsTextEdit()) // Otherwise crash! return; - OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView(); + OutlinerView* pOLV = m_pSdrView->GetTextEditOutlinerView(); ESelection aSel(pOLV->GetSelection()); const bool bCopy = (aSel.nStartPara != aSel.nEndPara) || (aSel.nStartPos != aSel.nEndPos); @@ -1093,6 +1101,7 @@ void SwDrawTextShell::ExecClpbrd(SfxRequest const &rReq) pDlg->Insert(SotClipboardFormatId::STRING, OUString()); pDlg->Insert(SotClipboardFormatId::RTF, OUString()); pDlg->Insert(SotClipboardFormatId::RICHTEXT, OUString()); + pDlg->Insert(SotClipboardFormatId::HTML_SIMPLE, OUString()); TransferableDataHelper aDataHelper(TransferableDataHelper::CreateFromSystemClipboard(&GetView().GetEditWin())); SotClipboardFormatId nFormat = pDlg->GetFormat(aDataHelper.GetTransferable()); @@ -1102,7 +1111,7 @@ void SwDrawTextShell::ExecClpbrd(SfxRequest const &rReq) if (nFormat == SotClipboardFormatId::STRING) pOLV->Paste(); else - pOLV->PasteSpecial(); + pOLV->PasteSpecial(nFormat); } break; @@ -1123,7 +1132,7 @@ void SwDrawTextShell::ExecClpbrd(SfxRequest const &rReq) if (nFormat == SotClipboardFormatId::STRING) pOLV->Paste(); else - pOLV->PasteSpecial(); + pOLV->PasteSpecial(nFormat); } break; @@ -1140,7 +1149,7 @@ void SwDrawTextShell::StateClpbrd(SfxItemSet &rSet) if (!IsTextEdit()) // Otherwise crash! return; - OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView(); + OutlinerView* pOLV = m_pSdrView->GetTextEditOutlinerView(); ESelection aSel(pOLV->GetSelection()); const bool bCopy = (aSel.nStartPara != aSel.nEndPara) || (aSel.nStartPos != aSel.nEndPos); @@ -1148,7 +1157,8 @@ void SwDrawTextShell::StateClpbrd(SfxItemSet &rSet) TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( &GetView().GetEditWin() ) ); const bool bPaste = aDataHelper.HasFormat( SotClipboardFormatId::STRING ) || aDataHelper.HasFormat( SotClipboardFormatId::RTF ) || - aDataHelper.HasFormat( SotClipboardFormatId::RICHTEXT ); + aDataHelper.HasFormat( SotClipboardFormatId::RICHTEXT ) || + aDataHelper.HasFormat( SotClipboardFormatId::HTML_SIMPLE); SfxWhichIter aIter(rSet); sal_uInt16 nWhich = aIter.FirstWhich(); @@ -1181,6 +1191,8 @@ void SwDrawTextShell::StateClpbrd(SfxItemSet &rSet) aFormats.AddClipbrdFormat( SotClipboardFormatId::RTF ); if ( aDataHelper.HasFormat( SotClipboardFormatId::RICHTEXT ) ) aFormats.AddClipbrdFormat( SotClipboardFormatId::RICHTEXT ); + if (aDataHelper.HasFormat(SotClipboardFormatId::HTML_SIMPLE)) + aFormats.AddClipbrdFormat(SotClipboardFormatId::HTML_SIMPLE); rSet.Put( aFormats ); } @@ -1200,7 +1212,7 @@ void SwDrawTextShell::StateInsert(SfxItemSet &rSet) if (!IsTextEdit()) // Otherwise crash! return; - OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView(); + OutlinerView* pOLV = m_pSdrView->GetTextEditOutlinerView(); SfxWhichIter aIter(rSet); sal_uInt16 nWhich = aIter.FirstWhich(); diff --git a/sw/source/uibase/shells/drwtxtsh.cxx b/sw/source/uibase/shells/drwtxtsh.cxx index f8e34eabde29..eccfa7936f2c 100644 --- a/sw/source/uibase/shells/drwtxtsh.cxx +++ b/sw/source/uibase/shells/drwtxtsh.cxx @@ -24,6 +24,7 @@ #include <svl/slstitm.hxx> #include <svl/stritem.hxx> #include <editeng/fontitem.hxx> +#include <editeng/editund2.hxx> #include <svx/svdview.hxx> #include <sfx2/viewfrm.hxx> #include <sfx2/objface.hxx> @@ -48,6 +49,7 @@ #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> @@ -89,12 +91,12 @@ void SwDrawTextShell::InitInterface_Impl() void SwDrawTextShell::Init() { SwWrtShell &rSh = GetShell(); - pSdrView = rSh.GetDrawView(); - SdrOutliner * pOutliner = pSdrView->GetTextEditOutliner(); + m_pSdrView = rSh.GetDrawView(); + SdrOutliner * pOutliner = m_pSdrView->GetTextEditOutliner(); //#97471# mouse click _and_ key input at the same time if( !pOutliner ) return ; - OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView(); + OutlinerView* pOLV = m_pSdrView->GetTextEditOutlinerView(); EEControlBits nCtrl = pOutliner->GetControlWord(); nCtrl |= EEControlBits::AUTOCORRECT; @@ -116,7 +118,7 @@ void SwDrawTextShell::Init() SwDrawTextShell::SwDrawTextShell(SwView &rV) : SfxShell(&rV), - rView(rV) + m_rView(rV) { SwWrtShell &rSh = GetShell(); SetPool(rSh.GetAttrPool().GetSecondaryPool()); @@ -131,12 +133,12 @@ SwDrawTextShell::SwDrawTextShell(SwView &rV) : SwDrawTextShell::~SwDrawTextShell() { if ( GetView().GetCurShell() == this ) - rView.ResetSubShell(); + m_rView.ResetSubShell(); } SwWrtShell& SwDrawTextShell::GetShell() { - return rView.GetWrtShell(); + return m_rView.GetWrtShell(); } // Disable slots with this status method @@ -155,7 +157,7 @@ void SwDrawTextShell::StateDisableItems( SfxItemSet &rSet ) void SwDrawTextShell::SetAttrToMarked(const SfxItemSet& rAttr) { - OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView(); + OutlinerView* pOLV = m_pSdrView->GetTextEditOutlinerView(); tools::Rectangle aOutRect = pOLV->GetOutputArea(); if (tools::Rectangle() != aOutRect) @@ -166,7 +168,7 @@ void SwDrawTextShell::SetAttrToMarked(const SfxItemSet& rAttr) bool SwDrawTextShell::IsTextEdit() const { - return pSdrView->IsTextEdit(); + return m_pSdrView->IsTextEdit(); } void SwDrawTextShell::ExecFontWork(SfxRequest const & rReq) @@ -174,23 +176,23 @@ 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(); + SfxViewFrame& rVFrame = GetView().GetViewFrame(); if ( rReq.GetArgs() ) { - pVFrame->SetChildWindow(SvxFontWorkChildWindow::GetChildWindowId(), + rVFrame.SetChildWindow(SvxFontWorkChildWindow::GetChildWindowId(), static_cast<const SfxBoolItem&>( (rReq.GetArgs()-> Get(SID_FONTWORK))).GetValue()); } else - pVFrame->ToggleChildWindow(SvxFontWorkChildWindow::GetChildWindowId()); + rVFrame.ToggleChildWindow(SvxFontWorkChildWindow::GetChildWindowId()); - pVFrame->GetBindings().Invalidate(SID_FONTWORK); + rVFrame.GetBindings().Invalidate(SID_FONTWORK); } void SwDrawTextShell::StateFontWork(SfxItemSet& rSet) { const sal_uInt16 nId = SvxFontWorkChildWindow::GetChildWindowId(); - rSet.Put(SfxBoolItem(SID_FONTWORK, GetView().GetViewFrame()->HasChildWindow(nId))); + rSet.Put(SfxBoolItem(SID_FONTWORK, GetView().GetViewFrame().HasChildWindow(nId))); } // Edit SfxRequests for FontWork @@ -233,7 +235,7 @@ void SwDrawTextShell::GetFormTextState(SfxItemSet& rSet) if ( rMarkList.GetMarkCount() == 1 ) pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); - const SdrTextObj* pTextObj = dynamic_cast< const SdrTextObj* >(pObj); + const SdrTextObj* pTextObj = DynCastSdrTextObj(pObj); const bool bDeactivate( !pObj || !pTextObj || @@ -263,18 +265,19 @@ void SwDrawTextShell::GetFormTextState(SfxItemSet& rSet) void SwDrawTextShell::ExecDrawLingu(SfxRequest const &rReq) { SwWrtShell &rSh = GetShell(); - OutlinerView* pOutlinerView = pSdrView->GetTextEditOutlinerView(); + OutlinerView* pOutlinerView = m_pSdrView->GetTextEditOutlinerView(); if( !rSh.GetDrawView()->GetMarkedObjectList().GetMarkCount() ) return; switch(rReq.GetSlot()) { case SID_THESAURUS: - pOutlinerView->StartThesaurus(); + pOutlinerView->StartThesaurus(rReq.GetFrameWeld()); break; case SID_HANGUL_HANJA_CONVERSION: - pOutlinerView->StartTextConversion(LANGUAGE_KOREAN, LANGUAGE_KOREAN, nullptr, + pOutlinerView->StartTextConversion(rReq.GetFrameWeld(), + LANGUAGE_KOREAN, LANGUAGE_KOREAN, nullptr, i18n::TextConversionOption::CHARACTER_BY_CHARACTER, true, false); break; @@ -335,7 +338,7 @@ void SwDrawTextShell::ExecDrawLingu(SfxRequest const &rReq) vcl::Font aTargetFont = OutputDevice::GetDefaultFont(DefaultFontType::CJK_TEXT, nTargetLang, GetDefaultFontFlags::OnlyOne); - pOutlinerView->StartTextConversion(nSourceLang, nTargetLang, &aTargetFont, nOptions, false, false); + pOutlinerView->StartTextConversion(rReq.GetFrameWeld(), nSourceLang, nTargetLang, &aTargetFont, nOptions, false, false); } Reference<lang::XComponent> xComponent(xDialog, UNO_QUERY); @@ -352,8 +355,8 @@ void SwDrawTextShell::ExecDrawLingu(SfxRequest const &rReq) void SwDrawTextShell::ExecDraw(SfxRequest &rReq) { SwWrtShell &rSh = GetShell(); - pSdrView = rSh.GetDrawView(); - OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView(); + m_pSdrView = rSh.GetDrawView(); + OutlinerView* pOLV = m_pSdrView->GetTextEditOutlinerView(); switch (rReq.GetSlot()) { @@ -363,7 +366,7 @@ void SwDrawTextShell::ExecDraw(SfxRequest &rReq) case FN_INSERT_NNBSP: case SID_INSERT_RLM : case SID_INSERT_LRM : - case SID_INSERT_ZWNBSP : + case SID_INSERT_WJ : case SID_INSERT_ZWSP: { sal_Unicode cIns = 0; @@ -376,7 +379,7 @@ void SwDrawTextShell::ExecDraw(SfxRequest &rReq) 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_ZWNBSP: cIns = CHAR_ZWNBSP; break; + case SID_INSERT_WJ: cIns = CHAR_WJ; break; } pOLV->InsertText( OUString(cIns)); rReq.Done(); @@ -402,7 +405,7 @@ void SwDrawTextShell::ExecDraw(SfxRequest &rReq) case SID_SELECTALL: { - SdrOutliner * pOutliner = pSdrView->GetTextEditOutliner(); + SdrOutliner * pOutliner = m_pSdrView->GetTextEditOutliner(); if(pOutliner) { sal_Int32 nParaCount = pOutliner->GetParagraphCount(); @@ -415,13 +418,13 @@ void SwDrawTextShell::ExecDraw(SfxRequest &rReq) case FN_FORMAT_RESET: // delete hard text attributes { pOLV->RemoveAttribsKeepLanguages( true ); - pOLV->GetEditView().GetEditEngine()->RemoveFields(); + pOLV->GetEditView().getEditEngine().RemoveFields(); rReq.Done(); } break; case FN_ESCAPE: - if (pSdrView->IsTextEdit()) + if (m_pSdrView->IsTextEdit()) { // Shell switch! rSh.EndTextEdit(); @@ -433,22 +436,28 @@ void SwDrawTextShell::ExecDraw(SfxRequest &rReq) break; case FN_DRAWTEXT_ATTR_DLG: { - SfxItemSet aNewAttr( pSdrView->GetModel()->GetItemPool() ); - pSdrView->GetAttributes( aNewAttr ); + SfxItemSet aNewAttr(m_pSdrView->GetModel().GetItemPool()); + m_pSdrView->GetAttributes( aNewAttr ); SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); - ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateTextTabDialog( + VclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateTextTabDialog( GetView().GetFrameWeld(), - &aNewAttr, pSdrView )); - sal_uInt16 nResult = pDlg->Execute(); - - if (nResult == RET_OK) - { - if (pSdrView->AreObjectsMarked()) + &aNewAttr, m_pSdrView )); + auto xRequest = std::make_shared<SfxRequest>(rReq); + rReq.Ignore(); // the 'old' request is not relevant any more + pDlg->StartExecuteAsync( + [this, pDlg, xRequest=std::move(xRequest)] (sal_Int32 nResult)->void { - pSdrView->SetAttributes(*pDlg->GetOutputItemSet()); - rReq.Done(*(pDlg->GetOutputItemSet())); + if (nResult == RET_OK) + { + if (m_pSdrView->AreObjectsMarked()) + { + m_pSdrView->SetAttributes(*pDlg->GetOutputItemSet()); + xRequest->Done(*(pDlg->GetOutputItemSet())); + } + } + pDlg->disposeOnce(); } - } + ); } break; case SID_TABLE_VERT_NONE: @@ -456,7 +465,7 @@ void SwDrawTextShell::ExecDraw(SfxRequest &rReq) case SID_TABLE_VERT_BOTTOM: { sal_uInt16 nSId = rReq.GetSlot(); - if (pSdrView->AreObjectsMarked()) + if (m_pSdrView->AreObjectsMarked()) { SdrTextVertAdjust eTVA = SDRTEXTVERTADJUST_TOP; if (nSId == SID_TABLE_VERT_CENTER) @@ -464,10 +473,10 @@ void SwDrawTextShell::ExecDraw(SfxRequest &rReq) else if (nSId == SID_TABLE_VERT_BOTTOM) eTVA = SDRTEXTVERTADJUST_BOTTOM; - SfxItemSet aNewAttr( pSdrView->GetModel()->GetItemPool() ); - pSdrView->GetAttributes( aNewAttr ); + SfxItemSet aNewAttr(m_pSdrView->GetModel().GetItemPool()); + m_pSdrView->GetAttributes( aNewAttr ); aNewAttr.Put(SdrTextVertAdjustItem(eTVA)); - pSdrView->SetAttributes(aNewAttr); + m_pSdrView->SetAttributes(aNewAttr); rReq.Done(); } @@ -479,7 +488,7 @@ void SwDrawTextShell::ExecDraw(SfxRequest &rReq) return; } - GetView().GetViewFrame()->GetBindings().InvalidateAll(false); + GetView().GetViewFrame().GetBindings().InvalidateAll(false); if (IsTextEdit() && pOLV->GetOutliner()->IsModified()) rSh.SetModified(); @@ -517,15 +526,15 @@ void SwDrawTextShell::ExecUndo(SfxRequest &rReq) pUndoManager->Redo(); } bCallBase = false; - GetView().GetViewFrame()->GetBindings().InvalidateAll(false); + GetView().GetViewFrame().GetBindings().InvalidateAll(false); } break; } } if( bCallBase ) { - SfxViewFrame *pSfxViewFrame = GetView().GetViewFrame(); - pSfxViewFrame->ExecuteSlot(rReq, pSfxViewFrame->GetInterface()); + SfxViewFrame& rSfxViewFrame = GetView().GetViewFrame(); + rSfxViewFrame.ExecuteSlot(rReq, rSfxViewFrame.GetInterface()); } } @@ -536,7 +545,7 @@ void SwDrawTextShell::StateUndo(SfxItemSet &rSet) if ( !IsTextEdit() ) return; - SfxViewFrame *pSfxViewFrame = GetView().GetViewFrame(); + SfxViewFrame& rSfxViewFrame = GetView().GetViewFrame(); SfxWhichIter aIter(rSet); sal_uInt16 nWhich = aIter.FirstWhich(); while( nWhich ) @@ -566,7 +575,7 @@ void SwDrawTextShell::StateUndo(SfxItemSet &rSet) { OUStringBuffer sList; for( sal_uInt16 n = 0; n < nCount; ++n ) - sList.append( (pUndoManager->*fnGetComment)( n, SfxUndoManager::TopLevel ) ).append("\n"); + sList.append( (pUndoManager->*fnGetComment)( n, SfxUndoManager::TopLevel ) + "\n"); SfxStringListItem aItem( nWhich ); aItem.SetString( sList.makeStringAndClear() ); @@ -583,7 +592,7 @@ void SwDrawTextShell::StateUndo(SfxItemSet &rSet) auto* pUndoManager = dynamic_cast<IDocumentUndoRedo*>(GetUndoManager()); if (pUndoManager) pUndoManager->SetView(&GetView()); - pSfxViewFrame->GetSlotState(nWhich, pSfxViewFrame->GetInterface(), &rSet); + rSfxViewFrame.GetSlotState(nWhich, rSfxViewFrame.GetInterface(), &rSet); if (pUndoManager) pUndoManager->SetView(nullptr); } @@ -595,7 +604,7 @@ void SwDrawTextShell::StateUndo(SfxItemSet &rSet) void SwDrawTextShell::ExecTransliteration( SfxRequest const & rReq ) { - if (!pSdrView) + if (!m_pSdrView) return; using namespace i18n; @@ -640,7 +649,7 @@ void SwDrawTextShell::ExecTransliteration( SfxRequest const & rReq ) if( nMode != TransliterationFlags::NONE ) { - OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView(); + OutlinerView* pOLV = m_pSdrView->GetTextEditOutlinerView(); if (!pOLV) return; @@ -653,10 +662,10 @@ void SwDrawTextShell::ExecRotateTransliteration( SfxRequest const & rReq ) { if( rReq.GetSlot() == SID_TRANSLITERATE_ROTATE_CASE ) { - if (!pSdrView) + if (!m_pSdrView) return; - OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView(); + OutlinerView* pOLV = m_pSdrView->GetTextEditOutlinerView(); if (!pOLV) return; @@ -669,22 +678,20 @@ void SwDrawTextShell::ExecRotateTransliteration( SfxRequest const & rReq ) void SwDrawTextShell::InsertSymbol(SfxRequest& rReq) { - OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView(); + OutlinerView* pOLV = m_pSdrView->GetTextEditOutlinerView(); if(!pOLV) return; const SfxItemSet *pArgs = rReq.GetArgs(); - const SfxPoolItem* pItem = nullptr; + const SfxStringItem* pItem = nullptr; if( pArgs ) - pArgs->GetItemState(GetPool().GetWhich(SID_CHARMAP), false, &pItem); + pItem = pArgs->GetItemIfSet(SID_CHARMAP, false); OUString sSym; OUString sFontName; if ( pItem ) { - sSym = static_cast<const SfxStringItem*>(pItem)->GetValue(); - const SfxPoolItem* pFtItem = nullptr; - pArgs->GetItemState( GetPool().GetWhich(SID_ATTR_SPECIALCHAR), false, &pFtItem); - const SfxStringItem* pFontItem = dynamic_cast<const SfxStringItem*>( pFtItem ); + sSym = pItem->GetValue(); + const SfxStringItem* pFontItem = pArgs->GetItemIfSet( SID_ATTR_SPECIALCHAR, false); if ( pFontItem ) sFontName = pFontItem->GetValue(); } @@ -699,9 +706,13 @@ void SwDrawTextShell::InsertSymbol(SfxRequest& rReq) if( pI ) aSetDlgFont.reset(static_cast<SvxFontItem*>(pI->Clone())); else - aSetDlgFont.reset(static_cast<SvxFontItem*>(aSet.Get( GetWhichOfScript( + { + TypedWhichId<SvxFontItem> nFontWhich = + GetWhichOfScript( SID_ATTR_CHAR_FONT, - SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() ) )).Clone())); + SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() ) ); + aSetDlgFont.reset(aSet.Get( nFontWhich ).Clone()); + } if (sFontName.isEmpty()) sFontName = aSetDlgFont->GetFamilyName(); } @@ -712,7 +723,7 @@ void SwDrawTextShell::InsertSymbol(SfxRequest& rReq) SfxAllItemSet aAllSet( GetPool() ); aAllSet.Put( SfxBoolItem( FN_PARAM_1, false ) ); - SwViewOption aOpt(*rView.GetWrtShell().GetViewOptions()); + SwViewOption aOpt(*m_rView.GetWrtShell().GetViewOptions()); const OUString& sSymbolFont = aOpt.GetSymbolFont(); if( !sSymbolFont.isEmpty() ) aAllSet.Put( SfxStringItem( SID_FONT_NAME, sSymbolFont ) ); @@ -721,23 +732,26 @@ void SwDrawTextShell::InsertSymbol(SfxRequest& rReq) // If character is selected, it can be shown SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); - auto xFrame = rView.GetViewFrame()->GetFrame().GetFrameInterface(); - ScopedVclPtr<SfxAbstractDialog> pDlg(pFact->CreateCharMapDialog(rView.GetFrameWeld(), aAllSet, xFrame)); - pDlg->Execute(); + auto xFrame = m_rView.GetViewFrame().GetFrame().GetFrameInterface(); + VclPtr<SfxAbstractDialog> pDlg(pFact->CreateCharMapDialog(m_rView.GetFrameWeld(), aAllSet, xFrame)); + pDlg->StartExecuteAsync( + [pDlg] (sal_Int32 /*nResult*/)->void + { + pDlg->disposeOnce(); + } + ); return; } // do not flicker pOLV->HideCursor(); - SdrOutliner * pOutliner = pSdrView->GetTextEditOutliner(); - pOutliner->SetUpdateMode(false); + SdrOutliner * pOutliner = m_pSdrView->GetTextEditOutliner(); + pOutliner->SetUpdateLayout(false); SfxItemSet aOldSet( pOLV->GetAttribs() ); - SfxItemSet aFontSet( - *aOldSet.GetPool(), - svl::Items< + SfxItemSetFixed< EE_CHAR_FONTINFO, EE_CHAR_FONTINFO, - EE_CHAR_FONTINFO_CJK, EE_CHAR_FONTINFO_CTL>{}); + EE_CHAR_FONTINFO_CJK, EE_CHAR_FONTINFO_CTL> aFontSet( *aOldSet.GetPool() ); aFontSet.Set( aOldSet ); // Insert string @@ -774,10 +788,10 @@ void SwDrawTextShell::InsertSymbol(SfxRequest& rReq) pOLV->SetAttribs( aFontSet ); // From now on show again - pOutliner->SetUpdateMode(true); + pOutliner->SetUpdateLayout(true); pOLV->ShowCursor(); - rReq.AppendItem( SfxStringItem( GetPool().GetWhich(SID_CHARMAP), sSym ) ); + rReq.AppendItem( SfxStringItem( SID_CHARMAP, sSym ) ); if(!aFont.GetFamilyName().isEmpty()) rReq.AppendItem( SfxStringItem( SID_ATTR_SPECIALCHAR, aFont.GetFamilyName() ) ); rReq.Done(); @@ -787,8 +801,8 @@ void SwDrawTextShell::InsertSymbol(SfxRequest& rReq) SfxUndoManager* SwDrawTextShell::GetUndoManager() { SwWrtShell &rSh = GetShell(); - pSdrView = rSh.GetDrawView(); - SdrOutliner * pOutliner = pSdrView->GetTextEditOutliner(); + m_pSdrView = rSh.GetDrawView(); + SdrOutliner * pOutliner = m_pSdrView->GetTextEditOutliner(); return &pOutliner->GetUndoManager(); } @@ -798,10 +812,10 @@ void SwDrawTextShell::GetStatePropPanelAttr(SfxItemSet &rSet) sal_uInt16 nWhich = aIter.FirstWhich(); SwWrtShell &rSh = GetShell(); - pSdrView = rSh.GetDrawView(); + m_pSdrView = rSh.GetDrawView(); - SfxItemSet aAttrs( pSdrView->GetModel()->GetItemPool() ); - pSdrView->GetAttributes( aAttrs ); + SfxItemSet aAttrs(m_pSdrView->GetModel().GetItemPool()); + m_pSdrView->GetAttributes( aAttrs ); while ( nWhich ) { @@ -815,7 +829,7 @@ void SwDrawTextShell::GetStatePropPanelAttr(SfxItemSet &rSet) case SID_TABLE_VERT_BOTTOM: bool bContour = false; SfxItemState eConState = aAttrs.GetItemState( SDRATTR_TEXT_CONTOURFRAME ); - if( eConState != SfxItemState::DONTCARE ) + if( eConState != SfxItemState::INVALID ) { bContour = aAttrs.Get( SDRATTR_TEXT_CONTOURFRAME ).GetValue(); } @@ -824,8 +838,8 @@ void SwDrawTextShell::GetStatePropPanelAttr(SfxItemSet &rSet) 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) + //if(SfxItemState::INVALID != eVState && SfxItemState::INVALID != eHState) + if(SfxItemState::INVALID != eVState) { SdrTextVertAdjust eTVA = aAttrs.Get(SDRATTR_TEXT_VERTADJUST).GetValue(); bool bSet = (nSlotId == SID_TABLE_VERT_NONE && eTVA == SDRTEXTVERTADJUST_TOP) || diff --git a/sw/source/uibase/shells/frmsh.cxx b/sw/source/uibase/shells/frmsh.cxx index 6e990cd632b6..2785f7133031 100644 --- a/sw/source/uibase/shells/frmsh.cxx +++ b/sw/source/uibase/shells/frmsh.cxx @@ -81,17 +81,6 @@ 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) @@ -167,7 +156,7 @@ void SwFrameShell::Execute(SfxRequest &rReq) { // Frame already exists, open frame dialog for editing. SfxStringItem aDefPage(FN_FORMAT_FRAME_DLG, "columns"); - rSh.GetView().GetViewFrame()->GetDispatcher()->ExecuteList( + rSh.GetView().GetViewFrame().GetDispatcher()->ExecuteList( FN_FORMAT_FRAME_DLG, SfxCallMode::SYNCHRON|SfxCallMode::RECORD, { &aDefPage }); @@ -177,10 +166,10 @@ void SwFrameShell::Execute(SfxRequest &rReq) { // Frame already exists, only the number of columns will be changed. sal_uInt16 nCols = 1; - if(pArgs->GetItemState(SID_ATTR_COLUMNS, false, &pItem) == SfxItemState::SET) - nCols = static_cast<const SfxUInt16Item *>(pItem)->GetValue(); + if(const SfxUInt16Item* pColsItem = pArgs->GetItemIfSet(SID_ATTR_COLUMNS, false)) + nCols = pColsItem->GetValue(); - SfxItemSet aSet(GetPool(),svl::Items<RES_COL,RES_COL>{}); + SfxItemSetFixed<RES_COL,RES_COL> aSet(GetPool()); rSh.GetFlyFrameAttr( aSet ); SwFormatCol aCol(aSet.Get(RES_COL)); // GutterWidth will not always passed, hence get firstly @@ -192,7 +181,7 @@ void SwFrameShell::Execute(SfxRequest &rReq) aSet.Put(aCol); // Template AutoUpdate SwFrameFormat* pFormat = rSh.GetSelectedFrameFormat(); - if(pFormat && pFormat->IsAutoUpdateFormat()) + if(pFormat && pFormat->IsAutoUpdateOnDirectFormat()) { rSh.AutoUpdateFrame(pFormat, aSet); } @@ -215,7 +204,7 @@ void SwFrameShell::Execute(SfxRequest &rReq) const OUString& rURL = rHLinkItem.GetURL(); const OUString& rTarget = rHLinkItem.GetTargetFrame(); - SfxItemSet aSet( rSh.GetAttrPool(), svl::Items<RES_URL, RES_URL>{} ); + SfxItemSetFixed<RES_URL, RES_URL> aSet( rSh.GetAttrPool() ); rSh.GetFlyFrameAttr( aSet ); SwFormatURL aURL( aSet.Get( RES_URL ) ); @@ -246,7 +235,7 @@ void SwFrameShell::Execute(SfxRequest &rReq) case FN_FRAME_UNCHAIN: rSh.Unchain( *rSh.GetFlyFrameFormat() ); - GetView().GetViewFrame()->GetBindings().Invalidate(FN_FRAME_CHAIN); + GetView().GetViewFrame().GetBindings().Invalidate(FN_FRAME_CHAIN); break; case FN_FORMAT_FOOTNOTE_DLG: { @@ -269,6 +258,12 @@ void SwFrameShell::Execute(SfxRequest &rReq) GetView().UpdateWordCount(this, nSlot); break; } + case FN_UNFLOAT_FRAME: + { + rSh.UnfloatFlyFrame(); + rReq.Done(); + break; + } default: bMore = true; } @@ -349,7 +344,7 @@ void SwFrameShell::Execute(SfxRequest &rReq) case SID_ATTR_ULSPACE: case SID_ATTR_LRSPACE: { - if(pArgs && SfxItemState::SET == pArgs->GetItemState(GetPool().GetWhich(nSlot), false, &pItem)) + if(pArgs && SfxItemState::SET == pArgs->GetItemState(GetPool().GetWhichIDFromSlotID(nSlot), false, &pItem)) { aMgr.SetAttrSet( *pArgs ); bCopyToFormat = true; @@ -363,44 +358,45 @@ void SwFrameShell::Execute(SfxRequest &rReq) bool bApplyNewSize = false; Point aNewPos = aMgr.GetPos(); - if (pArgs && - SfxItemState::SET == pArgs->GetItemState(SID_ATTR_TRANSFORM_POS_X, false, &pItem)) + if (pArgs) { - aNewPos.setX( static_cast<const SfxInt32Item*>(pItem)->GetValue() ); - bApplyNewPos = true; - } - if (pArgs && - SfxItemState::SET == pArgs->GetItemState(SID_ATTR_TRANSFORM_POS_Y, false, &pItem)) - { - aNewPos.setY( static_cast<const SfxInt32Item*>(pItem)->GetValue() ); - bApplyNewPos = true; + 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 && - SfxItemState::SET == pArgs->GetItemState(SID_ATTR_TRANSFORM_WIDTH, false, &pItem)) - { - aNewSize.setWidth( static_cast< const SfxUInt32Item* >(pItem)->GetValue() ); - bApplyNewSize = true; - } - - if (pArgs && - SfxItemState::SET == pArgs->GetItemState(SID_ATTR_TRANSFORM_HEIGHT, false, &pItem)) + if (pArgs) { - aNewSize.setHeight( static_cast< const SfxUInt32Item* >(pItem)->GetValue() ); - bApplyNewSize = true; + 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))) { - SfxItemSet aSet(rSh.GetAttrPool(), svl::Items<RES_GRFATR_ROTATION, RES_GRFATR_ROTATION>{} ); + 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 (pArgs && SfxItemState::SET == pArgs->GetItemState(SID_ATTR_TRANSFORM_DELTA_ANGLE, false, &pItem)) + if (const SdrAngleItem* pAngleItem = pArgs->GetItemIfSet(SID_ATTR_TRANSFORM_DELTA_ANGLE, false)) { - const Degree10 nDeltaRot = toDegree10(static_cast<const SdrAngleItem*>(pItem)->GetValue()); + const Degree10 nDeltaRot = to<Degree10>(pAngleItem->GetValue()); aMgr.SetRotation(nOldRot, nOldRot + nDeltaRot, rRotation.GetUnrotatedSize()); } @@ -408,9 +404,9 @@ void SwFrameShell::Execute(SfxRequest &rReq) // 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 (pArgs && SfxItemState::SET == pArgs->GetItemState(SID_ATTR_TRANSFORM_ANGLE, false, &pItem)) + if (const SdrAngleItem* pTransformItem = pArgs->GetItemIfSet(SID_ATTR_TRANSFORM_ANGLE, false)) { - const Degree10 nNewRot = toDegree10(static_cast<const SdrAngleItem*>(pItem)->GetValue()); + const Degree10 nNewRot = to<Degree10>(pTransformItem->GetValue()); // RotGrfFlyFrame: Rotation change here, SwFlyFrameAttrMgr aMgr is available aMgr.SetRotation(nOldRot, nNewRot, rRotation.GetUnrotatedSize()); @@ -439,14 +435,12 @@ void SwFrameShell::Execute(SfxRequest &rReq) const SelectionType nSel = rSh.GetSelectionType(); if (nSel & SelectionType::Graphic) { - rSh.GetView().GetViewFrame()->GetDispatcher()->Execute(FN_FORMAT_GRAFIC_DLG); + rSh.GetView().GetViewFrame().GetDispatcher()->Execute(FN_FORMAT_GRAFIC_DLG); bUpdateMgr = false; } else { - SfxItemSet aSet( - GetPool(), - svl::Items< + SfxItemSetFixed< RES_FRMATR_BEGIN, RES_FRMATR_END - 1, // FillAttribute support: XATTR_FILL_FIRST, XATTR_FILL_LAST, @@ -465,7 +459,7 @@ void SwFrameShell::Execute(SfxRequest &rReq) 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>{}); + 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 @@ -486,12 +480,12 @@ void SwFrameShell::Execute(SfxRequest &rReq) const SwRect &rPg = rSh.GetAnyCurRect(CurRectType::Page); SwFormatFrameSize aFrameSize(SwFrameSize::Variable, rPg.Width(), rPg.Height()); - aFrameSize.SetWhich(GetPool().GetWhich(SID_ATTR_PAGE_SIZE)); + aFrameSize.SetWhich(GetPool().GetWhichIDFromSlotID(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)); + aPrtSize.SetWhich(GetPool().GetWhichIDFromSlotID(FN_GET_PRINT_AREA)); aSet.Put(aPrtSize); aSet.Put(aMgr.GetAttrSet()); @@ -510,11 +504,12 @@ void SwFrameShell::Execute(SfxRequest &rReq) const uno::Reference < embed::XEmbeddedObject > xObj( rSh.GetOleRef() ); aSet.Put( SfxBoolItem( FN_OLE_IS_MATH, xObj.is() && SotExchange::IsMath( xObj->getClassID() ) ) ); - OString sDefPage; - if(pArgs && pArgs->GetItemState(FN_FORMAT_FRAME_DLG, false, &pItem) == SfxItemState::SET) - sDefPage = OUStringToOString(static_cast<const SfxStringItem *>(pItem)->GetValue(), RTL_TEXTENCODING_UTF8); + OUString sDefPage; + const SfxStringItem* pDlgItem; + if(pArgs && (pDlgItem = pArgs->GetItemIfSet(FN_FORMAT_FRAME_DLG, false))) + sDefPage = pDlgItem->GetValue(); - aSet.Put(SfxFrameItem( SID_DOCFRAME, &GetView().GetViewFrame()->GetFrame())); + 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(); @@ -539,51 +534,48 @@ void SwFrameShell::Execute(SfxRequest &rReq) if(pOutSet) { rReq.Done(*pOutSet); + const SfxBoolItem* pRatioItem = nullptr; if(nSel & SelectionType::Ole && - SfxItemState::SET == pOutSet->GetItemState(FN_KEEP_ASPECT_RATIO, true, &pItem)) + (pRatioItem = pOutSet->GetItemIfSet(FN_KEEP_ASPECT_RATIO))) { SwViewOption aUsrPref( *pVOpt ); - aUsrPref.SetKeepRatio(static_cast<const SfxBoolItem*>(pItem)->GetValue()); + aUsrPref.SetKeepRatio(pRatioItem->GetValue()); SW_MOD()->ApplyUsrPref(aUsrPref, &GetView()); } - if (SfxItemState::SET == pOutSet->GetItemState(FN_SET_FRM_ALT_NAME, true, &pItem)) + if (const SfxStringItem* pAltNameItem = pOutSet->GetItemIfSet(FN_SET_FRM_ALT_NAME)) { // #i73249# - rSh.SetObjTitle(static_cast<const SfxStringItem*>(pItem)->GetValue()); + rSh.SetObjTitle(pAltNameItem->GetValue()); } - if (SfxItemState::SET == pOutSet->GetItemState(FN_UNO_DESCRIPTION, true, &pItem)) - rSh.SetObjDescription(static_cast<const SfxStringItem*>(pItem)->GetValue()); + if (const SfxStringItem* pDescripItem = pOutSet->GetItemIfSet(FN_UNO_DESCRIPTION)) + rSh.SetObjDescription(pDescripItem->GetValue()); // Template AutoUpdate SwFrameFormat* pFormat = rSh.GetSelectedFrameFormat(); - if(pFormat && pFormat->IsAutoUpdateFormat()) + if(pFormat && pFormat->IsAutoUpdateOnDirectFormat()) { rSh.AutoUpdateFrame(pFormat, *pOutSet); // Anything which is not supported by the format must be set hard. - if(SfxItemState::SET == pOutSet->GetItemState(FN_SET_FRM_NAME, false, &pItem)) - rSh.SetFlyName(static_cast<const SfxStringItem*>(pItem)->GetValue()); - SfxItemSet aShellSet( - GetPool(), - svl::Items< + 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>{}); + RES_SURROUND, RES_ANCHOR> aShellSet( GetPool() ); aShellSet.Put(*pOutSet); aMgr.SetAttrSet(aShellSet); - if(SfxItemState::SET == pOutSet->GetItemState(FN_SET_FRM_NAME, false, &pItem)) - rSh.SetFlyName(static_cast<const SfxStringItem*>(pItem)->GetValue()); + 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(SfxItemState::SET == - pOutSet->GetItemState(FN_PARAM_CHAIN_PREVIOUS, - false, &pItem)) + if(const SfxStringItem* pPreviousItem = + pOutSet->GetItemIfSet(FN_PARAM_CHAIN_PREVIOUS, false)) { rSh.HideChainMarker(); - OUString sPrevName = - static_cast<const SfxStringItem*>(pItem)->GetValue(); + OUString sPrevName = pPreviousItem->GetValue(); const SwFormatChain &rChain = pCurrFlyFormat->GetChain(); //needs cast - no non-const method available SwFlyFrameFormat* pFlyFormat = @@ -601,8 +593,7 @@ void SwFrameShell::Execute(SfxRequest &rReq) if (!sPrevName.isEmpty()) { //needs cast - no non-const method available - SwFrameFormat* pPrevFormat = const_cast<SwFrameFormat*>( - lcl_GetFrameFormatByName(rSh, sPrevName)); + SwFrameFormat* pPrevFormat = rSh.GetDoc()->GetFlyFrameFormatByName(sPrevName); SAL_WARN_IF(!pPrevFormat, "sw.ui", "No frame found!"); if(pPrevFormat) { @@ -611,13 +602,11 @@ void SwFrameShell::Execute(SfxRequest &rReq) } rSh.SetChainMarker(); } - if(SfxItemState::SET == - pOutSet->GetItemState(FN_PARAM_CHAIN_NEXT, false, - &pItem)) + if(const SfxStringItem* pChainNextItem = + pOutSet->GetItemIfSet(FN_PARAM_CHAIN_NEXT, false)) { rSh.HideChainMarker(); - OUString sNextName = - static_cast<const SfxStringItem*>(pItem)->GetValue(); + OUString sNextName = pChainNextItem->GetValue(); const SwFormatChain &rChain = pCurrFlyFormat->GetChain(); //needs cast - no non-const method available SwFlyFrameFormat* pFlyFormat = @@ -635,8 +624,7 @@ void SwFrameShell::Execute(SfxRequest &rReq) if (!sNextName.isEmpty()) { //needs cast - no non-const method available - SwFrameFormat* pNextFormat = const_cast<SwFrameFormat*>( - lcl_GetFrameFormatByName(rSh, sNextName)); + SwFrameFormat* pNextFormat = rSh.GetDoc()->GetFlyFrameFormatByName(sNextName); SAL_WARN_IF(!pNextFormat, "sw.ui", "No frame found!"); if(pNextFormat) { @@ -658,7 +646,7 @@ void SwFrameShell::Execute(SfxRequest &rReq) SwFormatHoriOrient aHori(aMgr.GetHoriOrient()); bool bMirror = !aHori.IsPosToggle(); aHori.SetPosToggle(bMirror); - SfxItemSet aSet(GetPool(), svl::Items<RES_HORI_ORIENT, RES_HORI_ORIENT>{}); + SfxItemSetFixed<RES_HORI_ORIENT, RES_HORI_ORIENT> aSet(GetPool()); aSet.Put(aHori); aMgr.SetAttrSet(aSet); bCopyToFormat = true; @@ -674,14 +662,17 @@ void SwFrameShell::Execute(SfxRequest &rReq) { OUString aName(rSh.GetFlyName()); SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); - ScopedVclPtr<AbstractSvxObjectNameDialog> pDlg( + VclPtr<AbstractSvxObjectNameDialog> pDlg( pFact->CreateSvxObjectNameDialog(GetView().GetFrameWeld(), aName)); - if ( pDlg->Execute() == RET_OK ) - { - pDlg->GetName(aName); - rSh.SetFlyName(aName); - } + pDlg->StartExecuteAsync( + [this, pDlg] (sal_Int32 nResult)->void + { + if (nResult == RET_OK) + GetShell().SetFlyName(pDlg->GetName()); + pDlg->disposeOnce(); + } + ); } } break; @@ -695,20 +686,25 @@ void SwFrameShell::Execute(SfxRequest &rReq) { OUString aDescription(rSh.GetObjDescription()); OUString aTitle(rSh.GetObjTitle()); + bool isDecorative(rSh.IsObjDecorative()); SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); - ScopedVclPtr<AbstractSvxObjectTitleDescDialog> pDlg( + VclPtr<AbstractSvxObjectTitleDescDialog> pDlg( pFact->CreateSvxObjectTitleDescDialog(GetView().GetFrameWeld(), - aTitle, aDescription )); + aTitle, aDescription, isDecorative)); - if ( pDlg->Execute() == RET_OK ) - { - pDlg->GetDescription(aDescription); - pDlg->GetTitle(aTitle); - - rSh.SetObjDescription(aDescription); - rSh.SetObjTitle(aTitle); - } + pDlg->StartExecuteAsync( + [this, pDlg] (sal_Int32 nResult)->void + { + if (nResult == RET_OK) + { + GetShell().SetObjDescription(pDlg->GetDescription()); + GetShell().SetObjTitle(pDlg->GetTitle()); + GetShell().SetObjDecorative(pDlg->IsDecorative()); + } + pDlg->disposeOnce(); + } + ); } } break; @@ -719,7 +715,7 @@ void SwFrameShell::Execute(SfxRequest &rReq) if ( bUpdateMgr ) { SwFrameFormat* pFormat = rSh.GetSelectedFrameFormat(); - if ( bCopyToFormat && pFormat && pFormat->IsAutoUpdateFormat() ) + if ( bCopyToFormat && pFormat && pFormat->IsAutoUpdateOnDirectFormat() ) { rSh.AutoUpdateFrame(pFormat, aMgr.GetAttrSet()); } @@ -738,11 +734,9 @@ void SwFrameShell::GetState(SfxItemSet& rSet) if (!rSh.IsFrameSelected()) return; - SfxItemSet aSet( - rSh.GetAttrPool(), - svl::Items< + SfxItemSetFixed< RES_LR_SPACE, RES_UL_SPACE, - RES_PRINT, RES_HORI_ORIENT>{}); + RES_PRINT, RES_HORI_ORIENT> aSet(rSh.GetAttrPool() ); rSh.GetFlyFrameAttr( aSet ); bool bProtect = rSh.IsSelObjProtected(FlyProtectFlags::Pos) != FlyProtectFlags::NONE; @@ -776,7 +770,7 @@ void SwFrameShell::GetState(SfxItemSet& rSet) case RES_PRINT: case RES_SURROUND: { - rSet.Put(aSet.Get(GetPool().GetWhich(nWhich))); + rSet.Put(aSet.Get(GetPool().GetWhichIDFromSlotID(nWhich))); } break; case SID_OBJECT_ALIGN: @@ -918,14 +912,12 @@ void SwFrameShell::GetState(SfxItemSet& rSet) case SID_HYPERLINK_GETLINK: { SvxHyperlinkItem aHLinkItem; - const SfxPoolItem* pItem; - SfxItemSet aURLSet(GetPool(), svl::Items<RES_URL, RES_URL>{}); + SfxItemSetFixed<RES_URL, RES_URL> aURLSet(GetPool()); rSh.GetFlyFrameAttr( aURLSet ); - if(SfxItemState::SET == aURLSet.GetItemState(RES_URL, true, &pItem)) + if(const SwFormatURL* pFormatURL = aURLSet.GetItemIfSet(RES_URL)) { - const SwFormatURL* pFormatURL = static_cast<const SwFormatURL*>(pItem); aHLinkItem.SetURL(pFormatURL->GetURL()); aHLinkItem.SetTargetFrame(pFormatURL->GetTargetFrameName()); aHLinkItem.SetName(rSh.GetFlyName()); @@ -1094,18 +1086,17 @@ void SwFrameShell::ExecFrameStyle(SfxRequest const & rReq) const SvxBoxItem* pPoolBoxItem = ::GetDfltAttr(RES_BOX); const SfxItemSet *pArgs = rReq.GetArgs(); - SfxItemSet aFrameSet(rSh.GetAttrPool(), svl::Items<RES_BOX, RES_BOX>{}); + SfxItemSetFixed<RES_BOX, RES_BOX> aFrameSet(rSh.GetAttrPool()); rSh.GetFlyFrameAttr( aFrameSet ); const SvxBoxItem& rBoxItem = aFrameSet.Get(RES_BOX); - if (pPoolBoxItem == &rBoxItem) + if (SfxPoolItem::areSame(pPoolBoxItem, &rBoxItem)) bDefault = true; std::unique_ptr<SvxBoxItem> aBoxItem(rBoxItem.Clone()); SvxBorderLine aBorderLine; - const SfxPoolItem *pItem = nullptr; if(pArgs) // Any controller can sometimes deliver nothing #48169# { @@ -1113,9 +1104,9 @@ void SwFrameShell::ExecFrameStyle(SfxRequest const & rReq) { case SID_ATTR_BORDER: { - if (pArgs->GetItemState(RES_BOX, true, &pItem) == SfxItemState::SET) + if (const SvxBoxItem* pBoxItem = pArgs->GetItemIfSet(RES_BOX)) { - std::unique_ptr<SvxBoxItem> aNewBox(static_cast<SvxBoxItem*>(pItem->Clone())); + std::unique_ptr<SvxBoxItem> aNewBox(pBoxItem->Clone()); const SvxBorderLine* pBorderLine; pBorderLine = aBoxItem->GetTop(); @@ -1135,7 +1126,7 @@ void SwFrameShell::ExecFrameStyle(SfxRequest const & rReq) { aBorderLine.SetBorderLineStyle( SvxBorderLineStyle::SOLID); - aBorderLine.SetWidth( DEF_LINE_WIDTH_0 ); + aBorderLine.SetWidth( SvxBorderLineWidth::Hairline ); } //Set distance only if the request is received from the controller. @@ -1163,11 +1154,8 @@ void SwFrameShell::ExecFrameStyle(SfxRequest const & rReq) case SID_FRAME_LINESTYLE: { - if (pArgs->GetItemState(SID_FRAME_LINESTYLE, false, &pItem) == SfxItemState::SET) + if ( const SvxLineItem* pLineItem = pArgs->GetItemIfSet(SID_FRAME_LINESTYLE, false)) { - const SvxLineItem* pLineItem = - static_cast<const SvxLineItem*>(pItem); - if ( pLineItem->GetLine() ) { aBorderLine = *(pLineItem->GetLine()); @@ -1217,14 +1205,17 @@ void SwFrameShell::ExecFrameStyle(SfxRequest const & rReq) case SID_FRAME_LINECOLOR: { - if (pArgs->GetItemState(SID_FRAME_LINECOLOR, false, &pItem) == SfxItemState::SET) + if (const SvxColorItem* pColorItem = pArgs->GetItemIfSet(SID_FRAME_LINECOLOR, false)) { - const Color& rNewColor = static_cast<const SvxColorItem*>(pItem)->GetValue(); + 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); @@ -1232,14 +1223,14 @@ void SwFrameShell::ExecFrameStyle(SfxRequest const & rReq) } 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 ); + if (aBoxItem->GetTop()) + aBoxItem->GetTop()->SetColor(rNewColor); + if (aBoxItem->GetBottom()) + aBoxItem->GetBottom()->SetColor(rNewColor); + if (aBoxItem->GetLeft()) + aBoxItem->GetLeft()->SetColor(rNewColor); + if (aBoxItem->GetRight()) + aBoxItem->GetRight()->SetColor(rNewColor); } } } @@ -1251,10 +1242,10 @@ void SwFrameShell::ExecFrameStyle(SfxRequest const & rReq) { aBoxItem->SetAllDistances(MIN_BORDER_DIST); } - aFrameSet.Put( *aBoxItem ); + aFrameSet.Put( std::move(aBoxItem) ); // Template AutoUpdate SwFrameFormat* pFormat = rSh.GetSelectedFrameFormat(); - if(pFormat && pFormat->IsAutoUpdateFormat()) + if(pFormat && pFormat->IsAutoUpdateOnDirectFormat()) { rSh.AutoUpdateFrame(pFormat, aFrameSet); } @@ -1289,7 +1280,7 @@ void SwFrameShell::GetLineStyleState(SfxItemSet &rSet) { if (rSh.IsFrameSelected()) { - SfxItemSet aFrameSet( rSh.GetAttrPool(), svl::Items<RES_BOX, RES_BOX>{} ); + SfxItemSetFixed<RES_BOX, RES_BOX> aFrameSet( rSh.GetAttrPool() ); rSh.GetFlyFrameAttr(aFrameSet); @@ -1355,7 +1346,7 @@ void SwFrameShell::ExecDrawAttrArgsTextFrame(SfxRequest const & rReq) } else { - SfxDispatcher* pDis = rSh.GetView().GetViewFrame()->GetDispatcher(); + SfxDispatcher* pDis = rSh.GetView().GetViewFrame().GetDispatcher(); switch(rReq.GetSlot()) { @@ -1384,8 +1375,8 @@ void SwFrameShell::ExecDrawDlgTextFrame(SfxRequest const & rReq) if(rSh.IsFrameSelected()) { - SdrModel* pDoc = rSh.GetDrawView()->GetModel(); - SfxItemSet aNewAttr(pDoc->GetItemPool()); + SdrModel& rModel = rSh.GetDrawView()->GetModel(); + SfxItemSet aNewAttr(rModel.GetItemPool()); // get attributes from FlyFrame rSh.GetFlyFrameAttr(aNewAttr); @@ -1394,7 +1385,8 @@ void SwFrameShell::ExecDrawDlgTextFrame(SfxRequest const & rReq) VclPtr<AbstractSvxAreaTabDialog> pDlg(pFact->CreateSvxAreaTabDialog( GetView().GetFrameWeld(), &aNewAttr, - pDoc, + &rModel, + false, false)); pDlg->StartExecuteAsync([pDlg, this](sal_Int32 nResult){ @@ -1412,7 +1404,7 @@ void SwFrameShell::ExecDrawDlgTextFrame(SfxRequest const & rReq) 0 }; - SfxBindings &rBnd = GetView().GetViewFrame()->GetBindings(); + SfxBindings &rBnd = GetView().GetViewFrame().GetBindings(); rBnd.Invalidate(aInval); rBnd.Update(SID_ATTR_FILL_STYLE); diff --git a/sw/source/uibase/shells/grfsh.cxx b/sw/source/uibase/shells/grfsh.cxx index 0ed3e1daa146..c1421a861df1 100644 --- a/sw/source/uibase/shells/grfsh.cxx +++ b/sw/source/uibase/shells/grfsh.cxx @@ -38,6 +38,7 @@ #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> @@ -62,9 +63,10 @@ #include <swslots.hxx> #include <swabstdlg.hxx> #include <unocrsr.hxx> +#include <flyfrm.hxx> #include <memory> -#define TOOLBOX_NAME u"colorbar" +constexpr OUString TOOLBOX_NAME = u"colorbar"_ustr; class SwGrfShell::SwExternalToolEdit : public ExternalToolEdit @@ -190,7 +192,7 @@ void SwGrfShell::Execute(SfxRequest &rReq) convertTwipToMm100(rSh.GetAnyCurRect(CurRectType::FlyEmbedded).Width()), convertTwipToMm100(rSh.GetAnyCurRect(CurRectType::FlyEmbedded).Height())); - SfxItemSet aSet( rSh.GetAttrPool(), svl::Items<RES_GRFATR_MIRRORGRF, RES_GRFATR_CROPGRF>{} ); + 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) ); @@ -203,17 +205,17 @@ void SwGrfShell::Execute(SfxRequest &rReq) Graphic aGraphic = *pGraphic; - CompressGraphicsDialog aDialog(GetView().GetFrameWeld(), aGraphic, aSize, aCropRectangle, GetView().GetViewFrame()->GetBindings()); + CompressGraphicsDialog aDialog(GetView().GetFrameWeld(), std::move(aGraphic), aSize, aCropRectangle, GetView().GetViewFrame().GetBindings()); if (aDialog.run() == RET_OK) { rSh.StartAllAction(); rSh.StartUndo(SwUndoId::START); tools::Rectangle aScaledCropedRectangle = aDialog.GetScaledCropRectangle(); - aCrop.SetLeft( convertMm100ToTwip( aScaledCropedRectangle.Left() )); - aCrop.SetTop( convertMm100ToTwip( aScaledCropedRectangle.Top() )); - aCrop.SetRight( convertMm100ToTwip( aScaledCropedRectangle.Right() )); - aCrop.SetBottom( convertMm100ToTwip( aScaledCropedRectangle.Bottom() )); + 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)); @@ -257,9 +259,7 @@ void SwGrfShell::Execute(SfxRequest &rReq) const SwViewOption* pVOpt = rSh.GetViewOptions(); SwViewOption aUsrPref( *pVOpt ); - SfxItemSet aSet( - GetPool(), - svl::Items< + SfxItemSetFixed< RES_FRMATR_BEGIN, RES_GRFATR_CROPGRF, // FillAttribute support: XATTR_FILL_FIRST, XATTR_FILL_LAST, @@ -279,10 +279,9 @@ void SwGrfShell::Execute(SfxRequest &rReq) // contains SID_ATTR_GRAF_FRMSIZE_PERCENT FN_GET_PRINT_AREA, FN_GET_PRINT_AREA, FN_PARAM_GRF_CONNECT, FN_PARAM_GRF_CONNECT, - FN_PARAM_GRF_DIALOG, FN_PARAM_GRF_DIALOG, FN_SET_FRM_NAME, FN_KEEP_ASPECT_RATIO, FN_SET_FRM_ALT_NAME, FN_SET_FRM_ALT_NAME, - FN_UNO_DESCRIPTION, FN_UNO_DESCRIPTION>{}); + 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 @@ -301,7 +300,7 @@ void SwGrfShell::Execute(SfxRequest &rReq) const SwRect* pRect = &rSh.GetAnyCurRect(CurRectType::Page); SwFormatFrameSize aFrameSize( SwFrameSize::Variable, pRect->Width(), pRect->Height()); - aFrameSize.SetWhich( GetPool().GetWhich( SID_ATTR_PAGE_SIZE ) ); + aFrameSize.SetWhich( GetPool().GetWhichIDFromSlotID( SID_ATTR_PAGE_SIZE ) ); aSet.Put( aFrameSize ); aSet.Put(SfxStringItem(FN_SET_FRM_NAME, rSh.GetFlyName())); @@ -315,10 +314,19 @@ void SwGrfShell::Execute(SfxRequest &rReq) pRect = &rSh.GetAnyCurRect(CurRectType::PagePrt); aFrameSize.SetWidth( pRect->Width() ); aFrameSize.SetHeight( pRect->Height() ); - aFrameSize.SetWhich( GetPool().GetWhich(FN_GET_PRINT_AREA) ); + aFrameSize.SetWhich( GetPool().GetWhichIDFromSlotID(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 @@ -365,8 +373,7 @@ void SwGrfShell::Execute(SfxRequest &rReq) // get Mirror and Crop { - SfxItemSet aTmpSet( rSh.GetAttrPool(), - svl::Items<RES_GRFATR_MIRRORGRF, RES_GRFATR_CROPGRF>{} ); + SfxItemSetFixed<RES_GRFATR_MIRRORGRF, RES_GRFATR_CROPGRF> aTmpSet( rSh.GetAttrPool() ); rSh.GetCurAttr( aTmpSet ); aSet.Put( aTmpSet ); @@ -375,7 +382,7 @@ void SwGrfShell::Execute(SfxRequest &rReq) 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())); + aSet.Put(SfxFrameItem( SID_DOCFRAME, &GetView().GetViewFrame().GetFrame())); SfxObjectShell * sh = rSh.GetDoc()->GetPersist(); if (sh != nullptr && sh->HasName()) @@ -389,12 +396,12 @@ void SwGrfShell::Execute(SfxRequest &rReq) { // 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 - SfxItemSet aTmpSet( rSh.GetAttrPool(), svl::Items<RES_GRFATR_ROTATION, RES_GRFATR_ROTATION>{} ); + 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, toDegree100(nCurrentRotation))); + aSet.Put(SdrAngleItem(SID_ATTR_TRANSFORM_ANGLE, to<Degree100>(nCurrentRotation))); } SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); @@ -409,22 +416,21 @@ void SwGrfShell::Execute(SfxRequest &rReq) { rSh.StartAllAction(); rSh.StartUndo(SwUndoId::START); - const SfxPoolItem* pItem; SfxItemSet* pSet = const_cast<SfxItemSet*>(pDlg->GetOutputItemSet()); rReq.Done(*pSet); // change the 2 frmsize SizeItems to the correct SwFrameSizeItem - if( SfxItemState::SET == pSet->GetItemState( - SID_ATTR_GRAF_FRMSIZE, false, &pItem )) + if( const SvxSizeItem* pSizeItem = pSet->GetItemIfSet( + SID_ATTR_GRAF_FRMSIZE, false )) { SwFormatFrameSize aSize; - const Size& rSz = static_cast<const SvxSizeItem*>(pItem)->GetSize(); + const Size& rSz = pSizeItem->GetSize(); aSize.SetWidth( rSz.Width() ); aSize.SetHeight( rSz.Height() ); - if( SfxItemState::SET == pSet->GetItemState( - SID_ATTR_GRAF_FRMSIZE_PERCENT, false, &pItem )) + pSizeItem = pSet->GetItemIfSet( SID_ATTR_GRAF_FRMSIZE_PERCENT, false ); + if( pSizeItem ) { - const Size& rRelativeSize = static_cast<const SvxSizeItem*>(pItem)->GetSize(); + const Size& rRelativeSize = pSizeItem->GetSize(); aSize.SetWidthPercent( static_cast< sal_uInt8 >( rRelativeSize.Width() ) ); aSize.SetHeightPercent( static_cast< sal_uInt8 >( rRelativeSize.Height() ) ); } @@ -433,14 +439,12 @@ void SwGrfShell::Execute(SfxRequest &rReq) // Templates AutoUpdate SwFrameFormat* pFormat = rSh.GetSelectedFrameFormat(); - if(pFormat && pFormat->IsAutoUpdateFormat()) + if(pFormat && pFormat->IsAutoUpdateOnDirectFormat()) { pFormat->SetFormatAttr(*pSet); - SfxItemSet aShellSet( - GetPool(), - svl::Items< + SfxItemSetFixed< RES_FRM_SIZE, RES_FRM_SIZE, - RES_SURROUND, RES_ANCHOR>{}); + RES_SURROUND, RES_ANCHOR> aShellSet( GetPool() ); aShellSet.Put(*pSet); aMgr.SetAttrSet(aShellSet); } @@ -451,18 +455,16 @@ void SwGrfShell::Execute(SfxRequest &rReq) aMgr.UpdateFlyFrame(); bool bApplyUsrPref = false; - if (SfxItemState::SET == pSet->GetItemState( - FN_KEEP_ASPECT_RATIO, true, &pItem )) + if (const SfxBoolItem* pRatioItem = pSet->GetItemIfSet( + FN_KEEP_ASPECT_RATIO )) { - aUsrPref.SetKeepRatio( - static_cast<const SfxBoolItem*>(pItem)->GetValue() ); + aUsrPref.SetKeepRatio( pRatioItem->GetValue() ); bApplyUsrPref = true; } - if( SfxItemState::SET == pSet->GetItemState( - SID_ATTR_GRAF_KEEP_ZOOM, true, &pItem )) + if( const SfxBoolItem* pZoomItem = pSet->GetItemIfSet( + SID_ATTR_GRAF_KEEP_ZOOM )) { - aUsrPref.SetGrfKeepZoom( - static_cast<const SfxBoolItem*>(pItem)->GetValue() ); + aUsrPref.SetGrfKeepZoom( pZoomItem->GetValue() ); bApplyUsrPref = true; } @@ -470,16 +472,16 @@ void SwGrfShell::Execute(SfxRequest &rReq) SW_MOD()->ApplyUsrPref(aUsrPref, &GetView()); // and now set all the graphic attributes and other stuff - if( SfxItemState::SET == pSet->GetItemState( - SID_ATTR_GRAF_GRAPHIC, true, &pItem )) + if( const SvxBrushItem* pGraphicBrushItem = pSet->GetItemIfSet( + SID_ATTR_GRAF_GRAPHIC )) { - if( !static_cast<const SvxBrushItem*>(pItem)->GetGraphicLink().isEmpty() ) - sGrfNm = static_cast<const SvxBrushItem*>(pItem)->GetGraphicLink(); + if( !pGraphicBrushItem->GetGraphicLink().isEmpty() ) + sGrfNm = pGraphicBrushItem->GetGraphicLink(); else sGrfNm.clear(); - if( !static_cast<const SvxBrushItem*>(pItem)->GetGraphicFilter().isEmpty() ) - sFilterNm = static_cast<const SvxBrushItem*>(pItem)->GetGraphicFilter(); + if( !pGraphicBrushItem->GetGraphicFilter().isEmpty() ) + sFilterNm = pGraphicBrushItem->GetGraphicFilter(); else sFilterNm.clear(); @@ -497,28 +499,27 @@ void SwGrfShell::Execute(SfxRequest &rReq) sFilterNm ); } } - if ( SfxItemState::SET == pSet->GetItemState( - FN_SET_FRM_ALT_NAME, true, &pItem )) + if ( const SfxStringItem* pNameItem = pSet->GetItemIfSet( + FN_SET_FRM_ALT_NAME )) { // #i73249# - rSh.SetObjTitle( static_cast<const SfxStringItem*>(pItem)->GetValue() ); + rSh.SetObjTitle( pNameItem->GetValue() ); } - if ( SfxItemState::SET == pSet->GetItemState( - FN_UNO_DESCRIPTION, true, &pItem )) - rSh.SetObjDescription( static_cast<const SfxStringItem*>(pItem)->GetValue() ); + if ( const SfxStringItem* pDescriptionItem = pSet->GetItemIfSet( + FN_UNO_DESCRIPTION )) + rSh.SetObjDescription( pDescriptionItem->GetValue() ); // RotGrfFlyFrame: Get and process evtl. changed RotationAngle - if ( SfxItemState::SET == pSet->GetItemState(SID_ATTR_TRANSFORM_ANGLE, false, &pItem )) + if ( const SdrAngleItem* pAngleItem = pSet->GetItemIfSet(SID_ATTR_TRANSFORM_ANGLE, false )) { - const Degree10 aNewRotation = toDegree10(static_cast<const SdrAngleItem*>(pItem)->GetValue() % 36000_deg100); + const Degree10 aNewRotation = to<Degree10>(pAngleItem->GetValue() % 36000_deg100); // RotGrfFlyFrame: Possible rotation change here, SwFlyFrameAttrMgr aMgr is available aMgr.SetRotation(nCurrentRotation, aNewRotation, aUnrotatedSize); } - SfxItemSet aGrfSet( rSh.GetAttrPool(), svl::Items<RES_GRFATR_BEGIN, - RES_GRFATR_END-1>{} ); + SfxItemSetFixed<RES_GRFATR_BEGIN, RES_GRFATR_END-1> aGrfSet( rSh.GetAttrPool() ); aGrfSet.Put( *pSet ); if( aGrfSet.Count() ) rSh.SetAttrSet( aGrfSet ); @@ -531,7 +532,7 @@ void SwGrfShell::Execute(SfxRequest &rReq) case FN_GRAPHIC_MIRROR_ON_EVEN_PAGES: { - SfxItemSet aSet(rSh.GetAttrPool(), svl::Items<RES_GRFATR_MIRRORGRF, RES_GRFATR_MIRRORGRF>{}); + SfxItemSetFixed<RES_GRFATR_MIRRORGRF, RES_GRFATR_MIRRORGRF> aSet(rSh.GetAttrPool()); rSh.GetCurAttr( aSet ); SwMirrorGrf aGrf(aSet.Get(RES_GRFATR_MIRRORGRF)); aGrf.SetGrfToggle(!aGrf.IsGrfToggle()); @@ -562,8 +563,7 @@ void SwGrfShell::ExecAttr( SfxRequest const &rReq ) if (GraphicType::Bitmap == nGrfType || GraphicType::GdiMetafile == nGrfType) { - SfxItemSet aGrfSet( GetShell().GetAttrPool(), svl::Items<RES_GRFATR_BEGIN, - RES_GRFATR_END -1>{} ); + SfxItemSetFixed<RES_GRFATR_BEGIN, RES_GRFATR_END -1> aGrfSet( GetShell().GetAttrPool() ); const SfxItemSet *pArgs = rReq.GetArgs(); const SfxPoolItem* pItem; sal_uInt16 nSlot = rReq.GetSlot(); @@ -689,11 +689,12 @@ void SwGrfShell::ExecAttr( SfxRequest const &rReq ) const GraphicObject* pFilterObj( GetShell().GetGraphicObj() ); if ( pFilterObj ) { - GraphicObject aFilterObj( *pFilterObj ); - if( SvxGraphicFilterResult::NONE == - SvxGraphicFilter::ExecuteGrfFilterSlot( rReq, aFilterObj )) - GetShell().ReRead( OUString(), OUString(), - &aFilterObj.GetGraphic() ); + SvxGraphicFilter::ExecuteGrfFilterSlot( rReq, *pFilterObj, + [this] (GraphicObject aFilteredObject) -> void + { + GetShell().ReRead( OUString(), OUString(), + &aFilteredObject.GetGraphic() ); + }); } } break; @@ -705,7 +706,7 @@ void SwGrfShell::ExecAttr( SfxRequest const &rReq ) if( aGrfSet.Count() ) GetShell().SetAttrSet( aGrfSet ); } - GetView().GetViewFrame()->GetBindings().Invalidate(rReq.GetSlot()); + GetView().GetViewFrame().GetBindings().Invalidate(rReq.GetSlot()); } void SwGrfShell::GetAttrState(SfxItemSet &rSet) @@ -932,7 +933,7 @@ void SwGrfShell::ExecuteRotation(SfxRequest const &rReq) return; SwWrtShell& rShell = GetShell(); - SfxItemSet aSet( rShell.GetAttrPool(), svl::Items<RES_GRFATR_ROTATION, RES_GRFATR_ROTATION>{} ); + 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); @@ -977,7 +978,7 @@ void SwGrfShell::GetAttrStateForRotation(SfxItemSet &rSet) case SID_ROTATE_GRAPHIC_RESET: { // RotGrfFlyFrame: disable when already no rotation - SfxItemSet aSet( rShell.GetAttrPool(), svl::Items<RES_GRFATR_ROTATION, RES_GRFATR_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()); @@ -987,10 +988,10 @@ void SwGrfShell::GetAttrStateForRotation(SfxItemSet &rSet) { // RotGrfFlyFrame: get rotation value from RES_GRFATR_ROTATION and copy to rSet as // SID_ATTR_TRANSFORM_ANGLE, convert from 10th degrees to 100th degrees - SfxItemSet aSet( rShell.GetAttrPool(), svl::Items<RES_GRFATR_ROTATION, RES_GRFATR_ROTATION>{} ); + 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, toDegree100(rRotation.GetValue()))); + rSet.Put(SdrAngleItem(SID_ATTR_TRANSFORM_ANGLE, to<Degree100>(rRotation.GetValue()))); break; } default: diff --git a/sw/source/uibase/shells/grfshex.cxx b/sw/source/uibase/shells/grfshex.cxx index c3aa1c980505..654fb8364daf 100644 --- a/sw/source/uibase/shells/grfshex.cxx +++ b/sw/source/uibase/shells/grfshex.cxx @@ -17,6 +17,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <config_features.h> #include <wrtsh.hxx> #include <view.hxx> #include <textsh.hxx> @@ -24,24 +25,33 @@ #include <doc.hxx> #include <IDocumentDrawModelAccess.hxx> #include <docsh.hxx> -#include <svx/svdomedia.hxx> - +#include <avmedia/mediawindow.hxx> +#include <editeng/sizeitem.hxx> #include <sfx2/request.hxx> #include <sfx2/viewfrm.hxx> #include <svl/stritem.hxx> -#include <avmedia/mediawindow.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, bRet = false; + 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 ) { @@ -53,68 +63,89 @@ bool SwTextShell::InsertMediaDlg( SfxRequest const & rReq ) } } - bool bLink(true); + bool bLink(pLinkItem ? pLinkItem->GetValue() : true); + if (bAPI || ::avmedia::MediaWindow::executeMediaURLDialog(rWindow.GetFrameWeld(), aURL, & bLink)) { Size aPrefSize; - rWindow.EnterWait(); - - if( !::avmedia::MediaWindow::isMediaURL( aURL, "", true, &aPrefSize ) ) - { - rWindow.LeaveWait(); - - if( !bAPI ) - ::avmedia::MediaWindow::executeFormatErrorBox(rWindow.GetFrameWeld()); - } + if (!bSizeUnknown) + aPrefSize = pSizeItem->GetSize(); else { - SwWrtShell& rSh = GetShell(); + rWindow.EnterWait(); - if( !rSh.HasDrawView() ) - rSh.MakeDrawView(); + css::uno::Reference<css::frame::XDispatchProvider> xDispatchProvider(GetView().GetViewFrame().GetFrame().GetFrameInterface(), css::uno::UNO_QUERY); - Size aDocSz( rSh.GetDocSize() ); - const SwRect& rVisArea = rSh.VisArea(); - Point aPos( rVisArea.Center() ); - Size aSize; + rtl::Reference<avmedia::PlayerListener> xPlayerListener(new avmedia::PlayerListener( + [xDispatchProvider=std::move(xDispatchProvider), aURL, bLink](const css::uno::Reference<css::media::XPlayer>& rPlayer){ + css::awt::Size aSize = rPlayer->getPreferredPlayerWindowSize(); + avmedia::MediaWindow::dispatchInsertAVMedia(xDispatchProvider, aSize, aURL, bLink); + })); - if( rVisArea.Width() > aDocSz.Width()) - aPos.setX( aDocSz.Width() / 2 + rVisArea.Left() ); + const bool bIsMediaURL = ::avmedia::MediaWindow::isMediaURL(aURL, "", true, xPlayerListener); - 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 ); + rWindow.LeaveWait(); - OUString realURL; - if (bLink) - { - realURL = aURL; - } - else + if (!bIsMediaURL) { - uno::Reference<frame::XModel> const xModel( - rSh.GetDoc()->GetDocShell()->GetModel()); - bRet = ::avmedia::EmbedMedia(xModel, aURL, realURL); - if (!bRet) { return bRet; } + if( !bAPI ) + ::avmedia::MediaWindow::executeFormatErrorBox(rWindow.GetFrameWeld()); + + return bRet; } - SdrMediaObj* pObj = new SdrMediaObj( - *rSh.GetDoc()->getIDocumentDrawModelAccess().GetDrawModel(), - tools::Rectangle(aPos, aSize)); + return true; + } - pObj->setURL( realURL, "" ); - rSh.EnterStdMode(); - rSh.SwFEShell::InsertDrawObj( *pObj, aPos ); - bRet = true; + rWindow.EnterWait(); - rWindow.LeaveWait(); + SwWrtShell& rSh = GetShell(); + + if( !rSh.HasDrawView() ) + rSh.MakeDrawView(); + + Size aDocSz( rSh.GetDocSize() ); + const SwRect& rVisArea = rSh.VisArea(); + Point aPos( rVisArea.Center() ); + Size aSize; + + if( rVisArea.Width() > aDocSz.Width()) + aPos.setX( aDocSz.Width() / 2 + rVisArea.Left() ); + + if(rVisArea.Height() > aDocSz.Height()) + aPos.setY( aDocSz.Height() / 2 + rVisArea.Top() ); + + if( aPrefSize.Width() && aPrefSize.Height() ) + aSize = rWindow.PixelToLogic(aPrefSize, MapMode(MapUnit::MapTwip)); + else + aSize = Size( 2835, 2835 ); + + OUString realURL; + if (bLink) + { + realURL = aURL; } + else + { + uno::Reference<frame::XModel> const xModel( + rSh.GetDoc()->GetDocShell()->GetModel()); + bRet = ::avmedia::EmbedMedia(xModel, aURL, realURL); + if (!bRet) { return bRet; } + } + + rtl::Reference<SdrMediaObj> pObj = new SdrMediaObj( + *rSh.GetDoc()->getIDocumentDrawModelAccess().GetDrawModel(), + tools::Rectangle(aPos, aSize)); + + pObj->setURL( realURL, "" ); + rSh.EnterStdMode(); + rSh.SwFEShell::InsertDrawObj( *pObj, aPos ); + bRet = true; + + rWindow.LeaveWait(); } +#endif return bRet; } diff --git a/sw/source/uibase/shells/langhelper.cxx b/sw/source/uibase/shells/langhelper.cxx index aa7f5ae06089..b7c2f44828f8 100644 --- a/sw/source/uibase/shells/langhelper.cxx +++ b/sw/source/uibase/shells/langhelper.cxx @@ -19,8 +19,6 @@ #include <string.h> -#include <vcl/window.hxx> - #include <wrtsh.hxx> #include <doc.hxx> #include <docary.hxx> @@ -42,6 +40,7 @@ #include <svl/slstitm.hxx> #include <svl/stritem.hxx> #include <svx/svxids.hrc> +#include <osl/diagnose.h> #include <ndtxt.hxx> #include <pam.hxx> @@ -59,19 +58,15 @@ namespace SwLangHelper { ESelection aSelection = pOLV->GetSelection(); EditView& rEditView=pOLV->GetEditView(); - EditEngine* pEditEngine=rEditView.GetEditEngine(); + EditEngine& rEditEngine = rEditView.getEditEngine(); // the value of used script types const SvtScriptType nScriptType =pOLV->GetSelectedScriptType(); - OUString aScriptTypesInUse( OUString::number( static_cast<int>(nScriptType) ) );//pEditEngine->GetScriptType(aSelection) + OUString aScriptTypesInUse( OUString::number( static_cast<int>(nScriptType) ) );//rEditEngine.GetScriptType(aSelection) // get keyboard language OUString aKeyboardLang; - LanguageType nLang = LANGUAGE_DONTKNOW; - - vcl::Window* pWin = rEditView.GetWindow(); - if(pWin) - nLang = pWin->GetInputLanguage(); + LanguageType nLang = rEditView.GetInputLanguage(); if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM) aKeyboardLang = SvtLanguageTable::GetLanguageString( nLang ); @@ -83,11 +78,11 @@ namespace SwLangHelper aCurrentLang = SvtLanguageTable::GetLanguageString( nLang ); // build sequence for status value - uno::Sequence< OUString > aSeq( 4 ); - aSeq[0] = aCurrentLang; - aSeq[1] = aScriptTypesInUse; - aSeq[2] = aKeyboardLang; - aSeq[3] = SwLangHelper::GetTextForLanguageGuessing( pEditEngine, aSelection ); + uno::Sequence<OUString> aSeq{ aCurrentLang, + aScriptTypesInUse, + aKeyboardLang, + SwLangHelper::GetTextForLanguageGuessing(&rEditEngine, aSelection) + }; // set sequence as status value SfxStringListItem aItem( SID_LANGUAGE_STATUS ); @@ -98,10 +93,9 @@ namespace SwLangHelper 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(); + SfxItemSet aEditAttr(rEditView.GetEmptyItemSet()); // get the language OUString aNewLangText; @@ -113,11 +107,11 @@ namespace SwLangHelper //!! Remember the view frame right now... //!! (call to GetView().GetViewFrame() will break if the //!! SwTextShell got destroyed meanwhile.) - SfxViewFrame *pViewFrame = rView.GetViewFrame(); + SfxViewFrame& rViewFrame = rView.GetViewFrame(); if (aNewLangText == "*" ) { - // open the dialog "Tools/Options/Language Settings - Language" + // open the dialog "Tools/Options/Languages and Locales - General" SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateVclDialog( rView.GetFrameWeld(), SID_LANGUAGE_OPTIONS )); pDlg->Execute(); @@ -127,9 +121,9 @@ namespace SwLangHelper // setting the new language... if (!aNewLangText.isEmpty()) { - const OUString aSelectionLangPrefix("Current_"); - const OUString aParagraphLangPrefix("Paragraph_"); - const OUString aDocumentLangPrefix("Default_"); + static constexpr OUString aSelectionLangPrefix(u"Current_"_ustr); + static constexpr OUString aParagraphLangPrefix(u"Paragraph_"_ustr); + static constexpr OUString aDocumentLangPrefix(u"Default_"_ustr); sal_Int32 nPos = 0; bool bForSelection = true; @@ -137,20 +131,20 @@ namespace SwLangHelper if (-1 != (nPos = aNewLangText.indexOf( aSelectionLangPrefix ))) { // ... for the current selection - aNewLangText = aNewLangText.replaceAt(nPos, aSelectionLangPrefix.getLength(), ""); + 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(), ""); + 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(), ""); + aNewLangText = aNewLangText.replaceAt(nPos, aDocumentLangPrefix.getLength(), u""); bForSelection = false; } @@ -178,27 +172,6 @@ namespace SwLangHelper 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... @@ -210,7 +183,7 @@ namespace SwLangHelper } // invalidate slot to get the new language displayed - pViewFrame->GetBindings().Invalidate( rReq.GetSlot() ); + rViewFrame.GetBindings().Invalidate( rReq.GetSlot() ); rReq.Done(); return bRestoreSelection; @@ -227,17 +200,17 @@ namespace SwLangHelper if (nLang == LANGUAGE_DONTKNOW) return; - EditEngine* pEditEngine = pOLV ? pOLV->GetEditView().GetEditEngine() : nullptr; + EditEngine* pEditEngine = pOLV ? &pOLV->GetEditView().getEditEngine() : nullptr; OSL_ENSURE( !pOLV || pEditEngine, "OutlinerView without EditEngine???" ); //get ScriptType - sal_uInt16 nLangWhichId = 0; + TypedWhichId<SvxLanguageItem> 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; + case SvtScriptType::LATIN : nLangWhichId = pEditEngine ? EE_CHAR_LANGUAGE : RES_CHRATR_LANGUAGE; break; + case SvtScriptType::ASIAN : nLangWhichId = pEditEngine ? EE_CHAR_LANGUAGE_CJK : RES_CHRATR_CJK_LANGUAGE; break; + case SvtScriptType::COMPLEX : nLangWhichId = pEditEngine ? EE_CHAR_LANGUAGE_CTL : RES_CHRATR_CTL_LANGUAGE; break; default: bIsSingleScriptType = false; OSL_FAIL("unexpected case" ); @@ -274,23 +247,7 @@ namespace SwLangHelper } //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); - } + rWrtSh.GetDoc()->GetDocShell()->Broadcast(SfxHint(SfxHintId::LanguageChanged)); // #i102191: hard set respective language attribute in text document // (for all text in the document - which should be selected by now...) @@ -327,7 +284,7 @@ namespace SwLangHelper // (for paragraph is handled by previously having set the selection to the // whole paragraph) - EditEngine* pEditEngine = pOLV ? pOLV->GetEditView().GetEditEngine() : nullptr; + EditEngine* pEditEngine = pOLV ? &pOLV->GetEditView().getEditEngine() : nullptr; OSL_ENSURE( !pOLV || pEditEngine, "OutlinerView without EditEngine???" ); if (pEditEngine) { @@ -351,6 +308,7 @@ namespace SwLangHelper rWrtSh.SetDefault( SvxLanguageItem( LANGUAGE_NONE, i ) ); aAttribs.insert( i ); } + rWrtSh.GetDoc()->GetDocShell()->Broadcast(SfxHint(SfxHintId::LanguageChanged)); // set all language attributes to default // (for all text in the document - which should be selected by now...) @@ -371,6 +329,18 @@ namespace SwLangHelper rEditView.RemoveAttribs( true, EE_CHAR_LANGUAGE ); rEditView.RemoveAttribs( true, EE_CHAR_LANGUAGE_CJK ); rEditView.RemoveAttribs( true, EE_CHAR_LANGUAGE_CTL ); + + // ugly hack, as it seems that EditView/EditEngine does not update their spellchecking marks + // when setting a new language attribute + EditEngine& rEditEngine = rEditView.getEditEngine(); + EEControlBits nCntrl = rEditEngine.GetControlWord(); + // turn off + rEditEngine.SetControlWord(nCntrl & ~EEControlBits::ONLINESPELLING); + //turn back on + rEditEngine.SetControlWord(nCntrl); + rEditEngine.CompleteOnlineSpelling(); + + rEditView.Invalidate(); } else { @@ -384,32 +354,32 @@ namespace SwLangHelper /// 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 ) + LanguageType GetLanguage( SwWrtShell &rSh, TypedWhichId<SvxLanguageItem> nLangWhichId ) { - SfxItemSet aSet( rSh.GetAttrPool(), {{nLangWhichId, nLangWhichId}} ); + SfxItemSet aSet( rSh.GetAttrPool(), nLangWhichId, nLangWhichId ); rSh.GetCurAttr( aSet ); return GetLanguage(aSet,nLangWhichId); } - LanguageType GetLanguage( SfxItemSet const & aSet, sal_uInt16 nLangWhichId ) + LanguageType GetLanguage( SfxItemSet const & aSet, TypedWhichId<SvxLanguageItem> nLangWhichId ) { LanguageType nLang = LANGUAGE_SYSTEM; - const SfxPoolItem *pItem = nullptr; + const SvxLanguageItem *pItem = nullptr; SfxItemState nState = aSet.GetItemState( nLangWhichId, true, &pItem ); if (nState > SfxItemState::DEFAULT && pItem) { // the item is set and can be used - nLang = dynamic_cast<const SvxLanguageItem&>(*pItem).GetLanguage(); + nLang = 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(); + nLang = aSet.GetPool()->GetUserOrPoolDefaultItem( nLangWhichId ).GetLanguage(); } - else if (nState == SfxItemState::DONTCARE) + else if (nState == SfxItemState::INVALID) { // there is more than one language... nLang = LANGUAGE_DONTKNOW; @@ -426,7 +396,7 @@ namespace SwLangHelper LanguageType GetCurrentLanguage( SwWrtShell &rSh ) { //set language attribute to use according to the script type - sal_uInt16 nLangWhichId = 0; + TypedWhichId<SvxLanguageItem> nLangWhichId(0); bool bIsSingleScriptType = true; switch (rSh.GetScriptType()) { @@ -445,14 +415,14 @@ namespace SwLangHelper // 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] = + const TypedWhichId<SvxLanguageItem> aScriptTypes[3] = { RES_CHRATR_LANGUAGE, RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CTL_LANGUAGE }; nCurrentLang = LANGUAGE_NONE; - for (sal_uInt16 aScriptType : aScriptTypes) + for (const TypedWhichId<SvxLanguageItem>& aScriptType : aScriptTypes) { LanguageType nTmpLang = GetLanguage( rSh, aScriptType ); if (nTmpLang != LANGUAGE_NONE) @@ -474,7 +444,7 @@ namespace SwLangHelper LanguageType GetCurrentLanguage( SfxItemSet const & aSet, SvtScriptType nScriptType ) { //set language attribute to use according to the script type - sal_uInt16 nLangWhichId = 0; + TypedWhichId<SvxLanguageItem> nLangWhichId(0); bool bIsSingleScriptType = true; switch (nScriptType) { @@ -493,14 +463,14 @@ namespace SwLangHelper // 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] = + const TypedWhichId<SvxLanguageItem> aScriptTypes[3] = { EE_CHAR_LANGUAGE, EE_CHAR_LANGUAGE_CJK, EE_CHAR_LANGUAGE_CTL }; nCurrentLang = LANGUAGE_NONE; - for (sal_uInt16 aScriptType : aScriptTypes) + for (const TypedWhichId<SvxLanguageItem>& aScriptType : aScriptTypes) { LanguageType nTmpLang = GetLanguage( aSet, aScriptType ); if (nTmpLang != LANGUAGE_NONE) @@ -520,13 +490,13 @@ namespace SwLangHelper // string for guessing language OUString aText; SwPaM *pCursor = rSh.GetCursor(); - SwTextNode *pNode = pCursor->GetNode().GetTextNode(); + SwTextNode *pNode = pCursor->GetPointNode().GetTextNode(); if (pNode) { aText = pNode->GetText(); if (!aText.isEmpty()) { - sal_Int32 nEnd = pCursor->GetPoint()->nContent.GetIndex(); + sal_Int32 nEnd = pCursor->GetPoint()->GetContentIndex(); // at most 100 chars to the left... const sal_Int32 nStt = nEnd > 100 ? nEnd - 100 : 0; // ... and 100 to the right of the cursor position @@ -573,11 +543,6 @@ namespace SwLangHelper rWrtSh.SwapPam(); if (!rWrtSh.IsEndPara()) rWrtSh.MovePara( GoCurrPara, fnParaEnd ); - #if OSL_DEBUG_LEVEL > 1 - OUString aSelText; - rWrtSh.GetSelectedText( aSelText ); - (void) aSelText; - #endif } } diff --git a/sw/source/uibase/shells/listsh.cxx b/sw/source/uibase/shells/listsh.cxx index 8220f6cd4ef1..0fe21755cc02 100644 --- a/sw/source/uibase/shells/listsh.cxx +++ b/sw/source/uibase/shells/listsh.cxx @@ -24,6 +24,7 @@ #include <sfx2/viewfrm.hxx> #include <svl/eitem.hxx> #include <svl/whiter.hxx> +#include <osl/diagnose.h> #include <numrule.hxx> #include <wrtsh.hxx> @@ -125,7 +126,6 @@ static void lcl_OutlineUpDownWithSubPoints( SwWrtShell& rSh, bool bMove, bool bU void SwListShell::Execute(SfxRequest &rReq) { - const SfxItemSet* pArgs = rReq.GetArgs(); const sal_uInt16 nSlot = rReq.GetSlot(); SwWrtShell& rSh = GetShell(); @@ -139,11 +139,11 @@ void SwListShell::Execute(SfxRequest &rReq) case FN_NUM_BULLET_DOWN: case FN_NUM_BULLET_UP: { - SfxViewFrame * pFrame = GetView().GetViewFrame(); + SfxViewFrame& rFrame = GetView().GetViewFrame(); rReq.Done(); rSh.NumUpDown( nSlot == FN_NUM_BULLET_DOWN ); - pFrame->GetBindings().Invalidate( SID_TABLE_CELL ); // Update status line! + rFrame.GetBindings().Invalidate( SID_TABLE_CELL ); // Update status line! } break; @@ -157,16 +157,6 @@ void SwListShell::Execute(SfxRequest &rReq) rReq.Done(); break; - case FN_NUM_BULLET_OFF: - { - rReq.Ignore(); - SfxRequest aReq( GetView().GetViewFrame(), FN_NUM_BULLET_ON ); - aReq.AppendItem( SfxBoolItem( FN_PARAM_1, false ) ); - aReq.Done(); - rSh.DelNumRules(); - break; - } - case FN_NUM_BULLET_OUTLINE_DOWN: if ( bOutline ) lcl_OutlineUpDownWithSubPoints( rSh, false, false ); @@ -203,18 +193,6 @@ void SwListShell::Execute(SfxRequest &rReq) 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; @@ -231,9 +209,6 @@ void SwListShell::GetState(SfxItemSet &rSet) { 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) diff --git a/sw/source/uibase/shells/mediash.cxx b/sw/source/uibase/shells/mediash.cxx index 7aaabc817c08..ab3628bfe10e 100644 --- a/sw/source/uibase/shells/mediash.cxx +++ b/sw/source/uibase/shells/mediash.cxx @@ -18,7 +18,6 @@ */ #include <cmdid.h> -#include <svl/whiter.hxx> #include <sfx2/request.hxx> #include <svx/svdview.hxx> #include <view.hxx> @@ -27,14 +26,12 @@ #include <sfx2/objface.hxx> #include <vcl/EnumContext.hxx> -#include <svx/svdomedia.hxx> -#include <svx/sdr/contact/viewcontactofsdrmediaobj.hxx> -#include <avmedia/mediaitem.hxx> +#include <svx/MediaShellHelpers.hxx> #define ShellClass_SwMediaShell -#include <sfx2/msg.hxx> #include <swslots.hxx> -#include <memory> + +using namespace svx; SFX_IMPL_INTERFACE(SwMediaShell, SwBaseShell) @@ -42,120 +39,58 @@ void SwMediaShell::InitInterface_Impl() { GetStaticInterface()->RegisterPopupMenu("media"); - GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Invisible, ToolbarId::Media_Toolbox); + GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Invisible, + ToolbarId::Media_Toolbox); } -void SwMediaShell::ExecMedia(SfxRequest const &rReq) +void SwMediaShell::ExecMedia(SfxRequest const& rReq) { SwWrtShell* pSh = &GetShell(); - SdrView* pSdrView = pSh->GetDrawView(); + SdrView* pSdrView = pSh->GetDrawView(); - if( !pSdrView ) + if (!pSdrView) return; - const SfxItemSet* pArgs = rReq.GetArgs(); - bool bChanged = pSdrView->GetModel()->IsChanged(); - - pSdrView->GetModel()->SetChanged( false ); + const bool bChanged = pSdrView->GetModel().IsChanged(); + pSdrView->GetModel().SetChanged(false); - switch( rReq.GetSlot() ) + switch (rReq.GetSlot()) { case SID_DELETE: - { - if( pSh->IsObjSelected() ) + if (pSh->IsObjSelected()) { pSh->SetModified(); pSh->DelSelectedObj(); - if( pSh->IsSelFrameMode() ) + if (pSh->IsSelFrameMode()) pSh->LeaveSelFrameMode(); GetView().AttrChangedNotify(nullptr); } - } - break; + break; case SID_AVMEDIA_TOOLBOX: - { - if( pSh->IsObjSelected() ) - { - const SfxPoolItem* pItem; - - if( !pArgs || ( SfxItemState::SET != pArgs->GetItemState( SID_AVMEDIA_TOOLBOX, false, &pItem ) ) ) - pItem = nullptr; - - if( pItem ) - { - std::unique_ptr<SdrMarkList> pMarkList(new SdrMarkList( pSdrView->GetMarkedObjectList() )); - - if( 1 == pMarkList->GetMarkCount() ) - { - SdrObject* pObj = pMarkList->GetMark( 0 )->GetMarkedSdrObj(); - - if( dynamic_cast< const SdrMediaObj *>( pObj ) ) - { - static_cast< sdr::contact::ViewContactOfSdrMediaObj& >( pObj->GetViewContact() ).executeMediaItem( - static_cast< const ::avmedia::MediaItem& >( *pItem ) ); - } - } - } - } - } - break; + if (pSh->IsObjSelected()) + MediaShellHelpers::Execute(pSdrView, rReq); + break; default: - break; + break; } - if( pSdrView->GetModel()->IsChanged() ) + if (pSdrView->GetModel().IsChanged()) GetShell().SetModified(); - else if( bChanged ) - pSdrView->GetModel()->SetChanged(); + else if (bChanged) + pSdrView->GetModel().SetChanged(); } -void SwMediaShell::GetMediaState(SfxItemSet &rSet) +void SwMediaShell::GetMediaState(SfxItemSet& rSet) { - SfxWhichIter aIter( rSet ); - sal_uInt16 nWhich = aIter.FirstWhich(); - - while( nWhich ) - { - if( SID_AVMEDIA_TOOLBOX == nWhich ) - { - SwWrtShell& rSh = GetShell(); - SdrView* pView = rSh.GetDrawView(); - - if( pView ) - { - bool bDisable = true; - std::unique_ptr<SdrMarkList> pMarkList(new SdrMarkList( pView->GetMarkedObjectList() )); - - if( 1 == pMarkList->GetMarkCount() ) - { - SdrObject* pObj = pMarkList->GetMark( 0 )->GetMarkedSdrObj(); - - if( dynamic_cast< const SdrMediaObj *>( pObj ) ) - { - ::avmedia::MediaItem aItem( SID_AVMEDIA_TOOLBOX ); - - static_cast< sdr::contact::ViewContactOfSdrMediaObj& >( pObj->GetViewContact() ).updateMediaItem( aItem ); - rSet.Put( aItem ); - bDisable = false; - } - } - - if( bDisable ) - rSet.DisableItem( SID_AVMEDIA_TOOLBOX ); - } - } - - nWhich = aIter.NextWhich(); - } + MediaShellHelpers::GetState(GetShell().GetDrawView(), rSet); } -SwMediaShell::SwMediaShell(SwView &_rView) : - SwBaseShell(_rView) - +SwMediaShell::SwMediaShell(SwView& _rView) + : SwBaseShell(_rView) { SetName("Media Playback"); SfxShell::SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::Media)); diff --git a/sw/source/uibase/shells/navsh.cxx b/sw/source/uibase/shells/navsh.cxx index 6f864ec7c126..c34bebdbc71e 100644 --- a/sw/source/uibase/shells/navsh.cxx +++ b/sw/source/uibase/shells/navsh.cxx @@ -35,8 +35,8 @@ void SwNavigationShell::Execute(SfxRequest const& rReq) SdrView* pSdrView = pSh->GetDrawView(); const SfxItemSet* pArgs = rReq.GetArgs(); const sal_uInt16 nSlotId = rReq.GetSlot(); - bool bChanged = pSdrView->GetModel()->IsChanged(); - pSdrView->GetModel()->SetChanged(false); + bool bChanged = pSdrView->GetModel().IsChanged(); + pSdrView->GetModel().SetChanged(false); SwNavigationMgr& aSwNavigationMgr = pSh->GetNavigationMgr(); const SfxPoolItem* pItem; if (pArgs) @@ -60,10 +60,10 @@ void SwNavigationShell::Execute(SfxRequest const& rReq) default: break; } - if (pSdrView->GetModel()->IsChanged()) + if (pSdrView->GetModel().IsChanged()) GetShell().SetModified(); else if (bChanged) - pSdrView->GetModel()->SetChanged(); + pSdrView->GetModel().SetChanged(); } // determine if the buttons should be enabled/disabled diff --git a/sw/source/uibase/shells/olesh.cxx b/sw/source/uibase/shells/olesh.cxx index b8207d200c94..28e8e153eeb1 100644 --- a/sw/source/uibase/shells/olesh.cxx +++ b/sw/source/uibase/shells/olesh.cxx @@ -23,10 +23,28 @@ #include <frmsh.hxx> #include <olesh.hxx> +#include <sfx2/sidebar/SidebarController.hxx> + #define ShellClass_SwOleShell #include <sfx2/msg.hxx> #include <swslots.hxx> +using namespace css::uno; +using namespace sfx2::sidebar; + +namespace { + +bool inChartOrMathContext(const SwView& rViewShell) +{ + SidebarController* pSidebar = SidebarController::GetSidebarControllerForView(&rViewShell); + if (pSidebar) + return pSidebar->hasChartOrMathContextCurrently(); + + return false; +} + +} // anonymous namespace + SFX_IMPL_INTERFACE(SwOleShell, SwFrameShell) void SwOleShell::InitInterface_Impl() @@ -36,6 +54,36 @@ void SwOleShell::InitInterface_Impl() GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Invisible, ToolbarId::Ole_Toolbox); } +void SwOleShell::Activate(bool bMDI) +{ + if(!inChartOrMathContext(GetView())) + SwFrameShell::Activate(bMDI); + else + { + // Avoid context changes for chart/math during activation / deactivation. + const bool bIsContextBroadcasterEnabled (SfxShell::SetContextBroadcasterEnabled(false)); + + SwFrameShell::Activate(bMDI); + + SfxShell::SetContextBroadcasterEnabled(bIsContextBroadcasterEnabled); + } +} + +void SwOleShell::Deactivate(bool bMDI) +{ + if(!inChartOrMathContext(GetView())) + SwFrameShell::Deactivate(bMDI); + else + { + // Avoid context changes for chart/math during activation / deactivation. + const bool bIsContextBroadcasterEnabled (SfxShell::SetContextBroadcasterEnabled(false)); + + SwFrameShell::Deactivate(bMDI); + + SfxShell::SetContextBroadcasterEnabled(bIsContextBroadcasterEnabled); + } +} + SwOleShell::SwOleShell(SwView &_rView) : SwFrameShell(_rView) diff --git a/sw/source/uibase/shells/slotadd.cxx b/sw/source/uibase/shells/slotadd.cxx index 3aa3469db14d..b8253ce75f0b 100644 --- a/sw/source/uibase/shells/slotadd.cxx +++ b/sw/source/uibase/shells/slotadd.cxx @@ -30,6 +30,7 @@ #include <sfx2/objitem.hxx> #include <sfx2/objsh.hxx> #include <svx/rulritem.hxx> +#include <svx/statusitem.hxx> #include <sfx2/zoomitem.hxx> #include <svx/viewlayoutitem.hxx> #include <svx/zoomslideritem.hxx> diff --git a/sw/source/uibase/shells/tabsh.cxx b/sw/source/uibase/shells/tabsh.cxx index 247d5b4955d6..63857cfea12f 100644 --- a/sw/source/uibase/shells/tabsh.cxx +++ b/sw/source/uibase/shells/tabsh.cxx @@ -18,6 +18,8 @@ */ #include <hintids.hxx> +#include <svl/imageitm.hxx> +#include <svl/numformat.hxx> #include <svl/zforlist.hxx> #include <svl/stritem.hxx> #include <svl/whiter.hxx> @@ -46,6 +48,7 @@ #include <comphelper/lok.hxx> #include <LibreOfficeKit/LibreOfficeKitEnums.h> #include <editeng/itemtype.hxx> +#include <osl/diagnose.h> #include <fmtornt.hxx> #include <fmtlsplt.hxx> @@ -53,6 +56,7 @@ #include <fmtfsize.hxx> #include <swmodule.hxx> #include <wrtsh.hxx> +#include <rootfrm.hxx> #include <wview.hxx> #include <frmatr.hxx> #include <uitool.hxx> @@ -68,6 +72,7 @@ #include <docsh.hxx> #include <tblsel.hxx> #include <viewopt.hxx> +#include <tabfrm.hxx> #include <strings.hrc> #include <cmdid.h> @@ -93,42 +98,39 @@ void SwTableShell::InitInterface_Impl() } -const sal_uInt16 aUITableAttrRange[] = -{ - XATTR_FILL_FIRST, XATTR_FILL_LAST, - FN_PARAM_TABLE_NAME, FN_PARAM_TABLE_NAME, - FN_PARAM_TABLE_HEADLINE, FN_PARAM_TABLE_HEADLINE, - FN_PARAM_TABLE_SPACE, FN_PARAM_TABLE_SPACE, - FN_TABLE_REP, FN_TABLE_REP, - SID_RULER_BORDERS, SID_RULER_BORDERS, +const WhichRangesContainer aUITableAttrRange(svl::Items< RES_LR_SPACE, RES_UL_SPACE, - SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_SHADOW, - RES_BOX, RES_SHADOW, - RES_BACKGROUND, RES_BACKGROUND, - SID_BACKGRND_DESTINATION, SID_BACKGRND_DESTINATION, - SID_HTML_MODE, SID_HTML_MODE, - SID_ATTR_BRUSH_ROW, SID_ATTR_BRUSH_TABLE, RES_PAGEDESC, RES_BREAK, + RES_BACKGROUND, RES_BACKGROUND, + RES_BOX, RES_SHADOW, RES_KEEP, RES_KEEP, RES_LAYOUT_SPLIT, RES_LAYOUT_SPLIT, - FN_TABLE_SET_VERT_ALIGN, FN_TABLE_SET_VERT_ALIGN, RES_FRAMEDIR, RES_FRAMEDIR, RES_ROW_SPLIT, RES_ROW_SPLIT, - FN_TABLE_BOX_TEXTORIENTATION, FN_TABLE_BOX_TEXTORIENTATION, // #i29550# RES_COLLAPSING_BORDERS, RES_COLLAPSING_BORDERS, // <-- collapsing borders - 0 -}; + 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 sal_uInt16* SwuiGetUITableAttrRange() +const WhichRangesContainer& SwuiGetUITableAttrRange() { return aUITableAttrRange; } static void lcl_SetAttr( SwWrtShell &rSh, const SfxPoolItem &rItem ) { - SfxItemSet aSet( rSh.GetView().GetPool(), {{rItem.Which(), rItem.Which()}}); + SfxItemSet aSet( rSh.GetView().GetPool(), rItem.Which(), rItem.Which()); aSet.Put( rItem ); rSh.SetTableAttr( aSet ); } @@ -173,13 +175,13 @@ static std::shared_ptr<SwTableRep> lcl_TableParamToItemSet( SfxItemSet& rSet, Sw rSet.Put(*aBoxDirection); } - bool bSelectAll = rSh.StartsWithTable() && rSh.ExtendedSelectedAll(); + bool bSelectAll = rSh.StartsWith_() == SwCursorShell::StartsWith::Table && rSh.ExtendedSelectedAll(); bool bTableSel = rSh.IsTableMode() || bSelectAll; if(!bTableSel) { rSh.StartAllAction(); rSh.Push(); - rSh.GetView().GetViewFrame()->GetDispatcher()->Execute( FN_TABLE_SELECT_ALL ); + rSh.GetView().GetViewFrame().GetDispatcher()->Execute( FN_TABLE_SELECT_ALL ); } SvxBoxInfoItem aBoxInfo( SID_ATTR_BORDER_INNER ); @@ -230,8 +232,7 @@ static std::shared_ptr<SwTableRep> lcl_TableParamToItemSet( SfxItemSet& rSet, Sw 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) + if(nAlign != text::HoriOrientation::FULL) { SwTwips nLR = pRep->GetSpace() - nWidth; switch ( nAlign ) @@ -272,25 +273,23 @@ void ItemSetToTableParam( const SfxItemSet& rSet, { rSh.StartAllAction(); rSh.StartUndo( SwUndoId::TABLE_ATTR ); - const SfxPoolItem* pItem = nullptr; - if(SfxItemState::SET == rSet.GetItemState(SID_BACKGRND_DESTINATION, false, &pItem)) + if(const SfxUInt16Item* pDestItem = rSet.GetItemIfSet(SID_BACKGRND_DESTINATION, false)) { SwViewOption aUsrPref( *rSh.GetViewOptions() ); - aUsrPref.SetTableDest(static_cast<sal_uInt8>(static_cast<const SfxUInt16Item*>(pItem)->GetValue())); + 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 ) ); - pItem = nullptr; - bool bBackground = SfxItemState::SET == rSet.GetItemState( RES_BACKGROUND, false, &pItem ); - const SfxPoolItem* pRowItem = nullptr, *pTableItem = nullptr; - bBackground |= SfxItemState::SET == rSet.GetItemState( SID_ATTR_BRUSH_ROW, false, &pRowItem ); - bBackground |= SfxItemState::SET == rSet.GetItemState( SID_ATTR_BRUSH_TABLE, false, &pTableItem ); - const SfxPoolItem* pSplit = nullptr; - bool bRowSplit = SfxItemState::SET == rSet.GetItemState( RES_ROW_SPLIT, false, &pSplit ); - const SfxPoolItem* pBoxDirection = nullptr; - bool bBoxDirection = SfxItemState::SET == rSet.GetItemState( FN_TABLE_BOX_TEXTORIENTATION, false, &pBoxDirection ); + 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. @@ -301,17 +300,17 @@ void ItemSetToTableParam( const SfxItemSet& rSet, if(bBackground) { - if(pItem) - rSh.SetBoxBackground( *static_cast<const SvxBrushItem*>(pItem) ); + if(pBackgroundItem) + rSh.SetBoxBackground( *pBackgroundItem ); if(pRowItem) { - std::unique_ptr<SvxBrushItem> aBrush(static_cast<SvxBrushItem*>(pRowItem->Clone())); + std::unique_ptr<SvxBrushItem> aBrush(pRowItem->Clone()); aBrush->SetWhich(RES_BACKGROUND); rSh.SetRowBackground(*aBrush); } if(pTableItem) { - std::unique_ptr<SvxBrushItem> aBrush(static_cast<SvxBrushItem*>(pTableItem->Clone())); + std::unique_ptr<SvxBrushItem> aBrush(pTableItem->Clone()); aBrush->SetWhich(RES_BACKGROUND); rSh.SetTabBackground( *aBrush ); } @@ -320,7 +319,7 @@ void ItemSetToTableParam( const SfxItemSet& rSet, if(bBoxDirection) { SvxFrameDirectionItem aDirection( SvxFrameDirection::Environment, RES_FRAMEDIR ); - aDirection.SetValue(static_cast< const SvxFrameDirectionItem* >(pBoxDirection)->GetValue()); + aDirection.SetValue(pBoxDirection->GetValue()); rSh.SetBoxDirection(aDirection); } @@ -329,14 +328,14 @@ void ItemSetToTableParam( const SfxItemSet& rSet, rSh.Push(); if(!bTableSel) { - rSh.GetView().GetViewFrame()->GetDispatcher()->Execute( FN_TABLE_SELECT_ALL ); + rSh.GetView().GetViewFrame().GetDispatcher()->Execute( FN_TABLE_SELECT_ALL ); } if(bBorder) rSh.SetTabBorders( rSet ); if(bRowSplit) { - rSh.SetRowSplit(*static_cast<const SwFormatRowSplit*>(pSplit)); + rSh.SetRowSplit(*pSplit); } if(!bTableSel) @@ -353,10 +352,10 @@ void ItemSetToTableParam( const SfxItemSet& rSet, bool bTabCols = false; SwTableRep* pRep = nullptr; SwFrameFormat *pFormat = rSh.GetTableFormat(); - SfxItemSet aSet( rSh.GetAttrPool(), svl::Items<RES_FRMATR_BEGIN, RES_FRMATR_END-1>{} ); - if(SfxItemState::SET == rSet.GetItemState( FN_TABLE_REP, false, &pItem )) + 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*>(static_cast<const SwPtrItem*>(pItem)->GetValue()); + pRep = static_cast<SwTableRep*>(pRepItem->GetValue()); const SwTwips nWidth = pRep->GetWidth(); if ( text::HoriOrientation::FULL == pRep->GetAlign() ) @@ -394,14 +393,14 @@ void ItemSetToTableParam( const SfxItemSet& rSet, } } - if( SfxItemState::SET == rSet.GetItemState( FN_PARAM_TABLE_HEADLINE, false, &pItem)) - rSh.SetRowsToRepeat( static_cast<const SfxUInt16Item*>(pItem)->GetValue() ); + if( const SfxUInt16Item* pHeadlineItem = rSet.GetItemIfSet( FN_PARAM_TABLE_HEADLINE, false )) + rSh.SetRowsToRepeat( pHeadlineItem->GetValue() ); - if( SfxItemState::SET == rSet.GetItemState( FN_TABLE_SET_VERT_ALIGN, false, &pItem)) - rSh.SetBoxAlign(static_cast<const SfxUInt16Item*>(pItem)->GetValue()); + if( const SfxUInt16Item* pAlignItem = rSet.GetItemIfSet( FN_TABLE_SET_VERT_ALIGN, false )) + rSh.SetBoxAlign(pAlignItem->GetValue()); - if( SfxItemState::SET == rSet.GetItemState( FN_PARAM_TABLE_NAME, false, &pItem )) - rSh.SetTableName( *pFormat, static_cast<const SfxStringItem*>(pItem)->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[] = @@ -418,6 +417,7 @@ void ItemSetToTableParam( const SfxItemSet& rSet, // <-- 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 ); @@ -445,6 +445,39 @@ static void lcl_TabGetMaxLineWidth(const SvxBorderLine* pBorderLine, SvxBorderLi rBorderLine.SetColor(pBorderLine->GetColor()); } +static bool lcl_BoxesInTrackedRows(SwWrtShell &rSh, const SwSelBoxes& rBoxes) +{ + // cursor and selection are there only in tracked rows + bool bRet = true; + SwRedlineTable::size_type nRedlinePos = 0; + if ( rBoxes.empty() ) + bRet = rSh.GetCursor()->GetPointNode().GetTableBox()->GetUpper()->IsTracked(nRedlinePos); + else + { + tools::Long nBoxes = rBoxes.size(); + SwTableLine* pPrevLine = nullptr; + for ( tools::Long i = 0; i < nBoxes; i++ ) + { + SwTableLine* pLine = rBoxes[i]->GetUpper(); + if ( pLine != pPrevLine ) + bRet &= pLine->IsTracked(nRedlinePos); + pPrevLine = pLine; + } + } + + return bRet; +} + +static bool lcl_CursorInDeletedTable(SwWrtShell &rSh) +{ + // cursor and selection are there only in deleted table in Show Changes mode + if ( rSh.GetLayout()->IsHideRedlines() ) + return false; + + SwTableNode* pTableNd = rSh.GetCursor()->GetPoint()->GetNode().FindTableNode(); + return pTableNd && pTableNd->GetTable().IsDeleted(); +} + void SwTableShell::Execute(SfxRequest &rReq) { const SfxItemSet* pArgs = rReq.GetArgs(); @@ -455,7 +488,7 @@ void SwTableShell::Execute(SfxRequest &rReq) const SfxPoolItem* pItem = nullptr; sal_uInt16 nSlot = rReq.GetSlot(); if(pArgs) - pArgs->GetItemState(GetPool().GetWhich(nSlot), false, &pItem); + pArgs->GetItemState(GetPool().GetWhichIDFromSlotID(nSlot), false, &pItem); bool bCallDone = false; switch ( nSlot ) { @@ -465,18 +498,18 @@ void SwTableShell::Execute(SfxRequest &rReq) break; // Create items, because we have to rework anyway. std::shared_ptr<SvxBoxItem> aBox(std::make_shared<SvxBoxItem>(RES_BOX)); - SfxItemSet aCoreSet( GetPool(), - svl::Items<RES_BOX, RES_BOX, - SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER>{}); + 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 SfxPoolItem *pBoxItem = nullptr; - if ( pArgs->GetItemState(RES_BOX, true, &pBoxItem) == SfxItemState::SET ) + const SvxBoxItem *pBoxItem = pArgs->GetItemIfSet(RES_BOX); + if ( pBoxItem ) { - aBox.reset(static_cast<SvxBoxItem*>(pBoxItem->Clone())); - sal_uInt16 nDefValue = MIN_BORDER_DIST; + aBox.reset(pBoxItem->Clone()); + sal_Int16 nDefValue = MIN_BORDER_DIST; if ( !rReq.IsAPI() ) nDefValue = 55; if (!rReq.IsAPI() || aBox->GetSmallestDistance() < MIN_BORDER_DIST) @@ -490,13 +523,13 @@ void SwTableShell::Execute(SfxRequest &rReq) //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 (pArgs->GetItemState(SID_ATTR_BORDER_INNER, true, &pBoxItem) == SfxItemState::SET) + if (const SvxBoxInfoItem* pBoxInfoItem = pArgs->GetItemIfSet(SID_ATTR_BORDER_INNER)) { - aInfo.reset(static_cast<SvxBoxInfoItem*>(pBoxItem->Clone())); + aInfo.reset(pBoxInfoItem->Clone()); } - else if( pArgs->GetItemState(SDRATTR_TABLE_BORDER_INNER, true, &pBoxItem) == SfxItemState::SET ) + else if( const SvxBoxInfoItem* pBoxInfoInnerItem = pArgs->GetItemIfSet(SDRATTR_TABLE_BORDER_INNER)) { - aInfo.reset(static_cast<SvxBoxInfoItem*>(pBoxItem->Clone())); + aInfo.reset(pBoxInfoInnerItem->Clone()); aInfo->SetWhich(SID_ATTR_BORDER_INNER); } @@ -522,7 +555,7 @@ void SwTableShell::Execute(SfxRequest &rReq) if(aBorderLine.GetOutWidth() == 0) { aBorderLine.SetBorderLineStyle(SvxBorderLineStyle::SOLID); - aBorderLine.SetWidth( DEF_LINE_WIDTH_5 ); + aBorderLine.SetWidth( SvxBorderLineWidth::VeryThin ); } if( aBox->GetTop() != nullptr ) @@ -569,12 +602,12 @@ void SwTableShell::Execute(SfxRequest &rReq) { //#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(); + 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)); + std::shared_ptr<SwTableRep> xTableRep(::lcl_TableParamToItemSet(aCoreSet, rSh)); aCoreSet.Put(SfxUInt16Item(SID_HTML_MODE, ::GetHtmlMode(GetView().GetDocShell()))); rSh.GetTableAttr(aCoreSet); @@ -591,22 +624,34 @@ void SwTableShell::Execute(SfxRequest &rReq) if (pDlg) { if (pItem) - pDlg->SetCurPageId(OUStringToOString(static_cast<const SfxStringItem *>(pItem)->GetValue(), RTL_TEXTENCODING_UTF8)); + pDlg->SetCurPageId(static_cast<const SfxStringItem *>(pItem)->GetValue()); - auto pRequest = std::make_shared<SfxRequest>(rReq); + auto xRequest = std::make_shared<SfxRequest>(rReq); rReq.Ignore(); // the 'old' request is not relevant any more - auto xPaM(std::make_shared<SwPaM>(*rSh.GetCursor(), nullptr)); // tdf#135636 make a copy to use at later apply - pDlg->StartExecuteAsync([pDlg, pRequest, pTableRep, &rBindings, &rSh, xPaM](sal_Int32 nResult){ + 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, xRequest=std::move(xRequest), xTableRep=std::move(xTableRep), + &rBindings, &rSh, vCursors=std::move(vCursors), bTableMode](sal_Int32 nResult){ if (RET_OK == nResult) { - rSh.SetSelection(*xPaM); // tdf#135636 set the table selected at dialog launch as current selection + 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); + xRequest->SetSlot(FN_FORMAT_TABLE_DLG); + xRequest->Done(*pOutSet); ItemSetToTableParam(*pOutSet, rSh); } @@ -640,66 +685,66 @@ void SwTableShell::Execute(SfxRequest &rReq) break; case FN_NUM_FORMAT_TABLE_DLG: { - SwView* pView = GetActiveView(); - if(pView) + 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(); - SfxItemSet aCoreSet( - GetPool(), - svl::Items< - SID_ATTR_NUMBERFORMAT_VALUE, - SID_ATTR_NUMBERFORMAT_INFO>{}); - - SfxItemSet aBoxSet( *aCoreSet.GetPool(), - svl::Items<RES_BOXATR_FORMAT, RES_BOXATR_FORMAT, - RES_BOXATR_VALUE, RES_BOXATR_VALUE>{} ); + auto pCoreSet = std::make_shared<SfxItemSetFixed<SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_INFO>>( GetPool() ); + + SfxItemSetFixed<RES_BOXATR_FORMAT, RES_BOXATR_FORMAT, + RES_BOXATR_VALUE, RES_BOXATR_VALUE> + aBoxSet( *pCoreSet->GetPool() ); rSh.GetTableBoxFormulaAttrs( aBoxSet ); SfxItemState eState = aBoxSet.GetItemState(RES_BOXATR_FORMAT); if(eState == SfxItemState::DEFAULT) { - aCoreSet.Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE, + pCoreSet->Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE, pFormatter->GetFormatIndex(NF_TEXT, LANGUAGE_SYSTEM))); } else - aCoreSet.Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE, + pCoreSet->Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE, aBoxSet.Get( RES_BOXATR_FORMAT ).GetValue() )); - OUString sCurText( rSh.GetTableBoxText() ); - aCoreSet.Put( SvxNumberInfoItem( pFormatter, + pCoreSet->Put( SvxNumberInfoItem( pFormatter, aBoxSet.Get( RES_BOXATR_VALUE).GetValue(), - sCurText, SID_ATTR_NUMBERFORMAT_INFO )); + rSh.GetTableBoxText(), SID_ATTR_NUMBERFORMAT_INFO )); + SwWrtShell* pSh = &rSh; SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); - ScopedVclPtr<SfxAbstractDialog> pDlg(pFact->CreateNumFormatDialog(GetView().GetFrameWeld(), aCoreSet)); + VclPtr<SfxAbstractDialog> pDlg(pFact->CreateNumFormatDialog(GetView().GetFrameWeld(), *pCoreSet)); - if (RET_OK == pDlg->Execute()) - { - const SvxNumberInfoItem* pNumberFormatItem - = GetView().GetDocShell()->GetItem( SID_ATTR_NUMBERFORMAT_INFO ); - - if( pNumberFormatItem ) + pDlg->StartExecuteAsync([pDlg, pCoreSet, pSh](sal_uInt32 nResult){ + if (RET_OK == nResult) { - for ( sal_uInt32 key : pNumberFormatItem->GetDelFormats() ) - pNumberFormatItem->GetNumberFormatter()->DeleteEntry( key ); + const SvxNumberInfoItem* pNumberFormatItem + = pSh->GetView().GetDocShell()->GetItem( SID_ATTR_NUMBERFORMAT_INFO ); + + if( pNumberFormatItem ) + { + for ( sal_uInt32 key : pNumberFormatItem->GetDelFormats() ) + pNumberFormatItem->GetNumberFormatter()->DeleteEntry( key ); + } + + const SfxPoolItem* pNumberFormatValueItem = + pDlg->GetOutputItemSet()->GetItemIfSet( + SID_ATTR_NUMBERFORMAT_VALUE, false); + if( pNumberFormatValueItem ) + { + SfxItemSetFixed<RES_BOXATR_FORMAT, RES_BOXATR_FORMAT> + aBoxFormatSet( *pCoreSet->GetPool() ); + aBoxFormatSet.Put( SwTableBoxNumFormat( + static_cast<const SfxUInt32Item*>(pNumberFormatValueItem)->GetValue() )); + pSh->SetTableBoxFormulaAttrs( aBoxFormatSet ); + + } } - const SfxPoolItem* pNumberFormatValueItem = nullptr; - if( SfxItemState::SET == pDlg->GetOutputItemSet()->GetItemState( - SID_ATTR_NUMBERFORMAT_VALUE, false, &pNumberFormatValueItem )) - { - SfxItemSet aBoxFormatSet( *aCoreSet.GetPool(), - svl::Items<RES_BOXATR_FORMAT, RES_BOXATR_FORMAT>{} ); - aBoxFormatSet.Put( SwTableBoxNumFormat( - static_cast<const SfxUInt32Item*>(pNumberFormatValueItem)->GetValue() )); - rSh.SetTableBoxFormulaAttrs( aBoxFormatSet ); - - } - } + pDlg->disposeOnce(); + }); } break; } @@ -827,15 +872,29 @@ void SwTableShell::Execute(SfxRequest &rReq) case SID_AUTOFORMAT: { SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); - ScopedVclPtr<AbstractSwAutoFormatDlg> pDlg(pFact->CreateSwAutoFormatDlg(GetView().GetFrameWeld(), &rSh)); - pDlg->Execute(); + VclPtr<AbstractSwAutoFormatDlg> pDlg(pFact->CreateSwAutoFormatDlg(GetView().GetFrameWeld(), &rSh)); + pDlg->StartExecuteAsync( + [pDlg] (sal_Int32 nResult)->void + { + if (nResult == RET_OK) + pDlg->Apply(); + pDlg->disposeOnce(); + } + ); break; } case FN_TABLE_SET_ROW_HEIGHT: { SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); - ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSwTableHeightDialog(GetView().GetFrameWeld(), rSh)); - pDlg->Execute(); + VclPtr<AbstractSwTableHeightDlg> pDlg(pFact->CreateSwTableHeightDialog(GetView().GetFrameWeld(), rSh)); + pDlg->StartExecuteAsync( + [pDlg] (sal_Int32 nResult)->void + { + if (nResult == RET_OK) + pDlg->Apply(); + pDlg->disposeOnce(); + } + ); break; } case FN_NUMBER_BULLETS: @@ -862,8 +921,8 @@ void SwTableShell::Execute(SfxRequest &rReq) if (pItem) { nCount = static_cast<const SfxInt16Item* >(pItem)->GetValue(); - if(SfxItemState::SET == pArgs->GetItemState(FN_PARAM_INSERT_AFTER, true, &pItem)) - bAfter = static_cast<const SfxBoolItem* >(pItem)->GetValue(); + if(const SfxBoolItem* pAfterItem = pArgs->GetItemIfSet(FN_PARAM_INSERT_AFTER)) + bAfter = pAfterItem->GetValue(); } else if( !rReq.IsAPI() ) { @@ -924,8 +983,7 @@ void SwTableShell::Execute(SfxRequest &rReq) if ( bSetInnerBorders ) { const SvxBoxInfoItem& aBoxInfo(aCoreSet.Get(SID_ATTR_BORDER_INNER)); - SfxItemSet aSet( GetPool(), svl::Items<SID_ATTR_BORDER_INNER, - SID_ATTR_BORDER_INNER>{}); + SfxItemSetFixed<SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER> aSet( GetPool() ); aSet.Put( aBoxInfo ); ItemSetToTableParam( aSet, rSh ); rSh.EndUndo( nUndoId ); @@ -945,21 +1003,29 @@ void SwTableShell::Execute(SfxRequest &rReq) const SfxSlot* pSlot = GetStaticInterface()->GetSlot(nSlot); if ( FN_TABLE_INSERT_ROW_DLG != nSlot || !rSh.IsInRepeatedHeadline()) { + auto xRequest = std::make_shared<SfxRequest>(rReq); + rReq.Ignore(); // the 'old' request is not relevant any more SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); - ScopedVclPtr<SvxAbstractInsRowColDlg> pDlg(pFact->CreateSvxInsRowColDlg(GetView().GetFrameWeld(), + VclPtr<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 }); - } + pDlg->StartExecuteAsync( + [this, pDlg, xRequest=std::move(xRequest), nSlot] (sal_Int32 nResult)->void + { + if (nResult == RET_OK) + { + const TypedWhichId<SfxUInt16Item> nDispatchSlot = (nSlot == FN_TABLE_INSERT_COL_DLG) + ? FN_TABLE_INSERT_COL_AFTER : FN_TABLE_INSERT_ROW_AFTER; + SfxUInt16Item aCountItem( nDispatchSlot, pDlg->getInsertCount() ); + SfxBoolItem aAfter( FN_PARAM_INSERT_AFTER, !pDlg->isInsertBefore() ); + SfxViewFrame& rVFrame = GetView().GetViewFrame(); + rVFrame.GetDispatcher()->ExecuteList(nDispatchSlot, + SfxCallMode::SYNCHRON|SfxCallMode::RECORD, + { &aCountItem, &aAfter }); + } + pDlg->disposeOnce(); + xRequest->Done(); + } + ); } break; } @@ -1036,10 +1102,20 @@ void SwTableShell::Execute(SfxRequest &rReq) 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; + VclPtr<AbstractSplitTableDialog> pDlg(pFact->CreateSplitTableDialog(GetView().GetFrameWeld(), rSh)); + + SwWrtShell* pSh = &rSh; + + pDlg->StartExecuteAsync([pDlg, pSh](int nResult) { + if (nResult == RET_OK) + { + const auto aSplitMode = pDlg->GetSplitMode(); + pSh->SplitTable( aSplitMode ); + } + + pDlg->disposeOnce(); + }); + rReq.Ignore(); // We're already handling the request in our async bit } break; } @@ -1072,7 +1148,7 @@ void SwTableShell::Execute(SfxRequest &rReq) ? TableChgMode::FixedWidthChangeProp : TableChgMode::VarWidthChangeAbs ); - SfxBindings& rBind = GetView().GetViewFrame()->GetBindings(); + SfxBindings& rBind = GetView().GetViewFrame().GetBindings(); static sal_uInt16 aInva[] = { FN_TABLE_MODE_FIX, FN_TABLE_MODE_FIX_PROP, @@ -1085,10 +1161,10 @@ void SwTableShell::Execute(SfxRequest &rReq) } case FN_TABLE_AUTOSUM: { - SfxViewFrame* pVFrame = GetView().GetViewFrame(); - pVFrame->GetDispatcher()->Execute(FN_EDIT_FORMULA, SfxCallMode::SYNCHRON); + SfxViewFrame& rVFrame = GetView().GetViewFrame(); + rVFrame.GetDispatcher()->Execute(FN_EDIT_FORMULA, SfxCallMode::SYNCHRON); const sal_uInt16 nId = SwInputChild::GetChildWindowId(); - SwInputChild* pChildWin = static_cast<SwInputChild*>(pVFrame-> + SwInputChild* pChildWin = static_cast<SwInputChild*>(rVFrame. GetChildWindow( nId )); OUString sSum; GetShell().GetAutoSum(sSum); @@ -1110,7 +1186,7 @@ void SwTableShell::Execute(SfxRequest &rReq) { rSh.StartAction(); rSh.StartUndo(); - rSh.GetView().GetViewFrame()->GetDispatcher()->Execute(FN_TABLE_SELECT_ALL); + rSh.GetView().GetViewFrame().GetDispatcher()->Execute(FN_TABLE_SELECT_ALL); rSh.DeleteTable(); rSh.EndUndo(); rSh.EndAction(); @@ -1146,6 +1222,96 @@ void SwTableShell::Execute(SfxRequest &rReq) } return; } + case SID_ATTR_TABLE_ALIGNMENT: + { + const SfxUInt16Item* pAlignItem = rReq.GetArg<SfxUInt16Item>(SID_ATTR_TABLE_ALIGNMENT); + if (pAlignItem && pAlignItem->GetValue() <= text::HoriOrientation::LEFT_AND_WIDTH) + { + SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END - 1> aSet( GetPool()); + rSh.StartUndo(SwUndoId::TABLE_ATTR); + SwFormatHoriOrient aAttr( 0, pAlignItem->GetValue()); + + const SfxInt32Item* pLeftItem = rReq.GetArg<SfxInt32Item>(SID_ATTR_TABLE_LEFT_SPACE); + const SfxInt32Item* pRightItem = rReq.GetArg<SfxInt32Item>(SID_ATTR_TABLE_RIGHT_SPACE); + + SvxLRSpaceItem aLRSpace( RES_LR_SPACE ); + SwTwips nLeft = pLeftItem ? pLeftItem->GetValue() : 0; + SwTwips nRight = pRightItem ? pRightItem->GetValue() : 0; + SwTabCols aTabCols; + rSh.GetTabCols(aTabCols); + tools::Long nSpace = aTabCols.GetRightMax(); + SwTwips nWidth = nSpace; + switch (pAlignItem->GetValue()) + { + case text::HoriOrientation::LEFT: + if (MINLAY < nSpace - nRight) + nWidth = nSpace - nRight; + else + { + nWidth = MINLAY; + nRight = nSpace - MINLAY; + } + nLeft = 0; + break; + case text::HoriOrientation::RIGHT: + if (MINLAY < nSpace - nLeft) + nWidth = nSpace - nLeft; + else + { + nWidth = MINLAY; + nLeft = nSpace - MINLAY; + } + nRight = 0; + break; + case text::HoriOrientation::LEFT_AND_WIDTH: + // width doesn't change + nRight = 0; + nLeft = std::min(nLeft, nSpace); + break; + case text::HoriOrientation::FULL: + nLeft = nRight = 0; + break; + case text::HoriOrientation::CENTER: + if (MINLAY < nSpace - 2 * nLeft) + nWidth = nSpace - 2 * nLeft; + else + { + nWidth = MINLAY; + nLeft = nRight = (nSpace - MINLAY) / 2; + } + break; + case text::HoriOrientation::NONE: + if (MINLAY < nSpace - nLeft - nRight) + nWidth = nSpace - nLeft - nRight; + else + { + nWidth = MINLAY; + //TODO: keep the previous value - if possible and reduce the 'new one' only + nLeft = nRight = (nSpace - MINLAY) / 2; + } + break; + default: + break; + } + SwFormatFrameSize aSz( SwFrameSize::Variable, nWidth ); + aSet.Put(aSz); + + aLRSpace.SetLeft(nLeft); + aLRSpace.SetRight(nRight); + aSet.Put( aLRSpace ); + + aSet.Put( aAttr ); + rSh.SetTableAttr( aSet ); + rSh.EndUndo(SwUndoId::TABLE_ATTR); + static sal_uInt16 aInva[] = + { SID_ATTR_TABLE_LEFT_SPACE, + SID_ATTR_TABLE_RIGHT_SPACE, + 0 + }; + GetView().GetViewFrame().GetBindings().Invalidate( aInva ); + } + return; + } default: bMore = true; } @@ -1172,8 +1338,8 @@ void SwTableShell::Execute(SfxRequest &rReq) case SID_ATTR_LRSPACE: if(pItem) { - SfxItemSet aSet( GetPool(), svl::Items<RES_LR_SPACE, RES_LR_SPACE, - RES_HORI_ORIENT, RES_HORI_ORIENT>{} ); + 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 ); @@ -1183,8 +1349,17 @@ void SwTableShell::Execute(SfxRequest &rReq) // The last case branch which needs a table manager!! case FN_TABLE_SET_COL_WIDTH: { - SwTableFUNC aMgr( &rSh ); - aMgr.ColWidthDlg(GetView().GetFrameWeld()); + // Adjust line height (dialogue) + SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); + VclPtr<AbstractSwTableWidthDlg> pDlg(pFact->CreateSwTableWidthDlg(GetView().GetFrameWeld(), &rSh)); + pDlg->StartExecuteAsync( + [pDlg] (sal_Int32 nResult)->void + { + if (nResult == RET_OK) + pDlg->Apply(); + pDlg->disposeOnce(); + } + ); break; } case SID_TABLE_VERT_NONE: @@ -1204,7 +1379,7 @@ void SwTableShell::Execute(SfxRequest &rReq) if ( pItem ) { SwFormatLayoutSplit aSplit( static_cast<const SvxFormatSplitItem*>(pItem)->GetValue()); - SfxItemSet aSet(GetPool(), svl::Items<RES_LAYOUT_SPLIT, RES_LAYOUT_SPLIT>{} ); + SfxItemSetFixed<RES_LAYOUT_SPLIT, RES_LAYOUT_SPLIT> aSet(GetPool()); aSet.Put(aSplit); rSh.SetTableAttr(aSet); } @@ -1215,7 +1390,7 @@ void SwTableShell::Execute(SfxRequest &rReq) { SvxFormatKeepItem aKeep( *static_cast<const SvxFormatKeepItem*>(pItem) ); aKeep.SetWhich( RES_KEEP ); - SfxItemSet aSet(GetPool(), svl::Items<RES_KEEP, RES_KEEP>{} ); + SfxItemSetFixed<RES_KEEP, RES_KEEP> aSet(GetPool()); aSet.Put(aKeep); rSh.SetTableAttr(aSet); } @@ -1314,6 +1489,24 @@ void SwTableShell::GetState(SfxItemSet &rSet) } break; } + case FN_TABLE_INSERT_COL_BEFORE: + case FN_TABLE_INSERT_COL_AFTER: + { + SfxImageItem aImageItem(nSlot); + if (pFormat->GetFrameDir().GetValue() == SvxFrameDirection::Environment) + { + // Inherited from superordinate object (page or frame). + // If the table spans multiple pages, direction is set by the first page. + SwIterator<SwTabFrame, SwFrameFormat> aIterT(*pFormat); + for (SwTabFrame* pFrame = aIterT.First(); pFrame; + pFrame = static_cast<SwTabFrame*>(pFrame->GetPrecede())) + aImageItem.SetMirrored(pFrame->IsRightToLeft()); + } + else + aImageItem.SetMirrored(pFormat->GetFrameDir().GetValue() == SvxFrameDirection::Horizontal_RL_TB); + rSet.Put(aImageItem); + break; + } case FN_TABLE_INSERT_ROW: case FN_TABLE_INSERT_ROW_AFTER: case FN_TABLE_INSERT_ROW_DLG: @@ -1374,7 +1567,7 @@ void SwTableShell::GetState(SfxItemSet &rSet) { SwSelBoxes aBoxes; ::GetTableSel( rSh, aBoxes, SwTableSearchType::Row ); - if( ::HasProtectedCells( aBoxes )) + if( ::HasProtectedCells( aBoxes ) || lcl_BoxesInTrackedRows( rSh, aBoxes ) ) rSet.DisableItem( nSlot ); } break; @@ -1382,10 +1575,14 @@ void SwTableShell::GetState(SfxItemSet &rSet) { SwSelBoxes aBoxes; ::GetTableSel( rSh, aBoxes, SwTableSearchType::Col ); - if( ::HasProtectedCells( aBoxes )) + 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 @@ -1441,7 +1638,7 @@ void SwTableShell::GetState(SfxItemSet &rSet) OUString sPayload = ".uno:TableRowHeight=" + sHeight; GetViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED, - OUStringToOString(sPayload, RTL_TEXTENCODING_ASCII_US).getStr()); + OUStringToOString(sPayload, RTL_TEXTENCODING_ASCII_US)); } } break; @@ -1465,11 +1662,62 @@ void SwTableShell::GetState(SfxItemSet &rSet) OUString sPayload = ".uno:TableColumWidth=" + sWidth; GetViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED, - OUStringToOString(sPayload, RTL_TEXTENCODING_ASCII_US).getStr()); + OUStringToOString(sPayload, RTL_TEXTENCODING_ASCII_US)); } break; } + case SID_ATTR_TABLE_ALIGNMENT: + { + const sal_uInt16 nAlign = pFormat->GetHoriOrient().GetHoriOrient(); + rSet.Put(SfxUInt16Item(nSlot, nAlign)); + break; + } + case SID_ATTR_TABLE_LEFT_SPACE: + case SID_ATTR_TABLE_RIGHT_SPACE: + { + SwTabCols aTabCols; + rSh.GetTabCols(aTabCols); + tools::Long nSpace = aTabCols.GetRightMax(); + SvxLRSpaceItem aLRSpace(pFormat->GetLRSpace()); + SwTwips nLeft = aLRSpace.GetLeft(); + SwTwips nRight = aLRSpace.GetRight(); + + sal_uInt16 nPercent = 0; + auto nWidth = ::GetTableWidth(pFormat, aTabCols, &nPercent, &rSh ); + // The table width is wrong for relative values. + if (nPercent) + nWidth = nSpace * nPercent / 100; + const sal_uInt16 nAlign = pFormat->GetHoriOrient().GetHoriOrient(); + if(nAlign != text::HoriOrientation::FULL ) + { + SwTwips nLR = nSpace - 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 = nSpace - nLeft - nRight; + break; + } + } + rSet.Put(SfxInt32Item(SID_ATTR_TABLE_LEFT_SPACE, nLeft)); + rSet.Put(SfxInt32Item(SID_ATTR_TABLE_RIGHT_SPACE, nRight)); + break; + } } nSlot = aIter.NextWhich(); } @@ -1484,9 +1732,8 @@ SwTableShell::SwTableShell(SwView &_rView) : void SwTableShell::GetFrameBorderState(SfxItemSet &rSet) { - SfxItemSet aCoreSet( GetPool(), - svl::Items<RES_BOX, RES_BOX, - SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER>{} ); + 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 ); @@ -1524,9 +1771,8 @@ void SwTableShell::ExecTableStyle(SfxRequest& rReq) void SwTableShell::GetLineStyleState(SfxItemSet &rSet) { - SfxItemSet aCoreSet( GetPool(), - svl::Items<RES_BOX, RES_BOX, - SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER>{}); + 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 ); @@ -1549,7 +1795,7 @@ void SwTableShell::ExecNumberFormat(SfxRequest const & rReq) const SfxPoolItem* pItem = nullptr; const sal_uInt16 nSlot = rReq.GetSlot(); if(pArgs) - pArgs->GetItemState(GetPool().GetWhich(nSlot), false, &pItem); + pArgs->GetItemState(GetPool().GetWhichIDFromSlotID(nSlot), false, &pItem); // Always acquire the language from the current cursor position. LanguageType eLang = rSh.GetCurLang(); @@ -1599,7 +1845,7 @@ void SwTableShell::ExecNumberFormat(SfxRequest const & rReq) if( NUMBERFORMAT_ENTRY_NOT_FOUND != nNumberFormat ) { - SfxItemSet aBoxSet( GetPool(), svl::Items<RES_BOXATR_FORMAT, RES_BOXATR_FORMAT>{} ); + SfxItemSetFixed<RES_BOXATR_FORMAT, RES_BOXATR_FORMAT> aBoxSet( GetPool() ); aBoxSet.Put( SwTableBoxNumFormat( nNumberFormat )); rSh.SetTableBoxFormulaAttrs( aBoxSet ); } diff --git a/sw/source/uibase/shells/textdrw.cxx b/sw/source/uibase/shells/textdrw.cxx index e92f11130b86..881468c5d717 100644 --- a/sw/source/uibase/shells/textdrw.cxx +++ b/sw/source/uibase/shells/textdrw.cxx @@ -25,6 +25,7 @@ #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> @@ -49,14 +50,14 @@ void SwBaseShell::InsertURLButton(const OUString& rURL, const OUString& rTarget, // OBJ_FM_BUTTON pSdrView->SetDesignMode(); - pSdrView->SetCurrentObj(OBJ_FM_BUTTON); + 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(OBJ_FM_BUTTON, SdrInventor::FmForm, aStartPos)) + if (rSh.BeginCreate(SdrObjKind::FormButton, SdrInventor::FmForm, aStartPos)) { pSdrView->SetOrtho(false); Size aSz(GetView().GetEditWin().PixelToLogic(Size(140, 20))); diff --git a/sw/source/uibase/shells/textfld.cxx b/sw/source/uibase/shells/textfld.cxx index a25de40e60ec..cec8afc3f76c 100644 --- a/sw/source/uibase/shells/textfld.cxx +++ b/sw/source/uibase/shells/textfld.cxx @@ -17,6 +17,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <com/sun/star/beans/PropertyValues.hpp> #include <AnnotationWin.hxx> #include <comphelper/lok.hxx> #include <hintids.hxx> @@ -25,6 +26,7 @@ #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> @@ -34,6 +36,8 @@ #include <svx/postattr.hxx> #include <svx/hlnkitem.hxx> #include <svx/svxdlg.hxx> +#include <osl/diagnose.h> +#include <fmthdft.hxx> #include <fmtinfmt.hxx> #include <fldwrap.hxx> #include <redline.hxx> @@ -52,15 +56,25 @@ #include <doc.hxx> #include <PostItMgr.hxx> #include <swmodule.hxx> +#include <svtools/strings.hrc> +#include <svtools/svtresid.hxx> + +#include <editeng/ulspitem.hxx> #include <xmloff/odffields.hxx> #include <IDocumentContentOperations.hxx> #include <IDocumentRedlineAccess.hxx> #include <IDocumentUndoRedo.hxx> #include <svl/zforlist.hxx> #include <svl/zformat.hxx> +#include <svx/xfillit0.hxx> +#include <svx/pageitem.hxx> +#include <comphelper/sequenceashashmap.hxx> #include <IMark.hxx> +#include <officecfg/Office/Common.hxx> #include <officecfg/Office/Compatibility.hxx> #include <ndtxt.hxx> +#include <translatehelper.hxx> +#include <sfx2/dispatch.hxx> using namespace nsSwDocInfoSubType; @@ -69,7 +83,7 @@ static OUString lcl_BuildTitleWithRedline( const SwRangeRedline *pRedline ) { const OUString sTitle(SwResId(STR_REDLINE_COMMENT)); - const char* pResId = nullptr; + TranslateId pResId; switch( pRedline->GetType() ) { case RedlineType::Insert: @@ -103,7 +117,7 @@ void SwTextShell::ExecField(SfxRequest &rReq) sal_uInt16 nSlot = rReq.GetSlot(); const SfxItemSet* pArgs = rReq.GetArgs(); if(pArgs) - pArgs->GetItemState(GetPool().GetWhich(nSlot), false, &pItem); + pArgs->GetItemState(GetPool().GetWhichIDFromSlotID(nSlot), false, &pItem); bool bMore = false; bool bIsText = true; @@ -126,22 +140,54 @@ void SwTextShell::ExecField(SfxRequest &rReq) GetBaseLink(); if(rLink.IsVisible()) { + if (officecfg::Office::Common::Security::Scripting::DisableActiveContent::get()) + { + std::unique_ptr<weld::MessageDialog> xError( + Application::CreateMessageDialog( + nullptr, VclMessageType::Warning, VclButtonsType::Ok, + SvtResId(STR_WARNING_EXTERNAL_LINK_EDIT_DISABLED))); + xError->run(); + break; + } + SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); - ScopedVclPtr<SfxAbstractLinksDialog> pDlg(pFact->CreateLinksDialog(GetView().GetFrameWeld(), &rSh.GetLinkManager(), false, &rLink)); - pDlg->Execute(); + VclPtr<SfxAbstractLinksDialog> pDlg(pFact->CreateLinksDialog(GetView().GetFrameWeld(), &rSh.GetLinkManager(), false, &rLink)); + pDlg->StartExecuteAsync( + [pDlg] (sal_Int32 /*nResult*/)->void + { + pDlg->disposeOnce(); + } + ); } break; } default: { SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); - ScopedVclPtr<SfxAbstractDialog> pDlg(pFact->CreateSwFieldEditDlg( GetView() )); - pDlg->Execute(); + VclPtr<SfxAbstractDialog> pDlg(pFact->CreateSwFieldEditDlg( GetView() )); + // without TabPage no dialog + if (pDlg) + pDlg->StartExecuteAsync( + [pDlg] (sal_Int32 /*nResult*/)->void + { + pDlg->disposeOnce(); + } + ); } } } break; } + case FN_UPDATE_SEL_FIELD: + { + SwField *pField = rSh.GetCurField(); + + if (pField) + { + rSh.UpdateOneField(*pField); + } + break; + } case FN_EXECUTE_MACROFIELD: { SwField* pField = rSh.GetCurField(); @@ -175,16 +221,16 @@ void SwTextShell::ExecField(SfxRequest &rReq) rSh.ClearMark(); if (!rSh.IsMultiSelection() && (nullptr != dynamic_cast<const SwTextInputField*>( - SwCursorShell::GetTextFieldAtCursor(rSh.GetCursor(), true)))) + SwCursorShell::GetTextFieldAtCursor(rSh.GetCursor(), ::sw::GetTextAttrMode::Default)))) { rSh.SttSelect(); - rSh.SelectText( + rSh.SelectTextModel( SwCursorShell::StartOfInputFieldAtPos( *(rSh.GetCursor()->Start()) ) + 1, SwCursorShell::EndOfInputFieldAtPos( *(rSh.GetCursor()->Start()) ) - 1 ); } - else + else if (SwField* pCurrentField = rSh.GetCurField(true)) { - rSh.StartInputFieldDlg(rSh.GetCurField(true), false, false, GetView().GetFrameWeld()); + rSh.StartInputFieldDlg(pCurrentField, false, false, GetView().GetFrameWeld()); } bRet = true; } @@ -193,6 +239,15 @@ void SwTextShell::ExecField(SfxRequest &rReq) } break; + case FN_GOTO_MARK: + { + const SfxStringItem* pName = rReq.GetArg<SfxStringItem>(FN_GOTO_MARK); + if (pName) + { + rSh.GotoMark(pName->GetValue()); + } + } + break; default: bMore = true; } @@ -214,9 +269,9 @@ void SwTextShell::ExecField(SfxRequest &rReq) OUString aPar2; sal_Int32 nCommand = 0; - if( SfxItemState::SET == pArgs->GetItemState( FN_PARAM_FIELD_TYPE, - false, &pItem )) - nType = static_cast<SwFieldTypesEnum>(static_cast<const SfxUInt16Item *>(pItem)->GetValue()); + 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 )) @@ -234,12 +289,12 @@ void SwTextShell::ExecField(SfxRequest &rReq) { aPar1 += static_cast<const SfxStringItem *>(pItem)->GetValue(); } - if( SfxItemState::SET == pArgs->GetItemState( - FN_PARAM_FIELD_CONTENT, false, &pItem )) - aPar2 = static_cast<const SfxStringItem *>(pItem)->GetValue(); - if( SfxItemState::SET == pArgs->GetItemState( - FN_PARAM_FIELD_FORMAT, false, &pItem )) - nFormat = static_cast<const SfxUInt32Item *>(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); @@ -260,18 +315,23 @@ void SwTextShell::ExecField(SfxRequest &rReq) OUString aPar2; sal_Unicode cSeparator = ' '; - if( SfxItemState::SET == pArgs->GetItemState( FN_PARAM_FIELD_TYPE, - false, &pItem )) - nType = static_cast<SwFieldTypesEnum>(static_cast<const SfxUInt16Item *>(pItem)->GetValue()); - if( SfxItemState::SET == pArgs->GetItemState( FN_PARAM_FIELD_SUBTYPE, - false, &pItem )) - nSubType = static_cast<const SfxUInt16Item *>(pItem)->GetValue(); - if( SfxItemState::SET == pArgs->GetItemState( - FN_PARAM_FIELD_CONTENT, false, &pItem )) - aPar2 = static_cast<const SfxStringItem *>(pItem)->GetValue(); - if( SfxItemState::SET == pArgs->GetItemState( - FN_PARAM_FIELD_FORMAT, false, &pItem )) - nFormat = static_cast<const SfxUInt32Item *>(pItem)->GetValue(); + if( const SfxUInt16Item* pTypeItem = pArgs->GetItemIfSet( FN_PARAM_FIELD_TYPE, + false )) + nType = static_cast<SwFieldTypesEnum>(pTypeItem->GetValue()); + else if (pArgs->GetItemState(FN_PARAM_4, false, &pItem) == SfxItemState::SET) + { + const OUString& rTypeName = static_cast<const SfxStringItem *>(pItem)->GetValue(); + nType = SwFieldTypeFromString(rTypeName); + } + if( const SfxUInt16Item* pSubtypeItem = pArgs->GetItemIfSet( FN_PARAM_FIELD_SUBTYPE, + false )) + nSubType = pSubtypeItem->GetValue(); + if( const SfxStringItem* pContentItem = pArgs->GetItemIfSet( + FN_PARAM_FIELD_CONTENT, false )) + aPar2 = pContentItem->GetValue(); + if( const SfxUInt32Item* pFormatItem = pArgs->GetItemIfSet( + FN_PARAM_FIELD_FORMAT, false )) + nFormat = pFormatItem->GetValue(); if( SfxItemState::SET == pArgs->GetItemState( FN_PARAM_3, false, &pItem )) { @@ -279,17 +339,31 @@ void SwTextShell::ExecField(SfxRequest &rReq) if(!sTmp.isEmpty()) cSeparator = sTmp[0]; } + if (pArgs->GetItemState(FN_PARAM_5, false, &pItem) == SfxItemState::SET) + { + // Wrap the field in the requested container instead of inserting it + // directly at the cursor position. + const OUString& rWrapper = static_cast<const SfxStringItem *>(pItem)->GetValue(); + if (rWrapper == "Footnote") + { + GetShellPtr()->InsertFootnote(OUString()); + } + else if (rWrapper == "Endnote") + { + GetShellPtr()->InsertFootnote(OUString(), /*bEndNote=*/true); + } + } SwInsertField_Data aData(nType, nSubType, aPar1, aPar2, nFormat, GetShellPtr(), cSeparator ); bRes = aFieldMgr.InsertField( aData ); } else { //#i5788# prevent closing of the field dialog while a modal dialog ( Input field dialog ) is active - if(!GetView().GetViewFrame()->IsInModalMode()) + if(!GetView().GetViewFrame().IsInModalMode()) { - SfxViewFrame* pVFrame = GetView().GetViewFrame(); - pVFrame->ToggleChildWindow(FN_INSERT_FIELD); - bRes = pVFrame->GetChildWindow( nSlot ) != nullptr; + SfxViewFrame& rVFrame = GetView().GetViewFrame(); + rVFrame.ToggleChildWindow(FN_INSERT_FIELD); + bRes = rVFrame.GetChildWindow( nSlot ) != nullptr; Invalidate(rReq.GetSlot()); Invalidate(FN_INSERT_FIELD_CTRL); rReq.Ignore(); @@ -301,13 +375,13 @@ void SwTextShell::ExecField(SfxRequest &rReq) case FN_INSERT_REF_FIELD: { - SfxViewFrame* pVFrame = GetView().GetViewFrame(); - if (!pVFrame->HasChildWindow(FN_INSERT_FIELD)) - pVFrame->ToggleChildWindow(FN_INSERT_FIELD); // Show dialog + SfxViewFrame& rVFrame = GetView().GetViewFrame(); + if (!rVFrame.HasChildWindow(FN_INSERT_FIELD)) + rVFrame.ToggleChildWindow(FN_INSERT_FIELD); // Show dialog // Switch Fielddlg at a new TabPage sal_uInt16 nId = SwFieldDlgWrapper::GetChildWindowId(); - SwFieldDlgWrapper *pWrp = static_cast<SwFieldDlgWrapper*>(pVFrame->GetChildWindow(nId)); + SwFieldDlgWrapper *pWrp = static_cast<SwFieldDlgWrapper*>(rVFrame.GetChildWindow(nId)); if (pWrp) pWrp->ShowReferencePage(); rReq.Ignore(); @@ -412,6 +486,18 @@ void SwTextShell::ExecField(SfxRequest &rReq) sText = pTextItem->GetValue(); pMgr->RegisterAnswerText(sText); pWin->ExecuteCommand(nSlot); + + SwPostItField* pLatestPostItField = pMgr->GetLatestPostItField(); + if (pLatestPostItField) + { + // Set the parent postit id of the reply. + pLatestPostItField->SetParentPostItId(pIdItem->GetValue().toUInt32()); + + // If name of the replied comment is empty, we need to set a name in order to connect them in the xml file. + pWin->GeneratePostItName(); // Generates a name if the current name is empty. + + pLatestPostItField->SetParentName(pWin->GetPostItField()->GetName()); + } } } } @@ -630,21 +716,25 @@ void SwTextShell::ExecField(SfxRequest &rReq) break; case FN_INSERT_FLD_DATE : + case FN_INSERT_FLD_DATE_VAR: { nInsertType = SwFieldTypesEnum::Date; + nInsertSubType = nSlot == FN_INSERT_FLD_DATE ? 0 : 1; bIsText = false; // use long date format for Hungarian SwPaM* pCursorPos = rSh.GetCursor(); if( pCursorPos ) { - LanguageType nLang = pCursorPos->GetPoint()->nNode.GetNode().GetTextNode()->GetLang(pCursorPos->GetPoint()->nContent.GetIndex()); + LanguageType nLang = pCursorPos->GetPoint()->GetNode().GetTextNode()->GetLang(pCursorPos->GetPoint()->GetContentIndex()); if (nLang == LANGUAGE_HUNGARIAN) nInsertFormat = rSh.GetNumberFormatter()->GetFormatIndex(NF_DATE_SYSTEM_LONG, nLang); } goto FIELD_INSERT; } case FN_INSERT_FLD_TIME : + case FN_INSERT_FLD_TIME_VAR: nInsertType = SwFieldTypesEnum::Time; + nInsertSubType = nSlot == FN_INSERT_FLD_TIME ? 0 : 1; bIsText = false; goto FIELD_INSERT; case FN_INSERT_FLD_PGNUMBER: @@ -684,26 +774,116 @@ FIELD_INSERT: case FN_INSERT_TEXT_FORMFIELD: { + OUString aFieldType(ODF_FORMTEXT); + const SfxStringItem* pFieldType = rReq.GetArg<SfxStringItem>(FN_PARAM_1); + if (pFieldType) + { + // Allow overwriting the default type. + aFieldType = pFieldType->GetValue(); + } + + OUString aFieldCode; + const SfxStringItem* pFieldCode = rReq.GetArg<SfxStringItem>(FN_PARAM_2); + if (pFieldCode) + { + // Allow specifying a field code/command. + aFieldCode = pFieldCode->GetValue(); + } + + if (rSh.HasReadonlySel()) + { + // Inform the user that the request has been ignored. + auto xInfo = std::make_shared<weld::GenericDialogController>( + GetView().GetFrameWeld(), "modules/swriter/ui/inforeadonlydialog.ui", + "InfoReadonlyDialog"); + weld::DialogController::runAsync(xInfo, [](sal_Int32 /*nResult*/) {}); + break; + } + rSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT_FORM_FIELD, nullptr); SwPaM* pCursorPos = rSh.GetCursor(); if(pCursorPos) { // Insert five En Space into the text field so the field has extent - static const 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)); + static constexpr OUStringLiteral vEnSpaces = u"\u2002\u2002\u2002\u2002\u2002"; + OUString aFieldResult(vEnSpaces); + const SfxStringItem* pFieldResult = rReq.GetArg<SfxStringItem>(FN_PARAM_3); + if (pFieldResult) + { + // Allow specifying a field result / expanded value. + aFieldResult = pFieldResult->GetValue(); + } + + const SfxStringItem* pWrapper = rReq.GetArg<SfxStringItem>(FN_PARAM_4); + if (pWrapper) + { + // Wrap the fieldmark in the requested container instead of inserting it + // directly at the cursor position. + OUString aWrapper = pWrapper->GetValue(); + if (aWrapper == "Footnote") + { + rSh.InsertFootnote(OUString()); + } + else if (aWrapper == "Endnote") + { + // It's important that there is no Start/EndAction() around this, so the + // inner EndAction() triggers a layout update and the cursor can jump to the + // created SwFootnoteFrame. + rSh.InsertFootnote(OUString(), /*bEndNote=*/true); + } + } + + // Don't update the layout after inserting content and before deleting temporary + // text nodes. + rSh.StartAction(); + + // Split node to remember where the start position is. + bool bSuccess = rSh.GetDoc()->getIDocumentContentOperations().SplitNode( + *pCursorPos->GetPoint(), false); if(bSuccess) { + SwPaM aFieldPam(*pCursorPos->GetPoint()); + aFieldPam.Move(fnMoveBackward, GoInContent); + if (pFieldResult) + { + // Paste HTML content. + SwTranslateHelper::PasteHTMLToPaM(rSh, pCursorPos, aFieldResult.toUtf8()); + if (pCursorPos->GetPoint()->GetContentIndex() == 0) + { + // The paste created a last empty text node, remove it. + SwPaM aPam(*pCursorPos->GetPoint()); + aPam.SetMark(); + aPam.Move(fnMoveBackward, GoInContent); + rSh.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(aPam); + } + } + else + { + // Insert default placeholder. + rSh.GetDoc()->getIDocumentContentOperations().InsertString(*pCursorPos, + aFieldResult); + } + // Undo the above SplitNode(). + aFieldPam.SetMark(); + aFieldPam.Move(fnMoveForward, GoInContent); + rSh.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(aFieldPam); + *aFieldPam.GetMark() = *pCursorPos->GetPoint(); + IDocumentMarkAccess* pMarksAccess = rSh.GetDoc()->getIDocumentMarkAccess(); - SwPaM aFieldPam(pCursorPos->GetPoint()->nNode, pCursorPos->GetPoint()->nContent.GetIndex() - ODF_FORMFIELD_DEFAULT_LENGTH, - pCursorPos->GetPoint()->nNode, pCursorPos->GetPoint()->nContent.GetIndex()); - pMarksAccess->makeFieldBookmark(aFieldPam, OUString(), ODF_FORMTEXT, - aFieldPam.Start()); + sw::mark::IFieldmark* pFieldmark = pMarksAccess->makeFieldBookmark( + aFieldPam, OUString(), aFieldType, aFieldPam.Start()); + if (pFieldmark && !aFieldCode.isEmpty()) + { + pFieldmark->GetParameters()->insert( + std::pair<OUString, uno::Any>(ODF_CODE_PARAM, uno::Any(aFieldCode))); + } } + rSh.EndAction(); } rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD, nullptr); - rSh.GetView().GetViewFrame()->GetBindings().Invalidate( SID_UNDO ); + rSh.GetView().GetViewFrame().GetBindings().Invalidate( SID_UNDO ); } break; case FN_INSERT_CHECKBOX_FORMFIELD: @@ -718,7 +898,7 @@ FIELD_INSERT: } rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD, nullptr); - rSh.GetView().GetViewFrame()->GetBindings().Invalidate( SID_UNDO ); + rSh.GetView().GetViewFrame().GetBindings().Invalidate( SID_UNDO ); } break; case FN_INSERT_DROPDOWN_FORMFIELD: @@ -733,7 +913,7 @@ FIELD_INSERT: } rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD, nullptr); - rSh.GetView().GetViewFrame()->GetBindings().Invalidate( SID_UNDO ); + rSh.GetView().GetViewFrame().GetBindings().Invalidate( SID_UNDO ); } break; case FN_INSERT_DATE_FORMFIELD: @@ -749,8 +929,8 @@ FIELD_INSERT: 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()); + SwPaM aFieldPam(pCursorPos->GetPoint()->GetNode(), pCursorPos->GetPoint()->GetContentIndex() - ODF_FORMFIELD_DEFAULT_LENGTH, + pCursorPos->GetPoint()->GetNode(), pCursorPos->GetPoint()->GetContentIndex()); sw::mark::IFieldmark* pFieldBM = pMarksAccess->makeFieldBookmark(aFieldPam, OUString(), ODF_FORMDATE, aFieldPam.Start()); @@ -766,7 +946,498 @@ FIELD_INSERT: } rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD, nullptr); - rSh.GetView().GetViewFrame()->GetBindings().Invalidate( SID_UNDO ); + rSh.GetView().GetViewFrame().GetBindings().Invalidate( SID_UNDO ); + } + break; + case FN_UPDATE_TEXT_FORMFIELDS: + { + // This updates multiple fieldmarks in a document, based on their field name & field command + // prefix. + OUString aFieldType; + const SfxStringItem* pFieldType = rReq.GetArg<SfxStringItem>(FN_PARAM_1); + if (pFieldType) + { + aFieldType = pFieldType->GetValue(); + } + OUString aFieldCommandPrefix; + const SfxStringItem* pFieldCommandPrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_2); + if (pFieldCommandPrefix) + { + aFieldCommandPrefix = pFieldCommandPrefix->GetValue(); + } + uno::Sequence<beans::PropertyValues> aFields; + const SfxUnoAnyItem* pFields = rReq.GetArg<SfxUnoAnyItem>(FN_PARAM_3); + if (pFields) + { + pFields->GetValue() >>= aFields; + } + + rSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::UPDATE_FORM_FIELDS, nullptr); + rSh.StartAction(); + + IDocumentMarkAccess* pMarkAccess = rSh.GetDoc()->getIDocumentMarkAccess(); + sal_Int32 nFieldIndex = 0; + for (auto it = pMarkAccess->getFieldmarksBegin(); it != pMarkAccess->getFieldmarksEnd(); ++it) + { + auto pFieldmark = dynamic_cast<sw::mark::IFieldmark*>(*it); + assert(pFieldmark); + if (pFieldmark->GetFieldname() != aFieldType) + { + continue; + } + + auto itParam = pFieldmark->GetParameters()->find(ODF_CODE_PARAM); + if (itParam == pFieldmark->GetParameters()->end()) + { + continue; + } + + OUString aCommand; + itParam->second >>= aCommand; + if (!aCommand.startsWith(aFieldCommandPrefix)) + { + continue; + } + + if (aFields.getLength() <= nFieldIndex) + { + continue; + } + + comphelper::SequenceAsHashMap aMap(aFields[nFieldIndex++]); + itParam->second = aMap["FieldCommand"]; + SwPaM aPaM(pFieldmark->GetMarkPos(), pFieldmark->GetOtherMarkPos()); + aPaM.Normalize(); + // Skip field start & separator. + aPaM.GetPoint()->AdjustContent(2); + // Skip field end. + aPaM.GetMark()->AdjustContent(-1); + rSh.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(aPaM); + OUString aFieldResult; + aMap["FieldResult"] >>= aFieldResult; + SwTranslateHelper::PasteHTMLToPaM(rSh, &aPaM, aFieldResult.toUtf8()); + } + + rSh.EndAction(); + rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::UPDATE_FORM_FIELDS, nullptr); + } + break; + case FN_DELETE_TEXT_FORMFIELDS: + { + // This deletes all fieldmarks that match the provided field type & field command prefix. + OUString aFieldType; + const SfxStringItem* pFieldType = rReq.GetArg<SfxStringItem>(FN_PARAM_1); + if (pFieldType) + { + aFieldType = pFieldType->GetValue(); + } + OUString aFieldCommandPrefix; + const SfxStringItem* pFieldCommandPrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_2); + if (pFieldCommandPrefix) + { + aFieldCommandPrefix = pFieldCommandPrefix->GetValue(); + } + rSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::DELETE_FORM_FIELDS, nullptr); + rSh.StartAction(); + + IDocumentMarkAccess* pMarkAccess = rSh.GetDoc()->getIDocumentMarkAccess(); + std::vector<sw::mark::IMark*> aRemovals; + for (auto it = pMarkAccess->getFieldmarksBegin(); it != pMarkAccess->getFieldmarksEnd(); ++it) + { + auto pFieldmark = dynamic_cast<sw::mark::IFieldmark*>(*it); + assert(pFieldmark); + if (pFieldmark->GetFieldname() != aFieldType) + { + continue; + } + + if (!aFieldCommandPrefix.isEmpty()) + { + auto itParam = pFieldmark->GetParameters()->find(ODF_CODE_PARAM); + if (itParam == pFieldmark->GetParameters()->end()) + { + continue; + } + + OUString aCommand; + itParam->second >>= aCommand; + if (!aCommand.startsWith(aFieldCommandPrefix)) + { + continue; + } + } + + aRemovals.push_back(pFieldmark); + } + + for (const auto& pMark : aRemovals) + { + pMarkAccess->deleteMark(pMark); + } + + rSh.EndAction(); + rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::DELETE_FORM_FIELDS, nullptr); + } + break; + case FN_PGNUMBER_WIZARD: + { + SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); + VclPtr<AbstractSwPageNumberDlg> pDlg( + pFact->CreateSwPageNumberDlg(GetView().GetFrameWeld())); + auto pShell = GetShellPtr(); + + const SwPageDesc& rCurrDesc = rSh.GetPageDesc(rSh.GetCurPageDesc()); + pDlg->SetPageNumberType(rCurrDesc.GetNumType().GetNumberingType()); + + pDlg->StartExecuteAsync([pShell, &rSh, pDlg](int nResult) { + if ( nResult == RET_OK ) + { + auto rDoc = rSh.GetDoc(); + + rSh.LockView(true); + rSh.StartAllAction(); + rSh.SwCursorShell::Push(); + rDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT_PAGE_NUMBER, nullptr); + + const size_t nPageDescIndex = rSh.GetCurPageDesc(); + const SwPageDesc& rDesc = rSh.GetPageDesc(nPageDescIndex); + const bool bHeader = !pDlg->GetPageNumberPosition(); + const bool bHeaderAlreadyOn = rDesc.GetMaster().GetHeader().IsActive(); + const bool bFooterAlreadyOn = rDesc.GetMaster().GetFooter().IsActive(); + const bool bIsSinglePage = rDesc.GetFollow() != &rDesc; + const size_t nMirrorPagesNeeded = rDesc.IsFirstShared() ? 2 : 3; + const OUString sBookmarkName = OUString::Concat("PageNumWizard_") + + (bHeader ? "HEADER" : "FOOTER") + "_" + rDesc.GetName(); + IDocumentMarkAccess& rIDMA = *rSh.getIDocumentMarkAccess(); + + // Allow wizard to be re-run: delete previously wizard-inserted page number. + // Try before creating non-shared header: avoid copying ODD bookmark onto EVEN page. + IDocumentMarkAccess::const_iterator_t ppMark = rIDMA.findMark( + sBookmarkName + OUString::number(rSh.GetVirtPageNum())); + if (ppMark != rIDMA.getAllMarksEnd() && *ppMark) + { + SwPaM aDeleteOldPageNum((*ppMark)->GetMarkStart(), (*ppMark)->GetMarkEnd()); + rDoc->getIDocumentContentOperations().DeleteAndJoin(aDeleteOldPageNum); + } + + SwPageDesc aNewDesc(rDesc); + bool bChangePageDesc = false; + if (pDlg->GetPageNumberType() != aNewDesc.GetNumType().GetNumberingType()) + { + bChangePageDesc = true; + SvxNumberType aNewType(rDesc.GetNumType()); + aNewType.SetNumberingType(pDlg->GetPageNumberType()); + aNewDesc.SetNumType(aNewType); + } + + // Insert header/footer + if ((bHeader && !bHeaderAlreadyOn) || (!bHeader && !bFooterAlreadyOn)) + { + bChangePageDesc = true; + SwFrameFormat &rMaster = aNewDesc.GetMaster(); + if (bHeader) + rMaster.SetFormatAttr(SwFormatHeader(/*On=*/true)); + else + rMaster.SetFormatAttr(SwFormatFooter(/*On=*/true)); + + // Init copied from ChangeHeaderOrFooter: keep in sync + constexpr tools::Long constTwips_5mm = o3tl::toTwips(5, o3tl::Length::mm); + const SvxULSpaceItem aUL(bHeader ? 0 : constTwips_5mm, + bHeader ? constTwips_5mm : 0, + RES_UL_SPACE); + const XFillStyleItem aFill(drawing::FillStyle_NONE); + SwFrameFormat& rFormat + = bHeader + ? const_cast<SwFrameFormat&>(*rMaster.GetHeader().GetHeaderFormat()) + : const_cast<SwFrameFormat&>(*rMaster.GetFooter().GetFooterFormat()); + rFormat.SetFormatAttr(aUL); + rFormat.SetFormatAttr(aFill); + + // Might as well turn on margin mirroring too - if appropriate + if (pDlg->GetMirrorOnEvenPages() && !bHeaderAlreadyOn && !bFooterAlreadyOn + && !bIsSinglePage + && (aNewDesc.ReadUseOn() & UseOnPage::Mirror) == UseOnPage::All) + { + aNewDesc.WriteUseOn(rDesc.ReadUseOn() | UseOnPage::Mirror); + } + } + + const bool bCreateMirror = !bIsSinglePage && pDlg->GetMirrorOnEvenPages() + && nMirrorPagesNeeded <= rSh.GetPageCnt(); + if (bCreateMirror) + { + // Use different left/right header/footer + if ((bHeader && rDesc.IsHeaderShared()) || (!bHeader && rDesc.IsFooterShared())) + { + bChangePageDesc = true; + if (bHeader) + aNewDesc.ChgHeaderShare(/*Share=*/false); + else + aNewDesc.ChgFooterShare(/*Share=*/false); + } + } + + if (bChangePageDesc) + rSh.ChgPageDesc(nPageDescIndex, aNewDesc); + + // Go to the header or footer insert position + bool bInHF = false; + bool bSkipMirror = true; + size_t nEvenPage = 0; + if (bCreateMirror || !rSh.GetCurrFrame()) + { + // Come here if Currframe can't be found, otherwise Goto*Text will crash. + // Get*PageNum will also be invalid (0), so we have no idea where we are. + // (Since not asking for mirror, the likelihood is that the bHeader is shared, + // in which case it doesn't matter anyway, and we just hope for the best.) + // Read the code in this block assuming that bCreateMirror is true. + + // There are enough pages that there probably is a valid odd page. + // However, that is not guaranteed: perhaps the page style switched, + // or a blank page was forced, or some other complexity. + bInHF = rSh.SetCursorInHdFt(nPageDescIndex, bHeader, /*Even=*/true); + if (bInHF) + { + // Remember valid EVEN page. Mirror it if also a valid ODD or FIRST page + nEvenPage = rSh.GetVirtPageNum(); + assert (nEvenPage && "couldn't find page number. Use a bool instead"); + } + + bInHF = rSh.SetCursorInHdFt(nPageDescIndex, bHeader, /*Even=*/false); + if (bInHF && nEvenPage) + { + // Even though the cursor may be on a FIRST page, + // the user requested mirrored pages, and we have both ODD and EVEN, + // so set page numbers on these two pages, and leave FIRST alone. + bSkipMirror = false; + } + if (!bInHF) + { + // no ODD page, look for FIRST page + bInHF = rSh.SetCursorInHdFt(nPageDescIndex, bHeader, false, /*First=*/true); + if (bInHF && nEvenPage) + { + // Unlikely but valid situation: EVEN and FIRST pages, but no ODD page. + // In this case, the first header gets the specified page number + // and the even header is mirrored, with an empty odd header, + // as the user (somewhat) requested. + bSkipMirror = false; + } + } + assert((bInHF || nEvenPage) && "Impossible - why couldn't the move happen?"); + assert((bInHF || nEvenPage == rSh.GetVirtPageNum()) && "Unexpected move"); + } + else + { + if (bHeader) + bInHF = rSh.GotoHeaderText(); + else + bInHF = rSh.GotoFooterText(); + assert(bInHF && "shouldn't have a problem going to text when no mirroring"); + } + + // Allow wizard to be re-run: delete previously wizard-inserted page number. + // Now that the cursor may have moved to a different page, try delete again. + ppMark = rIDMA.findMark(sBookmarkName + OUString::number(rSh.GetVirtPageNum())); + if (ppMark != rIDMA.getAllMarksEnd() && *ppMark) + { + SwPaM aDeleteOldPageNum((*ppMark)->GetMarkStart(), (*ppMark)->GetMarkEnd()); + rDoc->getIDocumentContentOperations().DeleteAndJoin(aDeleteOldPageNum); + } + + SwTextNode* pTextNode = rSh.GetCursor()->GetPoint()->GetNode().GetTextNode(); + + // Insert new line if there is already text in header/footer + if (pTextNode && !pTextNode->GetText().isEmpty()) + { + rDoc->getIDocumentContentOperations().SplitNode(*rSh.GetCursor()->GetPoint(), false); + + // Go back to start of header/footer + if (bHeader) + rSh.GotoHeaderText(); + else + rSh.GotoFooterText(); + } + + // Set alignment for the new line + switch (pDlg->GetPageNumberAlignment()) + { + case 0: + { + SvxAdjustItem aAdjustItem(SvxAdjust::Left, RES_PARATR_ADJUST); + rSh.SetAttrItem(aAdjustItem); + break; + } + case 1: + { + SvxAdjustItem aAdjustItem(SvxAdjust::Center, RES_PARATR_ADJUST); + rSh.SetAttrItem(aAdjustItem); + break; + } + case 2: + { + SvxAdjustItem aAdjustItem(SvxAdjust::Right, RES_PARATR_ADJUST); + rSh.SetAttrItem(aAdjustItem); + break; + } + } + + sal_Int32 nStartContentIndex = rSh.GetCursor()->Start()->GetContentIndex(); + assert(!nStartContentIndex && "earlier split node if not empty, but not zero?"); + + // Insert page number + SwFieldMgr aMgr(pShell); + SwInsertField_Data aData(SwFieldTypesEnum::PageNumber, 0, + OUString(), OUString(), SVX_NUM_PAGEDESC); + aMgr.InsertField(aData); + if (pDlg->GetIncludePageTotal()) + { + rDoc->getIDocumentContentOperations().InsertString(*rSh.GetCursor(), " / "); + SwInsertField_Data aPageTotalData(SwFieldTypesEnum::DocumentStatistics, DS_PAGE, + OUString(), OUString(), SVX_NUM_PAGEDESC); + aMgr.InsertField(aPageTotalData); + } + + // Mark inserted fields with a bookmark - so it can be found/removed if re-run + SwPaM aNewBookmarkPaM(*rSh.GetCursor()->Start()); + aNewBookmarkPaM.SetMark(); + assert(aNewBookmarkPaM.GetPointContentNode() && "only SetContent on content node"); + aNewBookmarkPaM.Start()->SetContent(nStartContentIndex); + rIDMA.makeMark(aNewBookmarkPaM, + sBookmarkName + OUString::number(rSh.GetVirtPageNum()), + IDocumentMarkAccess::MarkType::BOOKMARK, + sw::mark::InsertMode::New); + + // Mirror on the even pages + if (!bSkipMirror && bCreateMirror + && rSh.SetCursorInHdFt(nPageDescIndex, bHeader, /*Even=*/true)) + { + assert(nEvenPage && "what? no even page and yet we got here?"); + ppMark = rIDMA.findMark(sBookmarkName + OUString::number(rSh.GetVirtPageNum())); + if (ppMark != rIDMA.getAllMarksEnd() && *ppMark) + { + SwPaM aDeleteOldPageNum((*ppMark)->GetMarkStart(), (*ppMark)->GetMarkEnd()); + rDoc->getIDocumentContentOperations().DeleteAndJoin(aDeleteOldPageNum); + } + + pTextNode = rSh.GetCursor()->GetPoint()->GetNode().GetTextNode(); + + // Insert new line if there is already text in header/footer + if (pTextNode && !pTextNode->GetText().isEmpty()) + { + rDoc->getIDocumentContentOperations().SplitNode( + *rSh.GetCursor()->GetPoint(), false); + // Go back to start of header/footer + rSh.SetCursorInHdFt(nPageDescIndex, bHeader, /*Even=*/true); + } + + // mirror the adjustment + assert(pDlg->GetPageNumberAlignment() != 1 && "cannot have Center and bMirror"); + SvxAdjust eAdjust = SvxAdjust::Left; + if (!pDlg->GetPageNumberAlignment()) + eAdjust = SvxAdjust::Right; + SvxAdjustItem aMirrorAdjustItem(eAdjust, RES_PARATR_ADJUST); + rSh.SetAttrItem(aMirrorAdjustItem); + + nStartContentIndex = rSh.GetCursor()->Start()->GetContentIndex(); + + // Insert page number + SwFieldMgr aEvenMgr(pShell); + aEvenMgr.InsertField(aData); + if (pDlg->GetIncludePageTotal()) + { + rDoc->getIDocumentContentOperations().InsertString(*rSh.GetCursor(), " / "); + SwInsertField_Data aPageTotalData(SwFieldTypesEnum::DocumentStatistics, + DS_PAGE, OUString(), OUString(), + SVX_NUM_PAGEDESC); + aMgr.InsertField(aPageTotalData); + } + + // Mark inserted fields with a bookmark - so it can be found/removed if re-run + SwPaM aNewEvenBookmarkPaM(*rSh.GetCursor()->Start()); + aNewEvenBookmarkPaM.SetMark(); + aNewEvenBookmarkPaM.Start()->SetContent(nStartContentIndex); + rIDMA.makeMark(aNewEvenBookmarkPaM, + sBookmarkName + OUString::number(rSh.GetVirtPageNum()), + IDocumentMarkAccess::MarkType::BOOKMARK, + sw::mark::InsertMode::New); + } + + rSh.SwCursorShell::Pop(SwCursorShell::PopMode::DeleteCurrent); + rSh.EndAllAction(); + rSh.LockView(false); + rDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_PAGE_NUMBER, nullptr); + } + pDlg->disposeOnce(); + }); + rReq.Done(); + } + break; + case FN_UPDATE_TEXT_FORMFIELD: + { + // This updates a single fieldmark under the current cursor. + OUString aFieldType; + const SfxStringItem* pFieldType = rReq.GetArg<SfxStringItem>(FN_PARAM_1); + if (pFieldType) + { + aFieldType = pFieldType->GetValue(); + } + OUString aFieldCommandPrefix; + const SfxStringItem* pFieldCommandPrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_2); + if (pFieldCommandPrefix) + { + aFieldCommandPrefix = pFieldCommandPrefix->GetValue(); + } + uno::Sequence<beans::PropertyValue> aField; + const SfxUnoAnyItem* pFields = rReq.GetArg<SfxUnoAnyItem>(FN_PARAM_3); + if (pFields) + { + pFields->GetValue() >>= aField; + } + + IDocumentMarkAccess& rIDMA = *rSh.getIDocumentMarkAccess(); + SwPosition& rCursor = *rSh.GetCursor()->GetPoint(); + sw::mark::IFieldmark* pFieldmark = rIDMA.getInnerFieldmarkFor(rCursor); + if (!pFieldmark) + { + break; + } + + if (pFieldmark->GetFieldname() != aFieldType) + { + break; + } + + auto itParam = pFieldmark->GetParameters()->find(ODF_CODE_PARAM); + if (itParam == pFieldmark->GetParameters()->end()) + { + break; + } + + OUString aCommand; + itParam->second >>= aCommand; + if (!aCommand.startsWith(aFieldCommandPrefix)) + { + break; + } + + rSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::UPDATE_FORM_FIELD, nullptr); + rSh.StartAction(); + comphelper::SequenceAsHashMap aMap(aField); + itParam->second = aMap["FieldCommand"]; + SwPaM aPaM(pFieldmark->GetMarkPos(), pFieldmark->GetOtherMarkPos()); + aPaM.Normalize(); + // Skip field start & separator. + aPaM.GetPoint()->AdjustContent(2); + // Skip field end. + aPaM.GetMark()->AdjustContent(-1); + rSh.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(aPaM); + OUString aFieldResult; + aMap["FieldResult"] >>= aFieldResult; + SwTranslateHelper::PasteHTMLToPaM(rSh, &aPaM, aFieldResult.toUtf8()); + + rSh.EndAction(); + rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::UPDATE_FORM_FIELD, nullptr); } break; default: @@ -803,7 +1474,7 @@ void SwTextShell::StateField( SfxItemSet &rSet ) rSet.InvalidateItem( FN_DELETE_COMMENT ); rSet.InvalidateItem( FN_HIDE_NOTE ); } - // tdf#137568 do not offer comment formating, if no comments are present + // tdf#137568 do not offer comment formatting, if no comments are present if (!pPostItMgr || !pPostItMgr->HasNotes()) rSet.DisableItem( FN_FORMAT_ALL_NOTES ); } @@ -832,6 +1503,16 @@ void SwTextShell::StateField( SfxItemSet &rSet ) } break; + case FN_UPDATE_SEL_FIELD: + { + pField = rSh.GetCurField(); + + if (!pField) + rSet.DisableItem( nWhich ); + } + + break; + case FN_EXECUTE_MACROFIELD: { if(!bGetField) @@ -852,11 +1533,11 @@ void SwTextShell::StateField( SfxItemSet &rSet ) } else { - SfxViewFrame* pVFrame = GetView().GetViewFrame(); + SfxViewFrame& rVFrame = 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))); + if(!rVFrame.IsInModalMode() && + rVFrame.KnowsChildWindow(FN_INSERT_FIELD) && !rVFrame.HasChildWindow(FN_INSERT_FIELD_DATA_ONLY) ) + rSet.Put(SfxBoolItem( FN_INSERT_FIELD, rVFrame.HasChildWindow(nWhich))); else rSet.DisableItem(FN_INSERT_FIELD); } @@ -865,8 +1546,8 @@ void SwTextShell::StateField( SfxItemSet &rSet ) case FN_INSERT_REF_FIELD: { - SfxViewFrame* pVFrame = GetView().GetViewFrame(); - if ( !pVFrame->KnowsChildWindow(FN_INSERT_FIELD) + SfxViewFrame& rVFrame = GetView().GetViewFrame(); + if ( !rVFrame.KnowsChildWindow(FN_INSERT_FIELD) || rSh.CursorInsideInputField() ) { rSet.DisableItem(FN_INSERT_REF_FIELD); @@ -881,7 +1562,7 @@ void SwTextShell::StateField( SfxItemSet &rSet ) } else { - rSet.Put(SfxBoolItem( nWhich, GetView().GetViewFrame()->HasChildWindow(FN_INSERT_FIELD))); + rSet.Put(SfxBoolItem( nWhich, GetView().GetViewFrame().HasChildWindow(FN_INSERT_FIELD))); } break; @@ -913,8 +1594,11 @@ void SwTextShell::StateField( SfxItemSet &rSet ) { 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() ) + // tdf#86188, tdf#135794: Allow disabling comment insertion + // on footnote/endnote/header/frames for better OOXML interoperability + else if (!officecfg::Office::Compatibility::View::AllowCommentsInFootnotes::get() && + (rSh.IsCursorInFootnote() || rSh.IsInHeaderFooter() || + rSh.GetCurrFlyFrame(/*bCalcFrame=*/false))) { rSet.DisableItem(nWhich); } @@ -948,13 +1632,12 @@ void SwTextShell::StateField( SfxItemSet &rSet ) { // Check whether we are in a text form field SwPosition aCursorPos(*rSh.GetCursor()->GetPoint()); - sw::mark::IFieldmark* pFieldBM = GetShell().getIDocumentMarkAccess()->getFieldmarkFor(aCursorPos); + sw::mark::IFieldmark* pFieldBM = GetShell().getIDocumentMarkAccess()->getInnerFieldmarkFor(aCursorPos); if ((!pFieldBM || pFieldBM->GetFieldname() != ODF_FORMTEXT) - && aCursorPos.nContent.GetIndex() > 0) + && aCursorPos.GetContentIndex() > 0) { - SwPosition aPos(aCursorPos); - --aPos.nContent; - pFieldBM = GetShell().getIDocumentMarkAccess()->getFieldmarkFor(aPos); + SwPosition aPos(*aCursorPos.GetContentNode(), aCursorPos.GetContentIndex() - 1); + pFieldBM = GetShell().getIDocumentMarkAccess()->getInnerFieldmarkFor(aPos); } if (pFieldBM && pFieldBM->GetFieldname() == ODF_FORMTEXT && (aCursorPos > pFieldBM->GetMarkStart() && aCursorPos < pFieldBM->GetMarkEnd() )) @@ -974,7 +1657,8 @@ void SwTextShell::InsertHyperlink(const SvxHyperlinkItem& rHlnkItem) const OUString& rName = rHlnkItem.GetName(); const OUString& rURL = rHlnkItem.GetURL(); const OUString& rTarget = rHlnkItem.GetTargetFrame(); - sal_uInt16 nType = static_cast<sal_uInt16>(rHlnkItem.GetInsertMode()); + const OUString& rReplacementText = rHlnkItem.GetReplacementText(); + sal_uInt16 nType = o3tl::narrowing<sal_uInt16>(rHlnkItem.GetInsertMode()); nType &= ~HLINK_HTMLMODE; const SvxMacroTableDtor* pMacroTable = rHlnkItem.GetMacroTable(); @@ -984,11 +1668,10 @@ void SwTextShell::InsertHyperlink(const SvxHyperlinkItem& rHlnkItem) return; rSh.StartAction(); - SfxItemSet aSet(GetPool(), svl::Items<RES_TXTATR_INETFMT, RES_TXTATR_INETFMT>{}); + SfxItemSetFixed<RES_TXTATR_INETFMT, RES_TXTATR_INETFMT> aSet(GetPool()); rSh.GetCurAttr( aSet ); - const SfxPoolItem* pItem; - if(SfxItemState::SET == aSet.GetItemState(RES_TXTATR_INETFMT, false, &pItem)) + if(SfxItemState::SET == aSet.GetItemState(RES_TXTATR_INETFMT, false)) { // Select links rSh.SwCursorShell::SelectTextAttr(RES_TXTATR_INETFMT, false); @@ -1013,7 +1696,19 @@ void SwTextShell::InsertHyperlink(const SvxHyperlinkItem& rHlnkItem) aINetFormat.SetMacro(SvMacroItemId::OnMouseOut, *pMacro); } rSh.SttSelect(); - rSh.InsertURL( aINetFormat, rName, true ); + // inserting mention + if (comphelper::LibreOfficeKit::isActive() && !rReplacementText.isEmpty()) + { + SwPaM* pCursorPos = rSh.GetCursor(); + // move cursor backwards to select @mention + for(int i=0; i < rReplacementText.getLength(); i++) + pCursorPos->Move(fnMoveBackward); + rSh.InsertURL( aINetFormat, rName, false ); + } + else + { + rSh.InsertURL( aINetFormat, rName, true ); + } rSh.EndSelect(); } break; diff --git a/sw/source/uibase/shells/textglos.cxx b/sw/source/uibase/shells/textglos.cxx index b6aee47f7c55..7faa1aa58081 100644 --- a/sw/source/uibase/shells/textglos.cxx +++ b/sw/source/uibase/shells/textglos.cxx @@ -20,6 +20,7 @@ #include <sfx2/request.hxx> #include <svl/eitem.hxx> #include <svl/stritem.hxx> +#include <osl/diagnose.h> #include <view.hxx> #include <cmdid.h> @@ -47,8 +48,7 @@ void SwTextShell::ExecGlossary(SfxRequest &rReq) switch( nSlot ) { case FN_GLOSSARY_DLG: - pGlosHdl->GlossaryDlg(); - bUpdateList = true; + pGlosHdl->GlossaryDlg(); // async dialog rReq.Ignore(); break; case FN_EXPAND_GLOSSARY: diff --git a/sw/source/uibase/shells/textidx.cxx b/sw/source/uibase/shells/textidx.cxx index b577547347e6..35642a73f198 100644 --- a/sw/source/uibase/shells/textidx.cxx +++ b/sw/source/uibase/shells/textidx.cxx @@ -22,6 +22,7 @@ #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> @@ -34,35 +35,121 @@ #include <toxmgr.hxx> #include <swabstdlg.hxx> +#include <ndtxt.hxx> +#include <fmtfld.hxx> +#include <IDocumentFieldsAccess.hxx> + void SwTextShell::ExecIdx(SfxRequest const &rReq) { - const SfxItemSet *pArgs = rReq.GetArgs(); + const SfxItemSet* pArgs = rReq.GetArgs(); const SfxPoolItem* pItem = nullptr; const sal_uInt16 nSlot = rReq.GetSlot(); - if(pArgs) - pArgs->GetItemState(nSlot, false, &pItem ); + if (pArgs) + pArgs->GetItemState(nSlot, false, &pItem); - SfxViewFrame* pVFrame = GetView().GetViewFrame(); + SfxViewFrame& rVFrame = GetView().GetViewFrame(); - switch( nSlot ) + switch (nSlot) { - case FN_EDIT_AUTH_ENTRY_DLG : + case FN_EDIT_AUTH_ENTRY_DLG: { - SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); - ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSwAutoMarkDialog(GetView().GetFrameWeld(), GetShell())); - pDlg->Execute(); + SwWrtShell& rShell = GetShell(); + + const bool bWasViewLocked = rShell.IsViewLocked(); + rShell.LockView(true); + + if (const SwField* const pCurrentField = rShell.GetCurField(); + !rShell.HasReadonlySel() && pCurrentField != nullptr + && pCurrentField->GetTyp()->Which() == SwFieldIds::TableOfAuthorities) + { + // Since the cursor is on a bibliography mark (e.g. "[1]"), open the edit dialog as usual + SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); + ScopedVclPtr<VclAbstractDialog> pDlg( + pFact->CreateSwAutoMarkDialog(GetView().GetFrameWeld(), rShell)); + pDlg->Execute(); + } + else if (const SwTOXBase* const pCurrentTOX = rShell.GetCurTOX(); + pCurrentTOX != nullptr && pCurrentTOX->GetType() == TOX_AUTHORITIES + && (rShell.GetCursor()->GetPoint()->GetNode() + .FindSectionNode()->GetSection().GetType() + == SectionType::ToxContent)) + { + // Since the cursor is in the bibliography table, find the first mark that would match the given row + const SwNode* const pTableRowNode = &rShell.GetCursor()->GetPoint()->GetNode(); + const OUString& rTableRowText + = static_cast<const SwTextNode*>(pTableRowNode)->GetText(); + + const SwFieldType* pAuthField + = rShell.GetDoc()->getIDocumentFieldsAccess().GetFieldType( + SwFieldIds::TableOfAuthorities, OUString(), false); + + if (pAuthField) + { + bool bMatchingMarkFound = false; + { + std::vector<SwFormatField*> vFields; + pAuthField->GatherFields(vFields); + for (auto pFormatField : vFields) + { + if (const SwField* pIteratedField = nullptr; + pFormatField != nullptr + && (pIteratedField = pFormatField->GetField()) != nullptr + && (pIteratedField->GetTyp()->Which() + == SwFieldIds::TableOfAuthorities)) + { + OUString sMarkText + = static_cast<const SwAuthorityField*>(pIteratedField) + ->GetAuthority(rShell.GetLayout(), + &pCurrentTOX->GetTOXForm()); + + if (sMarkText == rTableRowText) + { + // Since the text generated from the mark would match the given row + // move cursor to it, set bMatchingMarkFound and break + rShell.GotoFormatField(*pFormatField); + bMatchingMarkFound = true; + break; + } + } + } + } + + if (bMatchingMarkFound) + { + // Since matching mark has been found and cursor has been moved to it, + // open the edit dialog + SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); + ScopedVclPtr<VclAbstractDialog> pDlg( + pFact->CreateSwAutoMarkDialog(GetView().GetFrameWeld(), rShell)); + pDlg->Execute(); + + // Refresh TOX + rShell.GetCursor_()->GetPoint()->Assign(*pTableRowNode); + rShell.UpdateTableOf(*pCurrentTOX); + } + else + { + // I think this ideally should be a pop-up warning, right? + SAL_WARN("sw", "No matching bibliography mark found. " + "This feature is only guaranteed to work if the bibliography table is up to date."); + } + } + } + + if (!bWasViewLocked) + rShell.LockView(false); } break; case FN_INSERT_AUTH_ENTRY_DLG: { // no BASIC support - pVFrame->ToggleChildWindow(FN_INSERT_AUTH_ENTRY_DLG); + rVFrame.ToggleChildWindow(FN_INSERT_AUTH_ENTRY_DLG); Invalidate(rReq.GetSlot()); } break; case FN_INSERT_IDX_ENTRY_DLG: { - pVFrame->ToggleChildWindow(FN_INSERT_IDX_ENTRY_DLG); + rVFrame.ToggleChildWindow(FN_INSERT_IDX_ENTRY_DLG); Invalidate(rReq.GetSlot()); } break; @@ -91,16 +178,14 @@ void SwTextShell::ExecIdx(SfxRequest const &rReq) } case FN_INSERT_MULTI_TOX: { - SfxItemSet aSet( - GetPool(), - svl::Items< + 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>{}); + FN_PARAM_TOX_TYPE, FN_PARAM_TOX_TYPE> aSet( GetPool() ); SwWrtShell& rSh = GetShell(); SwRect aRect; rSh.CalcBoundRect(aRect, RndStdIds::FLY_AS_CHAR); @@ -151,11 +236,11 @@ void SwTextShell::ExecIdx(SfxRequest const &rReq) void SwTextShell::GetIdxState(SfxItemSet &rSet) { SwWrtShell& rSh = GetShell(); - SfxViewFrame* pVFrame = GetView().GetViewFrame(); + SfxViewFrame& rVFrame = GetView().GetViewFrame(); SwInsertIdxMarkWrapper *pIdxMrk = static_cast<SwInsertIdxMarkWrapper*>( - pVFrame->GetChildWindow(FN_INSERT_IDX_ENTRY_DLG)); + rVFrame.GetChildWindow(FN_INSERT_IDX_ENTRY_DLG)); - SfxChildWindow* pAuthMark = pVFrame->GetChildWindow(FN_INSERT_AUTH_ENTRY_DLG); + SfxChildWindow* pAuthMark = rVFrame.GetChildWindow(FN_INSERT_AUTH_ENTRY_DLG); const bool bHtmlMode = 0 != ::GetHtmlMode( GetView().GetDocShell() ); const SwTOXBase* pBase = nullptr; @@ -170,7 +255,10 @@ void SwTextShell::GetIdxState(SfxItemSet &rSet) } rSet.DisableItem( FN_EDIT_IDX_ENTRY_DLG ); - rSet.DisableItem( FN_EDIT_AUTH_ENTRY_DLG ); + if(pBase == nullptr // tdf#72955: Hide the "Bibliography Entry" command if there is no TOX in the selection + || pBase->GetType() != TOX_AUTHORITIES // or if it is not a bibliography table + || (rSh.GetCursor()->GetPoint()->GetNode().FindSectionNode()->GetSection().GetType() != SectionType::ToxContent)) // or if it's the heading + rSet.DisableItem(FN_EDIT_AUTH_ENTRY_DLG); if(!pIdxMrk) rSet.DisableItem( FN_INSERT_IDX_ENTRY_DLG ); @@ -197,7 +285,7 @@ void SwTextShell::GetIdxState(SfxItemSet &rSet) bool bEnableEdit = true; bool bInReadonly = rSh.HasReadonlySel(); - if( rSh.HasSelection() || bInReadonly) + if(bInReadonly) bEnableEdit = false; else { diff --git a/sw/source/uibase/shells/textsh.cxx b/sw/source/uibase/shells/textsh.cxx index daa913816a63..93020de3bad2 100644 --- a/sw/source/uibase/shells/textsh.cxx +++ b/sw/source/uibase/shells/textsh.cxx @@ -44,6 +44,7 @@ #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> @@ -79,8 +80,6 @@ #include <SwRewriter.hxx> #include <SwCapObjType.hxx> -using namespace ::com::sun::star; - #include <svx/svxdlg.hxx> #include <swabstdlg.hxx> #include <IDocumentDrawModelAccess.hxx> @@ -90,24 +89,29 @@ using namespace ::com::sun::star; #include <com/sun/star/ui/dialogs/DialogClosedEvent.hpp> #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp> #include <IDocumentUndoRedo.hxx> +#include <formatcontentcontrol.hxx> + +using namespace ::com::sun::star; SFX_IMPL_INTERFACE(SwTextShell, SwBaseShell) IMPL_STATIC_LINK( SwTextShell, DialogClosedHdl, css::ui::dialogs::DialogClosedEvent*, pEvent, void ) { - SwView* pView = ::GetActiveView(); - SwWrtShell& rWrtShell = pView->GetWrtShell(); - - sal_Int16 nDialogRet = pEvent->DialogResult; - if( nDialogRet == ui::dialogs::ExecutableDialogResults::CANCEL ) + if (SwView* pView = GetActiveView()) { - rWrtShell.Undo(); - rWrtShell.GetIDocumentUndoRedo().ClearRedo(); - } - else - { - OSL_ENSURE( nDialogRet == ui::dialogs::ExecutableDialogResults::OK, - "dialog execution failed" ); + 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" ); + } } } @@ -163,7 +167,8 @@ void SwTextShell::ExecInsert(SfxRequest &rReq) && pACorr->IsAutoCorrFlag( ACFlags::CapitalStartSentence | ACFlags::CapitalStartWord | ACFlags::AddNonBrkSpace | ACFlags::ChgOrdinalNumber | ACFlags::TransliterateRTL | - ACFlags::ChgToEnEmDash | ACFlags::SetINetAttr | ACFlags::Autocorrect ) ) + ACFlags::ChgToEnEmDash | ACFlags::SetINetAttr | ACFlags::Autocorrect | + ACFlags::SetDOIAttr ) ) { rSh.AutoCorrect( *pACorr, cIns ); } @@ -177,7 +182,7 @@ void SwTextShell::ExecInsert(SfxRequest &rReq) 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_ZWNBSP : + case SID_INSERT_WJ : case SID_INSERT_ZWSP: { sal_Unicode cIns = 0; @@ -186,7 +191,7 @@ void SwTextShell::ExecInsert(SfxRequest &rReq) 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_ZWNBSP: cIns = CHAR_ZWNBSP; break; + case SID_INSERT_WJ: cIns = CHAR_WJ; break; case FN_INSERT_NNBSP: cIns = CHAR_NNBSP; break; } rSh.Insert( OUString( cIns ) ); @@ -195,7 +200,7 @@ void SwTextShell::ExecInsert(SfxRequest &rReq) case FN_INSERT_BREAK: { - if( !rSh.CursorInsideInputField() ) + if (!rSh.CursorInsideInputField() && !rSh.CursorInsideContentControl()) { rSh.SplitNode(); } @@ -217,6 +222,53 @@ void SwTextShell::ExecInsert(SfxRequest &rReq) rReq.Done(); break; + case FN_INSERT_CONTENT_CONTROL: + rSh.InsertContentControl(SwContentControlType::RICH_TEXT); + rReq.Done(); + break; + + case FN_INSERT_CHECKBOX_CONTENT_CONTROL: + rSh.InsertContentControl(SwContentControlType::CHECKBOX); + rReq.Done(); + break; + + case FN_INSERT_DROPDOWN_CONTENT_CONTROL: + rSh.InsertContentControl(SwContentControlType::DROP_DOWN_LIST); + rReq.Done(); + break; + + case FN_INSERT_PICTURE_CONTENT_CONTROL: + rSh.InsertContentControl(SwContentControlType::PICTURE); + rReq.Done(); + break; + + case FN_INSERT_DATE_CONTENT_CONTROL: + rSh.InsertContentControl(SwContentControlType::DATE); + rReq.Done(); + break; + + case FN_INSERT_PLAIN_TEXT_CONTENT_CONTROL: + rSh.InsertContentControl(SwContentControlType::PLAIN_TEXT); + rReq.Done(); + break; + + case FN_INSERT_COMBO_BOX_CONTENT_CONTROL: + rSh.InsertContentControl(SwContentControlType::COMBO_BOX); + rReq.Done(); + break; + + case FN_CONTENT_CONTROL_PROPERTIES: + { + SwWrtShell& rWrtSh = GetShell(); + SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); + ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSwContentControlDlg(GetView().GetFrameWeld(), rWrtSh)); + VclAbstractDialog::AsyncContext aContext; + aContext.maEndDialogFn = [](sal_Int32){}; + pDlg->StartExecuteAsync(aContext); + rReq.Done(); + break; + } + case FN_INSERT_COLUMN_BREAK: rSh.InsertColumnBreak(); rReq.Done(); @@ -265,7 +317,7 @@ void SwTextShell::ExecInsert(SfxRequest &rReq) OUString aName; xObj.Assign( aCnt.CreateEmbeddedObject( SvGlobalName( SO3_IFRAME_CLASSID ).GetByteSequence(), aName ), embed::Aspects::MSOLE_CONTENT ); - svt::EmbeddedObjectRef::TryRunningState( xObj.GetObject() ); + (void)svt::EmbeddedObjectRef::TryRunningState( xObj.GetObject() ); uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY ); if ( xSet.is() ) { @@ -279,28 +331,28 @@ void SwTextShell::ExecInsert(SfxRequest &rReq) if ( pMarginItem ) aMargin = pMarginItem->GetSize(); - xSet->setPropertyValue("FrameURL", uno::makeAny( pURLItem->GetValue() ) ); + xSet->setPropertyValue("FrameURL", uno::Any( pURLItem->GetValue() ) ); if ( pNameItem ) - xSet->setPropertyValue("FrameName", uno::makeAny( pNameItem->GetValue() ) ); + xSet->setPropertyValue("FrameName", uno::Any( pNameItem->GetValue() ) ); if ( eScroll == ScrollingMode::Auto ) xSet->setPropertyValue("FrameIsAutoScroll", - uno::makeAny( true ) ); + uno::Any( true ) ); else xSet->setPropertyValue("FrameIsScrollingMode", - uno::makeAny( eScroll == ScrollingMode::Yes ) ); + uno::Any( eScroll == ScrollingMode::Yes ) ); if ( pBorderItem ) xSet->setPropertyValue("FrameIsBorder", - uno::makeAny( pBorderItem->GetValue() ) ); + uno::Any( pBorderItem->GetValue() ) ); if ( pMarginItem ) { xSet->setPropertyValue("FrameMarginWidth", - uno::makeAny( sal_Int32( aMargin.Width() ) ) ); + uno::Any( sal_Int32( aMargin.Width() ) ) ); xSet->setPropertyValue("FrameMarginHeight", - uno::makeAny( sal_Int32( aMargin.Height() ) ) ); + uno::Any( sal_Int32( aMargin.Height() ) ) ); } } catch (const uno::Exception&) @@ -350,8 +402,7 @@ void SwTextShell::ExecInsert(SfxRequest &rReq) if(pItem && xObj.is()) { Size aSize(static_cast<const SvxSizeItem*>(pItem)->GetSize()); - aSize = OutputDevice::LogicToLogic - ( aSize, MapMode( MapUnit::MapTwip ), MapMode( MapUnit::Map100thMM ) ); + aSize = o3tl::convert(aSize, o3tl::Length::twip, o3tl::Length::mm100); if(aSize.Width() > MINLAY&& aSize.Height()> MINLAY) { @@ -386,11 +437,12 @@ void SwTextShell::ExecInsert(SfxRequest &rReq) bool bModifier1 = rReq.GetModifier() == KEY_MOD1; if(pArgs) { + const SfxUInt16Item* pColsItem = nullptr; if(FN_INSERT_FRAME_INTERACT_NOCOL != nSlot && - pArgs->GetItemState(SID_ATTR_COLUMNS, false, &pItem) == SfxItemState::SET) - nCols = static_cast<const SfxUInt16Item *>(pItem)->GetValue(); - if(pArgs->GetItemState(SID_MODIFIER, false, &pItem) == SfxItemState::SET) - bModifier1 |= KEY_MOD1 == static_cast<const SfxUInt16Item *>(pItem)->GetValue(); + (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 ) { @@ -398,10 +450,12 @@ void SwTextShell::ExecInsert(SfxRequest &rReq) Size aWinSize = rEdtWin.GetSizePixel(); Point aStartPos(aWinSize.Width()/2, aWinSize.Height() / 2); aStartPos = rEdtWin.PixelToLogic(aStartPos); - aStartPos.AdjustX( -(8 * MM50) ); - aStartPos.AdjustY( -(4 * MM50) ); - Size aSize(16 * MM50, 8 * MM50); - GetShell().LockPaint(); + constexpr tools::Long constTwips_2cm = o3tl::toTwips(2, o3tl::Length::cm); + constexpr tools::Long constTwips_4cm = o3tl::toTwips(4, o3tl::Length::cm); + aStartPos.AdjustX(-constTwips_4cm); + aStartPos.AdjustY(-constTwips_2cm); + Size aSize(2 * constTwips_4cm, 2 * constTwips_2cm); + GetShell().LockPaint(LockPaintReason::InsertFrame); GetShell().StartAllAction(); SwFlyFrameAttrMgr aMgr( true, GetShellPtr(), Frmmgr_Type::TEXT, nullptr ); if(nCols > 1) @@ -426,8 +480,7 @@ void SwTextShell::ExecInsert(SfxRequest &rReq) bool bSingleCol = false; if( nullptr!= dynamic_cast< SwWebDocShell*>( GetView().GetDocShell()) ) { - SvxHtmlOptions& rHtmlOpt = SvxHtmlOptions::Get(); - if( HTML_CFG_MSIE == rHtmlOpt.GetExportMode() ) + if( HTML_CFG_MSIE == SvxHtmlOptions::GetExportMode() ) { bSingleCol = true; } @@ -447,9 +500,9 @@ void SwTextShell::ExecInsert(SfxRequest &rReq) 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(pArgs->GetItemState(SID_ATTR_COLUMNS, false, &pItem) == SfxItemState::SET) + if(const SfxUInt16Item* pColsItem = pArgs->GetItemIfSet(SID_ATTR_COLUMNS, false)) { - const sal_uInt16 nCols = static_cast<const SfxUInt16Item *>(pItem)->GetValue(); + const sal_uInt16 nCols = pColsItem->GetValue(); if( !bSingleCol && 1 < nCols ) { SwFormatCol aFormatCol; @@ -459,7 +512,7 @@ void SwTextShell::ExecInsert(SfxRequest &rReq) } } - GetShell().LockPaint(); + GetShell().LockPaint(LockPaintReason::InsertFrame); GetShell().StartAllAction(); aMgr.InsertFlyFrame(eAnchor, aPos, aSize); @@ -474,51 +527,65 @@ void SwTextShell::ExecInsert(SfxRequest &rReq) 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", + VclPtr<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); + pDlg->StartExecuteAsync([aSet, pDlg, nSlot, this](sal_Int32 nResult) { + if (nResult == RET_OK && pDlg->GetOutputItemSet()) + { + SwFlyFrameAttrMgr aAttrMgr( true, GetShellPtr(), Frmmgr_Type::TEXT, nullptr ); + //local variable necessary at least after call of .AutoCaption() because this could be deleted at this point + SwWrtShell& rShell = GetShell(); + rShell.LockPaint(LockPaintReason::InsertFrame); + rShell.StartAllAction(); + rShell.StartUndo(SwUndoId::INSERT); + + SfxItemSet aOutSet(*pDlg->GetOutputItemSet()); + const SvxBoxItem* pBox = aSet.GetItem(RES_BOX); + if (pBox && !aOutSet.HasItem(RES_BOX)) + { + // The input set had border info but the output set not, then copy it over + // to not lose the custom border info. This can happen when a whole table + // is selected and that case has its own defaults, not matching the frame + // style. + aOutSet.Put(*pBox); + } + aAttrMgr.SetAttrSet(aOutSet); - // At first delete the selection at the ClickToEditField. - if( rShell.IsInClickToEdit() ) - rShell.DelRight(); + // At first delete the selection at the ClickToEditField. + if( rShell.IsInClickToEdit() ) + rShell.DelRight(); - aMgr.InsertFlyFrame(); + aAttrMgr.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(); - } + uno::Reference< frame::XDispatchRecorder > xRecorder = + GetView().GetViewFrame().GetBindings().GetRecorder(); + if ( xRecorder.is() ) + { + //FN_INSERT_FRAME + sal_uInt16 nAnchor = static_cast<sal_uInt16>(aAttrMgr.GetAnchor()); + SfxRequest aReq(GetView().GetViewFrame(), FN_INSERT_FRAME); + aReq.AppendItem(SfxUInt16Item(nSlot, nAnchor)); + aReq.AppendItem(SfxPointItem(FN_PARAM_1, rShell.GetObjAbsPos())); + aReq.AppendItem(SvxSizeItem(FN_PARAM_2, rShell.GetObjSize())); + aReq.Done(); + } - GetView().AutoCaption(FRAME_CAP); + GetView().AutoCaption(FRAME_CAP); - { - SwRewriter aRewriter; + { + SwRewriter aRewriter; - aRewriter.AddRule(UndoArg1, SwResId(STR_FRAME)); + aRewriter.AddRule(UndoArg1, SwResId(STR_FRAME)); - rShell.EndUndo(SwUndoId::INSERT, &aRewriter); + rShell.EndUndo(SwUndoId::INSERT, &aRewriter); + } + rShell.EndAllAction(); + rShell.UnlockPaint(); } - rShell.EndAllAction(); - rShell.UnlockPaint(); - } + pDlg->disposeOnce(); + }); } break; } @@ -555,14 +622,7 @@ void SwTextShell::StateInsert( SfxItemSet &rSet ) SvtModuleOptions aMOpt; SfxObjectCreateMode eCreateMode = GetView().GetDocShell()->GetCreateMode(); - - bool bCursorInHidden = false; - if( !rSh.HasMark() ) - { - rSh.Push(); - bCursorInHidden = rSh.SelectHiddenRange(); - rSh.Pop(); - } + const bool bCursorInHidden = rSh.IsInHiddenRange(/*bSelect=*/false); while ( nWhich ) { @@ -612,8 +672,7 @@ void SwTextShell::StateInsert( SfxItemSet &rSet ) } else if(SID_INSERT_FLOATINGFRAME == nWhich && bHtmlModeOn) { - SvxHtmlOptions& rHtmlOpt = SvxHtmlOptions::Get(); - const sal_uInt16 nExport = rHtmlOpt.GetExportMode(); + const sal_uInt16 nExport = SvxHtmlOptions::GetExportMode(); if(HTML_CFG_MSIE != nExport && HTML_CFG_WRITER != nExport ) rSet.DisableItem(nWhich); } @@ -633,14 +692,12 @@ void SwTextShell::StateInsert( SfxItemSet &rSet ) case SID_HYPERLINK_GETLINK: { - SfxItemSet aSet(GetPool(), svl::Items<RES_TXTATR_INETFMT, RES_TXTATR_INETFMT>{}); + SfxItemSetFixed<RES_TXTATR_INETFMT, RES_TXTATR_INETFMT> aSet(GetPool()); rSh.GetCurAttr( aSet ); SvxHyperlinkItem aHLinkItem; - const SfxPoolItem* pItem; - if(SfxItemState::SET == aSet.GetItemState(RES_TXTATR_INETFMT, false, &pItem)) + if(const SwFormatINetFormat* pINetFormat = aSet.GetItemIfSet(RES_TXTATR_INETFMT, false)) { - const SwFormatINetFormat* pINetFormat = static_cast<const SwFormatINetFormat*>(pItem); aHLinkItem.SetURL(pINetFormat->GetValue()); aHLinkItem.SetTargetFrame(pINetFormat->GetTargetFrame()); aHLinkItem.SetIntName(pINetFormat->GetName()); @@ -820,7 +877,36 @@ void SwTextShell::ExecTransliteration( SfxRequest const & rReq ) void SwTextShell::ExecRotateTransliteration( SfxRequest const & rReq ) { if( rReq.GetSlot() == SID_TRANSLITERATE_ROTATE_CASE ) - GetShell().TransliterateText( m_aRotateCase.getNextMode() ); + { + TransliterationFlags transFlags = m_aRotateCase.getNextMode(); + bool bSentenceCase = TransliterationFlags::SENTENCE_CASE == transFlags; + SwWrtShell& rSh = GetShell(); + if (rSh.HasSelection()) + { + if (bSentenceCase) + { + OUString aSelection = rSh.GetSelText().trim(); + if (aSelection.getLength() <= 2 || (aSelection.indexOf(' ') < 0 && aSelection.indexOf('\t') < 0)) + transFlags = m_aRotateCase.getNextMode(); + } + rSh.TransliterateText(transFlags); + } + else + { + if (bSentenceCase) + { + if (!rSh.IsEndSentence()) + rSh.EndSentence(false); + } + if (rSh.IsEndSentence()) + { + rSh.BwdSentence(true); + rSh.TransliterateText(transFlags); + } + else if ((rSh.IsEndWrd() || rSh.IsStartWord() || rSh.IsInWord()) && rSh.SelWrd()) + rSh.TransliterateText(transFlags); + } + } } SwTextShell::SwTextShell(SwView &_rView) : @@ -836,20 +922,15 @@ SwTextShell::~SwTextShell() SfxItemSet SwTextShell::CreateInsertFrameItemSet(SwFlyFrameAttrMgr& rMgr) { - static const sal_uInt16 aFrameAttrRange[] = - { + 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, - FN_GET_PRINT_AREA, FN_GET_PRINT_AREA, SID_ATTR_PAGE_SIZE, SID_ATTR_PAGE_SIZE, - FN_SET_FRM_NAME, FN_SET_FRM_NAME, - SID_HTML_MODE, SID_HTML_MODE, SID_COLOR_TABLE, SID_PATTERN_LIST, - XATTR_FILL_FIRST, XATTR_FILL_LAST, // tdf#95003 - 0 - }; - - SfxItemSet aSet(GetPool(), aFrameAttrRange ); + 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. @@ -857,12 +938,12 @@ SfxItemSet SwTextShell::CreateInsertFrameItemSet(SwFlyFrameAttrMgr& rMgr) const SwRect &rPg = GetShell().GetAnyCurRect(CurRectType::Page); SwFormatFrameSize aFrameSize(SwFrameSize::Variable, rPg.Width(), rPg.Height()); - aFrameSize.SetWhich(GetPool().GetWhich(SID_ATTR_PAGE_SIZE)); + aFrameSize.SetWhich(GetPool().GetWhichIDFromSlotID(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)); + aPrtSize.SetWhich(GetPool().GetWhichIDFromSlotID(FN_GET_PRINT_AREA)); aSet.Put(aPrtSize); aSet.Put(rMgr.GetAttrSet()); @@ -875,31 +956,35 @@ SfxItemSet SwTextShell::CreateInsertFrameItemSet(SwFlyFrameAttrMgr& rMgr) aBoxInfo.SetDefDist(rBox.GetDistance(SvxBoxItemLine::LEFT)); aSet.Put(aBoxInfo); + if (!SwFlyFrameAttrMgr::SingleTableSelected(GetShell())) + { + SwFormatAnchor aAnchor(RndStdIds::FLY_AT_CHAR); + aSet.Put(aAnchor); + } + return aSet; } void SwTextShell::InsertSymbol( SfxRequest& rReq ) { const SfxItemSet *pArgs = rReq.GetArgs(); - const SfxPoolItem* pItem = nullptr; + const SfxStringItem* pItem = nullptr; if( pArgs ) - pArgs->GetItemState(GetPool().GetWhich(SID_CHARMAP), false, &pItem); + pItem = pArgs->GetItemIfSet(SID_CHARMAP, false); OUString aChars, aFontName; if ( pItem ) { - aChars = static_cast<const SfxStringItem*>(pItem)->GetValue(); - const SfxPoolItem* pFtItem = nullptr; - pArgs->GetItemState( GetPool().GetWhich(SID_ATTR_SPECIALCHAR), false, &pFtItem); - const SfxStringItem* pFontItem = dynamic_cast<const SfxStringItem*>( pFtItem ); + aChars = pItem->GetValue(); + const SfxStringItem* pFontItem = pArgs->GetItemIfSet( SID_ATTR_SPECIALCHAR, false ); if ( pFontItem ) aFontName = pFontItem->GetValue(); } SwWrtShell &rSh = GetShell(); - SfxItemSet aSet( GetPool(), svl::Items<RES_CHRATR_FONT, RES_CHRATR_FONT, - RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONT, - RES_CHRATR_CTL_FONT, RES_CHRATR_CTL_FONT>{} ); + 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(); @@ -914,11 +999,11 @@ void SwTextShell::InsertSymbol( SfxRequest& rReq ) } else { - aFont.reset(static_cast<SvxFontItem*>( - aSet.Get( + TypedWhichId<SvxFontItem> nFontWhich = GetWhichOfScript( RES_CHRATR_FONT, - SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() ) )).Clone())); + SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() ) ); + aFont.reset(aSet.Get(nFontWhich).Clone()); } if (aFontName.isEmpty()) @@ -940,9 +1025,14 @@ void SwTextShell::InsertSymbol( SfxRequest& rReq ) 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(); + auto xFrame = GetView().GetViewFrame().GetFrame().GetFrameInterface(); + VclPtr<SfxAbstractDialog> pDlg(pFact->CreateCharMapDialog(GetView().GetFrameWeld(), aAllSet, xFrame)); + pDlg->StartExecuteAsync( + [pDlg] (sal_Int32 /*nResult*/)->void + { + pDlg->disposeOnce(); + } + ); return; } @@ -971,9 +1061,11 @@ void SwTextShell::InsertSymbol( SfxRequest& rReq ) } else { - aFont.reset(static_cast<SvxFontItem*>(aSet.Get( GetWhichOfScript( + TypedWhichId<SvxFontItem> nFontWhich = + GetWhichOfScript( RES_CHRATR_FONT, - SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() ) )).Clone())); + SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() ) ); + aFont.reset(aSet.Get( nFontWhich ).Clone()); } } @@ -989,9 +1081,9 @@ void SwTextShell::InsertSymbol( SfxRequest& rReq ) aNewFontItem->SetPitch( aNewFont.GetPitch()); aNewFontItem->SetCharSet( aNewFont.GetCharSet() ); - SfxItemSet aRestoreSet( GetPool(), svl::Items<RES_CHRATR_FONT, RES_CHRATR_FONT, - RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONT, - RES_CHRATR_CTL_FONT, RES_CHRATR_CTL_FONT>{} ); + 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 ) @@ -1040,7 +1132,7 @@ void SwTextShell::InsertSymbol( SfxRequest& rReq ) if ( !aChars.isEmpty() ) { - rReq.AppendItem( SfxStringItem( GetPool().GetWhich(SID_CHARMAP), aChars ) ); + rReq.AppendItem( SfxStringItem( SID_CHARMAP, aChars ) ); rReq.AppendItem( SfxStringItem( SID_ATTR_SPECIALCHAR, aNewFont.GetFamilyName() ) ); rReq.Done(); } diff --git a/sw/source/uibase/shells/textsh1.cxx b/sw/source/uibase/shells/textsh1.cxx index 1aae087262d0..39f655d115bd 100644 --- a/sw/source/uibase/shells/textsh1.cxx +++ b/sw/source/uibase/shells/textsh1.cxx @@ -17,6 +17,10 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <sal/config.h> + +#include <config_features.h> + #include <com/sun/star/i18n/WordType.hpp> #include <com/sun/star/linguistic2/XThesaurus.hpp> @@ -27,6 +31,7 @@ #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> @@ -48,6 +53,9 @@ #include <IDocumentSettingAccess.hxx> #include <charfmt.hxx> #include <svx/SmartTagItem.hxx> +#include <svx/xflgrit.hxx> +#include <svx/xflhtit.hxx> +#include <svx/xfillit0.hxx> #include <fmtinfmt.hxx> #include <wrtsh.hxx> #include <wview.hxx> @@ -66,7 +74,9 @@ #include <cellatr.hxx> #include <edtwin.hxx> #include <fldmgr.hxx> +#include <ndtxt.hxx> #include <strings.hrc> +#include <txatbase.hxx> #include <paratr.hxx> #include <vcl/svapp.hxx> #include <sfx2/app.hxx> @@ -97,8 +107,25 @@ #include <numrule.hxx> #include <memory> #include <xmloff/odffields.hxx> -#include <bookmrk.hxx> +#include <bookmark.hxx> #include <linguistic/misc.hxx> +#include <comphelper/sequenceashashmap.hxx> +#include <comphelper/scopeguard.hxx> +#include <authfld.hxx> +#include <config_wasm_strip.h> +#if HAVE_FEATURE_CURL && !ENABLE_WASM_STRIP_EXTRA +#include <officecfg/Office/Common.hxx> +#include <officecfg/Office/Linguistic.hxx> +#include <svl/visitem.hxx> +#include <translatelangselect.hxx> +#endif // HAVE_FEATURE_CURL && ENABLE_WASM_STRIP_EXTRA +#include <translatehelper.hxx> +#include <IDocumentContentOperations.hxx> +#include <IDocumentUndoRedo.hxx> +#include <fmtcntnt.hxx> +#include <fmtrfmrk.hxx> +#include <cntfrm.hxx> +#include <flyfrm.hxx> using namespace ::com::sun::star; using namespace com::sun::star::beans; @@ -106,23 +133,22 @@ 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_CharDialogResult(const SfxItemSet* pSet, SwWrtShell &rWrtSh, std::shared_ptr<SfxItemSet> const & pCoreSet, bool bSel, + bool bSelectionPut, bool bApplyToParagraph, SfxRequest *pReq); -static void sw_CharDialog(SwWrtShell &rWrtSh, bool bUseDialog, sal_uInt16 nSlot, const SfxItemSet *pArgs, SfxRequest *pReq ) +static void sw_CharDialog(SwWrtShell& rWrtSh, bool bUseDialog, bool bApplyToParagraph, + sal_uInt16 nSlot, const SfxItemSet* pArgs, SfxRequest* pReq) { FieldUnit eMetric = ::GetDfltMetric(dynamic_cast<SwWebView*>( &rWrtSh.GetView()) != nullptr ); SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric))); - auto pCoreSet = std::make_shared<SfxItemSet>( - rWrtSh.GetView().GetPool(), - svl::Items< + 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>{}); + FN_PARAM_SELECTION, FN_PARAM_SELECTION>> ( rWrtSh.GetView().GetPool() ); rWrtSh.GetCurAttr(*pCoreSet); bool bSel = rWrtSh.HasSelection(); @@ -162,13 +188,15 @@ static void sw_CharDialog(SwWrtShell &rWrtSh, bool bUseDialog, sal_uInt16 nSlot, 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)); + pDlg->SetCurPageId(pItem->GetValue()); } } @@ -180,33 +208,44 @@ static void sw_CharDialog(SwWrtShell &rWrtSh, bool bUseDialog, sal_uInt16 nSlot, 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){ + pDlg->StartExecuteAsync([pDlg, &rWrtSh, pCoreSet, bSel, bSelectionPut, bApplyToParagraph, pRequest](sal_Int32 nResult){ if (nResult == RET_OK) { - sw_CharDialogResult(pDlg->GetOutputItemSet(), rWrtSh, pCoreSet, bSel, bSelectionPut, pRequest.get()); + sw_CharDialogResult(pDlg->GetOutputItemSet(), rWrtSh, pCoreSet, bSel, bSelectionPut, + bApplyToParagraph, pRequest.get()); } pDlg->disposeOnce(); }); } else if (pArgs) { - sw_CharDialogResult(pArgs, rWrtSh, pCoreSet, bSel, bSelectionPut, pReq); + sw_CharDialogResult(pArgs, rWrtSh, pCoreSet, bSel, bSelectionPut, bApplyToParagraph, pReq); } } -static void sw_CharDialogResult(const SfxItemSet* pSet, SwWrtShell &rWrtSh, std::shared_ptr<SfxItemSet> const & pCoreSet, bool bSel, bool bSelectionPut, SfxRequest *pReq) +static void sw_CharDialogResult(const SfxItemSet* pSet, SwWrtShell& rWrtSh, std::shared_ptr<SfxItemSet> const & pCoreSet, bool bSel, + bool bSelectionPut, bool bApplyToParagraph, SfxRequest* pReq) { SfxItemSet aTmpSet( *pSet ); ::ConvertAttrGenToChar(aTmpSet, *pCoreSet); - const SfxPoolItem* pSelectionItem; + const bool bWasLocked = rWrtSh.IsViewLocked(); + if (bApplyToParagraph) + { + rWrtSh.StartAction(); + rWrtSh.LockView(true); + rWrtSh.Push(); + SwLangHelper::SelectCurrentPara(rWrtSh); + } + + const SfxStringItem* pSelectionItem; bool bInsert = false; sal_Int32 nInsert = 0; // The old item is for unknown reasons back in the set again. - if( !bSelectionPut && SfxItemState::SET == aTmpSet.GetItemState(FN_PARAM_SELECTION, false, &pSelectionItem) ) + if( !bSelectionPut && (pSelectionItem = aTmpSet.GetItemIfSet(FN_PARAM_SELECTION, false)) ) { - OUString sInsert = static_cast<const SfxStringItem*>(pSelectionItem)->GetValue(); + OUString sInsert = pSelectionItem->GetValue(); bInsert = !sInsert.isEmpty(); if(bInsert) { @@ -215,10 +254,10 @@ static void sw_CharDialogResult(const SfxItemSet* pSet, SwWrtShell &rWrtSh, std: rWrtSh.Insert( sInsert ); rWrtSh.SetMark(); rWrtSh.ExtendSelection(false, sInsert.getLength()); - SfxRequest aReq( rWrtSh.GetView().GetViewFrame(), FN_INSERT_STRING ); + 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 ); + 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(); @@ -227,7 +266,7 @@ static void sw_CharDialogResult(const SfxItemSet* pSet, SwWrtShell &rWrtSh, std: aTmpSet.ClearItem(FN_PARAM_SELECTION); SwTextFormatColl* pColl = rWrtSh.GetCurTextFormatColl(); - if(bSel && rWrtSh.IsSelFullPara() && pColl && pColl->IsAutoUpdateFormat()) + if(bSel && rWrtSh.IsSelFullPara() && pColl && pColl->IsAutoUpdateOnDirectFormat()) { rWrtSh.AutoUpdatePara(pColl, aTmpSet); } @@ -237,7 +276,7 @@ static void sw_CharDialogResult(const SfxItemSet* pSet, SwWrtShell &rWrtSh, std: pReq->Done(aTmpSet); if(bInsert) { - SfxRequest aReq1( rWrtSh.GetView().GetViewFrame(), FN_CHAR_RIGHT ); + 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(); @@ -247,14 +286,14 @@ static void sw_CharDialogResult(const SfxItemSet* pSet, SwWrtShell &rWrtSh, std: rWrtSh.EndAction(); } + if (bApplyToParagraph) + { + rWrtSh.Pop(SwCursorShell::PopMode::DeleteCurrent); + rWrtSh.LockView(bWasLocked); + 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) { @@ -276,16 +315,15 @@ static void sw_ParagraphDialogResult(SfxItemSet* pSet, SwWrtShell &rWrtSh, SfxRe if( pSet->Count() ) { rWrtSh.StartAction(); - const SfxPoolItem* pItem = nullptr; - if ( SfxItemState::SET == pSet->GetItemState(FN_DROP_TEXT, false, &pItem) ) + if ( const SfxStringItem* pDropTextItem = pSet->GetItemIfSet(FN_DROP_TEXT, false) ) { - if ( !static_cast<const SfxStringItem*>(pItem)->GetValue().isEmpty() ) - rWrtSh.ReplaceDropText(static_cast<const SfxStringItem*>(pItem)->GetValue(), pPaM); + 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()) + if(pColl && pColl->IsAutoUpdateOnDirectFormat()) { rWrtSh.AutoUpdatePara(pColl, *pSet, pPaM); } @@ -306,14 +344,14 @@ static void sw_ParagraphDialogResult(SfxItemSet* pSet, SwWrtShell &rWrtSh, SfxRe 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(); + nNumStart = pSet->Get(FN_NUMBER_NEWSTART_AT).GetValue(); } rWrtSh.SetNumRuleStart(bStart, pPaM); rWrtSh.SetNodeNumStart(nNumStart); } else if( SfxItemState::SET == pSet->GetItemState(FN_NUMBER_NEWSTART_AT) ) { - rWrtSh.SetNodeNumStart(static_cast<const SfxUInt16Item&>(pSet->Get(FN_NUMBER_NEWSTART_AT)).GetValue()); + rWrtSh.SetNodeNumStart(pSet->Get(FN_NUMBER_NEWSTART_AT).GetValue()); rWrtSh.SetNumRuleStart(false, pPaM); } // #i56253# @@ -328,12 +366,13 @@ namespace { void InsertBreak(SwWrtShell& rWrtSh, sal_uInt16 nKind, ::std::optional<sal_uInt16> oPageNumber, - const OUString& rTemplateName) + const OUString& rTemplateName, std::optional<SwLineBreakClear> oClear) { switch ( nKind ) { case 1 : - rWrtSh.InsertLineBreak(); break; + rWrtSh.InsertLineBreak(oClear); + break; case 2 : rWrtSh.InsertColumnBreak(); break; case 3 : @@ -348,6 +387,400 @@ void InsertBreak(SwWrtShell& rWrtSh, } } +OUString GetLocalURL(const SwWrtShell& rSh) +{ + SwField* pField = rSh.GetCurField(); + if (!pField) + { + return OUString(); + } + + if (pField->GetTyp()->Which() != SwFieldIds::TableOfAuthorities) + { + return OUString(); + } + + const auto& rAuthorityField = *static_cast<const SwAuthorityField*>(pField); + SwAuthEntry* pAuthEntry = rAuthorityField.GetAuthEntry(); + if (!pAuthEntry) + { + return OUString(); + } + + const OUString& rLocalURL = pAuthEntry->GetAuthorField(AUTH_FIELD_LOCAL_URL); + return rLocalURL; +} + +void UpdateSections(SfxRequest& rReq, SwWrtShell& rWrtSh) +{ + OUString aSectionNamePrefix; + const SfxStringItem* pSectionNamePrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_1); + if (pSectionNamePrefix) + { + aSectionNamePrefix = pSectionNamePrefix->GetValue(); + } + + uno::Sequence<beans::PropertyValues> aSections; + const SfxUnoAnyItem* pSections = rReq.GetArg<SfxUnoAnyItem>(FN_PARAM_2); + if (pSections) + { + pSections->GetValue() >>= aSections; + } + + rWrtSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::UPDATE_SECTIONS, nullptr); + rWrtSh.StartAction(); + + SwDoc* pDoc = rWrtSh.GetDoc(); + sal_Int32 nSectionIndex = 0; + const SwSectionFormats& rFormats = pDoc->GetSections(); + IDocumentContentOperations& rIDCO = pDoc->getIDocumentContentOperations(); + for (size_t i = 0; i < rFormats.size(); ++i) + { + const SwSectionFormat* pFormat = rFormats[i]; + if (!pFormat->GetName().startsWith(aSectionNamePrefix)) + { + continue; + } + + if (nSectionIndex >= aSections.getLength()) + { + break; + } + + comphelper::SequenceAsHashMap aMap(aSections[nSectionIndex++]); + OUString aSectionName = aMap["RegionName"].get<OUString>(); + if (aSectionName != pFormat->GetName()) + { + const_cast<SwSectionFormat*>(pFormat)->SetFormatName(aSectionName, /*bBroadcast=*/true); + SwSectionData aSectionData(*pFormat->GetSection()); + aSectionData.SetSectionName(aSectionName); + pDoc->UpdateSection(i, aSectionData); + } + + const SwFormatContent& rContent = pFormat->GetContent(); + const SwNodeIndex* pContentNodeIndex = rContent.GetContentIdx(); + if (pContentNodeIndex) + { + SwPaM aSectionStart(SwPosition{*pContentNodeIndex}); + aSectionStart.Move(fnMoveForward, GoInContent); + SwPaM* pCursorPos = rWrtSh.GetCursor(); + *pCursorPos = aSectionStart; + rWrtSh.EndOfSection(/*bSelect=*/true); + rIDCO.DeleteAndJoin(*pCursorPos); + rWrtSh.EndSelect(); + + OUString aSectionText = aMap["Content"].get<OUString>(); + SwTranslateHelper::PasteHTMLToPaM(rWrtSh, pCursorPos, aSectionText.toUtf8()); + } + } + + rWrtSh.EndAction(); + rWrtSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::UPDATE_SECTIONS, nullptr); +} + +void DeleteSections(SfxRequest& rReq, SwWrtShell& rWrtSh) +{ + OUString aSectionNamePrefix; + const SfxStringItem* pSectionNamePrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_1); + if (pSectionNamePrefix) + { + aSectionNamePrefix = pSectionNamePrefix->GetValue(); + } + + rWrtSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::DELETE_SECTIONS, nullptr); + rWrtSh.StartAction(); + comphelper::ScopeGuard g( + [&rWrtSh] + { + rWrtSh.EndAction(); + rWrtSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::DELETE_SECTIONS, nullptr); + }); + + SwDoc* pDoc = rWrtSh.GetDoc(); + SwSectionFormats& rFormats = pDoc->GetSections(); + std::vector<SwSectionFormat*> aRemovals; + for (size_t i = 0; i < rFormats.size(); ++i) + { + SwSectionFormat* pFormat = rFormats[i]; + + if (!aSectionNamePrefix.isEmpty()) + { + if (!pFormat->GetName().startsWith(aSectionNamePrefix)) + { + continue; + } + } + + aRemovals.push_back(pFormat); + } + + for (const auto& pFormat : aRemovals) + { + // Just delete the format, not the content of the section. + pDoc->DelSectionFormat(pFormat); + } +} + +void UpdateBookmarks(SfxRequest& rReq, SwWrtShell& rWrtSh) +{ + if (rWrtSh.getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS)) + { + return; + } + + OUString aBookmarkNamePrefix; + const SfxStringItem* pBookmarkNamePrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_1); + if (pBookmarkNamePrefix) + { + aBookmarkNamePrefix = pBookmarkNamePrefix->GetValue(); + } + + uno::Sequence<beans::PropertyValues> aBookmarks; + const SfxUnoAnyItem* pBookmarks = rReq.GetArg<SfxUnoAnyItem>(FN_PARAM_2); + if (pBookmarks) + { + pBookmarks->GetValue() >>= aBookmarks; + } + + rWrtSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::UPDATE_BOOKMARKS, nullptr); + rWrtSh.StartAction(); + + IDocumentMarkAccess& rIDMA = *rWrtSh.GetDoc()->getIDocumentMarkAccess(); + sal_Int32 nBookmarkIndex = 0; + bool bSortMarks = false; + for (auto it = rIDMA.getBookmarksBegin(); it != rIDMA.getBookmarksEnd(); ++it) + { + auto pMark = dynamic_cast<sw::mark::Bookmark*>(*it); + assert(pMark); + if (!pMark->GetName().startsWith(aBookmarkNamePrefix)) + { + continue; + } + + if (aBookmarks.getLength() <= nBookmarkIndex) + { + continue; + } + + comphelper::SequenceAsHashMap aMap(aBookmarks[nBookmarkIndex++]); + if (aMap["Bookmark"].get<OUString>() != pMark->GetName()) + { + rIDMA.renameMark(pMark, aMap["Bookmark"].get<OUString>()); + } + + OUString aBookmarkText = aMap["BookmarkText"].get<OUString>(); + + // Insert markers to remember where the paste positions are. + SwPaM aMarkers(pMark->GetMarkEnd()); + IDocumentContentOperations& rIDCO = rWrtSh.GetDoc()->getIDocumentContentOperations(); + bool bSuccess = rIDCO.InsertString(aMarkers, "XY"); + if (bSuccess) + { + SwPaM aPasteEnd(pMark->GetMarkEnd()); + aPasteEnd.Move(fnMoveForward, GoInContent); + + // Paste HTML content. + SwPaM* pCursorPos = rWrtSh.GetCursor(); + *pCursorPos = aPasteEnd; + SwTranslateHelper::PasteHTMLToPaM(rWrtSh, pCursorPos, aBookmarkText.toUtf8()); + + // Update the bookmark to point to the new content. + SwPaM aPasteStart(pMark->GetMarkEnd()); + aPasteStart.Move(fnMoveForward, GoInContent); + SwPaM aStartMarker(pMark->GetMarkStart(), *aPasteStart.GetPoint()); + SwPaM aEndMarker(*aPasteEnd.GetPoint(), *aPasteEnd.GetPoint()); + aEndMarker.GetMark()->AdjustContent(1); + pMark->SetMarkPos(*aPasteStart.GetPoint()); + pMark->SetOtherMarkPos(*aPasteEnd.GetPoint()); + bSortMarks = true; + + // Remove markers. the start marker includes the old content as well. + rIDCO.DeleteAndJoin(aStartMarker); + rIDCO.DeleteAndJoin(aEndMarker); + } + } + if (bSortMarks) + { + rIDMA.assureSortedMarkContainers(); + } + + rWrtSh.EndAction(); + rWrtSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::UPDATE_BOOKMARKS, nullptr); +} + +void UpdateBookmark(SfxRequest& rReq, SwWrtShell& rWrtSh) +{ + if (rWrtSh.getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS)) + { + return; + } + + OUString aBookmarkNamePrefix; + const SfxStringItem* pBookmarkNamePrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_1); + if (pBookmarkNamePrefix) + { + aBookmarkNamePrefix = pBookmarkNamePrefix->GetValue(); + } + + uno::Sequence<beans::PropertyValue> aBookmark; + const SfxUnoAnyItem* pBookmarks = rReq.GetArg<SfxUnoAnyItem>(FN_PARAM_2); + if (pBookmarks) + { + pBookmarks->GetValue() >>= aBookmark; + } + + IDocumentMarkAccess& rIDMA = *rWrtSh.GetDoc()->getIDocumentMarkAccess(); + SwPosition& rCursor = *rWrtSh.GetCursor()->GetPoint(); + auto pBookmark = dynamic_cast<sw::mark::Bookmark*>(rIDMA.getOneInnermostBookmarkFor(rCursor)); + if (!pBookmark || !pBookmark->GetName().startsWith(aBookmarkNamePrefix)) + { + return; + } + + SwRewriter aRewriter; + aRewriter.AddRule(UndoArg1, pBookmark->GetName()); + rWrtSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::UPDATE_BOOKMARK, &aRewriter); + rWrtSh.StartAction(); + comphelper::ScopeGuard g( + [&rWrtSh, &aRewriter] + { + rWrtSh.EndAction(); + rWrtSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::UPDATE_BOOKMARK, &aRewriter); + }); + + + comphelper::SequenceAsHashMap aMap(aBookmark); + if (aMap["Bookmark"].get<OUString>() != pBookmark->GetName()) + { + rIDMA.renameMark(pBookmark, aMap["Bookmark"].get<OUString>()); + } + + // Insert markers to remember where the paste positions are. + SwPaM aMarkers(pBookmark->GetMarkEnd()); + IDocumentContentOperations& rIDCO = rWrtSh.GetDoc()->getIDocumentContentOperations(); + if (!rIDCO.InsertString(aMarkers, "XY")) + { + return; + } + + SwPaM aPasteEnd(pBookmark->GetMarkEnd()); + aPasteEnd.Move(fnMoveForward, GoInContent); + + OUString aBookmarkText = aMap["BookmarkText"].get<OUString>(); + + // Paste HTML content. + SwPaM* pCursorPos = rWrtSh.GetCursor(); + *pCursorPos = aPasteEnd; + SwTranslateHelper::PasteHTMLToPaM(rWrtSh, pCursorPos, aBookmarkText.toUtf8()); + + // Update the bookmark to point to the new content. + SwPaM aPasteStart(pBookmark->GetMarkEnd()); + aPasteStart.Move(fnMoveForward, GoInContent); + SwPaM aStartMarker(pBookmark->GetMarkStart(), *aPasteStart.GetPoint()); + SwPaM aEndMarker(*aPasteEnd.GetPoint(), *aPasteEnd.GetPoint()); + aEndMarker.GetMark()->AdjustContent(1); + pBookmark->SetMarkPos(*aPasteStart.GetPoint()); + pBookmark->SetOtherMarkPos(*aPasteEnd.GetPoint()); + + // Remove markers. the start marker includes the old content as well. + rIDCO.DeleteAndJoin(aStartMarker); + rIDCO.DeleteAndJoin(aEndMarker); + rIDMA.assureSortedMarkContainers(); +} + +void DeleteBookmarks(SfxRequest& rReq, SwWrtShell& rWrtSh) +{ + if (rWrtSh.getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS)) + { + return; + } + + OUString aBookmarkNamePrefix; + const SfxStringItem* pBookmarkNamePrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_1); + if (pBookmarkNamePrefix) + { + aBookmarkNamePrefix = pBookmarkNamePrefix->GetValue(); + } + + rWrtSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::DELETE_BOOKMARKS, nullptr); + rWrtSh.StartAction(); + comphelper::ScopeGuard g( + [&rWrtSh] + { + rWrtSh.EndAction(); + rWrtSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::DELETE_BOOKMARKS, nullptr); + }); + + IDocumentMarkAccess* pMarkAccess = rWrtSh.GetDoc()->getIDocumentMarkAccess(); + std::vector<sw::mark::IMark*> aRemovals; + for (auto it = pMarkAccess->getBookmarksBegin(); it != pMarkAccess->getBookmarksEnd(); ++it) + { + auto pBookmark = dynamic_cast<sw::mark::Bookmark*>(*it); + assert(pBookmark); + + if (!aBookmarkNamePrefix.isEmpty()) + { + if (!pBookmark->GetName().startsWith(aBookmarkNamePrefix)) + { + continue; + } + } + + aRemovals.push_back(pBookmark); + } + + for (const auto& pMark : aRemovals) + { + pMarkAccess->deleteMark(pMark); + } +} + +void DeleteFields(SfxRequest& rReq, SwWrtShell& rWrtSh) +{ + const SfxStringItem* pTypeName = rReq.GetArg<SfxStringItem>(FN_PARAM_1); + if (!pTypeName || pTypeName->GetValue() != "SetRef") + { + // This is implemented so far only for reference marks. + return; + } + + OUString aNamePrefix; + const SfxStringItem* pNamePrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_2); + if (pNamePrefix) + { + aNamePrefix = pNamePrefix->GetValue(); + } + + SwDoc* pDoc = rWrtSh.GetDoc(); + pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::DELETE_FIELDS, nullptr); + rWrtSh.StartAction(); + comphelper::ScopeGuard g( + [&rWrtSh] + { + rWrtSh.EndAction(); + rWrtSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::DELETE_FIELDS, nullptr); + }); + + std::vector<const SwFormatRefMark*> aRemovals; + for (sal_uInt16 i = 0; i < pDoc->GetRefMarks(); ++i) + { + const SwFormatRefMark* pRefMark = pDoc->GetRefMark(i); + if (!aNamePrefix.isEmpty()) + { + if (!pRefMark->GetRefName().startsWith(aNamePrefix)) + { + continue; + } + } + + aRemovals.push_back(pRefMark); + } + + for (const auto& pMark : aRemovals) + { + pDoc->DeleteFormatRefMark(pMark); + } +} } void SwTextShell::Execute(SfxRequest &rReq) @@ -358,7 +791,7 @@ void SwTextShell::Execute(SfxRequest &rReq) const SfxPoolItem* pItem = nullptr; const sal_uInt16 nSlot = rReq.GetSlot(); if(pArgs) - pArgs->GetItemState(GetPool().GetWhich(nSlot), false, &pItem); + pArgs->GetItemState(GetPool().GetWhichIDFromSlotID(nSlot), false, &pItem); switch( nSlot ) { case SID_UNICODE_NOTATION_TOGGLE: @@ -379,10 +812,7 @@ void SwTextShell::Execute(SfxRequest &rReq) 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(); + rWrtSh.InfoReadOnlyDialog(false); break; } SwRewriter aRewriter; @@ -415,11 +845,11 @@ void SwTextShell::Execute(SfxRequest &rReq) //!! Remember the view frame right now... //!! (call to GetView().GetViewFrame() will break if the //!! SwTextShell got destroyed meanwhile.) - SfxViewFrame *pViewFrame = GetView().GetViewFrame(); + SfxViewFrame& rViewFrame = GetView().GetViewFrame(); if (aNewLangText == "*") { - // open the dialog "Tools/Options/Language Settings - Language" + // open the dialog "Tools/Options/Languages and Locales - General" // to set the documents default language SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateVclDialog(GetView().GetFrameWeld(), SID_LANGUAGE_OPTIONS)); @@ -437,14 +867,14 @@ void SwTextShell::Execute(SfxRequest &rReq) // setting the new language... if (!aNewLangText.isEmpty()) { - const OUString aSelectionLangPrefix("Current_"); - const OUString aParagraphLangPrefix("Paragraph_"); - const OUString aDocumentLangPrefix("Default_"); + static constexpr OUString aSelectionLangPrefix(u"Current_"_ustr); + static constexpr OUString aParagraphLangPrefix(u"Paragraph_"_ustr); + static constexpr OUString aDocumentLangPrefix(u"Default_"_ustr); - SfxItemSet aCoreSet( GetPool(), - svl::Items<RES_CHRATR_LANGUAGE, RES_CHRATR_LANGUAGE, + SfxItemSetFixed + <RES_CHRATR_LANGUAGE, RES_CHRATR_LANGUAGE, RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CJK_LANGUAGE, - RES_CHRATR_CTL_LANGUAGE, RES_CHRATR_CTL_LANGUAGE>{} ); + RES_CHRATR_CTL_LANGUAGE, RES_CHRATR_CTL_LANGUAGE> aCoreSet( GetPool() ); sal_Int32 nPos = 0; bool bForSelection = true; @@ -452,20 +882,20 @@ void SwTextShell::Execute(SfxRequest &rReq) if (-1 != (nPos = aNewLangText.indexOf( aSelectionLangPrefix ))) { // ... for the current selection - aNewLangText = aNewLangText.replaceAt(nPos, aSelectionLangPrefix.getLength(), ""); + 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(), ""); + 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(), ""); + aNewLangText = aNewLangText.replaceAt(nPos, aDocumentLangPrefix.getLength(), u""); bForSelection = false; } @@ -504,7 +934,7 @@ void SwTextShell::Execute(SfxRequest &rReq) } // invalidate slot to get the new language displayed - pViewFrame->GetBindings().Invalidate( nSlot ); + rViewFrame.GetBindings().Invalidate( nSlot ); rReq.Done(); break; @@ -514,7 +944,7 @@ void SwTextShell::Execute(SfxRequest &rReq) { // replace word/selection with text from selected sub menu entry OUString aReplaceText; - const SfxStringItem* pItem2 = rReq.GetArg<SfxStringItem>(SID_THES); + const SfxStringItem* pItem2 = rReq.GetArg(FN_PARAM_THES_WORD_REPLACE); if (pItem2) aReplaceText = pItem2->GetValue(); if (!aReplaceText.isEmpty()) @@ -545,8 +975,8 @@ void SwTextShell::Execute(SfxRequest &rReq) rWrtSh.InsertFootnote( aStr, nSlot == FN_INSERT_ENDNOTE, !bFont ); if ( bFont ) { - rWrtSh.Left( CRSR_SKIP_CHARS, true, 1, false ); - SfxItemSet aSet( rWrtSh.GetAttrPool(), svl::Items<RES_CHRATR_FONT, RES_CHRATR_FONT>{} ); + rWrtSh.Left( SwCursorSkipMode::Chars, true, 1, false ); + SfxItemSetFixed<RES_CHRATR_FONT, RES_CHRATR_FONT> aSet( rWrtSh.GetAttrPool() ); rWrtSh.GetCurAttr( aSet ); rWrtSh.SetAttrSet( aSet, SetAttrMode::DONTEXPAND ); rWrtSh.ResetSelect(nullptr, false); @@ -560,20 +990,26 @@ void SwTextShell::Execute(SfxRequest &rReq) case FN_INSERT_FOOTNOTE_DLG: { SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); - ScopedVclPtr<AbstractInsFootNoteDlg> pDlg(pFact->CreateInsFootNoteDlg( + VclPtr<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 ); - } - + pDlg->StartExecuteAsync( + [this, pDlg] (sal_Int32 nResult)->void + { + if ( nResult == RET_OK ) + { + pDlg->Apply(); + 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 ); + } + pDlg->disposeOnce(); + } + ); rReq.Ignore(); } break; @@ -604,6 +1040,7 @@ void SwTextShell::Execute(SfxRequest &rReq) { RES_CHRATR_CJK_LANGUAGE + 1, RES_CHRATR_CTL_LANGUAGE - 1 }, { RES_CHRATR_CTL_LANGUAGE + 1, RES_CHRATR_END - 1 }, { RES_PARATR_BEGIN, RES_PARATR_END - 1 }, + { RES_PARATR_LIST_AUTOFMT, RES_PARATR_LIST_AUTOFMT }, { RES_TXTATR_UNKNOWN_CONTAINER, RES_TXTATR_UNKNOWN_CONTAINER }, { RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END - 1 }, }; @@ -615,7 +1052,8 @@ void SwTextShell::Execute(SfxRequest &rReq) rWrtSh.ResetAttr( aAttribs ); // also clear the direct formatting flag inside SwTableBox(es) - GetView().GetDocShell()->GetFEShell()->UpdateTableStyleFormatting(nullptr, true); + if (SwFEShell* pFEShell = GetView().GetDocShell()->GetFEShell()) + pFEShell->UpdateTableStyleFormatting(nullptr, true); rReq.Done(); break; @@ -625,6 +1063,7 @@ void SwTextShell::Execute(SfxRequest &rReq) 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); @@ -635,7 +1074,7 @@ void SwTextShell::Execute(SfxRequest &rReq) if ( pNumber && pIsNumberFilled && pIsNumberFilled->GetValue() ) oPageNumber = pNumber->GetValue(); - InsertBreak(rWrtSh, nKind, oPageNumber, aTemplateName); + InsertBreak(rWrtSh, nKind, oPageNumber, aTemplateName, oClear); } else { @@ -651,8 +1090,9 @@ void SwTextShell::Execute(SfxRequest &rReq) 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); + InsertBreak(rWrtSh, nKind, oPageNumber, aTemplateName, oClear); } }); } @@ -661,15 +1101,66 @@ void SwTextShell::Execute(SfxRequest &rReq) } case FN_INSERT_BOOKMARK: { + const SfxStringItem* pBookmarkText = rReq.GetArg<SfxStringItem>(FN_PARAM_1); + SwPaM* pCursorPos = rWrtSh.GetCursor(); if ( pItem ) { + rWrtSh.StartAction(); OUString sName = static_cast<const SfxStringItem*>(pItem)->GetValue(); + + if (pBookmarkText) + { + OUString aBookmarkText = pBookmarkText->GetValue(); + // Split node to remember where the start position is. + bool bSuccess = rWrtSh.GetDoc()->getIDocumentContentOperations().SplitNode( + *pCursorPos->GetPoint(), /*bChkTableStart=*/false); + if (bSuccess) + { + SwPaM aBookmarkPam(*pCursorPos->GetPoint()); + aBookmarkPam.Move(fnMoveBackward, GoInContent); + + // Paste HTML content. + SwTranslateHelper::PasteHTMLToPaM( + rWrtSh, pCursorPos, aBookmarkText.toUtf8()); + if (pCursorPos->GetPoint()->GetContentIndex() == 0) + { + // The paste created a last empty text node, remove it. + SwPaM aPam(*pCursorPos->GetPoint()); + aPam.SetMark(); + aPam.Move(fnMoveBackward, GoInContent); + rWrtSh.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(aPam); + } + + // Undo the above SplitNode(). + aBookmarkPam.SetMark(); + aBookmarkPam.Move(fnMoveForward, GoInContent); + rWrtSh.GetDoc()->getIDocumentContentOperations().DeleteAndJoin( + aBookmarkPam); + *aBookmarkPam.GetMark() = *pCursorPos->GetPoint(); + *pCursorPos = aBookmarkPam; + } + } + rWrtSh.SetBookmark( vcl::KeyCode(), sName ); + if (pBookmarkText) + { + pCursorPos->DeleteMark(); + } + rWrtSh.EndAction(); + break; + } + [[fallthrough]]; + } + case FN_EDIT_BOOKMARK: + { + ::std::optional<OUString> oName; + if (pItem) + { + oName.emplace(static_cast<const SfxStringItem*>(pItem)->GetValue()); } - else { SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); - ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSwInsertBookmarkDlg(GetView().GetFrameWeld(), rWrtSh)); + ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSwInsertBookmarkDlg(GetView().GetFrameWeld(), rWrtSh, oName ? &*oName : nullptr)); VclAbstractDialog::AsyncContext aContext; aContext.maEndDialogFn = [](sal_Int32){}; pDlg->StartExecuteAsync(aContext); @@ -677,15 +1168,53 @@ void SwTextShell::Execute(SfxRequest &rReq) break; } + case FN_UPDATE_BOOKMARKS: + { + // This updates all bookmarks in the document that match the conditions specified in + // rReq. + UpdateBookmarks(rReq, rWrtSh); + break; + } + case FN_UPDATE_BOOKMARK: + { + // This updates the bookmark under the cursor. + UpdateBookmark(rReq, rWrtSh); + break; + } case FN_DELETE_BOOKMARK: { + // This deletes a bookmark with the specified name. if (pItem && !rWrtSh.getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS)) { IDocumentMarkAccess* const pMarkAccess = rWrtSh.getIDocumentMarkAccess(); - pMarkAccess->deleteMark( pMarkAccess->findMark(static_cast<const SfxStringItem*>(pItem)->GetValue()) ); + pMarkAccess->deleteMark(pMarkAccess->findMark(static_cast<const SfxStringItem*>(pItem)->GetValue()), false); } break; } + case FN_DELETE_BOOKMARKS: + { + // This deletes all bookmarks in the document matching a specified prefix. + DeleteBookmarks(rReq, rWrtSh); + break; + } + case FN_DELETE_FIELDS: + { + // This deletes all fields in the document matching a specified type & prefix. + DeleteFields(rReq, rWrtSh); + break; + } + case FN_UPDATE_SECTIONS: + { + UpdateSections(rReq, rWrtSh); + break; + } + case FN_DELETE_SECTIONS: + { + // This deletes all sections in the document matching a specified prefix. Note that the + // section is deleted, but not its contents. + DeleteSections(rReq, rWrtSh); + break; + } case FN_SET_REMINDER: { // collect and sort navigator reminder names @@ -703,7 +1232,7 @@ void SwTextShell::Execute(SfxRequest &rReq) // 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])); + 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); @@ -716,37 +1245,24 @@ void SwTextShell::Execute(SfxRequest &rReq) // This must always be false for the postprocessing. aFlags.bAFormatByInput = false; aFlags.bWithRedlining = true; - rWrtSh.AutoFormat( &aFlags ); + rWrtSh.AutoFormat( &aFlags, false ); aFlags.bWithRedlining = false; - SfxViewFrame* pVFrame = GetView().GetViewFrame(); - if (pVFrame->HasChildWindow(FN_REDLINE_ACCEPT)) - pVFrame->ToggleChildWindow(FN_REDLINE_ACCEPT); + SfxViewFrame& rVFrame = GetView().GetViewFrame(); + if (rVFrame.HasChildWindow(FN_REDLINE_ACCEPT)) + rVFrame.ToggleChildWindow(FN_REDLINE_ACCEPT); SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); - ScopedVclPtr<AbstractSwModalRedlineAcceptDlg> xDlg(pFact->CreateSwModalRedlineAcceptDlg(GetView().GetEditWin().GetFrameWeld())); - - switch (lcl_AskRedlineFlags(GetView().GetFrameWeld())) - { - case RET_OK: + auto xRequest = std::make_shared<SfxRequest>(rReq); + rReq.Ignore(); // the 'old' request is not relevant any more + VclPtr<AbstractSwModalRedlineAcceptDlg> pDlg(pFact->CreateSwModalRedlineAcceptDlg(GetView().GetEditWin().GetFrameWeld())); + pDlg->StartExecuteAsync( + [pDlg, xRequest] (sal_Int32 /*nResult*/)->void { - xDlg->AcceptAll(true); - SfxRequest aReq( pVFrame, FN_AUTOFORMAT_APPLY ); - aReq.Done(); - rReq.Ignore(); - break; + pDlg->disposeOnce(); + xRequest->Done(); } - - case RET_CANCEL: - xDlg->AcceptAll(false); - rReq.Ignore(); - break; - - case 102: - xDlg->Execute(); - rReq.Done(); - break; - } + ); } break; @@ -755,7 +1271,7 @@ void SwTextShell::Execute(SfxRequest &rReq) SvxSwAutoFormatFlags aFlags(SvxAutoCorrCfg::Get().GetAutoCorrect()->GetSwFlags()); // This must always be false for the postprocessing. aFlags.bAFormatByInput = false; - rWrtSh.AutoFormat( &aFlags ); + rWrtSh.AutoFormat( &aFlags, false ); rReq.Done(); } break; @@ -767,9 +1283,9 @@ void SwTextShell::Execute(SfxRequest &rReq) { rACfg.SetAutoFormatByInput( bSet ); rACfg.Commit(); - GetView().GetViewFrame()->GetBindings().Invalidate( nSlot ); + GetView().GetViewFrame().GetBindings().Invalidate( nSlot ); if ( !pItem ) - rReq.AppendItem( SfxBoolItem( GetPool().GetWhich(nSlot), bSet ) ); + rReq.AppendItem( SfxBoolItem( GetPool().GetWhichIDFromSlotID(nSlot), bSet ) ); rReq.Done(); } } @@ -785,9 +1301,18 @@ void SwTextShell::Execute(SfxRequest &rReq) case FN_SORTING_DLG: { SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); - ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSwSortingDialog(GetView().GetFrameWeld(), rWrtSh)); - pDlg->Execute(); - rReq.Done(); + VclPtr<AbstractSwSortDlg> pDlg(pFact->CreateSwSortingDialog(GetView().GetFrameWeld(), rWrtSh)); + auto xRequest = std::make_shared<SfxRequest>(rReq); + rReq.Ignore(); // the 'old' request is not relevant any more + pDlg->StartExecuteAsync( + [pDlg, xRequest] (sal_Int32 nResult)->void + { + if (nResult == RET_OK) + pDlg->Apply(); + pDlg->disposeOnce(); + xRequest->Done(); + } + ); } break; case FN_NUMBERING_OUTLINE_DLG: @@ -811,7 +1336,8 @@ void SwTextShell::Execute(SfxRequest &rReq) rWrtSh.StartAllAction(); rWrtSh.SwCursorShell::GotoRefMark( static_cast<SwGetRefField*>(pField)->GetSetRefName(), static_cast<SwGetRefField*>(pField)->GetSubType(), - static_cast<SwGetRefField*>(pField)->GetSeqNo() ); + static_cast<SwGetRefField*>(pField)->GetSeqNo(), + static_cast<SwGetRefField*>(pField)->GetFlags() ); rWrtSh.EndAllAction(); rReq.Done(); } @@ -820,14 +1346,14 @@ void SwTextShell::Execute(SfxRequest &rReq) case FN_EDIT_FORMULA: { const sal_uInt16 nId = SwInputChild::GetChildWindowId(); - SfxViewFrame* pVFrame = GetView().GetViewFrame(); + SfxViewFrame& rVFrame = GetView().GetViewFrame(); if(pItem) { //if the ChildWindow is active it has to be removed - if( pVFrame->HasChildWindow( nId ) ) + if( rVFrame.HasChildWindow( nId ) ) { - pVFrame->ToggleChildWindow( nId ); - pVFrame->GetBindings().InvalidateAll( true ); + rVFrame.ToggleChildWindow( nId ); + rVFrame.GetBindings().InvalidateAll( true ); } OUString sFormula(static_cast<const SfxStringItem*>(pItem)->GetValue()); @@ -850,7 +1376,7 @@ void SwTextShell::Execute(SfxRequest &rReq) { if( rWrtSh.IsCursorInTable() ) { - SfxItemSet aSet( rWrtSh.GetAttrPool(), svl::Items<RES_BOXATR_FORMULA, RES_BOXATR_FORMULA>{} ); + SfxItemSetFixed<RES_BOXATR_FORMULA, RES_BOXATR_FORMULA> aSet( rWrtSh.GetAttrPool() ); aSet.Put( SwTableBoxFormula( sFormula )); rWrtSh.SetTableBoxFormulaAttrs( aSet ); rWrtSh.UpdateTable(); @@ -872,9 +1398,9 @@ void SwTextShell::Execute(SfxRequest &rReq) else { rWrtSh.EndAllTableBoxEdit(); - pVFrame->ToggleChildWindow( nId ); - if( !pVFrame->HasChildWindow( nId ) ) - pVFrame->GetBindings().InvalidateAll( true ); + rVFrame.ToggleChildWindow( nId ); + if( !rVFrame.HasChildWindow( nId ) ) + rVFrame.GetBindings().InvalidateAll( true ); rReq.Ignore(); } } @@ -886,7 +1412,27 @@ void SwTextShell::Execute(SfxRequest &rReq) } break; case SID_EDIT_HYPERLINK: - GetView().GetViewFrame()->SetChildWindow(SID_HYPERLINK_DIALOG, true); + { + if (!rWrtSh.HasSelection()) + { + SfxItemSetFixed<RES_TXTATR_INETFMT, RES_TXTATR_INETFMT> aSet(GetPool()); + rWrtSh.GetCurAttr(aSet); + if (SfxItemState::SET > aSet.GetItemState(RES_TXTATR_INETFMT)) + { + // Didn't find a hyperlink to edit yet. + + // If the cursor is just before an unselected hyperlink, + // the dialog will not know that it should edit that hyperlink, + // so in this case, first select it so the dialog will find the hyperlink. + // The dialog would leave the hyperlink selected anyway after a successful edit + // (although it isn't normally selected after a cancel, but oh well). + if (!rWrtSh.SelectTextAttr(RES_TXTATR_INETFMT)) + break; + } + } + + GetView().GetViewFrame().SetChildWindow(SID_HYPERLINK_DIALOG, true); + } break; case SID_REMOVE_HYPERLINK: { @@ -913,23 +1459,21 @@ void SwTextShell::Execute(SfxRequest &rReq) case FN_TXTATR_INET : case FN_INSERT_HYPERLINK: { - const sal_uInt16 nWhich = GetPool().GetWhich( nSlot ); + const sal_uInt16 nWhich = GetPool().GetWhichIDFromSlotID( 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 ); + sw_CharDialog(rWrtSh, bUseDialog, /*ApplyToParagraph*/false, 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 + sw_CharDialog(rWrtSh, /*UseDialog*/true, /*ApplyToParagraph*/true, nSlot, pArgs, &rReq); } break; case SID_ATTR_LRSPACE : @@ -946,7 +1490,7 @@ void SwTextShell::Execute(SfxRequest &rReq) case FN_DROP_TEXT: case SID_ATTR_PARA_LRSPACE: { - const sal_uInt16 nWhich = GetPool().GetWhich( nSlot ); + const sal_uInt16 nWhich = GetPool().GetWhichIDFromSlotID( nSlot ); if ( pArgs && pArgs->GetItemState( nWhich ) == SfxItemState::SET ) bUseDialog = false; [[fallthrough]]; @@ -957,10 +1501,9 @@ void SwTextShell::Execute(SfxRequest &rReq) if ( pArgs ) { - const SfxPoolItem* pPaMItem = nullptr; - pArgs->GetItemState( GetPool().GetWhich( FN_PARAM_PAM ), false, &pPaMItem ); + const SwPaMItem* pPaMItem = pArgs->GetItemIfSet( GetPool().GetWhichIDFromSlotID( FN_PARAM_PAM ), false ); if ( pPaMItem ) - pPaM = static_cast< const SwPaMItem* >( pPaMItem )->GetValue( ); + pPaM = pPaMItem->GetValue( ); } if ( !pPaM ) @@ -972,9 +1515,7 @@ void SwTextShell::Execute(SfxRequest &rReq) bool bApplyCharUnit = ::HasCharUnit( dynamic_cast<SwWebView*>( &GetView()) != nullptr ); SW_MOD()->PutItem(SfxBoolItem(SID_ATTR_APPLYCHARUNIT, bApplyCharUnit)); - SfxItemSet aCoreSet( - GetPool(), - svl::Items< + SfxItemSetFixed< RES_PARATR_BEGIN, RES_FRMATR_END - 1, // FillAttribute support: XATTR_FILL_FIRST, XATTR_FILL_LAST, @@ -990,7 +1531,7 @@ void SwTextShell::Execute(SfxRequest &rReq) 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>{}); + 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 ); @@ -998,7 +1539,7 @@ void SwTextShell::Execute(SfxRequest &rReq) // 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 - const SwDrawModel* pDrawModel = GetView().GetDocShell()->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel(); + SwDrawModel* pDrawModel = GetView().GetDocShell()->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel(); aCoreSet.Put(SvxColorListItem(pDrawModel->GetColorList(), SID_COLOR_TABLE)); aCoreSet.Put(SvxGradientListItem(pDrawModel->GetGradientList(), SID_GRADIENT_LIST)); @@ -1010,9 +1551,9 @@ void SwTextShell::Execute(SfxRequest &rReq) // Tabulators: Put DefaultTabs into ItemSet const SvxTabStopItem& rDefTabs = - GetPool().GetDefaultItem(RES_PARATR_TABSTOP); + GetPool().GetUserOrPoolDefaultItem(RES_PARATR_TABSTOP); - const sal_uInt16 nDefDist = static_cast<sal_uInt16>(::GetTabDist( rDefTabs )); + const sal_uInt16 nDefDist = o3tl::narrowing<sal_uInt16>(::GetTabDist( rDefTabs )); SfxUInt16Item aDefDistItem( SID_ATTR_TABSTOP_DEFAULTS, nDefDist ); aCoreSet.Put( aDefDistItem ); @@ -1022,8 +1563,8 @@ void SwTextShell::Execute(SfxRequest &rReq) // 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; + const tools::Long nOff = rWrtSh.getIDocumentSettingAccess().get(DocumentSettingId::TABS_RELATIVE_TO_INDENT) + ? aCoreSet.Get(RES_MARGIN_TEXTLEFT).GetTextLeft() : 0; SfxInt32Item aOff( SID_ATTR_TABSTOP_OFFSET, nOff ); aCoreSet.Put( aOff ); @@ -1046,9 +1587,9 @@ void SwTextShell::Execute(SfxRequest &rReq) if ( bUseDialog && GetActiveView() ) { - OString sDefPage; + OUString sDefPage; if (pItem) - sDefPage = OUStringToOString(static_cast<const SfxStringItem*>(pItem)->GetValue(), RTL_TEXTENCODING_UTF8); + sDefPage = static_cast<const SfxStringItem*>(pItem)->GetValue(); SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); pDlg.reset(pFact->CreateSwParaDlg(GetView().GetFrameWeld(), GetView(), aCoreSet, false, sDefPage)); @@ -1059,8 +1600,16 @@ void SwTextShell::Execute(SfxRequest &rReq) if ( nSlot == SID_ATTR_PARA_LRSPACE) { SvxLRSpaceItem aParaMargin(static_cast<const SvxLRSpaceItem&>(pArgs->Get(nSlot))); - aParaMargin.SetWhich( RES_LR_SPACE); - aCoreSet.Put(aParaMargin); + SvxFirstLineIndentItem firstLine(RES_MARGIN_FIRSTLINE); + SvxTextLeftMarginItem leftMargin(RES_MARGIN_TEXTLEFT); + SvxRightMarginItem rightMargin(RES_MARGIN_RIGHT); + firstLine.SetTextFirstLineOffset(aParaMargin.GetTextFirstLineOffset(), aParaMargin.GetPropTextFirstLineOffset()); + firstLine.SetAutoFirst(aParaMargin.IsAutoFirst()); + leftMargin.SetTextLeft(aParaMargin.GetTextLeft(), aParaMargin.GetPropLeft()); + rightMargin.SetRight(aParaMargin.GetRight(), aParaMargin.GetPropRight()); + aCoreSet.Put(firstLine); + aCoreSet.Put(leftMargin); + aCoreSet.Put(rightMargin); sw_ParagraphDialogResult(&aCoreSet, rWrtSh, rReq, pPaM); } @@ -1072,16 +1621,15 @@ void SwTextShell::Execute(SfxRequest &rReq) auto pRequest = std::make_shared<SfxRequest>(rReq); rReq.Ignore(); // the 'old' request is not relevant any more - auto xPaM(std::make_shared<SwPaM>(*pPaM, nullptr)); // tdf#134439 make a copy to use at later apply - pDlg->StartExecuteAsync([pDlg, &rWrtSh, pRequest, nDefDist, xPaM](sal_Int32 nResult){ + 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 SfxPoolItem* pItem2 = nullptr; - if (SfxItemState::SET == pSet->GetItemState(SID_ATTR_TABSTOP_DEFAULTS, false, &pItem2) && - nDefDist != (nNewDist = static_cast<const SfxUInt16Item*>(pItem2)->GetValue()) ) + 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 ); @@ -1089,21 +1637,44 @@ void SwTextShell::Execute(SfxRequest &rReq) 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 (SfxItemState::SET == pSet->GetItemState(RES_PARATR_DROP, false, &pItem2)) + if (const SwFormatDrop* pDropItem = pSet->GetItemIfSet(RES_PARATR_DROP, false)) { OUString sCharStyleName; - if (static_cast<const SwFormatDrop*>(pItem2)->GetCharFormat()) - sCharStyleName = static_cast<const SwFormatDrop*>(pItem2)->GetCharFormat()->GetName(); + if (pDropItem->GetCharFormat()) + sCharStyleName = pDropItem->GetCharFormat()->GetName(); pSet->Put(SfxStringItem(FN_DROP_CHAR_STYLE_NAME, sCharStyleName)); } - sw_ParagraphDialogResult(pSet, rWrtSh, *pRequest, xPaM.get()); + const XFillStyleItem* pFS = pSet->GetItem<XFillStyleItem>(XATTR_FILLSTYLE); + bool bSet = pFS && pFS->GetValue() == drawing::FillStyle_GRADIENT; + const XFillGradientItem* pTempGradItem + = bSet ? pSet->GetItem<XFillGradientItem>(XATTR_FILLGRADIENT) : nullptr; + if (pTempGradItem && pTempGradItem->GetName().isEmpty()) + { + // MigrateItemSet guarantees unique gradient names + SfxItemSetFixed<XATTR_FILLGRADIENT, XATTR_FILLGRADIENT> aMigrateSet(rWrtSh.GetView().GetPool()); + aMigrateSet.Put(XFillGradientItem("gradient", pTempGradItem->GetGradientValue())); + SdrModel::MigrateItemSet(&aMigrateSet, pSet, pDrawModel); + } + + bSet = pFS && pFS->GetValue() == drawing::FillStyle_HATCH; + const XFillHatchItem* pTempHatchItem + = bSet ? pSet->GetItem<XFillHatchItem>(XATTR_FILLHATCH) : nullptr; + if (pTempHatchItem && pTempHatchItem->GetName().isEmpty()) + { + SfxItemSetFixed<XATTR_FILLHATCH, XATTR_FILLHATCH> aMigrateSet(rWrtSh.GetView().GetPool()); + aMigrateSet.Put(XFillHatchItem("hatch", pTempHatchItem->GetHatchValue())); + SdrModel::MigrateItemSet(&aMigrateSet, pSet, pDrawModel); + } + + sw_ParagraphDialogResult(pSet, rWrtSh, *pRequest, vCursors->front().get()); } pDlg->disposeOnce(); }); @@ -1175,64 +1746,45 @@ void SwTextShell::Execute(SfxRequest &rReq) case SID_ATTR_CHAR_COLOR2: { - Color aSet; - const SfxPoolItem* pColorStringItem = nullptr; - bool bHasItem = false; - - if(pItem) - { - aSet = static_cast<const SvxColorItem*>(pItem)->GetValue(); - bHasItem = true; - } - else if (pArgs && SfxItemState::SET == pArgs->GetItemState(SID_ATTR_COLOR_STR, false, &pColorStringItem)) - { - OUString sColor = static_cast<const SfxStringItem*>(pColorStringItem)->GetValue(); - aSet = Color(ColorTransparency, sColor.toInt32(16)); - bHasItem = true; - } - - if (bHasItem) + if (pItem) { + auto* pColorItem = static_cast<const SvxColorItem*>(pItem); SwEditWin& rEditWin = GetView().GetEditWin(); - rEditWin.SetWaterCanTextColor(aSet); + rEditWin.SetWaterCanTextColor(pColorItem->GetValue()); SwApplyTemplate* pApply = rEditWin.GetApplyTemplate(); // If there is a selection, then set the color on it // otherwise, it'll be the color for the next text to be typed - if(!pApply || pApply->nColor != SID_ATTR_CHAR_COLOR_EXT) + if (!pApply || pApply->nColor != SID_ATTR_CHAR_COLOR_EXT) { - rWrtSh.SetAttrItem(SvxColorItem (aSet, RES_CHRATR_COLOR)); + rWrtSh.SetAttrItem(SvxColorItem(pColorItem->GetValue(), pColorItem->getComplexColor(), RES_CHRATR_COLOR)); } rReq.Done(); } } break; - case SID_ATTR_CHAR_COLOR_BACKGROUND: - case SID_ATTR_CHAR_COLOR_BACKGROUND_EXT: + case SID_ATTR_CHAR_BACK_COLOR: + case SID_ATTR_CHAR_COLOR_BACKGROUND: // deprecated case SID_ATTR_CHAR_COLOR_EXT: { - Color aSet; - const SfxPoolItem* pColorStringItem = nullptr; + Color aColor; + model::ComplexColor aComplexColor; - if (pArgs && SfxItemState::SET == pArgs->GetItemState(SID_ATTR_COLOR_STR, false, &pColorStringItem)) + if (pItem) { - OUString sColor = static_cast<const SfxStringItem*>(pColorStringItem)->GetValue(); - if (sColor == "transparent") - aSet = COL_TRANSPARENT; - else - aSet = Color(ColorTransparency, sColor.toInt32(16)); + auto* pColorItem = static_cast<const SvxColorItem*>(pItem); + aColor = pColorItem->GetValue(); + aComplexColor = pColorItem->getComplexColor(); } - else if (pItem) - aSet = static_cast<const SvxColorItem*>(pItem)->GetValue(); else - aSet = COL_TRANSPARENT; + aColor = COL_TRANSPARENT; SwEditWin& rEdtWin = GetView().GetEditWin(); if (nSlot != SID_ATTR_CHAR_COLOR_EXT) - rEdtWin.SetWaterCanTextBackColor(aSet); + rEdtWin.SetWaterCanTextBackColor(aColor); else if (pItem) - rEdtWin.SetWaterCanTextColor(aSet); + rEdtWin.SetWaterCanTextColor(aColor); SwApplyTemplate* pApply = rEdtWin.GetApplyTemplate(); SwApplyTemplate aTempl; @@ -1240,29 +1792,21 @@ void SwTextShell::Execute(SfxRequest &rReq) { if (nSlot != SID_ATTR_CHAR_COLOR_EXT) { - SfxItemSet aCoreSet( rWrtSh.GetView().GetPool(), svl::Items< - RES_CHRATR_BACKGROUND, RES_CHRATR_BACKGROUND>{} ); + SfxItemSetFixed<RES_CHRATR_BACKGROUND, RES_CHRATR_BACKGROUND> aCoreSet( rWrtSh.GetView().GetPool() ); - rWrtSh.GetCurAttr( aCoreSet ); + 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); + if (aColor == rBrushItem.GetColor()) + { + aComplexColor = model::ComplexColor(); + aColor = COL_TRANSPARENT; + } + ApplyCharBackground(aColor, aComplexColor, 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); - } + rWrtSh.SetAttrItem(SvxColorItem(aColor, aComplexColor, RES_CHRATR_COLOR)); } else { @@ -1283,14 +1827,14 @@ void SwTextShell::Execute(SfxRequest &rReq) case FN_NUM_BULLET_MOVEUP: if (!rWrtSh.IsAddMode()) - rWrtSh.MoveParagraph(-1); + 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); + GetView().GetViewFrame().ExecuteSlot( aReq); rReq.Ignore(); } break; @@ -1326,7 +1870,7 @@ void SwTextShell::Execute(SfxRequest &rReq) rWrtSh.EnterBlockMode(); else rWrtSh.EnterStdMode(); - SfxBindings &rBnd = GetView().GetViewFrame()->GetBindings(); + SfxBindings &rBnd = GetView().GetViewFrame().GetBindings(); rBnd.Invalidate(FN_STAT_SELMODE); rBnd.Update(FN_STAT_SELMODE); } @@ -1334,22 +1878,76 @@ void SwTextShell::Execute(SfxRequest &rReq) case SID_OPEN_HYPERLINK: case SID_COPY_HYPERLINK_LOCATION: { - SfxItemSet aSet(GetPool(), - svl::Items<RES_TXTATR_INETFMT, - RES_TXTATR_INETFMT>{}); + SfxItemSetFixed<RES_TXTATR_INETFMT, RES_TXTATR_INETFMT> aSet(GetPool()); rWrtSh.GetCurAttr(aSet); + + const SwFormatINetFormat* pINetFormat = nullptr; if(SfxItemState::SET <= aSet.GetItemState( RES_TXTATR_INETFMT )) + pINetFormat = &aSet.Get(RES_TXTATR_INETFMT); + else if (!rWrtSh.HasSelection()) { - const SwFormatINetFormat& rINetFormat = dynamic_cast<const SwFormatINetFormat&>( aSet.Get(RES_TXTATR_INETFMT) ); - if( nSlot == SID_COPY_HYPERLINK_LOCATION ) + // is the cursor at the beginning of a hyperlink? + const SwTextNode* pTextNd = rWrtSh.GetCursor()->GetPointNode().GetTextNode(); + if (pTextNd) { - OUString hyperlinkLocation = rINetFormat.GetValue(); - ::uno::Reference< datatransfer::clipboard::XClipboard > xClipboard = GetView().GetEditWin().GetClipboard(); + const sal_Int32 nIndex = rWrtSh.GetCursor()->Start()->GetContentIndex(); + const SwTextAttr* pINetFmt = pTextNd->GetTextAttrAt(nIndex, RES_TXTATR_INETFMT); + if (pINetFmt && !pINetFmt->GetINetFormat().GetValue().isEmpty()) + pINetFormat = &pINetFmt->GetINetFormat(); + } + } + if (pINetFormat) + { + if (nSlot == SID_OPEN_HYPERLINK) + { + rWrtSh.ClickToINetAttr(*pINetFormat); + } + else if (nSlot == SID_COPY_HYPERLINK_LOCATION) + { + OUString hyperlinkLocation = pINetFormat->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); + OUString targetURL = ""; + + if (auto targetType = rAuthorityField.GetTargetType(); + targetType == SwAuthorityField::TargetType::UseDisplayURL + || targetType == SwAuthorityField::TargetType::UseTargetURL) + { + // Bibliography entry with URL also provides a hyperlink. + targetURL = rAuthorityField.GetAbsoluteURL(); + } + + if (targetURL.getLength() > 0) + { + if (nSlot == SID_OPEN_HYPERLINK) + { + ::LoadURL(rWrtSh, targetURL, LoadUrlFlags::NewView, /*rTargetFrameName=*/OUString()); + } + else if (nSlot == SID_COPY_HYPERLINK_LOCATION) + { + ::uno::Reference< datatransfer::clipboard::XClipboard > xClipboard = GetView().GetEditWin().GetClipboard(); + vcl::unohelper::TextDataObject::CopyStringTo(targetURL, xClipboard, SfxViewShell::Current()); + } + } + } + } + } + break; + case FN_OPEN_LOCAL_URL: + { + OUString aLocalURL = GetLocalURL(rWrtSh); + if (!aLocalURL.isEmpty()) + { + ::LoadURL(rWrtSh, aLocalURL, LoadUrlFlags::NewView, /*rTargetFrameName=*/OUString()); } } break; @@ -1392,56 +1990,104 @@ void SwTextShell::Execute(SfxRequest &rReq) : 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); + SfxViewFrame& rViewFrame = GetView().GetViewFrame(); + rViewFrame.GetBindings().Invalidate(nSlot); + rViewFrame.GetBindings().Update(nSlot); } break; case SID_FM_CTL_PROPERTIES: { SwPosition aPos(*GetShell().GetCursor()->GetPoint()); - sw::mark::IFieldmark* pFieldBM = GetShell().getIDocumentMarkAccess()->getFieldmarkFor(aPos); + sw::mark::IFieldmark* pFieldBM = GetShell().getIDocumentMarkAccess()->getInnerFieldmarkFor(aPos); if ( !pFieldBM ) { - --aPos.nContent; - pFieldBM = GetShell().getIDocumentMarkAccess()->getFieldmarkFor(aPos); + aPos.AdjustContent(-1); + pFieldBM = GetShell().getIDocumentMarkAccess()->getInnerFieldmarkFor(aPos); } - if ( pFieldBM && pFieldBM->GetFieldname() == ODF_FORMDROPDOWN ) + 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( rWrtSh.GetView().GetVisArea() ); - rWrtSh.UpdateCursor(); // cursor position might be invalid - // Hide the button here and make it visible later, to make transparent background work with SAL_USE_VCLPLUGIN=gen - dynamic_cast<::sw::mark::DropDownFieldmark&>(*pFieldBM).HideButton(); - } + VclPtr<AbstractDropDownFormFieldDialog> pDlg(pFact->CreateDropDownFormFieldDialog(rWrtSh.GetView().GetFrameWeld(), pFieldBM)); + auto xRequest = std::make_shared<SfxRequest>(rReq); + rReq.Ignore(); // the 'old' request is not relevant any more + auto pWrtSh = &rWrtSh; + pDlg->StartExecuteAsync( + [pDlg, pFieldBM, pWrtSh, xRequest] (sal_Int32 nResult)->void + { + if (nResult == RET_OK) + { + pDlg->Apply(); + pFieldBM->Invalidate(); + pWrtSh->InvalidateWindows( SwRect(pWrtSh->GetView().GetVisArea()) ); + pWrtSh->UpdateCursor(); // cursor position might be invalid + } + pDlg->disposeOnce(); + xRequest->Done(); + } + ); } 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( rWrtSh.GetView().GetVisArea() ); - rWrtSh.UpdateCursor(); // cursor position might be invalid - // Hide the button here and make it visible later, to make transparent background work with SAL_USE_VCLPLUGIN=gen - rDateField.HideButton(); - } + sw::mark::DateFieldmark* pDateField = &dynamic_cast<sw::mark::DateFieldmark&>(*pFieldBM); + VclPtr<AbstractDateFormFieldDialog> pDlg(pFact->CreateDateFormFieldDialog(rWrtSh.GetView().GetFrameWeld(), pDateField, *GetView().GetDocShell()->GetDoc())); + auto pWrtSh = &rWrtSh; + auto xRequest = std::make_shared<SfxRequest>(rReq); + rReq.Ignore(); // the 'old' request is not relevant any more + pDlg->StartExecuteAsync( + [pDlg, pWrtSh, pDateField, xRequest] (sal_Int32 nResult)->void + { + if (nResult == RET_OK) + { + pDlg->Apply(); + pDateField->Invalidate(); + pWrtSh->InvalidateWindows( SwRect(pWrtSh->GetView().GetVisArea()) ); + pWrtSh->UpdateCursor(); // cursor position might be invalid + } + pDlg->disposeOnce(); + xRequest->Done(); + } + ); } else { - SfxRequest aReq( GetView().GetViewFrame(), SID_FM_CTL_PROPERTIES ); + SfxRequest aReq(GetView().GetViewFrame(), SID_FM_CTL_PROPERTIES); aReq.AppendItem( SfxBoolItem( SID_FM_CTL_PROPERTIES, true ) ); rWrtSh.GetView().GetFormShell()->Execute( aReq ); } } break; + case SID_FM_TRANSLATE: + { +#if HAVE_FEATURE_CURL && !ENABLE_WASM_STRIP_EXTRA + const SfxPoolItem* pTargetLangStringItem = nullptr; + if (pArgs && SfxItemState::SET == pArgs->GetItemState(SID_ATTR_TARGETLANG_STR, false, &pTargetLangStringItem)) + { + std::optional<OUString> oDeeplAPIUrl = officecfg::Office::Linguistic::Translation::Deepl::ApiURL::get(); + std::optional<OUString> oDeeplKey = officecfg::Office::Linguistic::Translation::Deepl::AuthKey::get(); + if (!oDeeplAPIUrl || oDeeplAPIUrl->isEmpty() || !oDeeplKey || oDeeplKey->isEmpty()) + { + SAL_WARN("sw.ui", "SID_FM_TRANSLATE: API options are not set"); + break; + } + const OString aAPIUrl = OUStringToOString(rtl::Concat2View(*oDeeplAPIUrl + "?tag_handling=html"), RTL_TEXTENCODING_UTF8).trim(); + const OString aAuthKey = OUStringToOString(*oDeeplKey, RTL_TEXTENCODING_UTF8).trim(); + OString aTargetLang = OUStringToOString(static_cast<const SfxStringItem*>(pTargetLangStringItem)->GetValue(), RTL_TEXTENCODING_UTF8); + SwTranslateHelper::TranslateAPIConfig aConfig({aAPIUrl, aAuthKey, aTargetLang}); + SwTranslateHelper::TranslateDocument(rWrtSh, aConfig); + } + else + { + SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); + std::shared_ptr<AbstractSwTranslateLangSelectDlg> pAbstractDialog(pFact->CreateSwTranslateLangSelectDlg(GetView().GetFrameWeld(), rWrtSh)); + std::shared_ptr<weld::DialogController> pDialogController(pAbstractDialog->getDialogController()); + weld::DialogController::runAsync(pDialogController, [] (sal_Int32 /*nResult*/) { }); + } +#endif // HAVE_FEATURE_CURL && ENABLE_WASM_STRIP_EXTRA + } + break; case SID_SPELLCHECK_IGNORE: { SwPaM *pPaM = rWrtSh.GetCursor(); @@ -1475,9 +2121,13 @@ void SwTextShell::Execute(SfxRequest &rReq) SwPaM *pPaM = rWrtSh.GetCursor(); if (pPaM) SwEditShell::IgnoreGrammarErrorAt( *pPaM ); - // refresh the layout of all paragraphs (workaround to launch a dictionary event) - xDictionary->setActive(false); - xDictionary->setActive(true); + if (xDictionary.is() && pPaM) + { + linguistic::AddEntryToDic( xDictionary, pPaM->GetText(), false, OUString() ); + // refresh the layout of all paragraphs (workaround to launch a dictionary event) + xDictionary->setActive(false); + xDictionary->setActive(true); + } } catch( const uno::Exception& ) { @@ -1487,12 +2137,14 @@ void SwTextShell::Execute(SfxRequest &rReq) else if (sApplyText == "Spelling") { SwRect aToFill; - uno::Reference< linguistic2::XSpellAlternatives > xSpellAlt( rWrtSh.GetCorrection(nullptr, 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->getEntry(sWord).is()) + if (linguistic::DictionaryError::NONE != nAddRes && xDictionary.is() && !xDictionary->getEntry(sWord).is()) { SvxDicError(rWrtSh.GetView().GetFrameWeld(), nAddRes); } @@ -1506,20 +2158,20 @@ void SwTextShell::Execute(SfxRequest &rReq) if (pItem2) sApplyText = pItem2->GetValue(); - const OUString sSpellingRule("Spelling_"); - const OUString sGrammarRule("Grammar_"); + static constexpr OUString sSpellingRule(u"Spelling_"_ustr); + static constexpr OUString sGrammarRule(u"Grammar_"_ustr); bool bGrammar = false; sal_Int32 nPos = 0; uno::Reference< linguistic2::XSpellAlternatives > xSpellAlt; if(-1 != (nPos = sApplyText.indexOf( sGrammarRule ))) { - sApplyText = sApplyText.replaceAt(nPos, sGrammarRule.getLength(), ""); + sApplyText = sApplyText.replaceAt(nPos, sGrammarRule.getLength(), u""); bGrammar = true; } else if (-1 != (nPos = sApplyText.indexOf( sSpellingRule ))) { - sApplyText = sApplyText.replaceAt(nPos, sSpellingRule.getLength(), ""); + sApplyText = sApplyText.replaceAt(nPos, sSpellingRule.getLength(), u""); SwRect aToFill; xSpellAlt.set(rWrtSh.GetCorrection(nullptr, aToFill)); bGrammar = false; @@ -1545,7 +2197,9 @@ void SwTextShell::Execute(SfxRequest &rReq) SwRewriter aRewriter; - aRewriter.AddRule(UndoArg1, rWrtSh.GetCursorDescr()); + aRewriter.AddRule(UndoArg1, rWrtSh.GetCursorDescr() + // don't show the hidden control character of the comment + .replaceAll(OUStringChar(CH_TXTATR_INWORD), "") ); aRewriter.AddRule(UndoArg2, SwResId(STR_YIELDS)); OUString aTmpStr = SwResId(STR_START_QUOTE) + @@ -1555,7 +2209,9 @@ void SwTextShell::Execute(SfxRequest &rReq) rWrtSh.StartUndo(SwUndoId::UI_REPLACE, &aRewriter); rWrtSh.StartAction(); - rWrtSh.Replace(aTmp, false); + // keep comments at the end of the replacement in case spelling correction is + // invoked via the context menu. The spell check dialog does the correction in edlingu.cxx. + rWrtSh.ReplaceKeepComments(aTmp); rWrtSh.EndAction(); rWrtSh.EndUndo(); @@ -1576,7 +2232,8 @@ void SwTextShell::GetState( SfxItemSet &rSet ) sal_uInt16 nWhich = aIter.FirstWhich(); while ( nWhich ) { - switch ( nWhich ) + const sal_uInt16 nSlotId = GetPool().GetSlotId(nWhich); + switch (nSlotId) { case FN_FORMAT_CURRENT_FOOTNOTE_DLG: if( !rSh.IsCursorInFootnote() ) @@ -1615,11 +2272,10 @@ void SwTextShell::GetState( SfxItemSet &rSet ) } // build sequence for status value - uno::Sequence< OUString > aSeq( 4 ); - aSeq[0] = aCurrentLang; - aSeq[1] = aScriptTypesInUse; - aSeq[2] = aKeyboardLang; - aSeq[3] = SwLangHelper::GetTextForLanguageGuessing( rSh ); + uno::Sequence< OUString > aSeq{ aCurrentLang, + aScriptTypesInUse, + aKeyboardLang, + SwLangHelper::GetTextForLanguageGuessing( rSh ) }; // set sequence as status value SfxStringListItem aItem( SID_LANGUAGE_STATUS ); @@ -1669,7 +2325,6 @@ void SwTextShell::GetState( SfxItemSet &rSet ) case FN_EDIT_FORMULA: case SID_CHARMAP: - case SID_EMOJI_CONTROL: case SID_CHARMAP_CONTROL: { const SelectionType nType = rSh.GetSelectionType(); @@ -1693,7 +2348,18 @@ void SwTextShell::GetState( SfxItemSet &rSet ) { const FrameTypeFlags nNoType = FrameTypeFlags::FLY_ANY | FrameTypeFlags::HEADER | FrameTypeFlags::FOOTER | FrameTypeFlags::FOOTNOTE; - if ( rSh.GetFrameType(nullptr,true) & nNoType ) + FrameTypeFlags eType = rSh.GetFrameType(nullptr, true); + bool bSplitFly = false; + if (eType & FrameTypeFlags::FLY_ATCNT) + { + SwContentFrame* pContentFrame = rSh.GetCurrFrame(/*bCalcFrame=*/false); + if (pContentFrame) + { + SwFlyFrame* pFlyFrame = pContentFrame->FindFlyFrame(); + bSplitFly = pFlyFrame && pFlyFrame->IsFlySplitAllowed(); + } + } + if (eType & nNoType && !bSplitFly) rSet.DisableItem(nWhich); if ( rSh.CursorInsideInputField() ) @@ -1787,6 +2453,7 @@ void SwTextShell::GetState( SfxItemSet &rSet ) rSet.Put( aColorItem.CloneSetWhich(SID_ATTR_CHAR_COLOR2) ); } break; + case SID_ATTR_CHAR_BACK_COLOR: case SID_ATTR_CHAR_COLOR_BACKGROUND: { // Always use the visible background @@ -1795,16 +2462,25 @@ void SwTextShell::GetState( SfxItemSet &rSet ) const SvxBrushItem& aBrushItem = aSet.Get(RES_CHRATR_HIGHLIGHT); if( aBrushItem.GetColor() != COL_TRANSPARENT ) { - rSet.Put( SvxColorItem(aBrushItem.GetColor(), nWhich) ); + rSet.Put(SvxColorItem(aBrushItem.GetColor(), aBrushItem.getComplexColor(), nWhich)); } else { const SvxBrushItem& aBrushItem2 = aSet.Get(RES_CHRATR_BACKGROUND); - rSet.Put( SvxColorItem(aBrushItem2.GetColor(), nWhich) ); + rSet.Put(SvxColorItem(aBrushItem2.GetColor(), aBrushItem2.getComplexColor(), nWhich)); } } break; case SID_ATTR_CHAR_COLOR_BACKGROUND_EXT: + { + SwEditWin& rEdtWin = GetView().GetEditWin(); + SwApplyTemplate* pApply = rEdtWin.GetApplyTemplate(); + const sal_uInt32 nColWhich = pApply ? pApply->nColor : 0; + const bool bUseTemplate = nColWhich == SID_ATTR_CHAR_BACK_COLOR + || nColWhich == SID_ATTR_CHAR_COLOR_BACKGROUND; + rSet.Put(SfxBoolItem(nWhich, bUseTemplate)); + } + break; case SID_ATTR_CHAR_COLOR_EXT: { SwEditWin& rEdtWin = GetView().GetEditWin(); @@ -1832,7 +2508,7 @@ void SwTextShell::GetState( SfxItemSet &rSet ) case FN_INSERT_BREAK_DLG: case FN_INSERT_COLUMN_BREAK: case FN_INSERT_PAGEBREAK: - if( rSh.CursorInsideInputField() ) + if( rSh.CursorInsideInputField() || rSh.CursorInsideContentControl() ) { rSet.DisableItem( nWhich ); } @@ -1848,8 +2524,8 @@ void SwTextShell::GetState( SfxItemSet &rSet ) OUString aStyleName; std::vector<OUString> aList; - const OUString sPhysical("IsPhysical"); - const OUString sDisplay("DisplayName"); + static constexpr OUStringLiteral sPhysical(u"IsPhysical"); + static constexpr OUStringLiteral sDisplay(u"DisplayName"); const OUString sHeaderOn(nWhich == FN_INSERT_PAGEHEADER ? OUString("HeaderIsOn") : OUString("FooterIsOn")); uno::Reference< XStyleFamiliesSupplier > xSupplier(GetView().GetDocShell()->GetBaseModel(), uno::UNO_QUERY); @@ -1877,7 +2553,7 @@ void SwTextShell::GetState( SfxItemSet &rSet ) } else bIsPhysical = false; - } + } } } @@ -1900,21 +2576,39 @@ void SwTextShell::GetState( SfxItemSet &rSet ) case SID_RUBY_DIALOG: { - SvtCJKOptions aCJKOptions; - if( !aCJKOptions.IsRubyEnabled() + if( !SvtCJKOptions::IsRubyEnabled() || rSh.CursorInsideInputField() ) { - GetView().GetViewFrame()->GetBindings().SetVisibleState( nWhich, false ); + GetView().GetViewFrame().GetBindings().SetVisibleState( nWhich, false ); rSet.DisableItem(nWhich); } else - GetView().GetViewFrame()->GetBindings().SetVisibleState( nWhich, true ); + GetView().GetViewFrame().GetBindings().SetVisibleState( nWhich, true ); + } + break; + + case SID_FM_TRANSLATE: + { +#if HAVE_FEATURE_CURL && !ENABLE_WASM_STRIP_EXTRA + if (!officecfg::Office::Common::Misc::ExperimentalMode::get() + && !comphelper::LibreOfficeKit::isActive()) + { + rSet.Put(SfxVisibilityItem(nWhich, false)); + break; + } + std::optional<OUString> oDeeplAPIUrl = officecfg::Office::Linguistic::Translation::Deepl::ApiURL::get(); + std::optional<OUString> oDeeplKey = officecfg::Office::Linguistic::Translation::Deepl::AuthKey::get(); + if (!oDeeplAPIUrl || oDeeplAPIUrl->isEmpty() || !oDeeplKey || oDeeplKey->isEmpty()) + { + rSet.DisableItem(nWhich); + } +#endif } break; case SID_HYPERLINK_DIALOG: if( GetView().GetDocShell()->IsReadOnly() - || ( !GetView().GetViewFrame()->HasChildWindow(nWhich) + || ( !GetView().GetViewFrame().HasChildWindow(nWhich) && rSh.HasReadonlySel() ) || rSh.CursorInsideInputField() ) { @@ -1922,37 +2616,59 @@ void SwTextShell::GetState( SfxItemSet &rSet ) } else { - rSet.Put(SfxBoolItem( nWhich, nullptr != GetView().GetViewFrame()->GetChildWindow( nWhich ) )); + rSet.Put(SfxBoolItem( nWhich, nullptr != GetView().GetViewFrame().GetChildWindow( nWhich ) )); } break; case SID_EDIT_HYPERLINK: - case SID_COPY_HYPERLINK_LOCATION: { - SfxItemSet aSet(GetPool(), - svl::Items<RES_TXTATR_INETFMT, - RES_TXTATR_INETFMT>{}); - rSh.GetCurAttr(aSet); - if(SfxItemState::SET > aSet.GetItemState( RES_TXTATR_INETFMT ) || rSh.HasReadonlySel()) + if (!rSh.HasReadonlySel()) { - rSet.DisableItem(nWhich); + SfxItemSetFixed<RES_TXTATR_INETFMT, RES_TXTATR_INETFMT> aSet(GetPool()); + rSh.GetCurAttr(aSet); + if (SfxItemState::SET <= aSet.GetItemState(RES_TXTATR_INETFMT)) + break; + + // is the cursor at the beginning of a hyperlink? + const SwTextNode* pTextNd = rSh.GetCursor()->GetPointNode().GetTextNode(); + if (pTextNd && !rSh.HasSelection()) + { + const sal_Int32 nIndex = rSh.GetCursor()->Start()->GetContentIndex(); + const SwTextAttr* pINetFmt + = pTextNd->GetTextAttrAt(nIndex, RES_TXTATR_INETFMT); + if (pINetFmt && !pINetFmt->GetINetFormat().GetValue().isEmpty()) + break; + } } + rSet.DisableItem(nWhich); } break; case SID_REMOVE_HYPERLINK: { - SfxItemSet aSet(GetPool(), - svl::Items<RES_TXTATR_INETFMT, - RES_TXTATR_INETFMT>{}); - 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()) + if (!rSh.HasReadonlySel()) { - rSet.DisableItem(nWhich); + 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 (SfxItemState::SET <= aSet.GetItemState(RES_TXTATR_INETFMT) + || aSet.GetItemState(RES_TXTATR_INETFMT) == SfxItemState::INVALID) + { + break; + } + + // is the cursor at the beginning of a hyperlink? + const SwTextNode* pTextNd = rSh.GetCursor()->GetPointNode().GetTextNode(); + if (pTextNd && !rSh.HasSelection()) + { + const sal_Int32 nIndex = rSh.GetCursor()->Start()->GetContentIndex(); + const SwTextAttr* pINetFmt + = pTextNd->GetTextAttrAt(nIndex, RES_TXTATR_INETFMT); + if (pINetFmt && !pINetFmt->GetINetFormat().GetValue().isEmpty()) + break; + } } + rSet.DisableItem(nWhich); } break; case SID_TRANSLITERATE_HALFWIDTH: @@ -1960,14 +2676,13 @@ void SwTextShell::GetState( SfxItemSet &rSet ) case SID_TRANSLITERATE_HIRAGANA: case SID_TRANSLITERATE_KATAKANA: { - SvtCJKOptions aCJKOptions; - if(!aCJKOptions.IsChangeCaseMapEnabled()) + if(!SvtCJKOptions::IsChangeCaseMapEnabled()) { - GetView().GetViewFrame()->GetBindings().SetVisibleState( nWhich, false ); + GetView().GetViewFrame().GetBindings().SetVisibleState( nWhich, false ); rSet.DisableItem(nWhich); } else - GetView().GetViewFrame()->GetBindings().SetVisibleState( nWhich, true ); + GetView().GetViewFrame().GetBindings().SetVisibleState( nWhich, true ); } break; case FN_READONLY_SELECTION_MODE : @@ -1982,14 +2697,47 @@ void SwTextShell::GetState( SfxItemSet &rSet ) case FN_SELECTION_MODE_BLOCK : rSet.Put(SfxBoolItem(nWhich, (nWhich == FN_SELECTION_MODE_DEFAULT) != rSh.IsBlockMode())); break; - case SID_OPEN_HYPERLINK: + case SID_COPY_HYPERLINK_LOCATION: + case SID_OPEN_HYPERLINK: { - SfxItemSet aSet(GetPool(), - svl::Items<RES_TXTATR_INETFMT, - RES_TXTATR_INETFMT>{}); + SfxItemSetFixed<RES_TXTATR_INETFMT, RES_TXTATR_INETFMT> aSet(GetPool()); rSh.GetCurAttr(aSet); - if(SfxItemState::SET > aSet.GetItemState( RES_TXTATR_INETFMT, false )) + if (SfxItemState::SET <= aSet.GetItemState(RES_TXTATR_INETFMT, false)) + break; + + // is the cursor at the beginning of a hyperlink? + const SwTextNode* pTextNd = rSh.GetCursor()->GetPointNode().GetTextNode(); + if (pTextNd && !rSh.HasSelection()) + { + const sal_Int32 nIndex = rSh.GetCursor()->Start()->GetContentIndex(); + const SwTextAttr* pINetFmt = pTextNd->GetTextAttrAt(nIndex, RES_TXTATR_INETFMT); + if (pINetFmt && !pINetFmt->GetINetFormat().GetValue().isEmpty()) + break; + } + + SwField* pField = rSh.GetCurField(); + if (pField && pField->GetTyp()->Which() == SwFieldIds::TableOfAuthorities) + { + const auto& rAuthorityField = *static_cast<const SwAuthorityField*>(pField); + if (auto targetType = rAuthorityField.GetTargetType(); + targetType == SwAuthorityField::TargetType::UseDisplayURL + || targetType == SwAuthorityField::TargetType::UseTargetURL) + { + // Check if the Bibliography entry has a target URL + if (rAuthorityField.GetAbsoluteURL().getLength() > 0) + break; + } + } + + rSet.DisableItem(nWhich); + } + break; + case FN_OPEN_LOCAL_URL: + { + if (GetLocalURL(rSh).isEmpty()) + { rSet.DisableItem(nWhich); + } } break; case SID_OPEN_SMARTTAGMENU: @@ -2011,17 +2759,17 @@ void SwTextShell::GetState( SfxItemSet &rSet ) aActionIndicesSequence ); uno::Reference <frame::XController> xController = GetView().GetController(); - const lang::Locale aLocale( SW_BREAKITER()->GetLocale( GetAppLanguageTag() ) ); + lang::Locale aLocale( SW_BREAKITER()->GetLocale( GetAppLanguageTag() ) ); const OUString& aApplicationName( rSmartTagMgr.GetApplicationName() ); const OUString aRangeText = xRange->getString(); - const SvxSmartTagItem aItem( nWhich, + const SvxSmartTagItem aItem( SID_OPEN_SMARTTAGMENU, aActionComponentsSequence, aActionIndicesSequence, aStringKeyMaps, xRange, - xController, - aLocale, + std::move(xController), + std::move(aLocale), aApplicationName, aRangeText ); @@ -2040,6 +2788,23 @@ void SwTextShell::GetState( SfxItemSet &rSet ) rSet.Put(SfxBoolItem(FN_NUM_BULLET_ON,rSh.SelectionHasBullet())); break; + case FN_NUM_BULLET_OFF: + rSet.Put(SfxBoolItem(FN_NUM_BULLET_OFF, !rSh.GetNumRuleAtCurrCursorPos() && + !rSh.GetNumRuleAtCurrentSelection())); + break; + + case FN_SVX_SET_OUTLINE: + { + NBOTypeMgrBase* pOutline = NBOutlineTypeMgrFact::CreateInstance(NBOType::Outline); + auto pCurRule = const_cast<SwNumRule*>(rSh.GetNumRuleAtCurrCursorPos()); + if (pOutline && pCurRule) + { + SvxNumRule aSvxRule = pCurRule->MakeSvxNumRule(); + const sal_uInt16 nIndex = pOutline->GetNBOIndexForNumRule(aSvxRule, 0); + rSet.Put(SfxBoolItem(FN_SVX_SET_OUTLINE, nIndex < USHRT_MAX)); + } + break; + } case FN_BUL_NUM_RULE_INDEX: case FN_NUM_NUM_RULE_INDEX: case FN_OUTLINE_RULE_INDEX: @@ -2106,9 +2871,8 @@ void SwTextShell::GetState( SfxItemSet &rSet ) case SID_INSERT_RLM : case SID_INSERT_LRM : { - SvtCTLOptions aCTLOptions; - bool bEnabled = aCTLOptions.IsCTLFontEnabled(); - GetView().GetViewFrame()->GetBindings().SetVisibleState( nWhich, bEnabled ); + bool bEnabled = SvtCTLOptions::IsCTLFontEnabled(); + GetView().GetViewFrame().GetBindings().SetVisibleState( nWhich, bEnabled ); if(!bEnabled) rSet.DisableItem(nWhich); } @@ -2118,7 +2882,7 @@ void SwTextShell::GetState( SfxItemSet &rSet ) bool bDisable = false; // First get the state from the form shell - SfxItemSet aSet(GetShell().GetAttrPool(), svl::Items<SID_FM_CTL_PROPERTIES, SID_FM_CTL_PROPERTIES>{}); + 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 ); @@ -2129,11 +2893,11 @@ void SwTextShell::GetState( SfxItemSet &rSet ) // 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) + sw::mark::IFieldmark* pFieldBM = GetShell().getIDocumentMarkAccess()->getInnerFieldmarkFor(aPos); + if ( !pFieldBM && aPos.GetContentIndex() > 0) { - --aPos.nContent; - pFieldBM = GetShell().getIDocumentMarkAccess()->getFieldmarkFor(aPos); + aPos.AdjustContent(-1); + pFieldBM = GetShell().getIDocumentMarkAccess()->getInnerFieldmarkFor(aPos); } if ( pFieldBM && (pFieldBM->GetFieldname() == ODF_FORMDROPDOWN || pFieldBM->GetFieldname() == ODF_FORMDATE) ) { @@ -2161,6 +2925,14 @@ void SwTextShell::GetState( SfxItemSet &rSet ) rSet.Put(SfxBoolItem(nWhich, bProtected)); } break; + case FN_CONTENT_CONTROL_PROPERTIES: + { + if (!GetShell().CursorInsideContentControl()) + { + rSet.DisableItem(nWhich); + } + } + break; } nWhich = aIter.NextWhich(); } diff --git a/sw/source/uibase/shells/textsh2.cxx b/sw/source/uibase/shells/textsh2.cxx index 0438d42aa3b1..feba747ebf6a 100644 --- a/sw/source/uibase/shells/textsh2.cxx +++ b/sw/source/uibase/shells/textsh2.cxx @@ -31,6 +31,7 @@ #include <fldbas.hxx> #include <dbmgr.hxx> #include <svx/dataaccessdescriptor.hxx> +#include <osl/diagnose.h> #include <vcl/svapp.hxx> @@ -44,12 +45,9 @@ 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 @@ -66,40 +64,36 @@ void SwTextShell::ExecDB(SfxRequest const &rReq) SwDBManager* pDBManager = GetShell().GetDBManager(); OUString sSourceArg, sCommandArg; sal_Int32 nCommandTypeArg = 0; - - const SfxPoolItem* pSourceItem = nullptr; - const SfxPoolItem* pCursorItem = nullptr; - const SfxPoolItem* pConnectionItem = nullptr; - const SfxPoolItem* pCommandItem = nullptr; - const SfxPoolItem* pCommandTypeItem = nullptr; - const SfxPoolItem* pSelectionItem = nullptr; + 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 - pArgs->GetItemState(FN_DB_DATA_SELECTION_ANY, false, &pSelectionItem); Sequence<Any> aSelection; - if(pSelectionItem) - static_cast<const SfxUnoAnyItem*>(pSelectionItem)->GetValue() >>= aSelection; + if(const SfxUnoAnyItem* pSelectionItem = pArgs->GetItemIfSet(FN_DB_DATA_SELECTION_ANY, false)) + pSelectionItem->GetValue() >>= aSelection; // get the data source name - pArgs->GetItemState(FN_DB_DATA_SOURCE_ANY, false, &pSourceItem); + pSourceItem = pArgs->GetItemIfSet(FN_DB_DATA_SOURCE_ANY, false); if(pSourceItem) - static_cast<const SfxUnoAnyItem*>(pSourceItem)->GetValue() >>= sSourceArg; + pSourceItem->GetValue() >>= sSourceArg; // get the command - pArgs->GetItemState(FN_DB_DATA_COMMAND_ANY, false, &pCommandItem); + pCommandItem = pArgs->GetItemIfSet(FN_DB_DATA_COMMAND_ANY, false); if(pCommandItem) - static_cast<const SfxUnoAnyItem*>(pCommandItem)->GetValue() >>= sCommandArg; + pCommandItem->GetValue() >>= sCommandArg; // get the command type - pArgs->GetItemState(FN_DB_DATA_COMMAND_TYPE_ANY, false, &pCommandTypeItem); + pCommandTypeItem = pArgs->GetItemIfSet(FN_DB_DATA_COMMAND_TYPE_ANY, false); if(pCommandTypeItem) - static_cast<const SfxUnoAnyItem*>(pCommandTypeItem)->GetValue() >>= nCommandTypeArg; + pCommandTypeItem->GetValue() >>= nCommandTypeArg; Reference<XConnection> xConnection; - pArgs->GetItemState(FN_DB_CONNECTION_ANY, false, &pConnectionItem); - if ( pConnectionItem ) - static_cast<const SfxUnoAnyItem*>(pConnectionItem)->GetValue() >>= xConnection; + pConnectionItem = pArgs->GetItemIfSet(FN_DB_CONNECTION_ANY, false); + if(pConnectionItem) + pConnectionItem->GetValue() >>= xConnection; // may be we even get no connection if ( !xConnection.is() ) { @@ -112,9 +106,8 @@ void SwTextShell::ExecDB(SfxRequest const &rReq) // get the cursor, we use to travel, may be NULL Reference<XResultSet> xCursor; - pArgs->GetItemState(FN_DB_DATA_CURSOR_ANY, false, &pCursorItem); - if ( pCursorItem ) - static_cast<const SfxUnoAnyItem*>(pCursorItem)->GetValue() >>= xCursor; + if ( const SfxUnoAnyItem* pCursorItem = pArgs->GetItemIfSet(FN_DB_DATA_CURSOR_ANY, false) ) + pCursorItem->GetValue() >>= xCursor; switch (rReq.GetSlot()) { @@ -166,15 +159,13 @@ void SwTextShell::ExecDB(SfxRequest const &rReq) case FN_QRY_INSERT_FIELD: { - const SfxPoolItem* pColumnItem = nullptr; - const SfxPoolItem* pColumnNameItem = nullptr; - - pArgs->GetItemState(FN_DB_COLUMN_ANY, false, &pColumnItem); - pArgs->GetItemState(FN_DB_DATA_COLUMN_NAME_ANY, false, &pColumnNameItem); + 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) - static_cast<const SfxUnoAnyItem*>(pColumnNameItem)->GetValue() >>= sColumnName; + pColumnNameItem->GetValue() >>= sColumnName; OUString sDBName = sSourceArg + OUStringChar(DB_DELIM) + sCommandArg + OUStringChar(DB_DELIM) + OUString::number(nCommandTypeArg) @@ -183,16 +174,16 @@ void SwTextShell::ExecDB(SfxRequest const &rReq) SwFieldMgr aFieldMgr(GetShellPtr()); SwInsertField_Data aData(SwFieldTypesEnum::Database, 0, sDBName, OUString(), 0); if(pConnectionItem) - aData.m_aDBConnection = static_cast<const SfxUnoAnyItem*>(pConnectionItem)->GetValue(); + aData.m_aDBConnection = pConnectionItem->GetValue(); if(pColumnItem) - aData.m_aDBColumn = static_cast<const SfxUnoAnyItem*>(pColumnItem)->GetValue(); + aData.m_aDBColumn = pColumnItem->GetValue(); aFieldMgr.InsertField(aData); - SfxViewFrame* pViewFrame = GetView().GetViewFrame(); + SfxViewFrame& rViewFrame = GetView().GetViewFrame(); uno::Reference< XDispatchRecorder > xRecorder = - pViewFrame->GetBindings().GetRecorder(); + rViewFrame.GetBindings().GetRecorder(); if ( xRecorder.is() ) { - SfxRequest aReq( pViewFrame, FN_INSERT_DBFIELD ); + SfxRequest aReq(rViewFrame, FN_INSERT_DBFIELD); aReq.AppendItem( SfxUInt16Item(FN_PARAM_FIELD_TYPE, static_cast<sal_uInt16>(SwFieldTypesEnum::Database))); aReq.AppendItem( SfxStringItem( FN_INSERT_DBFIELD, sDBName )); aReq.AppendItem( SfxStringItem( FN_PARAM_1, sCommandArg )); @@ -211,49 +202,53 @@ void SwTextShell::ExecDB(SfxRequest const &rReq) IMPL_LINK( SwBaseShell, InsertDBTextHdl, void*, p, void ) { - DBTextStruct_Impl* pDBStruct = static_cast<DBTextStruct_Impl*>(p); - if( pDBStruct ) + std::shared_ptr<DBTextStruct_Impl> pDBStruct(static_cast<DBTextStruct_Impl*>(p)); + if( !pDBStruct ) + return; + + 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() ) { - 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; - } + 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); + 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( !xColSupp ) + { if ( bDispose ) ::comphelper::disposeComponent(xConnection); + return; } - delete pDBStruct; + SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); + VclPtr<AbstractSwInsertDBColAutoPilot>pDlg (pFact->CreateSwInsertDBColAutoPilot(GetView(), + xSource, + xColSupp, + pDBStruct->aDBData)); + pDlg->StartExecuteAsync( + [pDlg, pDBStruct2=std::move(pDBStruct), xSource, xConnection, bDispose] (sal_Int32 nResult) mutable + { + if (nResult == RET_OK) + pDlg->DataToDoc(pDBStruct2->aSelection, xSource, xConnection, pDBStruct2->xCursor); + pDlg->disposeOnce(); + if ( bDispose ) + ::comphelper::disposeComponent(xConnection); + } + ); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/uibase/shells/translatehelper.cxx b/sw/source/uibase/shells/translatehelper.cxx new file mode 100644 index 000000000000..eb9bcaedbb05 --- /dev/null +++ b/sw/source/uibase/shells/translatehelper.cxx @@ -0,0 +1,216 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <config_features.h> +#include <config_wasm_strip.h> +#include <wrtsh.hxx> +#include <pam.hxx> +#include <node.hxx> +#include <ndtxt.hxx> +#include <translatehelper.hxx> +#include <sal/log.hxx> +#include <rtl/string.h> +#include <shellio.hxx> +#include <vcl/scheduler.hxx> +#include <vcl/svapp.hxx> +#include <boost/property_tree/ptree.hpp> +#include <boost/property_tree/json_parser.hpp> +#include <vcl/htmltransferable.hxx> +#include <vcl/transfer.hxx> +#include <swdtflvr.hxx> +#include <linguistic/translate.hxx> +#include <com/sun/star/task/XStatusIndicator.hpp> +#include <sfx2/viewfrm.hxx> +#include <com/sun/star/task/XStatusIndicatorFactory.hpp> +#include <strings.hrc> + +namespace SwTranslateHelper +{ +OString ExportPaMToHTML(SwPaM* pCursor) +{ + SolarMutexGuard gMutex; + OString aResult; + WriterRef xWrt; + GetHTMLWriter(u"NoLineLimit,SkipHeaderFooter,NoPrettyPrint", OUString(), xWrt); + if (pCursor != nullptr) + { + SvMemoryStream aMemoryStream; + SwWriter aWriter(aMemoryStream, *pCursor); + ErrCodeMsg nError = aWriter.Write(xWrt); + if (nError.IsError()) + { + SAL_WARN("sw.ui", "ExportPaMToHTML: failed to export selection to HTML " << nError); + return {}; + } + aResult + = OString(static_cast<const char*>(aMemoryStream.GetData()), aMemoryStream.GetSize()); + aResult = aResult.replaceAll("<p"_ostr, "<span"_ostr); + aResult = aResult.replaceAll("</p>"_ostr, "</span>"_ostr); + + // HTML has for that <br> and <p> also does new line + aResult = aResult.replaceAll("<ul>"_ostr, ""_ostr); + aResult = aResult.replaceAll("</ul>"_ostr, ""_ostr); + aResult = aResult.replaceAll("<ol>"_ostr, ""_ostr); + aResult = aResult.replaceAll("</ol>"_ostr, ""_ostr); + aResult = aResult.replaceAll("\n"_ostr, ""_ostr).trim(); + return aResult; + } + return {}; +} + +void PasteHTMLToPaM(SwWrtShell& rWrtSh, SwPaM* pCursor, const OString& rData) +{ + SolarMutexGuard gMutex; + rtl::Reference<vcl::unohelper::HtmlTransferable> pHtmlTransferable + = new vcl::unohelper::HtmlTransferable(rData); + if (pHtmlTransferable.is()) + { + TransferableDataHelper aDataHelper(pHtmlTransferable); + if (aDataHelper.GetXTransferable().is() + && SwTransferable::IsPasteSpecial(rWrtSh, aDataHelper)) + { + rWrtSh.SetSelection(*pCursor); + SwTransferable::Paste(rWrtSh, aDataHelper); + rWrtSh.KillSelection(nullptr, false); + } + } +} + +#if HAVE_FEATURE_CURL && !ENABLE_WASM_STRIP_EXTRA +void TranslateDocument(SwWrtShell& rWrtSh, const TranslateAPIConfig& rConfig) +{ + bool bCancel = false; + TranslateDocumentCancellable(rWrtSh, rConfig, bCancel); +} + +void TranslateDocumentCancellable(SwWrtShell& rWrtSh, const TranslateAPIConfig& rConfig, + bool& rCancelTranslation) +{ + auto m_pCurrentPam = rWrtSh.GetCursor(); + bool bHasSelection = rWrtSh.HasSelection(); + + if (bHasSelection) + { + // iteration will start top to bottom + if (m_pCurrentPam->GetPoint()->nNode > m_pCurrentPam->GetMark()->nNode) + m_pCurrentPam->Exchange(); + } + + auto const& pNodes = rWrtSh.GetNodes(); + SwPosition aPoint = *m_pCurrentPam->GetPoint(); + SwPosition aMark = *m_pCurrentPam->GetMark(); + auto startNode = bHasSelection ? aPoint.nNode.GetIndex() : SwNodeOffset(0); + auto endNode = bHasSelection ? aMark.nNode.GetIndex() : pNodes.Count() - 1; + + sal_Int32 nCount(0); + sal_Int32 nProgress(0); + + for (SwNodeOffset n(startNode); n <= endNode; ++n) + { + if (pNodes[n] && pNodes[n]->IsTextNode()) + { + if (pNodes[n]->GetTextNode()->GetText().isEmpty()) + continue; + nCount++; + } + } + + SfxViewFrame* pFrame = SfxViewFrame::Current(); + uno::Reference<frame::XFrame> xFrame(pFrame ? pFrame->GetFrame().GetFrameInterface() : nullptr); + uno::Reference<task::XStatusIndicatorFactory> xProgressFactory(xFrame, uno::UNO_QUERY); + uno::Reference<task::XStatusIndicator> xStatusIndicator; + + if (xProgressFactory.is()) + { + xStatusIndicator = xProgressFactory->createStatusIndicator(); + } + + if (xStatusIndicator.is()) + xStatusIndicator->start(SwResId(STR_STATSTR_SWTRANSLATE), nCount); + + for (SwNodeOffset n(startNode); n <= endNode; ++n) + { + if (rCancelTranslation) + break; + + if (n >= rWrtSh.GetNodes().Count()) + break; + + if (!pNodes[n]) + break; + + SwNode* pNode = pNodes[n]; + if (pNode->IsTextNode()) + { + if (pNode->GetTextNode()->GetText().isEmpty()) + continue; + + auto cursor + = Writer::NewUnoCursor(*rWrtSh.GetDoc(), pNode->GetIndex(), pNode->GetIndex()); + + // set edges (start, end) for nodes inside the selection. + if (bHasSelection) + { + if (startNode == endNode) + { + cursor->SetMark(); + cursor->GetPoint()->nContent = aPoint.nContent; + cursor->GetMark()->nContent = aMark.nContent; + } + else if (n == startNode) + { + cursor->SetMark(); + cursor->GetPoint()->nContent = aPoint.nContent; + } + else if (n == endNode) + { + cursor->SetMark(); + cursor->GetMark()->nContent = aMark.nContent; + cursor->GetPoint()->nContent = 0; + } + } + + const auto aOut = SwTranslateHelper::ExportPaMToHTML(cursor.get()); + const auto aTranslatedOut = linguistic::Translate( + rConfig.m_xTargetLanguage, rConfig.m_xAPIUrl, rConfig.m_xAuthKey, aOut); + SwTranslateHelper::PasteHTMLToPaM(rWrtSh, cursor.get(), aTranslatedOut); + + if (xStatusIndicator.is() && nCount) + xStatusIndicator->setValue((100 * ++nProgress) / nCount); + + Idle aIdle("ProgressBar::SetValue aIdle"); + aIdle.SetPriority(TaskPriority::POST_PAINT); + aIdle.Start(); + + rWrtSh.LockView(true); + while (aIdle.IsActive() && !Application::IsQuit()) + { + Application::Yield(); + } + rWrtSh.LockView(false); + } + } + + if (xStatusIndicator.is()) + xStatusIndicator->end(); +} +#endif // HAVE_FEATURE_CURL && !ENABLE_WASM_STRIP_EXTRA +} diff --git a/sw/source/uibase/shells/txtattr.cxx b/sw/source/uibase/shells/txtattr.cxx index 839e7f760e47..1fee6fde1987 100644 --- a/sw/source/uibase/shells/txtattr.cxx +++ b/sw/source/uibase/shells/txtattr.cxx @@ -32,10 +32,12 @@ #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> @@ -71,7 +73,7 @@ void SwTextShell::ExecCharAttr(SfxRequest &rReq) Get( nWhich )).GetValue() ? STATE_ON : STATE_OFF; } - SfxItemSet aSet( GetPool(), svl::Items<RES_CHRATR_BEGIN, RES_CHRATR_END-1>{} ); + SfxItemSetFixed<RES_CHRATR_BEGIN, RES_CHRATR_END-1> aSet( GetPool() ); if (STATE_TOGGLE == eState) rSh.GetCurAttr( aSet ); @@ -93,7 +95,7 @@ void SwTextShell::ExecCharAttr(SfxRequest &rReq) (nWhich == FN_SET_SUPER_SCRIPT && nTmpEsc > 0) ) eEscape = SvxEscapement::Off; - SfxBindings& rBind = GetView().GetViewFrame()->GetBindings(); + SfxBindings& rBind = GetView().GetViewFrame().GetBindings(); if( nWhich == FN_SET_SUB_SCRIPT ) rBind.SetState( SfxBoolItem( FN_SET_SUPER_SCRIPT, false ) ); @@ -113,10 +115,6 @@ void SwTextShell::ExecCharAttr(SfxRequest &rReq) 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(); @@ -211,11 +209,11 @@ void SwTextShell::ExecCharAttrArgs(SfxRequest &rReq) if (rWrtSh.HasSelection() && rWrtSh.IsSelFullPara()) { pColl = rWrtSh.GetCurTextFormatColl(); - if ( pColl && !pColl->IsAutoUpdateFormat() ) + if ( pColl && !pColl->IsAutoUpdateOnDirectFormat() ) pColl = nullptr; } SfxItemPool& rPool = GetPool(); - sal_uInt16 nWhich = rPool.GetWhich( nSlot ); + sal_uInt16 nWhich = rPool.GetWhichIDFromSlotID( nSlot ); switch (nSlot) { case FN_TXTATR_INET: @@ -318,9 +316,9 @@ void SwTextShell::ExecParaAttr(SfxRequest &rReq) const SfxItemSet* pArgs = rReq.GetArgs(); // Get both attributes immediately isn't more expensive!! - SfxItemSet aSet( GetPool(), - svl::Items<RES_PARATR_LINESPACING, RES_PARATR_ADJUST, - RES_FRAMEDIR, RES_FRAMEDIR>{} ); + SfxItemSetFixed + <RES_PARATR_LINESPACING, RES_PARATR_ADJUST, + RES_FRAMEDIR, RES_FRAMEDIR> aSet( GetPool() ); sal_uInt16 nSlot = rReq.GetSlot(); switch (nSlot) @@ -348,20 +346,21 @@ void SwTextShell::ExecParaAttr(SfxRequest &rReq) SET_ADJUST: { aSet.Put(SvxAdjustItem(eAdjst,RES_PARATR_ADJUST)); - rReq.AppendItem( SfxBoolItem( GetPool().GetWhich(nSlot), true ) ); + rReq.AppendItem( SfxBoolItem( GetPool().GetWhichIDFromSlotID(nSlot), true ) ); } break; case SID_ATTR_PARA_LINESPACE: - if(pArgs && SfxItemState::SET == pArgs->GetItemState( GetPool().GetWhich(nSlot) )) + if(pArgs && SfxItemState::SET == pArgs->GetItemState( GetPool().GetWhichIDFromSlotID(nSlot) )) { SvxLineSpacingItem aLineSpace = static_cast<const SvxLineSpacingItem&>( pArgs->Get( - GetPool().GetWhich(nSlot))); + GetPool().GetWhichIDFromSlotID(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: @@ -380,8 +379,7 @@ SET_LINESPACE: case SID_ATTR_PARA_LEFT_TO_RIGHT : case SID_ATTR_PARA_RIGHT_TO_LEFT : { - SfxItemSet aAdjustSet( GetPool(), - svl::Items<RES_PARATR_ADJUST, RES_PARATR_ADJUST>{} ); + SfxItemSetFixed<RES_PARATR_ADJUST, RES_PARATR_ADJUST> aAdjustSet( GetPool() ); GetShell().GetCurAttr(aAdjustSet); bool bChgAdjust = false; SfxItemState eAdjustState = aAdjustSet.GetItemState(RES_PARATR_ADJUST, false); @@ -407,7 +405,7 @@ SET_LINESPACE: SvxAdjustItem aAdjust( eAdjust, RES_PARATR_ADJUST ); aSet.Put( aAdjust ); aAdjust.SetWhich(SID_ATTR_PARA_ADJUST); - GetView().GetViewFrame()->GetBindings().SetState( aAdjust ); + GetView().GetViewFrame().GetBindings().SetState( aAdjust ); // Toggle numbering alignment const SwNumRule* pCurRule = GetShell().GetNumRuleAtCurrCursorPos(); if( pCurRule ) @@ -442,7 +440,7 @@ SET_LINESPACE: } SwWrtShell& rWrtSh = GetShell(); SwTextFormatColl* pColl = rWrtSh.GetCurTextFormatColl(); - if(pColl && pColl->IsAutoUpdateFormat()) + if(pColl && pColl->IsAutoUpdateOnDirectFormat()) { rWrtSh.AutoUpdatePara(pColl, aSet); } @@ -459,14 +457,14 @@ void SwTextShell::ExecParaAttrArgs(SfxRequest &rReq) sal_uInt16 nSlot = rReq.GetSlot(); if(pArgs) - pArgs->GetItemState(GetPool().GetWhich(nSlot), false, &pItem); + pArgs->GetItemState(GetPool().GetWhichIDFromSlotID(nSlot), false, &pItem); switch ( nSlot ) { case FN_DROP_CHAR_STYLE_NAME: if( pItem ) { OUString sCharStyleName = static_cast<const SfxStringItem*>(pItem)->GetValue(); - SfxItemSet aSet(GetPool(), svl::Items<RES_PARATR_DROP, RES_PARATR_DROP>{}); + SfxItemSetFixed<RES_PARATR_DROP, RES_PARATR_DROP> aSet(GetPool()); rSh.GetCurAttr(aSet); SwFormatDrop aDropItem(aSet.Get(RES_PARATR_DROP)); SwCharFormat* pFormat = nullptr; @@ -486,8 +484,8 @@ void SwTextShell::ExecParaAttrArgs(SfxRequest &rReq) } else { - SfxItemSet aSet(GetPool(), svl::Items<RES_PARATR_DROP, RES_PARATR_DROP, - HINT_END, HINT_END>{}); + 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)); @@ -495,10 +493,10 @@ void SwTextShell::ExecParaAttrArgs(SfxRequest &rReq) { rSh.StartAction(); rSh.StartUndo( SwUndoId::START ); - if ( SfxItemState::SET == aSet.GetItemState(HINT_END,false,&pItem) ) + if ( const SfxStringItem* pHintItem = aSet.GetItemIfSet(HINT_END,false) ) { - if ( !static_cast<const SfxStringItem*>(pItem)->GetValue().isEmpty() ) - rSh.ReplaceDropText(static_cast<const SfxStringItem*>(pItem)->GetValue()); + if ( !pHintItem->GetValue().isEmpty() ) + rSh.ReplaceDropText(pHintItem->GetValue()); } rSh.SetAttrSet(*pDlg->GetOutputItemSet()); rSh.EndUndo( SwUndoId::END ); @@ -519,9 +517,8 @@ void SwTextShell::ExecParaAttrArgs(SfxRequest &rReq) { if(pItem) { - SfxItemSet aCoreSet( GetPool(), - svl::Items<RES_PAGEDESC, RES_PAGEDESC, - SID_ATTR_PARA_MODEL, SID_ATTR_PARA_MODEL>{}); + SfxItemSetFixed<RES_PAGEDESC, RES_PAGEDESC, + SID_ATTR_PARA_MODEL, SID_ATTR_PARA_MODEL> aCoreSet( GetPool() ); aCoreSet.Put(*pItem); SfxToSwPageDescAttr( rSh, aCoreSet); rSh.SetAttrSet(aCoreSet); @@ -555,7 +552,7 @@ void SwTextShell::GetAttrState(SfxItemSet &rSet) SfxItemState eState = aCoreSet.GetItemState(RES_PARATR_ADJUST, false, &pItem); if( SfxItemState::DEFAULT == eState ) - pItem = &rPool.GetDefaultItem(RES_PARATR_ADJUST); + pItem = &rPool.GetUserOrPoolDefaultItem(RES_PARATR_ADJUST); if( SfxItemState::DEFAULT <= eState ) { eAdjust = static_cast<const SvxAdjustItem* >( pItem)->GetAdjust(); @@ -565,14 +562,14 @@ void SwTextShell::GetAttrState(SfxItemSet &rSet) short nEsc = 0; eState = aCoreSet.GetItemState(RES_CHRATR_ESCAPEMENT, false, &pItem); if( SfxItemState::DEFAULT == eState ) - pItem = &rPool.GetDefaultItem(RES_CHRATR_ESCAPEMENT); + pItem = &rPool.GetUserOrPoolDefaultItem(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); + pItem = &rPool.GetUserOrPoolDefaultItem(RES_PARATR_LINESPACING); if( SfxItemState::DEFAULT <= eState && static_cast<const SvxLineSpacingItem* >(pItem)->GetLineSpaceRule() == SvxLineSpaceRule::Auto ) { @@ -586,7 +583,7 @@ void SwTextShell::GetAttrState(SfxItemSet &rSet) SvxCaseMap eCaseMap = SvxCaseMap::NotMapped; eState = aCoreSet.GetItemState(RES_CHRATR_CASEMAP, false, &pItem); if (eState == SfxItemState::DEFAULT) - pItem = &rPool.GetDefaultItem(RES_CHRATR_CASEMAP); + pItem = &rPool.GetUserOrPoolDefaultItem(RES_CHRATR_CASEMAP); if (eState >= SfxItemState::DEFAULT) eCaseMap = static_cast<const SvxCaseMapItem*>(pItem)->GetCaseMap(); @@ -652,6 +649,9 @@ void SwTextShell::GetAttrState(SfxItemSet &rSet) 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; @@ -741,10 +741,19 @@ void SwTextShell::GetAttrState(SfxItemSet &rSet) case SID_ATTR_PARA_RIGHTSPACE: case SID_ATTR_PARA_FIRSTLINESPACE: { - eState = aCoreSet.GetItemState(RES_LR_SPACE); + eState = aCoreSet.GetItemState(RES_MARGIN_FIRSTLINE); + eState = std::min(aCoreSet.GetItemState(RES_MARGIN_TEXTLEFT), eState); + eState = std::min(aCoreSet.GetItemState(RES_MARGIN_RIGHT), eState); if( eState >= SfxItemState::DEFAULT ) { - SvxLRSpaceItem aLR = aCoreSet.Get( RES_LR_SPACE ); + SvxLRSpaceItem aLR(RES_LR_SPACE); + SvxFirstLineIndentItem const& rFirstLine(aCoreSet.Get(RES_MARGIN_FIRSTLINE)); + SvxTextLeftMarginItem const& rLeftMargin(aCoreSet.Get(RES_MARGIN_TEXTLEFT)); + SvxRightMarginItem const& rRightMargin(aCoreSet.Get(RES_MARGIN_RIGHT)); + aLR.SetTextFirstLineOffset(rFirstLine.GetTextFirstLineOffset(), rFirstLine.GetPropTextFirstLineOffset()); + aLR.SetAutoFirst(rFirstLine.IsAutoFirst()); + aLR.SetTextLeft(rLeftMargin.GetTextLeft(), rLeftMargin.GetPropLeft()); + aLR.SetRight(rRightMargin.GetRight(), rRightMargin.GetPropRight()); aLR.SetWhich(nSlot); rSet.Put(aLR); } @@ -757,7 +766,7 @@ void SwTextShell::GetAttrState(SfxItemSet &rSet) case SID_ATTR_PARA_LEFT_TO_RIGHT : case SID_ATTR_PARA_RIGHT_TO_LEFT : { - if ( !SW_MOD()->GetCTLOptions().IsCTLFontEnabled() ) + if ( !SvtCTLOptions::IsCTLFontEnabled() ) { rSet.DisableItem( nSlot ); nSlot = 0; @@ -794,20 +803,15 @@ void SwTextShell::GetAttrState(SfxItemSet &rSet) case SID_ATTR_CHAR_KERNING: case RES_PARATR_DROP: { -#if OSL_DEBUG_LEVEL > 1 - const SfxPoolItem& rItem = aCoreSet.Get(GetPool().GetWhich(nSlot), true); - rSet.Put(rItem); -#else - rSet.Put(aCoreSet.Get( GetPool().GetWhich(nSlot))); -#endif + rSet.Put(aCoreSet.Get( GetPool().GetWhichIDFromSlotID(nSlot))); nSlot = 0; } break; case SID_ATTR_PARA_MODEL: { - SfxItemSet aTemp(GetPool(), - svl::Items<RES_PAGEDESC,RES_PAGEDESC, - SID_ATTR_PARA_MODEL,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)); @@ -816,7 +820,7 @@ void SwTextShell::GetAttrState(SfxItemSet &rSet) break; case RES_TXTATR_INETFMT: { - SfxItemSet aSet(GetPool(), svl::Items<RES_TXTATR_INETFMT, 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); diff --git a/sw/source/uibase/shells/txtcrsr.cxx b/sw/source/uibase/shells/txtcrsr.cxx index 1290c2070679..6dc161cb1e58 100644 --- a/sw/source/uibase/shells/txtcrsr.cxx +++ b/sw/source/uibase/shells/txtcrsr.cxx @@ -25,6 +25,7 @@ #include <svl/eitem.hxx> #include <sfx2/viewfrm.hxx> #include <sfx2/bindings.hxx> +#include <osl/diagnose.h> #include <view.hxx> #include <wrtsh.hxx> @@ -51,11 +52,10 @@ void SwTextShell::ExecBasicMove(SfxRequest &rReq) sal_Int32 nCount = 1; if(pArgs) { - const SfxPoolItem *pItem; - if(SfxItemState::SET == pArgs->GetItemState(FN_PARAM_MOVE_COUNT, true, &pItem)) - nCount = static_cast<const SfxInt32Item *>(pItem)->GetValue(); - if(SfxItemState::SET == pArgs->GetItemState(FN_PARAM_MOVE_SELECTION, true, &pItem)) - bSelect = static_cast<const SfxBoolItem *>(pItem)->GetValue(); + 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()) { @@ -78,7 +78,7 @@ void SwTextShell::ExecBasicMove(SfxRequest &rReq) } uno::Reference< frame::XDispatchRecorder > xRecorder = - GetView().GetViewFrame()->GetBindings().GetRecorder(); + GetView().GetViewFrame().GetBindings().GetRecorder(); if ( xRecorder.is() ) { rReq.AppendItem( SfxInt32Item(FN_PARAM_MOVE_COUNT, nCount) ); @@ -93,10 +93,10 @@ void SwTextShell::ExecBasicMove(SfxRequest &rReq) switch(nSlot) { case FN_CHAR_LEFT: - rSh.Left( CRSR_SKIP_CELLS, bSelect, 1, false, true ); + rSh.Left( SwCursorSkipMode::Cells, bSelect, 1, false, true ); break; case FN_CHAR_RIGHT: - rSh.Right( CRSR_SKIP_CELLS, bSelect, 1, false, true ); + rSh.Right( SwCursorSkipMode::Cells, bSelect, 1, false, true ); break; case FN_LINE_UP: rSh.Up( bSelect ); @@ -334,7 +334,7 @@ void SwTextShell::ExecMoveMisc(SfxRequest &rReq) break; std::unique_ptr< svx::ISdrObjectFilter > pFilter( FmFormShell::CreateFocusableControlFilter( - *pDrawView, *pWindow ) ); + *pDrawView, *pWindow->GetOutDev() ) ); if (!pFilter) break; @@ -347,7 +347,7 @@ void SwTextShell::ExecMoveMisc(SfxRequest &rReq) if ( !pUnoObject ) break; - pFormShell->ToggleControlFocus( *pUnoObject, *pDrawView, *pWindow ); + pFormShell->ToggleControlFocus( *pUnoObject, *pDrawView, *pWindow->GetOutDev() ); } break; case FN_CNTNT_TO_NEXT_FRAME: diff --git a/sw/source/uibase/shells/txtnum.cxx b/sw/source/uibase/shells/txtnum.cxx index 3feff416724b..bdad7870afbf 100644 --- a/sw/source/uibase/shells/txtnum.cxx +++ b/sw/source/uibase/shells/txtnum.cxx @@ -22,6 +22,7 @@ #include <svl/stritem.hxx> #include <editeng/numitem.hxx> #include <editeng/brushitem.hxx> +#include <osl/diagnose.h> #include <numrule.hxx> #include <cmdid.h> @@ -65,7 +66,7 @@ void SwTextShell::ExecEnterNum(SfxRequest &rReq) } bool bNewResult = GetShell().SelectionHasNumber(); if (bNewResult!=bMode) { - SfxBindings& rBindings = GetView().GetViewFrame()->GetBindings(); + SfxBindings& rBindings = GetView().GetViewFrame().GetBindings(); SfxBoolItem aItem(FN_NUM_NUMBERING_ON,!bNewResult); rBindings.SetState(aItem); SfxBoolItem aNewItem(FN_NUM_NUMBERING_ON,bNewResult); @@ -94,7 +95,7 @@ void SwTextShell::ExecEnterNum(SfxRequest &rReq) } bool bNewResult = GetShell().SelectionHasBullet(); if (bNewResult!=bMode) { - SfxBindings& rBindings = GetView().GetViewFrame()->GetBindings(); + SfxBindings& rBindings = GetView().GetViewFrame().GetBindings(); SfxBoolItem aItem(FN_NUM_BULLET_ON,!bNewResult); rBindings.SetState(aItem); SfxBoolItem aNewItem(FN_NUM_BULLET_ON,bNewResult); @@ -104,12 +105,22 @@ void SwTextShell::ExecEnterNum(SfxRequest &rReq) } 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().DelNumRules(); + GetShell().EndAllAction(); + } + break; + case FN_NUMBER_BULLETS: case SID_OUTLINE_BULLET: { - SfxItemSet aSet( GetPool(), - svl::Items<SID_HTML_MODE, SID_HTML_MODE, - SID_ATTR_NUMBERING_RULE, SID_PARAM_CUR_NUM_LEVEL>{} ); + 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(); @@ -170,7 +181,7 @@ void SwTextShell::ExecEnterNum(SfxRequest &rReq) } aSvxRule.SetFeatureFlag(SvxNumRuleFlags::ENABLE_EMBEDDED_BMP, false); } - aSet.Put( SvxNumBulletItem( aSvxRule ) ); + aSet.Put( SvxNumBulletItem( std::move(aSvxRule) ) ); } aSet.Put( SfxBoolItem( SID_PARAM_NUM_PRESET,false )); @@ -180,29 +191,29 @@ void SwTextShell::ExecEnterNum(SfxRequest &rReq) SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); weld::Window *pParent = rReq.GetFrameWeld(); - VclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateSvxNumBulletTabDialog(pParent, &aSet, GetShell())); + VclPtr<AbstractNumBulletDialog> 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 ) ); + pDlg->SetCurPageId( pPageItem->GetValue() ); - auto pRequest = std::make_shared<SfxRequest>(rReq); + auto xRequest = 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){ + pDlg->StartExecuteAsync([pDlg, pNumRuleAtCurrentSelection, xRequest=std::move(xRequest), this](sal_Int32 nResult){ if (RET_OK == nResult) { - const SfxPoolItem* pItem; - if (SfxItemState::SET == pDlg->GetOutputItemSet()->GetItemState(SID_ATTR_NUMBERING_RULE, false, &pItem)) + const SvxNumBulletItem* pBulletItem = pDlg->GetOutputItemSet()->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false); + if (pBulletItem) { - pRequest->AppendItem(*pItem); - pRequest->Done(); - SvxNumRule* pSetRule = static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule(); - pSetRule->UnLinkGraphics(); + xRequest->AppendItem(*pBulletItem); + xRequest->Done(); + SvxNumRule& rSetRule = const_cast<SvxNumRule&>(pBulletItem->GetNumRule()); + rSetRule.UnLinkGraphics(); SwNumRule aSetRule(pNumRuleAtCurrentSelection != nullptr ? pNumRuleAtCurrentSelection->GetName() : GetShell().GetUniqueNumRuleName(), numfunc::GetDefaultPositionAndSpaceMode()); - aSetRule.SetSvxRule(*pSetRule, GetShell().GetDoc()); + 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. @@ -212,15 +223,15 @@ void SwTextShell::ExecEnterNum(SfxRequest &rReq) // 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 - && SfxItemState::SET == aSet.GetItemState(SID_ATTR_NUMBERING_RULE, false, &pItem)) + && (pBulletItem = pDlg->GetInputItemSet()->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false))) { - pRequest->AppendItem(*pItem); - pRequest->Done(); - SvxNumRule* pSetRule = static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule(); + xRequest->AppendItem(*pBulletItem); + xRequest->Done(); + const SvxNumRule& rSetRule = pBulletItem->GetNumRule(); SwNumRule aSetRule( GetShell().GetUniqueNumRuleName(), numfunc::GetDefaultPositionAndSpaceMode()); - aSetRule.SetSvxRule(*pSetRule, GetShell().GetDoc()); + aSetRule.SetSvxRule(rSetRule, GetShell().GetDoc()); aSetRule.SetAutoRule(true); // start new list GetShell().SetCurNumRule(aSetRule, true); @@ -298,6 +309,14 @@ void SwTextShell::ExecSetNumber(SfxRequest const &rReq) GetShell().SetCurNumRule( aNewNumRule, bCreateNewList ); } } + else if (nSlot == FN_SVX_SET_OUTLINE) + { + // no outline provided: launch dialog to request a specific outline + SfxBindings& rBindings = GetView().GetViewFrame().GetBindings(); + const SfxStringItem aPage(FN_PARAM_1, "outlinenum"); + const SfxPoolItem* aItems[] = { &aPage, nullptr }; + rBindings.Execute(SID_OUTLINE_BULLET, aItems); + } } break; |