sw/qa/extras/uiwriter/data2/image-comment.odt |binary sw/qa/extras/uiwriter/uiwriter2.cxx | 34 +++++++++ sw/sdi/_frmsh.sdi | 10 ++ sw/source/uibase/inc/frmsh.hxx | 2 sw/source/uibase/inc/wrtsh.hxx | 5 + sw/source/uibase/shells/frmsh.cxx | 27 +++++++ sw/source/uibase/shells/textfld.cxx | 65 ----------------- sw/source/uibase/wrtsh/wrtsh1.cxx | 96 ++++++++++++++++++++++++++ 8 files changed, 175 insertions(+), 64 deletions(-)
New commits: commit ab813ebf7a47d9e448ff93977600c06547e59d79 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Tue Jun 18 17:44:33 2019 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Mon Jul 1 16:43:03 2019 +0200 sw: implement inserting comments when an as-char image is selected Only the UI was missing in this case: creating a text selection around the placeholder character does what the user expects. (cherry picked from commit 351b9aefe3de7c68e907fdc7926d9b508560320e) Conflicts: sw/qa/extras/uiwriter/uiwriter2.cxx sw/source/uibase/wrtsh/wrtsh1.cxx Change-Id: I1068fcee3e3b6d0a6fa47b37beb1bd1b918a82df diff --git a/sw/qa/extras/uiwriter/data2/image-comment.odt b/sw/qa/extras/uiwriter/data2/image-comment.odt new file mode 100644 index 000000000000..4f0a520bcca3 Binary files /dev/null and b/sw/qa/extras/uiwriter/data2/image-comment.odt differ diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx index 122efa846efe..45bf0ecfd496 100644 --- a/sw/qa/extras/uiwriter/uiwriter2.cxx +++ b/sw/qa/extras/uiwriter/uiwriter2.cxx @@ -25,6 +25,10 @@ #include <itabenum.hxx> #include <fmtfsize.hxx> #include <fmtornt.hxx> +#include <sfx2/viewfrm.hxx> +#include <sfx2/dispatch.hxx> +#include <view.hxx> +#include <cmdid.h> #include <com/sun/star/style/BreakType.hpp> #include <flyfrms.hxx> #include <UndoManager.hxx> @@ -73,6 +77,7 @@ public: void testCheckboxFormFieldInsertion(); void testDropDownFormFieldInsertion(); void testMixedFormFieldInsertion(); + void testImageComment(); CPPUNIT_TEST_SUITE(SwUiWriterTest2); CPPUNIT_TEST(testRedlineMoveInsertInDelete); @@ -100,6 +105,7 @@ public: CPPUNIT_TEST(testCheckboxFormFieldInsertion); CPPUNIT_TEST(testDropDownFormFieldInsertion); CPPUNIT_TEST(testMixedFormFieldInsertion); + CPPUNIT_TEST(testImageComment); CPPUNIT_TEST_SUITE_END(); private: @@ -1104,6 +1110,34 @@ void SwUiWriterTest2::testMixedFormFieldInsertion() CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pMarkAccess->getAllMarksCount()); } +void SwUiWriterTest2::testImageComment() +{ + // Load a document with an as-char image in it. + SwDoc* pDoc = createDoc("image-comment.odt"); + SwView* pView = pDoc->GetDocShell()->GetView(); + + // Select the image. + pView->GetViewFrame()->GetDispatcher()->Execute(FN_CNTNT_TO_NEXT_FRAME, SfxCallMode::SYNCHRON); + + // Insert a comment while the image is selected. + pView->GetViewFrame()->GetDispatcher()->Execute(FN_POSTIT, SfxCallMode::SYNCHRON); + + // Verify that the comment is around the image. + // Without the accompanying fix in place, this test would have failed, as FN_POSTIT was disabled + // in the frame shell. + uno::Reference<text::XTextRange> xPara = getParagraph(1); + CPPUNIT_ASSERT_EQUAL(OUString("Text"), + getProperty<OUString>(getRun(xPara, 1), "TextPortionType")); + CPPUNIT_ASSERT_EQUAL(OUString("Annotation"), + getProperty<OUString>(getRun(xPara, 2), "TextPortionType")); + CPPUNIT_ASSERT_EQUAL(OUString("Frame"), + getProperty<OUString>(getRun(xPara, 3), "TextPortionType")); + CPPUNIT_ASSERT_EQUAL(OUString("AnnotationEnd"), + getProperty<OUString>(getRun(xPara, 4), "TextPortionType")); + CPPUNIT_ASSERT_EQUAL(OUString("Text"), + getProperty<OUString>(getRun(xPara, 5), "TextPortionType")); +} + CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest2); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/sdi/_frmsh.sdi b/sw/sdi/_frmsh.sdi index 398cd30a93ff..87df09bb3f5b 100644 --- a/sw/sdi/_frmsh.sdi +++ b/sw/sdi/_frmsh.sdi @@ -411,5 +411,10 @@ interface BaseTextFrame ExecMethod = ExecMove ; StateMethod = NoState ; ] + FN_POSTIT + [ + ExecMethod = ExecField ; + StateMethod = NoState ; + ] } diff --git a/sw/source/uibase/inc/frmsh.hxx b/sw/source/uibase/inc/frmsh.hxx index 4b8a64c75823..e3e900acce56 100644 --- a/sw/source/uibase/inc/frmsh.hxx +++ b/sw/source/uibase/inc/frmsh.hxx @@ -36,6 +36,7 @@ public: void Execute(SfxRequest &); void ExecMove(SfxRequest& rReq); + void ExecField(SfxRequest& rReq); void GetState(SfxItemSet &); void ExecFrameStyle(SfxRequest const & rReq); void GetLineStyleState(SfxItemSet &rSet); diff --git a/sw/source/uibase/shells/frmsh.cxx b/sw/source/uibase/shells/frmsh.cxx index 931ec500b6de..02a3a7376d7f 100644 --- a/sw/source/uibase/shells/frmsh.cxx +++ b/sw/source/uibase/shells/frmsh.cxx @@ -86,6 +86,7 @@ #include <sfx2/msg.hxx> #include <swslots.hxx> #include <grfatr.hxx> +#include <fldmgr.hxx> using ::editeng::SvxBorderLine; using namespace ::com::sun::star; @@ -127,6 +128,19 @@ void SwFrameShell::ExecMove(SfxRequest& rReq) } } +void SwFrameShell::ExecField(SfxRequest& rReq) +{ + SwWrtShell& rSh = GetShell(); + sal_uInt16 nSlot = rReq.GetSlot(); + switch (nSlot) + { + case FN_POSTIT: + SwFieldMgr aFieldMgr(&rSh); + rSh.InsertPostIt(aFieldMgr, rReq); + break; + } +} + void SwFrameShell::Execute(SfxRequest &rReq) { //First those who do not need FrameMgr. diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx b/sw/source/uibase/wrtsh/wrtsh1.cxx index 79f485ce30e8..3eae0e1bdb5b 100644 --- a/sw/source/uibase/wrtsh/wrtsh1.cxx +++ b/sw/source/uibase/wrtsh/wrtsh1.cxx @@ -88,6 +88,7 @@ #include <editeng/acorrcfg.hxx> #include <IMark.hxx> #include <sfx2/bindings.hxx> +#include <flyfrm.hxx> // -> #111827# #include <SwRewriter.hxx> @@ -1883,6 +1884,27 @@ void SwWrtShell::InsertPostIt(SwFieldMgr& rFieldMgr, SfxRequest& rReq) GetView().GetEditWin().StopQuickHelp(); SwInsertField_Data aData(TYP_POSTITFLD, 0, sAuthor, sText, 0); + + if (IsSelFrameMode()) + { + SwFlyFrame* pFly = GetSelectedFlyFrame(); + + // A frame is selected, end frame selection. + EnterStdMode(); + GetView().AttrChangedNotify(this); + + // Set up text selection, so the anchor of the frame will be the anchor of the + // comment. + if (pFly) + { + SwFrameFormat* pFormat = pFly->GetFormat(); + if (pFormat && pFormat->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR) + { + Right(CRSR_SKIP_CELLS, /*bSelect=*/true, 1, /*bBasicCall=*/false, /*bVisual=*/true); + } + } + } + rFieldMgr.InsertField( aData ); Push(); commit 4d2d4aa8d109cf57e9ff19afc97088ae365672e3 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Tue May 28 18:11:13 2019 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Mon Jul 1 16:34:13 2019 +0200 sw: implement select-all for the frame shell There is no reason why Ctrl-A should be a NOP when you have an image selected. No test, there is one in the cp-6.0 copy&paste code, that coverage will arrive as part of that copy&paste code forward-port. Change-Id: If0013ee0e9ff9a6fb038a22de7b5d3c76e5c52b9 Reviewed-on: https://gerrit.libreoffice.org/73118 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins (cherry picked from commit 40c096508da7ee14f36715eee3185041f4a36ddd) diff --git a/sw/sdi/_frmsh.sdi b/sw/sdi/_frmsh.sdi index 6d02c04efdeb..398cd30a93ff 100644 --- a/sw/sdi/_frmsh.sdi +++ b/sw/sdi/_frmsh.sdi @@ -406,5 +406,10 @@ interface BaseTextFrame ExecMethod = Execute ; DisableFlags="SfxDisableFlags::SwOnProtectedCursor"; ] + SID_SELECTALL + [ + ExecMethod = ExecMove ; + StateMethod = NoState ; + ] } diff --git a/sw/source/uibase/inc/frmsh.hxx b/sw/source/uibase/inc/frmsh.hxx index f86e0d06501f..4b8a64c75823 100644 --- a/sw/source/uibase/inc/frmsh.hxx +++ b/sw/source/uibase/inc/frmsh.hxx @@ -35,6 +35,7 @@ public: virtual ~SwFrameShell() override; void Execute(SfxRequest &); + void ExecMove(SfxRequest& rReq); void GetState(SfxItemSet &); void ExecFrameStyle(SfxRequest const & rReq); void GetLineStyleState(SfxItemSet &rSet); diff --git a/sw/source/uibase/shells/frmsh.cxx b/sw/source/uibase/shells/frmsh.cxx index 2a43d349d143..931ec500b6de 100644 --- a/sw/source/uibase/shells/frmsh.cxx +++ b/sw/source/uibase/shells/frmsh.cxx @@ -114,6 +114,19 @@ void SwFrameShell::InitInterface_Impl() GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Invisible, ToolbarId::Frame_Toolbox); } +void SwFrameShell::ExecMove(SfxRequest& rReq) +{ + SwWrtShell& rSh = GetShell(); + sal_uInt16 nSlot = rReq.GetSlot(); + switch (nSlot) + { + case SID_SELECTALL: + rSh.SelAll(); + rReq.Done(); + break; + } +} + void SwFrameShell::Execute(SfxRequest &rReq) { //First those who do not need FrameMgr. commit a31bafb2713aeaf0533e870002c53d8265e27dc9 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Tue Jun 18 12:17:22 2019 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Mon Jul 1 16:20:56 2019 +0200 sw: extract postit insert code from SwTextShell::ExecField() Into a new SwWrtShell::InsertPostIt(), so I can reuse it in SwFrameShell. Change-Id: Ib327aed033067250f021f3857f4ba3adb8e6c597 Reviewed-on: https://gerrit.libreoffice.org/74264 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins (cherry picked from commit 485e048c391da38f883adfbef920069bd7af2305) diff --git a/sw/source/uibase/inc/wrtsh.hxx b/sw/source/uibase/inc/wrtsh.hxx index 4beec06b13da..421107052c25 100644 --- a/sw/source/uibase/inc/wrtsh.hxx +++ b/sw/source/uibase/inc/wrtsh.hxx @@ -48,6 +48,8 @@ class NaviContentBookmark; struct SwCallMouseEvent; class SfxStringListItem; enum class SvMacroItemId : sal_uInt16; +class SwFieldMgr; +class SfxRequest; namespace i18nutil { struct SearchOptions2; @@ -479,6 +481,9 @@ typedef bool (SwWrtShell:: *FNSimpleMove)(); void ChangeHeaderOrFooter(const OUString& rStyleName, bool bHeader, bool bOn, bool bShowWarning); virtual void SetShowHeaderFooterSeparator( FrameControlType eControl, bool bShow ) override; + /// Inserts a new annotation/comment at the current cursor position / selection. + void InsertPostIt(SwFieldMgr& rFieldMgr, SfxRequest& rReq); + private: SAL_DLLPRIVATE void OpenMark(); diff --git a/sw/source/uibase/shells/textfld.cxx b/sw/source/uibase/shells/textfld.cxx index 6b1915e095b3..12e491df4573 100644 --- a/sw/source/uibase/shells/textfld.cxx +++ b/sw/source/uibase/shells/textfld.cxx @@ -405,70 +405,7 @@ void SwTextShell::ExecField(SfxRequest &rReq) break; case FN_POSTIT: { - SwPostItField* pPostIt = dynamic_cast<SwPostItField*>(aFieldMgr.GetCurField()); - bool bNew = !(pPostIt && pPostIt->GetTyp()->Which() == SwFieldIds::Postit); - if (bNew || GetView().GetPostItMgr()->IsAnswer()) - { - const SvxPostItAuthorItem* pAuthorItem = rReq.GetArg<SvxPostItAuthorItem>(SID_ATTR_POSTIT_AUTHOR); - OUString sAuthor; - if ( pAuthorItem ) - sAuthor = pAuthorItem->GetValue(); - else - { - std::size_t nAuthor = SW_MOD()->GetRedlineAuthor(); - sAuthor = SW_MOD()->GetRedlineAuthor(nAuthor); - } - - const SvxPostItTextItem* pTextItem = rReq.GetArg<SvxPostItTextItem>(SID_ATTR_POSTIT_TEXT); - OUString sText; - if ( pTextItem ) - sText = pTextItem->GetValue(); - - // If we have a text already registered for answer, use that - if (GetView().GetPostItMgr()->IsAnswer() && !GetView().GetPostItMgr()->GetAnswerText().isEmpty()) - { - sText = GetView().GetPostItMgr()->GetAnswerText(); - GetView().GetPostItMgr()->RegisterAnswerText(OUString()); - } - - if ( rSh.HasSelection() && !rSh.IsTableMode() ) - { - rSh.KillPams(); - } - - // #i120513# Inserting a comment into an autocompletion crashes - // --> suggestion has to be removed before - GetView().GetEditWin().StopQuickHelp(); - - SwInsertField_Data aData(TYP_POSTITFLD, 0, sAuthor, sText, 0); - aFieldMgr.InsertField( aData ); - - rSh.Push(); - rSh.SwCursorShell::Left(1, CRSR_SKIP_CHARS); - pPostIt = static_cast<SwPostItField*>(aFieldMgr.GetCurField()); - rSh.Pop(SwCursorShell::PopMode::DeleteCurrent); // Restore cursor position - } - - // Client has disabled annotations rendering, no need to - // focus the postit field - if (comphelper::LibreOfficeKit::isActive() && !comphelper::LibreOfficeKit::isTiledAnnotations()) - break; - - if (pPostIt) - { - SwFieldType* pType = rSh.GetDoc()->getIDocumentFieldsAccess().GetFieldType(SwFieldIds::Postit, OUString(), false); - SwIterator<SwFormatField,SwFieldType> aIter( *pType ); - SwFormatField* pSwFormatField = aIter.First(); - while( pSwFormatField ) - { - if ( pSwFormatField->GetField() == pPostIt ) - { - pSwFormatField->Broadcast( SwFormatFieldHint( nullptr, SwFormatFieldHintWhich::FOCUS, &GetView() ) ); - break; - } - pSwFormatField = aIter.Next(); - } - } + rSh.InsertPostIt(aFieldMgr, rReq); } break; case SID_EDIT_POSTIT: diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx b/sw/source/uibase/wrtsh/wrtsh1.cxx index 233947209bbe..79f485ce30e8 100644 --- a/sw/source/uibase/wrtsh/wrtsh1.cxx +++ b/sw/source/uibase/wrtsh/wrtsh1.cxx @@ -99,9 +99,15 @@ #include <PostItMgr.hxx> #include <FrameControlsManager.hxx> +#include <fldmgr.hxx> +#include <docufld.hxx> +#include <IDocumentFieldsAccess.hxx> +#include <fmtfld.hxx> #include <sfx2/msgpool.hxx> #include <svtools/embedhlp.hxx> +#include <svx/postattr.hxx> +#include <comphelper/lok.hxx> #include <memory> using namespace sw::mark; @@ -1839,4 +1845,72 @@ void SwWrtShell::SetShowHeaderFooterSeparator( FrameControlType eControl, bool b GetView().GetEditWin().GetFrameControlsManager().HideControls( eControl ); } +void SwWrtShell::InsertPostIt(SwFieldMgr& rFieldMgr, SfxRequest& rReq) +{ + SwPostItField* pPostIt = dynamic_cast<SwPostItField*>(rFieldMgr.GetCurField()); + bool bNew = !(pPostIt && pPostIt->GetTyp()->Which() == SwFieldIds::Postit); + if (bNew || GetView().GetPostItMgr()->IsAnswer()) + { + const SvxPostItAuthorItem* pAuthorItem = rReq.GetArg<SvxPostItAuthorItem>(SID_ATTR_POSTIT_AUTHOR); + OUString sAuthor; + if ( pAuthorItem ) + sAuthor = pAuthorItem->GetValue(); + else + { + std::size_t nAuthor = SW_MOD()->GetRedlineAuthor(); + sAuthor = SW_MOD()->GetRedlineAuthor(nAuthor); + } + + const SvxPostItTextItem* pTextItem = rReq.GetArg<SvxPostItTextItem>(SID_ATTR_POSTIT_TEXT); + OUString sText; + if ( pTextItem ) + sText = pTextItem->GetValue(); + + // If we have a text already registered for answer, use that + if (GetView().GetPostItMgr()->IsAnswer() && !GetView().GetPostItMgr()->GetAnswerText().isEmpty()) + { + sText = GetView().GetPostItMgr()->GetAnswerText(); + GetView().GetPostItMgr()->RegisterAnswerText(OUString()); + } + + if ( HasSelection() && !IsTableMode() ) + { + KillPams(); + } + + // #i120513# Inserting a comment into an autocompletion crashes + // --> suggestion has to be removed before + GetView().GetEditWin().StopQuickHelp(); + + SwInsertField_Data aData(TYP_POSTITFLD, 0, sAuthor, sText, 0); + rFieldMgr.InsertField( aData ); + + Push(); + SwCursorShell::Left(1, CRSR_SKIP_CHARS); + pPostIt = static_cast<SwPostItField*>(rFieldMgr.GetCurField()); + Pop(SwCursorShell::PopMode::DeleteCurrent); // Restore cursor position + } + + // Client has disabled annotations rendering, no need to + // focus the postit field + if (comphelper::LibreOfficeKit::isActive() && !comphelper::LibreOfficeKit::isTiledAnnotations()) + return; + + if (pPostIt) + { + SwFieldType* pType = GetDoc()->getIDocumentFieldsAccess().GetFieldType(SwFieldIds::Postit, OUString(), false); + SwIterator<SwFormatField,SwFieldType> aIter( *pType ); + SwFormatField* pSwFormatField = aIter.First(); + while( pSwFormatField ) + { + if ( pSwFormatField->GetField() == pPostIt ) + { + pSwFormatField->Broadcast( SwFormatFieldHint( nullptr, SwFormatFieldHintWhich::FOCUS, &GetView() ) ); + break; + } + pSwFormatField = aIter.Next(); + } + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits