summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <Michael.Stahl@cib.de>2018-12-10 15:25:37 +0100
committerMichael Stahl <Michael.Stahl@cib.de>2018-12-18 18:04:27 +0100
commit22b480fc99d57752b43db89f40287e70777d4362 (patch)
treeacc5322abc854d7c95e08c83ee0cf2f87cc9d88b
parent8abae4c68ab183add61332fc1d4c25fae4c269fd (diff)
sw_redlinehide_4b: FindText() adapt the replace part as well
When redlining is enabled, the result will be a delete redline for the existing text, and an insert redline for the new text; that much is obious (and ReplaceRange can deal with a selection larger than one SwTextNode easily, since it mostly adds redlines). For the case when redlining is disabled, there are 2 options, and i don't really know which is preferrable from UX point of view: One approach is to reuse GetRanges() to ignore delete redlines in the replace range; move its declaration to different header. Another approach is to DeleteAndJoin() the existing delete redlines, which is the same as the previous model based Hide mode, which calls DeleteRedline() to remove the hidden redlines. Also change ChgAutoCorrWord() to call DeleteSelImpl() directly. Change-Id: I5974409d09eb39e04cc0b5dfc20d4db510e1cf58 (cherry picked from commit 5e81b966778d82692b4763d892b457186a7f269d)
-rw-r--r--sw/inc/crsrsh.hxx14
-rw-r--r--sw/source/core/crsr/findattr.cxx5
-rw-r--r--sw/source/core/crsr/findtxt.cxx119
-rw-r--r--sw/source/core/doc/DocumentContentOperationsManager.cxx9
-rw-r--r--sw/source/core/edit/acorrect.cxx2
-rw-r--r--sw/source/core/edit/eddel.cxx4
-rw-r--r--sw/source/core/inc/acorrect.hxx10
-rw-r--r--sw/source/uibase/uiview/viewsrch.cxx3
8 files changed, 137 insertions, 29 deletions
diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx
index fca0cc4f78f5..a5c8e1acc4d2 100644
--- a/sw/inc/crsrsh.hxx
+++ b/sw/inc/crsrsh.hxx
@@ -43,6 +43,7 @@
class SfxItemSet;
class SfxPoolItem;
class SwContentFrame;
+class SwUnoCursor;
class SwFormatField;
class SwTextFormatColl;
class SwTextINetFormat;
@@ -125,8 +126,19 @@ struct SwContentAtPos
const int CRSR_POSOLD = 0x01, // cursor stays at old position
CRSR_POSCHG = 0x02; // position changed by the layout
+namespace sw {
+
+bool ReplaceImpl(SwPaM & rCursor, OUString const& rReplacement,
+ bool const bRegExp, SwDoc & rDoc, SwRootFrame const*const pLayout);
+
/// Helperfunction to resolve backward references in regular expressions
-OUString *ReplaceBackReferences( const i18nutil::SearchOptions2& rSearchOpt, SwPaM* pPam );
+OUString *ReplaceBackReferences(const i18nutil::SearchOptions2& rSearchOpt,
+ SwPaM* pPam, SwRootFrame const* pLayout );
+
+bool GetRanges(std::vector<std::shared_ptr<SwUnoCursor>> & rRanges,
+ SwDoc & rDoc, SwPaM const& rDelPam);
+
+} // namespace sw
class SW_DLLPUBLIC SwCursorShell
: public SwViewShell
diff --git a/sw/source/core/crsr/findattr.cxx b/sw/source/core/crsr/findattr.cxx
index 9da44ada4dfe..500d4628ad27 100644
--- a/sw/source/core/crsr/findattr.cxx
+++ b/sw/source/core/crsr/findattr.cxx
@@ -1164,8 +1164,9 @@ int SwFindParaAttr::DoFind(SwPaM & rCursor, SwMoveFnCollection const & fnMove,
const_cast<SwPaM &>(rRegion).GetRingContainer().merge( m_rCursor.GetRingContainer() );
}
- std::unique_ptr<OUString> pRepl( bRegExp ?
- ReplaceBackReferences(*pSearchOpt, &rCursor) : nullptr );
+ std::unique_ptr<OUString> pRepl(bRegExp
+ ? sw::ReplaceBackReferences(*pSearchOpt, &rCursor, nullptr/*FIXME*/)
+ : nullptr);
m_rCursor.GetDoc()->getIDocumentContentOperations().ReplaceRange(
rCursor, pRepl ? *pRepl : pSearchOpt->replaceString, bRegExp);
m_rCursor.SaveTableBoxContent( rCursor.GetPoint() );
diff --git a/sw/source/core/crsr/findtxt.cxx b/sw/source/core/crsr/findtxt.cxx
index 85c6cb7fd11a..f45516361c2d 100644
--- a/sw/source/core/crsr/findtxt.cxx
+++ b/sw/source/core/crsr/findtxt.cxx
@@ -36,11 +36,14 @@
#include <txtatr.hxx>
#include <txtfld.hxx>
#include <txtfrm.hxx>
+#include <rootfrm.hxx>
#include <swcrsr.hxx>
+#include <redline.hxx>
#include <doc.hxx>
#include <IDocumentUndoRedo.hxx>
#include <IDocumentState.hxx>
#include <IDocumentDrawModelAccess.hxx>
+#include <IDocumentRedlineAccess.hxx>
#include <dcontact.hxx>
#include <pamtyp.hxx>
#include <ndtxt.hxx>
@@ -940,9 +943,12 @@ int SwFindParaText::DoFind(SwPaM & rCursor, SwMoveFnCollection const & fnMove,
}
std::unique_ptr<OUString> pRepl( bRegExp
- ? ReplaceBackReferences(m_rSearchOpt, &rCursor) : nullptr );
- bool const bReplaced = m_rCursor.GetDoc()->getIDocumentContentOperations().ReplaceRange(
- rCursor, pRepl ? *pRepl : m_rSearchOpt.replaceString, bRegExp);
+ ? sw::ReplaceBackReferences(m_rSearchOpt, &rCursor, m_pLayout)
+ : nullptr );
+ bool const bReplaced = sw::ReplaceImpl(rCursor,
+ pRepl ? *pRepl : m_rSearchOpt.replaceString,
+ bRegExp, *m_rCursor.GetDoc(), m_pLayout);
+
m_rCursor.SaveTableBoxContent( rCursor.GetPoint() );
if( bRegExp )
@@ -1009,22 +1015,115 @@ sal_uLong SwCursor::Find_Text( const i18nutil::SearchOptions2& rSearchOpt, bool
return nRet;
}
-OUString *ReplaceBackReferences( const i18nutil::SearchOptions2& rSearchOpt, SwPaM* pPam )
+namespace sw {
+
+bool ReplaceImpl(
+ SwPaM & rCursor,
+ OUString const& rReplacement,
+ bool const bRegExp,
+ SwDoc & rDoc,
+ SwRootFrame const*const pLayout)
+{
+ bool bReplaced(true);
+ IDocumentContentOperations & rIDCO(rDoc.getIDocumentContentOperations());
+#if 0
+ // FIXME there's some problem with multiple redlines here on Undo
+ std::vector<std::shared_ptr<SwUnoCursor>> ranges;
+ if (rDoc.getIDocumentRedlineAccess().IsRedlineOn()
+ || !pLayout
+ || !pLayout->IsHideRedlines()
+ || sw::GetRanges(ranges, rDoc, rCursor))
+ {
+ bReplaced = rIDCO.ReplaceRange(rCursor, rReplacement, bRegExp);
+ }
+ else
+ {
+ assert(!ranges.empty());
+ assert(ranges.front()->GetPoint()->nNode == ranges.front()->GetMark()->nNode);
+ bReplaced = rIDCO.ReplaceRange(*ranges.front(), rReplacement, bRegExp);
+ for (auto it = ranges.begin() + 1; it != ranges.end(); ++it)
+ {
+ bReplaced &= rIDCO.DeleteAndJoin(**it);
+ }
+ }
+#else
+ IDocumentRedlineAccess const& rIDRA(rDoc.getIDocumentRedlineAccess());
+ if (pLayout && pLayout->IsHideRedlines()
+ && !rIDRA.IsRedlineOn() // otherwise: ReplaceRange will handle it
+ && (rIDRA.GetRedlineFlags() & RedlineFlags::ShowDelete)) // otherwise: ReplaceRange will DeleteRedline()
+ {
+ SwRedlineTable::size_type tmp;
+ rIDRA.GetRedline(*rCursor.Start(), &tmp);
+ while (tmp < rIDRA.GetRedlineTable().size())
+ {
+ SwRangeRedline const*const pRedline(rIDRA.GetRedlineTable()[tmp]);
+ if (*rCursor.End() <= *pRedline->Start())
+ {
+ break;
+ }
+ if (*pRedline->End() <= *rCursor.Start())
+ {
+ ++tmp;
+ continue;
+ }
+ if (pRedline->GetType() == nsRedlineType_t::REDLINE_DELETE)
+ {
+ assert(*pRedline->Start() != *pRedline->End());
+ // search in hidden layout can't overlap redlines
+ assert(*rCursor.Start() <= *pRedline->Start() && *pRedline->End() <= *rCursor.End());
+ SwPaM pam(*pRedline, nullptr);
+ bReplaced &= rIDCO.DeleteAndJoin(pam);
+ }
+ else
+ {
+ ++tmp;
+ }
+ }
+ }
+ bReplaced &= rIDCO.ReplaceRange(rCursor, rReplacement, bRegExp);
+#endif
+ return bReplaced;
+}
+
+OUString *ReplaceBackReferences(const i18nutil::SearchOptions2& rSearchOpt,
+ SwPaM *const pPam, SwRootFrame const*const pLayout)
{
OUString *pRet = nullptr;
if( pPam && pPam->HasMark() &&
SearchAlgorithms2::REGEXP == rSearchOpt.AlgorithmType2 )
{
const SwContentNode* pTextNode = pPam->GetContentNode();
+ if (!pTextNode || !pTextNode->IsTextNode())
+ {
+ return pRet;
+ }
+ SwTextFrame const*const pFrame(pLayout
+ ? static_cast<SwTextFrame const*>(pTextNode->getLayoutFrame(pLayout))
+ : nullptr);
const bool bParaEnd = rSearchOpt.searchString == "$" || rSearchOpt.searchString == "^$" || rSearchOpt.searchString == "$^";
- if ( pTextNode && pTextNode->IsTextNode() && (bParaEnd || pTextNode == pPam->GetContentNode( false )) )
+ if (bParaEnd || (pLayout
+ ? sw::FrameContainsNode(*pFrame, pPam->GetMark()->nNode.GetIndex())
+ : pTextNode == pPam->GetContentNode(false)))
{
utl::TextSearch aSText( utl::TextSearch::UpgradeToSearchOptions2( rSearchOpt) );
- OUString rStr = pTextNode->GetTextNode()->GetText();
- sal_Int32 nStart = pPam->Start()->nContent.GetIndex();
- sal_Int32 nEnd = pPam->End()->nContent.GetIndex();
+ OUString rStr = pLayout
+ ? pFrame->GetText()
+ : pTextNode->GetTextNode()->GetText();
+ AmbiguousIndex nStart;
+ AmbiguousIndex nEnd;
+ if (pLayout)
+ {
+ nStart.SetFrameIndex(pFrame->MapModelToViewPos(*pPam->Start()));
+ nEnd.SetFrameIndex(pFrame->MapModelToViewPos(*pPam->End()));
+ }
+ else
+ {
+ nStart.SetModelIndex(pPam->Start()->nContent.GetIndex());
+ nEnd.SetModelIndex(pPam->End()->nContent.GetIndex());
+ }
SearchResult aResult;
- if ( bParaEnd || aSText.SearchForward( rStr, &nStart, &nEnd, &aResult ) )
+ if (bParaEnd ||
+ aSText.SearchForward(rStr, &nStart.GetAnyIndex(), &nEnd.GetAnyIndex(), &aResult))
{
if ( bParaEnd )
{
@@ -1044,4 +1143,6 @@ OUString *ReplaceBackReferences( const i18nutil::SearchOptions2& rSearchOpt, SwP
return pRet;
}
+} // namespace sw
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index ceb468b7b1ae..45508b9ac8a7 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -4062,10 +4062,6 @@ bool DocumentContentOperationsManager::ReplaceRangeImpl( SwPaM& rPam, const OUSt
SwPosition *pStt = aDelPam.Start(),
*pEnd = aDelPam.End();
- OSL_ENSURE( pStt->nNode == pEnd->nNode ||
- ( pStt->nNode.GetIndex() + 1 == pEnd->nNode.GetIndex() &&
- !pEnd->nContent.GetIndex() ),
- "invalid range: Point and Mark on different nodes" );
bool bOneNode = pStt->nNode == pEnd->nNode;
// Own Undo?
@@ -4201,6 +4197,11 @@ bool DocumentContentOperationsManager::ReplaceRangeImpl( SwPaM& rPam, const OUSt
}
else
{
+ assert((pStt->nNode == pEnd->nNode ||
+ ( pStt->nNode.GetIndex() + 1 == pEnd->nNode.GetIndex() &&
+ !pEnd->nContent.GetIndex() )) &&
+ "invalid range: Point and Mark on different nodes" );
+
if( !m_rDoc.getIDocumentRedlineAccess().IsIgnoreRedline() && !m_rDoc.getIDocumentRedlineAccess().GetRedlineTable().empty() )
m_rDoc.getIDocumentRedlineAccess().DeleteRedline( aDelPam, true, USHRT_MAX );
diff --git a/sw/source/core/edit/acorrect.cxx b/sw/source/core/edit/acorrect.cxx
index e5ca4d63c69b..eaf61bec0451 100644
--- a/sw/source/core/edit/acorrect.cxx
+++ b/sw/source/core/edit/acorrect.cxx
@@ -416,7 +416,7 @@ bool SwAutoCorrDoc::ChgAutoCorrWord( sal_Int32& rSttPos, sal_Int32 nEndPos,
*ranges.front(), pFnd->GetLong(), false);
for (auto it = ranges.begin() + 1; it != ranges.end(); ++it)
{
- DeleteSel(**it);
+ DeleteSelImpl(**it);
}
}
diff --git a/sw/source/core/edit/eddel.cxx b/sw/source/core/edit/eddel.cxx
index 126b5000a923..1a37235190a9 100644
--- a/sw/source/core/edit/eddel.cxx
+++ b/sw/source/core/edit/eddel.cxx
@@ -22,9 +22,11 @@
#include <doc.hxx>
#include <IDocumentUndoRedo.hxx>
#include <IDocumentContentOperations.hxx>
+#include <IDocumentRedlineAccess.hxx>
#include <editsh.hxx>
#include <cntfrm.hxx>
#include <pam.hxx>
+#include <unocrsr.hxx>
#include <swundo.hxx>
#include <edimp.hxx>
#include <IMark.hxx>
@@ -318,7 +320,7 @@ bool SwEditShell::Replace( const OUString& rNewStr, bool bRegExpRplc )
{
if( rPaM.HasMark() && *rPaM.GetMark() != *rPaM.GetPoint() )
{
- bRet = GetDoc()->getIDocumentContentOperations().ReplaceRange( rPaM, rNewStr, bRegExpRplc )
+ bRet = sw::ReplaceImpl(rPaM, rNewStr, bRegExpRplc, *GetDoc(), GetLayout())
|| bRet;
SaveTableBoxContent( rPaM.GetPoint() );
}
diff --git a/sw/source/core/inc/acorrect.hxx b/sw/source/core/inc/acorrect.hxx
index 73f63c1ebac8..39bd19e91584 100644
--- a/sw/source/core/inc/acorrect.hxx
+++ b/sw/source/core/inc/acorrect.hxx
@@ -21,14 +21,11 @@
#define INCLUDED_SW_SOURCE_CORE_INC_ACORRECT_HXX
#include <memory>
-#include <vector>
#include <tools/solar.h>
#include <editeng/svxacorr.hxx>
#include <swundo.hxx>
-class SwDoc;
-class SwUnoCursor;
class SwEditShell;
class SwPaM;
class SwNodeIndex;
@@ -116,13 +113,6 @@ public:
bool CheckDelChar(const SwPosition& rPos);
};
-namespace sw {
-
-bool GetRanges(std::vector<std::shared_ptr<SwUnoCursor>> & rRanges,
- SwDoc & rDoc, SwPaM const& rDelPam);
-
-} // namespace sw
-
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/uiview/viewsrch.cxx b/sw/source/uibase/uiview/viewsrch.cxx
index 09fd18015ae6..96b1708eb4be 100644
--- a/sw/source/uibase/uiview/viewsrch.cxx
+++ b/sw/source/uibase/uiview/viewsrch.cxx
@@ -309,7 +309,8 @@ void SwView::ExecSearch(SfxRequest& rReq)
m_pWrtShell->Push();
OUString aReplace( m_pSrchItem->GetReplaceString() );
i18nutil::SearchOptions2 aTmp( m_pSrchItem->GetSearchOptions() );
- OUString *pBackRef = ReplaceBackReferences( aTmp, m_pWrtShell->GetCursor() );
+ OUString *pBackRef = sw::ReplaceBackReferences(aTmp,
+ m_pWrtShell->GetCursor(), m_pWrtShell->GetLayout());
if( pBackRef )
m_pSrchItem->SetReplaceString( *pBackRef );
Replace();