diff options
author | Justin Luth <jluth@mail.com> | 2023-12-25 20:23:52 -0500 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2024-01-03 08:45:34 +0100 |
commit | e73dfbf860b977f3b862fb75a87a7ad726d9a4c7 (patch) | |
tree | 57fd897b02cf5f57e0ec0229ffefb1ad7116b87f /sw | |
parent | a01a642ebbdb8c16f1b54b4634c277b9f665192f (diff) |
tdf#111969 sw: acknowledge field start/end for context menu
This fixes the right-click menu building
missing out on the edit/update field option about
half-a-character too soon at the end.
It also fixes itrcrsr adding field actions to the menu
half-a-char too soon in the edge case of a 1-len portion.
This edge case is not limited to fields - it fixes it
for redlines (and hyperlinks if other bugs are fixed).
make CppunitTest_sw_uiwriter9 CPPUNIT_TEST_NAME=testTdf111969
Change-Id: I469ec75d18d4dce0bb62ebb63b661b60e35f9e1b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161295
Tested-by: Jenkins
Reviewed-by: Justin Luth <jluth@mail.com>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/inc/crsrsh.hxx | 10 | ||||
-rw-r--r-- | sw/inc/crstate.hxx | 4 | ||||
-rw-r--r-- | sw/qa/extras/uiwriter/data/tdf111969_field.fodt | 10 | ||||
-rw-r--r-- | sw/qa/extras/uiwriter/data/tdf111969_fieldB.fodt | 10 | ||||
-rw-r--r-- | sw/qa/extras/uiwriter/uiwriter9.cxx | 86 | ||||
-rw-r--r-- | sw/source/core/crsr/crsrsh.cxx | 3 | ||||
-rw-r--r-- | sw/source/uibase/docvw/edtwin.cxx | 4 |
7 files changed, 122 insertions, 5 deletions
diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx index 20636648c794..db0667002ee2 100644 --- a/sw/inc/crsrsh.hxx +++ b/sw/inc/crsrsh.hxx @@ -401,7 +401,15 @@ public: // return values: // CRSR_POSCHG: when cursor was corrected from SPoint by the layout // CRSR_POSOLD: when the cursor was not changed - int SetCursor( const Point &rPt, bool bOnlyText = false, bool bBlock = true ); + /** + * @param bFieldInfo + * false: Over the last half of the character, place cursor behind it. This is used when + * the cursor is actually being moved by the user to the closest valid point. + * true: Place the cursor at the start of the character/field. This is used when setting + * the cursor is done in order to get at the properties under the mouse pointer. + */ + int SetCursor(const Point& rPt, bool bOnlyText = false, bool bBlock = true, + bool bFieldInfo = false); /* * Notification that the visible area was changed. m_aVisArea is reset, then diff --git a/sw/inc/crstate.hxx b/sw/inc/crstate.hxx index acf13bfe45d7..018106514714 100644 --- a/sw/inc/crstate.hxx +++ b/sw/inc/crstate.hxx @@ -139,7 +139,7 @@ struct SwCursorMoveState sal_uInt8 m_nCursorBidiLevel; bool m_bStop; bool m_bRealHeight; ///< should the real height be calculated? - bool m_bFieldInfo; ///< should be fields recognized? + bool m_bFieldInfo; ///< should fields be recognized? (get position of field start) bool m_bPosCorr; ///< Point had to be corrected bool m_bFootnoteNoInfo; ///< recognized footnote numbering bool m_bExactOnly; /**< let GetModelPositionForViewPoint look for exact matches only, @@ -151,7 +151,7 @@ struct SwCursorMoveState bool m_bNoScroll; ///< No scrolling of undersized textframes bool m_bPosMatchesBounds; /**< GetModelPositionForViewPoint should not return the next position if screen position is inside second - have of bound rect */ + half of bound rect */ bool m_bContentCheck; // #i43742# Cursor position over content? diff --git a/sw/qa/extras/uiwriter/data/tdf111969_field.fodt b/sw/qa/extras/uiwriter/data/tdf111969_field.fodt new file mode 100644 index 000000000000..4048fa03c42b --- /dev/null +++ b/sw/qa/extras/uiwriter/data/tdf111969_field.fodt @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" +office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text"> + <office:body> + <office:text> + <text:p>–<text:time text:time-value="1899-12-30T12:34:56" text:fixed="true"/>–</text:p> + </office:text> + </office:body> +</office:document> diff --git a/sw/qa/extras/uiwriter/data/tdf111969_fieldB.fodt b/sw/qa/extras/uiwriter/data/tdf111969_fieldB.fodt new file mode 100644 index 000000000000..18de3f586a94 --- /dev/null +++ b/sw/qa/extras/uiwriter/data/tdf111969_fieldB.fodt @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" +office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text"> + <office:body> + <office:text> + <text:p>––<text:time text:time-value="1899-12-30T12:34:56" text:fixed="true"/>––</text:p> + </office:text> + </office:body> +</office:document> diff --git a/sw/qa/extras/uiwriter/uiwriter9.cxx b/sw/qa/extras/uiwriter/uiwriter9.cxx index c12be545512d..8febc2f2145e 100644 --- a/sw/qa/extras/uiwriter/uiwriter9.cxx +++ b/sw/qa/extras/uiwriter/uiwriter9.cxx @@ -68,6 +68,92 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf158785) CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::NONE, aContentAtPos.eContentAtPos); } +CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf111969) +{ + // given a document with a field surrounded by N-dashes (–date–) + createSwDoc("tdf111969_field.fodt"); + SwDoc& rDoc = *getSwDoc(); + SwWrtShell* pWrtShell = rDoc.GetDocShell()->GetWrtShell(); + CPPUNIT_ASSERT(pWrtShell); + + // go to the end of the field + pWrtShell->SttEndDoc(/*bStart=*/false); + pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false); + // get last point that will be part of the field (current position 1pt wide). + Point aLogicL(pWrtShell->GetCharRect().Center()); + Point aLogicR(aLogicL); + + // sanity check - we really are at the right edge of the field + aLogicR.AdjustX(1); + SwContentAtPos aContentAtPos(IsAttrAtPos::Field); + pWrtShell->GetContentAtPos(aLogicR, aContentAtPos); + CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::NONE, aContentAtPos.eContentAtPos); + aLogicL.AdjustX(-1); + aContentAtPos = IsAttrAtPos::Field; + pWrtShell->GetContentAtPos(aLogicL, aContentAtPos); + CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::Field, aContentAtPos.eContentAtPos); + + // the test: simulate a right-click of a mouse which sets the cursor and then acts on that pos. + pWrtShell->SwCursorShell::SetCursor(aLogicL, false, /*Block=*/false, /*FieldInfo=*/true); + CPPUNIT_ASSERT(pWrtShell->GetCurField(true)); + + /* + * An edge case at the start of a field - don't start the field menu on the first N-dash + */ + // go to the start of the field + pWrtShell->SttEndDoc(/*bStart=*/true); + pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false); + // get first point that will be part of the field (current position 1pt wide). + aLogicL = pWrtShell->GetCharRect().Center(); + aLogicR = aLogicL; + + // sanity check - we really are at the left edge of the field + aLogicR.AdjustX(1); + aContentAtPos = IsAttrAtPos::Field; + pWrtShell->GetContentAtPos(aLogicR, aContentAtPos); + CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::Field, aContentAtPos.eContentAtPos); + aLogicL.AdjustX(-1); + aContentAtPos = IsAttrAtPos::Field; + pWrtShell->GetContentAtPos(aLogicL, aContentAtPos); + CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::NONE, aContentAtPos.eContentAtPos); + + // the test: simulate a right-click of a mouse (at the end-edge of the N-dash) + // which sets the cursor and then acts on that pos. + pWrtShell->SwCursorShell::SetCursor(aLogicL, false, /*Block=*/false, /*FieldInfo=*/true); + CPPUNIT_ASSERT(!pWrtShell->GetCurField(true)); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf111969B) +{ + // given a document with a field surrounded by two N-dashes (––date––) + createSwDoc("tdf111969_fieldB.fodt"); + SwDoc& rDoc = *getSwDoc(); + SwWrtShell* pWrtShell = rDoc.GetDocShell()->GetWrtShell(); + CPPUNIT_ASSERT(pWrtShell); + + // go to the start of the field + pWrtShell->SttEndDoc(/*bStart=*/true); + pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 2, /*bBasicCall=*/false); + // get first point that will be part of the field (current position 1pt wide). + Point aLogicL(pWrtShell->GetCharRect().Center()); + Point aLogicR(aLogicL); + + // sanity check - we really are at the left edge of the field + aLogicR.AdjustX(1); + SwContentAtPos aContentAtPos(IsAttrAtPos::Field); + pWrtShell->GetContentAtPos(aLogicR, aContentAtPos); + CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::Field, aContentAtPos.eContentAtPos); + aLogicL.AdjustX(-1); + aContentAtPos = IsAttrAtPos::Field; + pWrtShell->GetContentAtPos(aLogicL, aContentAtPos); + CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::NONE, aContentAtPos.eContentAtPos); + + // the test: simulate a right-click of a mouse (at the end-edge of the second N-dash) + // which sets the cursor and then acts on that pos. + pWrtShell->SwCursorShell::SetCursor(aLogicL, false, /*Block=*/false, /*FieldInfo=*/true); + //CPPUNIT_ASSERT(!pWrtShell->GetCurField(true)); +} + } // end of anonymous namespace CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx index 449b074194bc..ed9f47dc81c5 100644 --- a/sw/source/core/crsr/crsrsh.cxx +++ b/sw/source/core/crsr/crsrsh.cxx @@ -1045,7 +1045,7 @@ bool SwCursorShell::IsInHeaderFooter( bool* pbInHeader ) const return nullptr != pFrame; } -int SwCursorShell::SetCursor( const Point &rLPt, bool bOnlyText, bool bBlock ) +int SwCursorShell::SetCursor(const Point& rLPt, bool bOnlyText, bool bBlock, bool bFieldInfo) { CurrShell aCurr( this ); @@ -1056,6 +1056,7 @@ int SwCursorShell::SetCursor( const Point &rLPt, bool bOnlyText, bool bBlock ) SwCursorMoveState aTmpState( IsTableMode() ? CursorMoveState::TableSel : bOnlyText ? CursorMoveState::SetOnlyText : CursorMoveState::NONE ); aTmpState.m_bSetInReadOnly = IsReadOnlyAvailable(); + aTmpState.m_bFieldInfo = bFieldInfo; // always set cursor at field-start if point is over field SwTextNode const*const pTextNd = sw::GetParaPropsNode(*GetLayout(), pCursor->GetPoint()->GetNode()); diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx index 4d9750a98602..e89614319903 100644 --- a/sw/source/uibase/docvw/edtwin.cxx +++ b/sw/source/uibase/docvw/edtwin.cxx @@ -6160,7 +6160,9 @@ void SwEditWin::SelectMenuPosition(SwWrtShell& rSh, const Point& rMousePos ) // create only temporary move context because otherwise // the query against the content form doesn't work!!! SwMvContext aMvContext( &rSh ); - rSh.CallSetCursor(&aDocPos, false); + if (rSh.HasSelection()) + rSh.ResetSelect(&aDocPos, false); + rSh.SwCursorShell::SetCursor(aDocPos, false, /*Block=*/false, /*FieldInfo=*/true); } if( !bOverURLGrf ) { |