[Libreoffice-commits] core.git: Branch 'distro/suse/suse-3.6' - 2 commits - i18npool/qa i18npool/source sw/CppunitTest_sw_swdoc_test.mk sw/inc sw/qa sw/source
Michael Stahl
mstahl at redhat.com
Thu Apr 18 01:53:51 PDT 2013
i18npool/qa/cppunit/test_breakiterator.cxx | 33 +
i18npool/source/breakiterator/data/dict_word.txt | 2
i18npool/source/breakiterator/data/dict_word_ca.txt | 2
i18npool/source/breakiterator/data/dict_word_fi.txt | 2
i18npool/source/breakiterator/data/dict_word_he.txt | 2
i18npool/source/breakiterator/data/dict_word_hu.txt | 2
i18npool/source/breakiterator/data/dict_word_nodash.txt | 2
i18npool/source/breakiterator/data/dict_word_prepostdash.txt | 2
i18npool/source/breakiterator/data/edit_word.txt | 2
i18npool/source/breakiterator/data/edit_word_he.txt | 2
i18npool/source/breakiterator/data/edit_word_hu.txt | 2
sw/CppunitTest_sw_swdoc_test.mk | 1
sw/inc/modeltoviewhelper.hxx | 66 ++-
sw/inc/ndtxt.hxx | 8
sw/inc/swscanner.hxx | 4
sw/inc/unoflatpara.hxx | 2
sw/inc/unotextmarkup.hxx | 7
sw/qa/complex/writer/TextPortionEnumerationTest.java | 32 +
sw/qa/core/swdoc-test.cxx | 2
sw/source/core/doc/docedt.cxx | 22 -
sw/source/core/docnode/node.cxx | 40 +-
sw/source/core/edit/edlingu.cxx | 19 -
sw/source/core/inc/scriptinfo.hxx | 5
sw/source/core/text/porlay.cxx | 198 +++--------
sw/source/core/txtnode/modeltoviewhelper.cxx | 25 -
sw/source/core/txtnode/ndtxt.cxx | 163 +++++++--
sw/source/core/txtnode/txtedt.cxx | 53 +-
sw/source/core/unocore/unoflatpara.cxx | 25 -
sw/source/core/unocore/unotextmarkup.cxx | 29 -
29 files changed, 439 insertions(+), 315 deletions(-)
New commits:
commit 0c153a22254bf7d83041192037ee7268c40f06f1
Author: Michael Stahl <mstahl at redhat.com>
Date: Thu Feb 14 19:27:28 2013 +0100
bnc#796202, fdo#60732: SwTxtNode: limit to less than STRING_LEN chars
It's not a good idea to have STRING_LEN characters in a SwTxtNode
because then there is no valid SwPosition at the end of the paragraph.
Also it turns out that LO 3.6 and 4.0 do rather stupid things with a
full SwTxtNode. So enforce a limit, at first in the usual places that
are used during file import, SwTxtNode::InsertText() and
SwCntntNode::CanJoinPrev()/CanJoinNext().
(cherry picked from commit 549c0f785d4b6d4bc1b39b22827d77d66f48430a)
Conflicts:
sw/source/core/docnode/node.cxx
Change-Id: Icb0f44acd20aa81635d42b84d4ae0f9b693a661c
Reviewed-on: https://gerrit.libreoffice.org/2178
Reviewed-by: Miklos Vajna <vmiklos at suse.cz>
Tested-by: Miklos Vajna <vmiklos at suse.cz>
diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx
index 39565cf..8f5d31d 100644
--- a/sw/inc/ndtxt.hxx
+++ b/sw/inc/ndtxt.hxx
@@ -79,6 +79,11 @@ namespace com { namespace sun { namespace star {
typedef std::set< xub_StrLen > SwSoftPageBreakList;
+// do not fill the String up to the max - need to be able to have a
+// SwPosition "behind" the last character, i.e., at index TXTNODE_MAX + 1
+// (also STRING_LEN is often used for "not found")
+const xub_StrLen TXTNODE_MAX = STRING_LEN - 2;
+
/// SwTxtNode is a paragraph in the document model.
class SW_DLLPUBLIC SwTxtNode: public SwCntntNode, public ::sfx2::Metadatable
{
diff --git a/sw/source/core/docnode/node.cxx b/sw/source/core/docnode/node.cxx
index f795732..a3ce49e 100644
--- a/sw/source/core/docnode/node.cxx
+++ b/sw/source/core/docnode/node.cxx
@@ -1684,12 +1684,26 @@ const SfxPoolItem* SwCntntNode::GetNoCondAttr( sal_uInt16 nWhich,
return pFnd;
}
- // koennen 2 Nodes zusammengefasst werden ?
- // in pIdx kann die 2. Position returnt werden.
+static bool lcl_CheckMaxLength(SwNode const& rPrev, SwNode const& rNext)
+{
+ if (rPrev.GetNodeType() != rNext.GetNodeType())
+ {
+ return false;
+ }
+ if (!rPrev.IsTxtNode())
+ {
+ return true;
+ }
+ size_t const nSum( static_cast<const SwTxtNode&>(rPrev).GetTxt().Len()
+ + static_cast<const SwTxtNode&>(rNext).GetTxt().Len());
+ return (nSum <= TXTNODE_MAX);
+}
+
+// Can we join two Nodes?
+// We can return the 2nd position in pIdx.
int SwCntntNode::CanJoinNext( SwNodeIndex* pIdx ) const
{
const SwNodes& rNds = GetNodes();
- sal_uInt8 nNdType = GetNodeType();
SwNodeIndex aIdx( *this, 1 );
const SwNode* pNd = this;
@@ -1698,16 +1712,11 @@ int SwCntntNode::CanJoinNext( SwNodeIndex* pIdx ) const
( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() )))
aIdx++;
- if( pNd->GetNodeType() != nNdType || rNds.Count()-1 == aIdx.GetIndex() )
+ if (rNds.Count()-1 == aIdx.GetIndex())
return sal_False;
- if( IsTxtNode() )
- { // Do not merge strings if the result exceeds the allowed string length
- const SwTxtNode* pTxtNd = static_cast<const SwTxtNode*>(this);
- sal_uInt64 nSum = pTxtNd->GetTxt().Len();
- pTxtNd = static_cast<const SwTxtNode*>(pNd);
- nSum += pTxtNd->GetTxt().Len();
- if( nSum > STRING_LEN )
- return sal_False;
+ if (!lcl_CheckMaxLength(*this, *pNd))
+ {
+ return false;
}
if( pIdx )
*pIdx = aIdx;
@@ -1719,7 +1728,6 @@ int SwCntntNode::CanJoinNext( SwNodeIndex* pIdx ) const
// in pIdx kann die 2. Position returnt werden.
int SwCntntNode::CanJoinPrev( SwNodeIndex* pIdx ) const
{
- sal_uInt8 nNdType = GetNodeType();
SwNodeIndex aIdx( *this, -1 );
const SwNode* pNd = this;
@@ -1728,8 +1736,12 @@ int SwCntntNode::CanJoinPrev( SwNodeIndex* pIdx ) const
( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() )))
aIdx--;
- if( pNd->GetNodeType() != nNdType || 0 == aIdx.GetIndex() )
+ if (0 == aIdx.GetIndex())
return sal_False;
+ if (!lcl_CheckMaxLength(*pNd, *this))
+ {
+ return false;
+ }
if( pIdx )
*pIdx = aIdx;
return sal_True;
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index fc0a192..9e88202 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -1723,7 +1723,11 @@ void SwTxtNode::InsertText( const XubString & rStr, const SwIndex & rIdx,
xub_StrLen aPos = rIdx.GetIndex();
xub_StrLen nLen = m_Text.Len() - aPos;
- m_Text.Insert( rStr, aPos );
+ ssize_t const nOverflow(static_cast<ssize_t>(m_Text.Len())
+ + static_cast<ssize_t>(rStr.Len()) - TXTNODE_MAX);
+ m_Text.Insert((nOverflow > 0) ? rStr.Copy(0, rStr.Len() - nOverflow) : rStr,
+ aPos);
+ assert(m_Text.Len() <= TXTNODE_MAX);
nLen = m_Text.Len() - aPos - nLen;
if ( !nLen ) return;
commit e59c8a2f885ae1166aa29d40b2442d4b447ab01d
Author: Miklos Vajna <vmiklos at suse.cz>
Date: Thu Apr 18 10:31:03 2013 +0200
bnc#796202 backport various word-count-related fixes from 4.0
With these, the word-count of the bugdoc no longer hangs.
3442913accc4e44c3a1ac69a990edee15117948e Related: fdo#46757 fix weird word/char count with hidden deleted text
e88f6ca683a333d927b1e5a63fcae7a88a01ab6b behind (hinter) -> after
f8f05d43de8728db58c8224c8aebf31ff570b6fc Resolves: fdo49629 GotoEndOfWord fails with footnote at word end
331e4d03a70900bc390b376f4073d0efd868b919 refactor ModelToViewHelper, should have unchanged results
b8aa2fa9506967e20fd0db0af30de599f91cf10a warning C4701: potentially uninitialized local variable used
27c2fe405ca55a2630176a657fb4895c5e31fcea Related: fdo#46757 extend ModelToViewHelper for more cases
92236c0fc4c8704a72f20a3c2e6f22df3c5ae333 Related: fdo#46757 unsafe to pass expanded text to masking
561aeedfb7513342bcbb4e76d5f8348a195dc374 Clean up whitespace and remove silly comments
4ba497818357b000016a16ec041517de57820e9e split CalcHiddenRanges into hidden text and redline deletion handlers
Change-Id: I6a473398f413a55190a5a9f1bc73a50673f5da84
diff --git a/i18npool/qa/cppunit/test_breakiterator.cxx b/i18npool/qa/cppunit/test_breakiterator.cxx
index 3a64c31..22f45ab 100644
--- a/i18npool/qa/cppunit/test_breakiterator.cxx
+++ b/i18npool/qa/cppunit/test_breakiterator.cxx
@@ -126,6 +126,39 @@ void TestBreakIterator::testLineBreaking()
CPPUNIT_ASSERT_MESSAGE("Expected a break at the the start of the word", aResult.breakIndex == aWord.getLength()+1);
}
}
+
+ //See https://bugs.freedesktop.org/show_bug.cgi?id=49629
+ for (int mode = i18n::WordType::ANY_WORD; mode <= i18n::WordType::WORD_COUNT; ++mode)
+ {
+ //make sure that in all cases isBeginWord and isEndWord matches getWordBoundary
+ //
+ //test "Word", then "Word\x01" then "Word\x02"
+ for (sal_Unicode i = 0; i < 3; ++i)
+ {
+ ::rtl::OUString aTest("Word");
+ if (i > 0)
+ aTest += rtl::OUString(i) + rtl::OUString("Word");
+ i18n::Boundary aBounds = m_xBreak->getWordBoundary(aTest, 0, aLocale, mode, true);
+ switch (mode)
+ {
+ case i18n::WordType::ANY_WORD:
+ CPPUNIT_ASSERT(aBounds.startPos == 0 && aBounds.endPos == 4);
+ break;
+ case i18n::WordType::ANYWORD_IGNOREWHITESPACES:
+ CPPUNIT_ASSERT(aBounds.startPos == 0 && aBounds.endPos == 4);
+ break;
+ case i18n::WordType::DICTIONARY_WORD:
+ CPPUNIT_ASSERT(aBounds.startPos == 0 && aBounds.endPos == 4);
+ break;
+ case i18n::WordType::WORD_COUNT:
+ CPPUNIT_ASSERT(aBounds.startPos == 0 && aBounds.endPos == 4);
+ break;
+ }
+
+ CPPUNIT_ASSERT(m_xBreak->isBeginWord(aTest, aBounds.startPos, aLocale, mode));
+ CPPUNIT_ASSERT(m_xBreak->isEndWord(aTest, aBounds.endPos, aLocale, mode));
+ }
+ }
}
//See http://qa.openoffice.org/issues/show_bug.cgi?id=111152
diff --git a/i18npool/source/breakiterator/data/dict_word.txt b/i18npool/source/breakiterator/data/dict_word.txt
index f69f038..b1666f4 100644
--- a/i18npool/source/breakiterator/data/dict_word.txt
+++ b/i18npool/source/breakiterator/data/dict_word.txt
@@ -24,7 +24,7 @@ $Katakana = [[:Script = KATAKANA:] [:name = KATAKANA-HIRAGANA PROLONGED SOUND M
$Ideographic = [:Ideographic:];
$Hangul = [:Script = HANGUL:];
-$ALetter = [\u0002 [:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:]
+$ALetter = [[:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:]
- $Ideographic
- $Katakana
- $Hangul
diff --git a/i18npool/source/breakiterator/data/dict_word_ca.txt b/i18npool/source/breakiterator/data/dict_word_ca.txt
index ca4a14a..6ad6a0b 100644
--- a/i18npool/source/breakiterator/data/dict_word_ca.txt
+++ b/i18npool/source/breakiterator/data/dict_word_ca.txt
@@ -22,7 +22,7 @@ $Katakana = [[:Script = KATAKANA:] [:name = KATAKANA-HIRAGANA PROLONGED SOUND M
[:name = HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK:]];
-$ALetter = [\u0002 [:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:]
+$ALetter = [[:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:]
- $Katakana
- [:Script = Thai:]
- [:Script = Lao:]
diff --git a/i18npool/source/breakiterator/data/dict_word_fi.txt b/i18npool/source/breakiterator/data/dict_word_fi.txt
index 2d76179..7026c99 100644
--- a/i18npool/source/breakiterator/data/dict_word_fi.txt
+++ b/i18npool/source/breakiterator/data/dict_word_fi.txt
@@ -24,7 +24,7 @@ $Katakana = [[:Script = KATAKANA:] [:name = KATAKANA-HIRAGANA PROLONGED SOUND M
$Ideographic = [:Ideographic:];
$Hangul = [:Script = HANGUL:];
-$ALetter = [\u0002 [:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:] [:name = HYPHEN-MINUS:]
+$ALetter = [[:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:] [:name = HYPHEN-MINUS:]
- $Ideographic
- $Katakana
- $Hangul
diff --git a/i18npool/source/breakiterator/data/dict_word_he.txt b/i18npool/source/breakiterator/data/dict_word_he.txt
index b98350e..40197d9 100644
--- a/i18npool/source/breakiterator/data/dict_word_he.txt
+++ b/i18npool/source/breakiterator/data/dict_word_he.txt
@@ -22,7 +22,7 @@ $Katakana = [[:Script = KATAKANA:] [:name = KATAKANA-HIRAGANA PROLONGED SOUND M
[:name = HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK:]];
-$ALetter = [\u0002 [:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:]
+$ALetter = [[:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:]
- $Katakana
- [:Script = Thai:]
- [:Script = Lao:]
diff --git a/i18npool/source/breakiterator/data/dict_word_hu.txt b/i18npool/source/breakiterator/data/dict_word_hu.txt
index 49ae8b5..33d014e 100644
--- a/i18npool/source/breakiterator/data/dict_word_hu.txt
+++ b/i18npool/source/breakiterator/data/dict_word_hu.txt
@@ -24,7 +24,7 @@ $Katakana = [[:Script = KATAKANA:] [:name = KATAKANA-HIRAGANA PROLONGED SOUND M
$Ideographic = [:Ideographic:];
$Hangul = [:Script = HANGUL:];
-$ALetter = [\u0002 [:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:]
+$ALetter = [[:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:]
[:name = PERCENT SIGN:] [:name = PER MILLE SIGN:] [:name = PER TEN THOUSAND SIGN:]
[:name = SECTION SIGN:] [:name = DEGREE SIGN:] [:name = EURO SIGN:]
[:name = HYPHEN-MINUS:] [:name = EN DASH:] [:name = EM DASH:]
diff --git a/i18npool/source/breakiterator/data/dict_word_nodash.txt b/i18npool/source/breakiterator/data/dict_word_nodash.txt
index 4c5c808..279cc50 100644
--- a/i18npool/source/breakiterator/data/dict_word_nodash.txt
+++ b/i18npool/source/breakiterator/data/dict_word_nodash.txt
@@ -24,7 +24,7 @@ $Katakana = [[:Script = KATAKANA:] [:name = KATAKANA-HIRAGANA PROLONGED SOUND M
$Ideographic = [:Ideographic:];
$Hangul = [:Script = HANGUL:];
-$ALetter = [\u0002 [:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:]
+$ALetter = [[:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:]
- $Ideographic
- $Katakana
- $Hangul
diff --git a/i18npool/source/breakiterator/data/dict_word_prepostdash.txt b/i18npool/source/breakiterator/data/dict_word_prepostdash.txt
index 0a60cc5..fb29b47 100644
--- a/i18npool/source/breakiterator/data/dict_word_prepostdash.txt
+++ b/i18npool/source/breakiterator/data/dict_word_prepostdash.txt
@@ -30,7 +30,7 @@ $Hangul = [:Script = HANGUL:];
$PrePostDashHyphen = [ [:name = HYPHEN-MINUS:] ];
-$ALetter = [\u0002 [:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:]
+$ALetter = [[:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:]
- $Ideographic
- $Katakana
- $Hangul
diff --git a/i18npool/source/breakiterator/data/edit_word.txt b/i18npool/source/breakiterator/data/edit_word.txt
index ff83212..92b344c 100644
--- a/i18npool/source/breakiterator/data/edit_word.txt
+++ b/i18npool/source/breakiterator/data/edit_word.txt
@@ -24,7 +24,7 @@ $Katakana = [[:Script = KATAKANA:] [:name = KATAKANA-HIRAGANA PROLONGED SOUND M
$Ideographic = [:Ideographic:];
$Hangul = [:Script = HANGUL:];
-$ALetter = [\u0002 [:Alphabetic:] [:name= NO-BREAK SPACE:] [:name= HEBREW PUNCTUATION GERESH:]
+$ALetter = [[:Alphabetic:] [:name= NO-BREAK SPACE:] [:name= HEBREW PUNCTUATION GERESH:]
- $Ideographic
- $Katakana
- $Hangul
diff --git a/i18npool/source/breakiterator/data/edit_word_he.txt b/i18npool/source/breakiterator/data/edit_word_he.txt
index 0061f55..0b59088 100644
--- a/i18npool/source/breakiterator/data/edit_word_he.txt
+++ b/i18npool/source/breakiterator/data/edit_word_he.txt
@@ -24,7 +24,7 @@ $Katakana = [[:Script = KATAKANA:] [:name = KATAKANA-HIRAGANA PROLONGED SOUND M
$Ideographic = [:Ideographic:];
$Hangul = [:Script = HANGUL:];
-$ALetter = [\u0002 [:Alphabetic:] [:name= NO-BREAK SPACE:] [:name= HEBREW PUNCTUATION GERESH:]
+$ALetter = [[:Alphabetic:] [:name= NO-BREAK SPACE:] [:name= HEBREW PUNCTUATION GERESH:]
- $Ideographic
- $Katakana
- $Hangul
diff --git a/i18npool/source/breakiterator/data/edit_word_hu.txt b/i18npool/source/breakiterator/data/edit_word_hu.txt
index 5262726..4a08aca 100644
--- a/i18npool/source/breakiterator/data/edit_word_hu.txt
+++ b/i18npool/source/breakiterator/data/edit_word_hu.txt
@@ -24,7 +24,7 @@ $Katakana = [[:Script = KATAKANA:] [:name = KATAKANA-HIRAGANA PROLONGED SOUND M
$Ideographic = [:Ideographic:];
$Hangul = [:Script = HANGUL:];
-$ALetter = [\u0002 [:Alphabetic:] [:name= NO-BREAK SPACE:] [:name= HEBREW PUNCTUATION GERESH:]
+$ALetter = [[:Alphabetic:] [:name= NO-BREAK SPACE:] [:name= HEBREW PUNCTUATION GERESH:]
[:name = PERCENT SIGN:] [:name = PER MILLE SIGN:] [:name = PER TEN THOUSAND SIGN:]
[:name = SECTION SIGN:] [:name = DEGREE SIGN:] [:name = EURO SIGN:]
[:name = HYPHEN-MINUS:] [:name = EN DASH:] [:name = EM DASH:]
diff --git a/sw/CppunitTest_sw_swdoc_test.mk b/sw/CppunitTest_sw_swdoc_test.mk
index 94ebab3..b3ab7d72 100644
--- a/sw/CppunitTest_sw_swdoc_test.mk
+++ b/sw/CppunitTest_sw_swdoc_test.mk
@@ -77,6 +77,7 @@ $(eval $(call gb_CppunitTest_use_externals,sw_swdoc_test,\
$(eval $(call gb_CppunitTest_set_include,sw_swdoc_test,\
-I$(SRCDIR)/sw/source/ui/inc \
+ -I$(SRCDIR)/sw/source/core/inc \
-I$(SRCDIR)/sw/inc \
$$(INCLUDE) \
))
diff --git a/sw/inc/modeltoviewhelper.hxx b/sw/inc/modeltoviewhelper.hxx
index cf09567..c37e14b 100644
--- a/sw/inc/modeltoviewhelper.hxx
+++ b/sw/inc/modeltoviewhelper.hxx
@@ -29,10 +29,12 @@
#ifndef _MODELTOVIEWHELPER_HXX
#define _MODELTOVIEWHELPER_HXX
+#include <rtl/ustring.hxx>
#include <sal/types.h>
-
#include <vector>
+class SwTxtNode;
+
/** Some helpers for converting model strings to view strings.
A paragraph string does not have its fields expanded, i.e., they are
@@ -41,8 +43,39 @@
to expand the fields to get the string as it appears in the view. Two
helper functions are provided to convert model positions to view positions
and vice versa.
+
+ CH_TXTATR_BREAKWORD -> SwTxtNode will have field attributes associated with these
+ . .
+ . .
+ . .
+ AAAAA BBBBB # CCCCC # DDDDD
+ | | | |
+ | | | |
+ | ---------
+ | | .
+ | | .
+ | | .......... bounds of a hidden text character attribute
+ ------
+ .
+ .
+ .............. a range of text defined in redline region as deleted
+
+ 0000: pass through gives: AAAAA BBBBB # CCCCC # DDDDD
+ 0001: only expanding fields gives: AAAAA BBBBB foo CCCCC foo DDDDD
+ 0010: only hiding hiddens gives: AAAAA CCCCC # DDDDD
+ 0100: only hiding redlines gives: AAAABB # CCCCC # DDDDD
+ 0011: expanding fields + hiding hiddens gives: AAAAA CCCC foo DDDDD
+ 0101: expanding fields + hiding redlines gives: AAAA B foo CCCCC foo DDDDD
+ 0110: hiding hiddens + hiding redlines gives: AAAACCCC # DDDDD
+ 0111: expanding fields + hiding hiddens + hiding redlines gives: AAAABB foo CCCCC foo DDDDD
*/
-namespace ModelToViewHelper
+
+#define PASSTHROUGH 0x0000
+#define EXPANDFIELDS 0x0001
+#define HIDEINVISIBLE 0x0002
+#define HIDEREDLINED 0x0004
+
+class ModelToViewHelper
{
/** For each field in the model string, there is an entry in the conversion
map. The first value of the ConversionMapEntry points to the field
@@ -53,6 +86,12 @@ namespace ModelToViewHelper
typedef std::pair< sal_uInt32 , sal_uInt32 > ConversionMapEntry;
typedef std::vector< ConversionMapEntry > ConversionMap;
+ ConversionMap m_aMap;
+
+ rtl::OUString m_aRetText;
+
+public:
+
/** This struct defines a position in the model string.
The 'main' position is given by mnPos. If there's a field located at
@@ -68,12 +107,12 @@ namespace ModelToViewHelper
ModelPosition() : mnPos(0), mnSubPos(0), mbIsField(false) {}
};
- /** Converts a model position into a view position
+ ModelToViewHelper(const SwTxtNode &rNode, int eMode = EXPANDFIELDS);
+ ModelToViewHelper() //pass through filter, view == model
+ {
+ }
- @param pMap
- pMap is the conversion map required for the calculation. If pMap is
- 0, no conversion takes place, i.e., it is assumed that the model
- string is identical to the view string.
+ /** Converts a model position into a view position
@param nPos
nPos denotes a position in the model string which should be
@@ -86,15 +125,10 @@ namespace ModelToViewHelper
nPos is behind the last entry in the conversion map) nPos will
be returned.
*/
- sal_uInt32 ConvertToViewPosition( const ConversionMap* pMap, sal_uInt32 nModelPos );
+ sal_uInt32 ConvertToViewPosition( sal_uInt32 nModelPos ) const;
/** Converts a view position into a model position
- @param pMap
- pMap is the conversion map required for the calculation. If pMap is
- 0, no conversion takes place, i.e., it is assumed that the model
- string is identical to the view string.
-
@param nPos
nPos denotes a position in the view string which should be
converted.
@@ -106,8 +140,10 @@ namespace ModelToViewHelper
model position with mnPos = nPos and mnIsField = false will be
returned.
*/
- ModelPosition ConvertToModelPosition( const ConversionMap* pMap, sal_uInt32 nViewPos );
-}
+ ModelPosition ConvertToModelPosition( sal_uInt32 nViewPos ) const;
+
+ rtl::OUString getViewText() const { return m_aRetText; }
+};
#endif
diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx
index 83b3e2f..39565cf 100644
--- a/sw/inc/ndtxt.hxx
+++ b/sw/inc/ndtxt.hxx
@@ -699,9 +699,6 @@ public:
sal_Bool bWithNum = sal_False, sal_Bool bWithFtn = sal_True,
sal_Bool bReplaceTabsWithSpaces = sal_False ) const;
- const ModelToViewHelper::ConversionMap*
- BuildConversionMap( rtl::OUString& rExpandText ) const;
-
XubString GetRedlineTxt( xub_StrLen nIdx = 0,
xub_StrLen nLen = STRING_LEN,
sal_Bool bExpandFlds = sal_False,
diff --git a/sw/inc/swscanner.hxx b/sw/inc/swscanner.hxx
index 3c05995..f657f23 100644
--- a/sw/inc/swscanner.hxx
+++ b/sw/inc/swscanner.hxx
@@ -45,7 +45,7 @@ class SwScanner
const SwTxtNode& rNode;
const rtl::OUString aText;
const LanguageType* pLanguage;
- const ModelToViewHelper::ConversionMap* pConversionMap;
+ const ModelToViewHelper& rConversionMap;
sal_Int32 nStartPos;
sal_Int32 nEndPos;
sal_Int32 nBegin;
@@ -57,7 +57,7 @@ class SwScanner
public:
SwScanner( const SwTxtNode& rNd, const rtl::OUString& rTxt,
const LanguageType* pLang,
- const ModelToViewHelper::ConversionMap* pConvMap,
+ const ModelToViewHelper& rConvMap,
sal_uInt16 nWordType,
sal_Int32 nStart, sal_Int32 nEnde, sal_Bool bClip = sal_False );
diff --git a/sw/inc/unoflatpara.hxx b/sw/inc/unoflatpara.hxx
index 2ab3e59..0945b3f 100644
--- a/sw/inc/unoflatpara.hxx
+++ b/sw/inc/unoflatpara.hxx
@@ -61,7 +61,7 @@ class SwXFlatParagraph:
public SwXTextMarkup
{
public:
- SwXFlatParagraph( SwTxtNode& rTxtNode, rtl::OUString aExpandText, const ModelToViewHelper::ConversionMap* pConversionMap );
+ SwXFlatParagraph( SwTxtNode& rTxtNode, rtl::OUString aExpandText, const ModelToViewHelper& rConversionMap );
virtual ~SwXFlatParagraph();
virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType ) throw(::com::sun::star::uno::RuntimeException);
diff --git a/sw/inc/unotextmarkup.hxx b/sw/inc/unotextmarkup.hxx
index b682a97..2ae333f 100644
--- a/sw/inc/unotextmarkup.hxx
+++ b/sw/inc/unotextmarkup.hxx
@@ -56,7 +56,7 @@ class SwXTextMarkup:
public SwClient
{
public:
- SwXTextMarkup( SwTxtNode& rTxtNode, const ModelToViewHelper::ConversionMap* pConversionMap );
+ SwXTextMarkup( SwTxtNode& rTxtNode, const ModelToViewHelper& rConversionMap );
virtual ~SwXTextMarkup();
// ::com::sun::star::text::XTextMarkup:
@@ -72,11 +72,10 @@ private:
protected:
//SwClient
- virtual void Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew);
+ virtual void Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew);
SwTxtNode* mpTxtNode;
- const ModelToViewHelper::ConversionMap* mpConversionMap;
-
+ const ModelToViewHelper maConversionMap;
};
diff --git a/sw/qa/complex/writer/TextPortionEnumerationTest.java b/sw/qa/complex/writer/TextPortionEnumerationTest.java
index 114359b..bd996fd 100644
--- a/sw/qa/complex/writer/TextPortionEnumerationTest.java
+++ b/sw/qa/complex/writer/TextPortionEnumerationTest.java
@@ -3259,26 +3259,31 @@ public class TextPortionEnumerationTest
XWordCursor xWordCursor = (XWordCursor)
UnoRuntime.queryInterface(XWordCursor.class, xTextCursor);
- bSuccess = xWordCursor.gotoNextWord(true);
+ bSuccess = xWordCursor.gotoNextWord(true); //at start of "words"
assertTrue("gotoNextWord(): failed", bSuccess);
{
String string = xTextCursor.getString();
assertEquals("gotoNextWord(): wrong string",
"Two ", string);
}
- bSuccess = xWordCursor.gotoNextWord(false);
+ bSuccess = xWordCursor.gotoNextWord(false); //at end of "words", cannot leave metafield
assertFalse("gotoNextWord(): succeeded", bSuccess);
xTextCursor.collapseToEnd();
- bSuccess = xWordCursor.gotoPreviousWord(true);
+ bSuccess = xWordCursor.gotoPreviousWord(true); //at start of "words"
assertTrue("gotoPreviousWord(): failed", bSuccess);
{
String string = xTextCursor.getString();
assertEquals("gotoPreviousWord(): wrong string",
"words", string);
}
- bSuccess = xWordCursor.gotoPreviousWord(false);
+ bSuccess = xWordCursor.gotoPreviousWord(false); //at start of "Two"
+ assertTrue("gotoPreviousWord(): failed", bSuccess);
+
+
+ bSuccess = xWordCursor.gotoPreviousWord(false); //cannot leave metafield
assertFalse("gotoPreviousWord(): succeeded", bSuccess);
- bSuccess = xWordCursor.gotoEndOfWord(true);
+
+ bSuccess = xWordCursor.gotoEndOfWord(true); //at end of "Two"
assertTrue("gotoEndOfWord(): failed", bSuccess);
{
String string = xTextCursor.getString();
@@ -3362,6 +3367,23 @@ public class TextPortionEnumerationTest
assertFalse("gotoEndOfParagraph(): succeeded", bSuccess);
}
+ /** See https://bugs.freedesktop.org/show_bug.cgi?id=49629
+ ensure that gotoEndOfWord does not fail when footnote is at word end*/
+ @Test public void testXTextCursor() throws Exception
+ {
+ RangeInserter inserter = new RangeInserter(m_xDoc);
+ XText xDocText = m_xDoc.getText();
+ XTextCursor xDocTextCursor = xDocText.createTextCursor();
+ inserter.insertText(xDocTextCursor, "Text");
+ XWordCursor xWordCursor = UnoRuntime.queryInterface(XWordCursor.class, xDocTextCursor);
+ xWordCursor.gotoEndOfWord(false);
+ inserter.insertFootnote(xDocTextCursor, "footnote");
+ xDocTextCursor.gotoStart(false);
+ boolean bSuccess = xWordCursor.gotoEndOfWord(true);
+ assertTrue("gotoEndOfWord(): failed", bSuccess);
+ String string = xWordCursor.getString();
+ assertEquals("gotoEndOfWord(): wrong string", "Text", string);
+ }
abstract class AttachHelper
{
diff --git a/sw/qa/core/swdoc-test.cxx b/sw/qa/core/swdoc-test.cxx
index f19e9e5..1ad4d25 100644
--- a/sw/qa/core/swdoc-test.cxx
+++ b/sw/qa/core/swdoc-test.cxx
@@ -233,7 +233,7 @@ void SwDocTest::testSwScanner()
{
SwScanner aScanner(*pTxtNode,
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Hello World")),
- 0, 0, i18n::WordType::DICTIONARY_WORD, 0,
+ 0, ModelToViewHelper(), i18n::WordType::DICTIONARY_WORD, 0,
RTL_CONSTASCII_LENGTH("Hello World"));
bool bFirstOk = aScanner.NextWord();
diff --git a/sw/source/core/doc/docedt.cxx b/sw/source/core/doc/docedt.cxx
index c805779..d32a4ba 100644
--- a/sw/source/core/doc/docedt.cxx
+++ b/sw/source/core/doc/docedt.cxx
@@ -1804,7 +1804,7 @@ bool SwDoc::DeleteRange( SwPaM & rPam )
void lcl_syncGrammarError( SwTxtNode &rTxtNode, linguistic2::ProofreadingResult& rResult,
- xub_StrLen /*nBeginGrammarCheck*/, const ModelToViewHelper::ConversionMap* pConversionMap )
+ xub_StrLen /*nBeginGrammarCheck*/, const ModelToViewHelper &rConversionMap )
{
if( rTxtNode.IsGrammarCheckDirty() )
return;
@@ -1816,8 +1816,8 @@ void lcl_syncGrammarError( SwTxtNode &rTxtNode, linguistic2::ProofreadingResult&
for( i = 0; i < rResult.aErrors.getLength(); ++i )
{
const linguistic2::SingleProofreadingError &rError = rResult.aErrors[i];
- xub_StrLen nStart = (xub_StrLen)ModelToViewHelper::ConvertToModelPosition( pConversionMap, rError.nErrorStart ).mnPos;
- xub_StrLen nEnd = (xub_StrLen)ModelToViewHelper::ConvertToModelPosition( pConversionMap, rError.nErrorStart + rError.nErrorLength ).mnPos;
+ xub_StrLen nStart = (xub_StrLen)rConversionMap.ConvertToModelPosition( rError.nErrorStart ).mnPos;
+ xub_StrLen nEnd = (xub_StrLen)rConversionMap.ConvertToModelPosition( rError.nErrorStart + rError.nErrorLength ).mnPos;
if( i != j )
pArray[j] = pArray[i];
if( pWrong->LookForEntry( nStart, nEnd ) )
@@ -1935,22 +1935,22 @@ uno::Any SwDoc::Spell( SwPaM& rPaM,
String aText( ((SwTxtNode*)pNd)->GetTxt().Copy( nBeginGrammarCheck, nEndGrammarCheck - nBeginGrammarCheck ) );
uno::Reference< lang::XComponent > xDoc( ((SwDocShell*)GetDocShell())->GetBaseModel(), uno::UNO_QUERY );
// Expand the string:
- rtl::OUString aExpandText;
- const ModelToViewHelper::ConversionMap* pConversionMap =
- ((SwTxtNode*)pNd)->BuildConversionMap( aExpandText );
+ const ModelToViewHelper aConversionMap(*(SwTxtNode*)pNd);
+ rtl::OUString aExpandText = aConversionMap.getViewText();
+
// get XFlatParagraph to use...
- uno::Reference< text::XFlatParagraph > xFlatPara = new SwXFlatParagraph( *((SwTxtNode*)pNd), aExpandText, pConversionMap );
+ uno::Reference< text::XFlatParagraph > xFlatPara = new SwXFlatParagraph( *((SwTxtNode*)pNd), aExpandText, aConversionMap );
// get error position of cursor in XFlatParagraph
linguistic2::ProofreadingResult aResult;
sal_Int32 nGrammarErrors;
do
{
- ModelToViewHelper::ConvertToViewPosition( pConversionMap, nBeginGrammarCheck );
+ aConversionMap.ConvertToViewPosition( nBeginGrammarCheck );
aResult = xGCIterator->checkSentenceAtPosition(
xDoc, xFlatPara, aExpandText, lang::Locale(), nBeginGrammarCheck, -1, -1 );
- lcl_syncGrammarError( *((SwTxtNode*)pNd), aResult, nBeginGrammarCheck, pConversionMap );
+ lcl_syncGrammarError( *((SwTxtNode*)pNd), aResult, nBeginGrammarCheck, aConversionMap );
// get suggestions to use for the specific error position
nGrammarErrors = aResult.aErrors.getLength();
@@ -1972,8 +1972,8 @@ uno::Any SwDoc::Spell( SwPaM& rPaM,
pEndPos->nNode = nCurrNd;
pSpellArgs->pStartNode = ((SwTxtNode*)pNd);
pSpellArgs->pEndNode = ((SwTxtNode*)pNd);
- pSpellArgs->pStartIdx->Assign(((SwTxtNode*)pNd), (xub_StrLen)ModelToViewHelper::ConvertToModelPosition( pConversionMap, rError.nErrorStart ).mnPos );
- pSpellArgs->pEndIdx->Assign(((SwTxtNode*)pNd), (xub_StrLen)ModelToViewHelper::ConvertToModelPosition( pConversionMap, rError.nErrorStart + rError.nErrorLength ).mnPos );
+ pSpellArgs->pStartIdx->Assign(((SwTxtNode*)pNd), (xub_StrLen)aConversionMap.ConvertToModelPosition( rError.nErrorStart ).mnPos );
+ pSpellArgs->pEndIdx->Assign(((SwTxtNode*)pNd), (xub_StrLen)aConversionMap.ConvertToModelPosition( rError.nErrorStart + rError.nErrorLength ).mnPos );
nCurrNd = nEndNd;
}
}
diff --git a/sw/source/core/edit/edlingu.cxx b/sw/source/core/edit/edlingu.cxx
index e95f967..d72fbf1 100644
--- a/sw/source/core/edit/edlingu.cxx
+++ b/sw/source/core/edit/edlingu.cxx
@@ -1132,17 +1132,16 @@ bool SwEditShell::GetGrammarCorrection(
uno::Reference< lang::XComponent > xDoc( pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY );
// Expand the string:
- rtl::OUString aExpandText;
- const ModelToViewHelper::ConversionMap* pConversionMap =
- pNode->BuildConversionMap( aExpandText );
+ const ModelToViewHelper aConversionMap(*pNode);
+ rtl::OUString aExpandText = aConversionMap.getViewText();
// get XFlatParagraph to use...
- uno::Reference< text::XFlatParagraph > xFlatPara = new SwXFlatParagraph( *pNode, aExpandText, pConversionMap );
+ uno::Reference< text::XFlatParagraph > xFlatPara = new SwXFlatParagraph( *pNode, aExpandText, aConversionMap );
// get error position of cursor in XFlatParagraph
- rErrorPosInText = ModelToViewHelper::ConvertToViewPosition( pConversionMap, nBegin );
+ rErrorPosInText = aConversionMap.ConvertToViewPosition( nBegin );
- sal_Int32 nStartOfSentence = ModelToViewHelper::ConvertToViewPosition( pConversionMap, pWrong->getSentenceStart( nBegin ) );
- sal_Int32 nEndOfSentence = ModelToViewHelper::ConvertToViewPosition( pConversionMap, pWrong->getSentenceEnd( nBegin ) );
+ sal_Int32 nStartOfSentence = aConversionMap.ConvertToViewPosition( pWrong->getSentenceStart( nBegin ) );
+ sal_Int32 nEndOfSentence = aConversionMap.ConvertToViewPosition( pWrong->getSentenceEnd( nBegin ) );
if( nEndOfSentence == STRING_LEN )
{
nEndOfSentence = aExpandText.getLength();
@@ -1603,9 +1602,9 @@ bool SwSpellIter::SpellSentence(::svx::SpellPortions& rPortions, bool bIsGrammar
pMySh->GoEndSentence();
if( bGrammarErrorFound )
{
- rtl::OUString aExpandText;
- const ModelToViewHelper::ConversionMap* pConversionMap = ((SwTxtNode*)pCrsr->GetNode())->BuildConversionMap( aExpandText );
- xub_StrLen nSentenceEnd = (xub_StrLen)ModelToViewHelper::ConvertToViewPosition( pConversionMap, aGrammarResult.nBehindEndOfSentencePosition );
+ const ModelToViewHelper aConversionMap(*(SwTxtNode*)pCrsr->GetNode());
+ rtl::OUString aExpandText = aConversionMap.getViewText();
+ xub_StrLen nSentenceEnd = (xub_StrLen)aConversionMap.ConvertToViewPosition( aGrammarResult.nBehindEndOfSentencePosition );
// remove trailing space
if( aExpandText[nSentenceEnd - 1] == ' ' )
--nSentenceEnd;
diff --git a/sw/source/core/inc/scriptinfo.hxx b/sw/source/core/inc/scriptinfo.hxx
index b58dbb2..01e5345 100644
--- a/sw/source/core/inc/scriptinfo.hxx
+++ b/sw/source/core/inc/scriptinfo.hxx
@@ -128,8 +128,9 @@ public:
inline size_t CountHiddenChg() const;
inline xub_StrLen GetHiddenChg( const size_t nCnt ) const;
- static void CalcHiddenRanges( const SwTxtNode& rNode,
- MultiSelection& rHiddenMulti );
+ static void CalcHiddenRanges(const SwTxtNode& rNode, MultiSelection& rHiddenMulti);
+ static void selectHiddenTextProperty(const SwTxtNode& rNode, MultiSelection &rHiddenMulti);
+ static void selectRedLineDeleted(const SwTxtNode& rNode, MultiSelection &rHiddenMulti, bool bSelect=true);
// "high" level operations, nPos refers to string position
xub_StrLen NextScriptChg( const xub_StrLen nPos ) const;
diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
index 8589becf..97da02e 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -34,8 +34,8 @@
#include "blink.hxx" // pBlink
#include "redlnitr.hxx" // SwRedlineItr
#include "porfly.hxx" // SwFlyCntPortion
-#include <porrst.hxx> // SwHangingPortion
-#include <pormulti.hxx> // SwMultiPortion
+#include <porrst.hxx> // SwHangingPortion
+#include <pormulti.hxx> // SwMultiPortion
#include <breakit.hxx>
#include <unicode/uchar.h>
#include <com/sun/star/i18n/ScriptType.hdl>
@@ -52,8 +52,8 @@
#include <i18npool/mslangid.hxx>
#include <charfmt.hxx>
#include <fchrfmt.hxx>
-#include <docary.hxx> // SwRedlineTbl
-#include <redline.hxx> // SwRedline
+#include <docary.hxx> // SwRedlineTbl
+#include <redline.hxx> // SwRedline
#include <section.hxx>
#include <switerator.hxx>
#include <IDocumentRedlineAccess.hxx>
@@ -94,7 +94,7 @@ sal_Bool isTransparentChar ( xub_Unicode cCh )
}
/*************************************************************************
- * lcl_IsLigature
+ * lcl_IsLigature
*
* Checks if cCh + cNectCh builds a ligature (used for Kashidas)
*************************************************************************/
@@ -106,7 +106,7 @@ sal_Bool lcl_IsLigature( xub_Unicode cCh, xub_Unicode cNextCh )
}
/*************************************************************************
- * lcl_ConnectToPrev
+ * lcl_ConnectToPrev
*
* Checks if cCh is connectable to cPrevCh (used for Kashidas)
*************************************************************************/
@@ -124,7 +124,7 @@ sal_Bool lcl_ConnectToPrev( xub_Unicode cCh, xub_Unicode cPrevCh )
}
/*************************************************************************
- * lcl_HasStrongLTR
+ * lcl_HasStrongLTR
*************************************************************************/
bool lcl_HasStrongLTR ( const String& rTxt, xub_StrLen nStart, xub_StrLen nEnd )
{
@@ -140,7 +140,7 @@ sal_Bool lcl_ConnectToPrev( xub_Unicode cCh, xub_Unicode cPrevCh )
}
/*************************************************************************
- * SwLineLayout::~SwLineLayout()
+ * SwLineLayout::~SwLineLayout()
*
* class SwLineLayout: Das Layout einer einzelnen Zeile. Dazu
* gehoeren vor allen Dingen die Dimension, die Anzahl der
@@ -161,10 +161,6 @@ SwLineLayout::~SwLineLayout()
delete pKanaComp;
}
-/*************************************************************************
- * virtual SwLineLayout::Insert()
- *************************************************************************/
-
SwLinePortion *SwLineLayout::Insert( SwLinePortion *pIns )
{
// Erster Attributwechsel, Masse und Laengen
@@ -190,10 +186,6 @@ SwLinePortion *SwLineLayout::Insert( SwLinePortion *pIns )
return pPortion->SwLinePortion::Insert( pIns );
}
-/*************************************************************************
- * virtual SwLineLayout::Append()
- *************************************************************************/
-
SwLinePortion *SwLineLayout::Append( SwLinePortion *pIns )
{
// Erster Attributwechsel, Masse und Laengen
@@ -204,10 +196,6 @@ SwLinePortion *SwLineLayout::Append( SwLinePortion *pIns )
return pPortion->SwLinePortion::Append( pIns );
}
-/*************************************************************************
- * virtual SwLineLayout::Format()
- *************************************************************************/
-
// fuer die Sonderbehandlung bei leeren Zeilen
sal_Bool SwLineLayout::Format( SwTxtFormatInfo &rInf )
@@ -222,7 +210,7 @@ sal_Bool SwLineLayout::Format( SwTxtFormatInfo &rInf )
}
/*************************************************************************
- * SwLineLayout::CalcLeftMargin()
+ * SwLineLayout::CalcLeftMargin()
*
* Wir sammeln alle FlyPortions am Anfang der Zeile zu einer MarginPortion.
*************************************************************************/
@@ -266,10 +254,6 @@ SwMarginPortion *SwLineLayout::CalcLeftMargin()
return pLeft;
}
-/*************************************************************************
- * SwLineLayout::InitSpaceAdd()
- *************************************************************************/
-
void SwLineLayout::InitSpaceAdd()
{
if ( !pLLSpaceAdd )
@@ -278,10 +262,6 @@ void SwLineLayout::InitSpaceAdd()
SetLLSpaceAdd( 0, 0 );
}
-/*************************************************************************
- * SwLineLayout::CreateSpaceAdd()
- *************************************************************************/
-
void SwLineLayout::CreateSpaceAdd( const long nInit )
{
pLLSpaceAdd = new std::vector<long>;
@@ -309,7 +289,7 @@ bool lcl_HasOnlyBlanks( const XubString& rTxt, xub_StrLen nStt, xub_StrLen nEnd
}
/*************************************************************************
- * SwLineLayout::CalcLine()
+ * SwLineLayout::CalcLine()
*
* Aus FormatLine() ausgelagert.
*************************************************************************/
@@ -626,10 +606,6 @@ void SwLineLayout::MaxAscentDescent( SwTwips& _orAscent,
}
}
-/*************************************************************************
- * class SwCharRange
- *************************************************************************/
-
SwCharRange &SwCharRange::operator+=(const SwCharRange &rRange)
{
if(0 != rRange.nLen ) {
@@ -650,28 +626,23 @@ SwCharRange &SwCharRange::operator+=(const SwCharRange &rRange)
return *this;
}
-/*************************************************************************
- * SwScriptInfo::SwScriptInfo()
- *************************************************************************/
SwScriptInfo::SwScriptInfo() :
nInvalidityPos( 0 ),
nDefaultDir( 0 )
{
};
-/*************************************************************************
- * SwScriptInfo::~SwScriptInfo()
- *************************************************************************/
SwScriptInfo::~SwScriptInfo()
{
}
/*************************************************************************
- * SwScriptInfo::WhichFont()
+ * SwScriptInfo::WhichFont()
*
* Converts i18n Script Type (LATIN, ASIAN, COMPLEX, WEAK) to
* Sw Script Types (SW_LATIN, SW_CJK, SW_CTL), used to identify the font
- *************************************************************************/
+*************************************************************************/
+
sal_uInt8 SwScriptInfo::WhichFont( xub_StrLen nIdx, const String* pTxt, const SwScriptInfo* pSI )
{
OSL_ENSURE( pTxt || pSI,"How should I determine the script type?" );
@@ -695,7 +666,7 @@ sal_uInt8 SwScriptInfo::WhichFont( xub_StrLen nIdx, const String* pTxt, const Sw
}
/*************************************************************************
- * SwScriptInfo::InitScriptInfo()
+ * SwScriptInfo::InitScriptInfo()
*
* searches for script changes in rTxt and stores them
*************************************************************************/
@@ -1020,7 +991,7 @@ void SwScriptInfo::InitScriptInfo( const SwTxtNode& rNode, sal_Bool bRTL )
// we search for connecting opportunities (kashida)
else if ( bAdjustBlock && i18n::ScriptType::COMPLEX == nScript )
{
- SwScanner aScanner( rNode, rNode.GetTxt(), 0, 0,
+ SwScanner aScanner( rNode, rNode.GetTxt(), 0, ModelToViewHelper(),
i18n::WordType::DICTIONARY_WORD,
nLastKashida, nChg );
@@ -1326,7 +1297,7 @@ void SwScriptInfo::UpdateBidiInfo( const String& rTxt )
/*************************************************************************
- * SwScriptInfo::NextScriptChg(..)
+ * SwScriptInfo::NextScriptChg(..)
* returns the position of the next character which belongs to another script
* than the character of the actual (input) position.
* If there's no script change until the end of the paragraph, it will return
@@ -1349,7 +1320,7 @@ xub_StrLen SwScriptInfo::NextScriptChg( const xub_StrLen nPos ) const
}
/*************************************************************************
- * SwScriptInfo::ScriptType(..)
+ * SwScriptInfo::ScriptType(..)
* returns the script of the character at the input position
*************************************************************************/
@@ -1394,7 +1365,7 @@ sal_uInt8 SwScriptInfo::DirType( const xub_StrLen nPos ) const
}
/*************************************************************************
- * SwScriptInfo::MaskHiddenRanges(..)
+ * SwScriptInfo::MaskHiddenRanges(..)
* Takes a string and replaced the hidden ranges with cChar.
**************************************************************************/
@@ -1434,7 +1405,7 @@ sal_uInt16 SwScriptInfo::MaskHiddenRanges( const SwTxtNode& rNode, XubString& rT
}
/*************************************************************************
- * SwScriptInfo::DeleteHiddenRanges(..)
+ * SwScriptInfo::DeleteHiddenRanges(..)
* Takes a SwTxtNode and deletes the hidden ranges from the node.
**************************************************************************/
@@ -1457,7 +1428,7 @@ void SwScriptInfo::DeleteHiddenRanges( SwTxtNode& rNode )
}
/*************************************************************************
- * SwScriptInfo::GetBoundsOfHiddenRange(..)
+ * SwScriptInfo::GetBoundsOfHiddenRange(..)
* static version
**************************************************************************/
@@ -1545,7 +1516,7 @@ bool SwScriptInfo::GetBoundsOfHiddenRange( const SwTxtNode& rNode, xub_StrLen nP
}
/*************************************************************************
- * SwScriptInfo::GetBoundsOfHiddenRange(..)
+ * SwScriptInfo::GetBoundsOfHiddenRange(..)
* non-static version
**************************************************************************/
@@ -1583,10 +1554,6 @@ bool SwScriptInfo::GetBoundsOfHiddenRange( xub_StrLen nPos, xub_StrLen& rnStartP
return CountHiddenChg() > 0;
}
-/*************************************************************************
- * SwScriptInfo::IsInHiddenRange()
- **************************************************************************/
-
bool SwScriptInfo::IsInHiddenRange( const SwTxtNode& rNode, xub_StrLen nPos )
{
xub_StrLen nStartPos;
@@ -1598,7 +1565,7 @@ bool SwScriptInfo::IsInHiddenRange( const SwTxtNode& rNode, xub_StrLen nPos )
#ifdef DBG_UTIL
/*************************************************************************
- * SwScriptInfo::CompType(..)
+ * SwScriptInfo::CompType(..)
* returns the type of the compressed character
*************************************************************************/
@@ -1620,7 +1587,7 @@ sal_uInt8 SwScriptInfo::CompType( const xub_StrLen nPos ) const
#endif
/*************************************************************************
- * SwScriptInfo::HasKana()
+ * SwScriptInfo::HasKana()
* returns, if there are compressable kanas or specials
* betwenn nStart and nEnd
*************************************************************************/
@@ -1645,10 +1612,6 @@ sal_uInt16 SwScriptInfo::HasKana( xub_StrLen nStart, const xub_StrLen nLen ) con
return USHRT_MAX;
}
-/*************************************************************************
- * SwScriptInfo::Compress()
- *************************************************************************/
-
long SwScriptInfo::Compress( sal_Int32* pKernArray, xub_StrLen nIdx, xub_StrLen nLen,
const sal_uInt16 nCompress, const sal_uInt16 nFontHeight,
Point* pPoint ) const
@@ -1762,7 +1725,7 @@ long SwScriptInfo::Compress( sal_Int32* pKernArray, xub_StrLen nIdx, xub_StrLen
}
/*************************************************************************
- * SwScriptInfo::KashidaJustify()
+ * SwScriptInfo::KashidaJustify()
*************************************************************************/
// Note on calling KashidaJustify():
@@ -1854,7 +1817,7 @@ sal_uInt16 SwScriptInfo::KashidaJustify( sal_Int32* pKernArray,
}
/*************************************************************************
- * SwScriptInfo::IsArabicText()
+ * SwScriptInfo::IsArabicText()
*
* Checks if the current text is 'Arabic' text. Note that only the first
* character has to be checked because a ctl portion only contains one
@@ -1896,10 +1859,6 @@ bool SwScriptInfo::IsArabicText( const rtl::OUString& rTxt, sal_Int32 nStt, sal_
return false;
}
-/*************************************************************************
- * SwScriptInfo::IsKashidaValid()
- *************************************************************************/
-
sal_Bool SwScriptInfo::IsKashidaValid ( xub_StrLen nKashPos ) const
{
for ( size_t i = 0; i < aKashidaInvalid.size(); ++i )
@@ -1910,10 +1869,6 @@ sal_Bool SwScriptInfo::IsKashidaValid ( xub_StrLen nKashPos ) const
return true;
}
-/*************************************************************************
- * SwScriptInfo::ClearKashidaInvalid()
- *************************************************************************/
-
void SwScriptInfo::ClearKashidaInvalid ( xub_StrLen nKashPos )
{
for ( size_t i = 0; i < aKashidaInvalid.size(); ++i )
@@ -1927,13 +1882,14 @@ void SwScriptInfo::ClearKashidaInvalid ( xub_StrLen nKashPos )
}
/*************************************************************************
- * SwScriptInfo::MarkOrClearKashidaInvalid()
- *************************************************************************/
-// bMark == true:
-// marks the first valid kashida in the given text range as invalid
-
-// bMark == false:
-// clears all kashida invalid flags in the given text range
+ * SwScriptInfo::MarkOrClearKashidaInvalid()
+ *
+ * bMark == true:
+ * marks the first valid kashida in the given text range as invalid
+ *
+ * bMark == false:
+ * clears all kashida invalid flags in the given text range
+*************************************************************************/
bool SwScriptInfo::MarkOrClearKashidaInvalid ( xub_StrLen nStt, xub_StrLen nLen, bool bMark, xub_StrLen nMarkCount )
{
@@ -1980,9 +1936,10 @@ void SwScriptInfo::MarkKashidaInvalid ( xub_StrLen nKashPos )
}
/*************************************************************************
- * SwScriptInfo::GetKashidaPositions()
- *************************************************************************/
-// retrieve the kashida positions in the given text range
+ * SwScriptInfo::GetKashidaPositions()
+ * retrieve the kashida positions in the given text range
+*************************************************************************/
+
sal_uInt16 SwScriptInfo::GetKashidaPositions ( xub_StrLen nStt, xub_StrLen nLen,
xub_StrLen* pKashidaPosition )
{
@@ -2018,9 +1975,9 @@ void SwScriptInfo::SetNoKashidaLine ( xub_StrLen nStt, xub_StrLen nLen )
}
/*************************************************************************
- * SwScriptInfo::IsKashidaLine()
- *************************************************************************/
-// determines if the line uses kashida justification
+ * SwScriptInfo::IsKashidaLine()
+ * determines if the line uses kashida justification
+*************************************************************************/
bool SwScriptInfo::IsKashidaLine ( xub_StrLen nCharIdx ) const
{
@@ -2031,9 +1988,6 @@ bool SwScriptInfo::IsKashidaLine ( xub_StrLen nCharIdx ) const
}
return true;
}
-/*************************************************************************
- * SwScriptInfo::ClearKashidaLine()
- *************************************************************************/
void SwScriptInfo::ClearNoKashidaLine ( xub_StrLen nStt, xub_StrLen nLen )
{
@@ -2052,8 +2006,10 @@ void SwScriptInfo::ClearNoKashidaLine ( xub_StrLen nStt, xub_StrLen nLen )
/*************************************************************************
* SwScriptInfo::MarkKashidasInvalid()
- *************************************************************************/
-// mark the given character indices as invalid kashida positions
+ *
+ * mark the given character indices as invalid kashida positions
+************************************************************************/
+
bool SwScriptInfo::MarkKashidasInvalid ( xub_StrLen nCnt, xub_StrLen* pKashidaPositions )
{
OSL_ENSURE( pKashidaPositions && nCnt > 0, "Where are kashidas?" );
@@ -2080,10 +2036,6 @@ bool SwScriptInfo::MarkKashidasInvalid ( xub_StrLen nCnt, xub_StrLen* pKashidaPo
return true;
}
-/*************************************************************************
- * SwScriptInfo::ThaiJustify()
- *************************************************************************/
-
sal_Int32 SwScriptInfo::ThaiJustify( const rtl::OUString& rTxt, sal_Int32* pKernArray,
sal_Int32* pScrArray, sal_Int32 nStt,
sal_Int32 nLen, sal_Int32 nNumberOfBlanks,
@@ -2122,10 +2074,6 @@ sal_Int32 SwScriptInfo::ThaiJustify( const rtl::OUString& rTxt, sal_Int32* pKern
return nCnt;
}
-/*************************************************************************
- * SwScriptInfo::GetScriptInfo()
- *************************************************************************/
-
SwScriptInfo* SwScriptInfo::GetScriptInfo( const SwTxtNode& rTNd,
sal_Bool bAllowInvalid )
{
@@ -2146,9 +2094,6 @@ SwScriptInfo* SwScriptInfo::GetScriptInfo( const SwTxtNode& rTNd,
return pScriptInfo;
}
-/*************************************************************************
- * SwParaPortion::SwParaPortion()
- *************************************************************************/
SwParaPortion::SwParaPortion()
{
FormatReset();
@@ -2156,16 +2101,10 @@ SwParaPortion::SwParaPortion()
SetWhichPor( POR_PARA );
}
-/*************************************************************************
- * SwParaPortion::~SwParaPortion()
- *************************************************************************/
SwParaPortion::~SwParaPortion()
{
}
-/*************************************************************************
- * SwParaPortion::GetParLen()
- *************************************************************************/
xub_StrLen SwParaPortion::GetParLen() const
{
xub_StrLen nLen = 0;
@@ -2178,10 +2117,6 @@ xub_StrLen SwParaPortion::GetParLen() const
return nLen;
}
-/*************************************************************************
- * SwParaPortion::FindDropPortion()
- *************************************************************************/
-
const SwDropPortion *SwParaPortion::FindDropPortion() const
{
const SwLineLayout *pLay = this;
@@ -2199,10 +2134,6 @@ const SwDropPortion *SwParaPortion::FindDropPortion() const
return NULL;
}
-/*************************************************************************
- * SwLineLayout::Init()
- *************************************************************************/
-
void SwLineLayout::Init( SwLinePortion* pNextPortion )
{
Height( 0 );
@@ -2263,14 +2194,7 @@ SwTwips SwTxtFrm::HangingMargin() const
return nRet;
}
-
-/*************************************************************************
- * SwScriptInfo::CalcHiddenRanges()
- *
- * Returns a MultiSection indicating the hidden ranges.
- *************************************************************************/
-
-void SwScriptInfo::CalcHiddenRanges( const SwTxtNode& rNode, MultiSelection& rHiddenMulti )
+void SwScriptInfo::selectHiddenTextProperty(const SwTxtNode& rNode, MultiSelection &rHiddenMulti)
{
const SfxPoolItem* pItem = 0;
if( SFX_ITEM_SET == rNode.GetSwAttrSet().GetItemState( RES_CHRATR_HIDDEN, sal_True, &pItem ) &&
@@ -2280,7 +2204,6 @@ void SwScriptInfo::CalcHiddenRanges( const SwTxtNode& rNode, MultiSelection& rHi
}
const SwpHints* pHints = rNode.GetpSwpHints();
- const SwTxtAttr* pTxtAttr = 0;
if( pHints )
{
@@ -2288,8 +2211,9 @@ void SwScriptInfo::CalcHiddenRanges( const SwTxtNode& rNode, MultiSelection& rHi
while( nTmp < pHints->GetStartCount() )
{
- pTxtAttr = pHints->GetStart( nTmp++ );
- const SvxCharHiddenItem* pHiddenItem = static_cast<const SvxCharHiddenItem*>( CharFmt::GetItem( *pTxtAttr, RES_CHRATR_HIDDEN ) );
+ const SwTxtAttr* pTxtAttr = pHints->GetStart( nTmp++ );
+ const SvxCharHiddenItem* pHiddenItem =
+ static_cast<const SvxCharHiddenItem*>( CharFmt::GetItem( *pTxtAttr, RES_CHRATR_HIDDEN ) );
if( pHiddenItem )
{
xub_StrLen nSt = *pTxtAttr->GetStart();
@@ -2302,11 +2226,12 @@ void SwScriptInfo::CalcHiddenRanges( const SwTxtNode& rNode, MultiSelection& rHi
}
}
}
+}
- // If there are any hidden ranges in the current text node, we have
- // to unhide the redlining ranges:
+void SwScriptInfo::selectRedLineDeleted(const SwTxtNode& rNode, MultiSelection &rHiddenMulti, bool bSelect)
+{
const IDocumentRedlineAccess& rIDRA = *rNode.getIDocumentRedlineAccess();
- if ( rHiddenMulti.GetRangeCount() && IDocumentRedlineAccess::IsShowChanges( rIDRA.GetRedlineMode() ) )
+ if ( IDocumentRedlineAccess::IsShowChanges( rIDRA.GetRedlineMode() ) )
{
sal_uInt16 nAct = rIDRA.GetRedlinePos( rNode, USHRT_MAX );
@@ -2320,13 +2245,30 @@ void SwScriptInfo::CalcHiddenRanges( const SwTxtNode& rNode, MultiSelection& rHi
xub_StrLen nRedlStart;
xub_StrLen nRedlnEnd;
pRed->CalcStartEnd( rNode.GetIndex(), nRedlStart, nRedlnEnd );
+ //clip it if the redline extends past the end of the nodes text
+ nRedlnEnd = std::min(nRedlnEnd, rNode.GetTxt().Len());
if ( nRedlnEnd > nRedlStart )
{
Range aTmp( nRedlStart, nRedlnEnd - 1 );
- rHiddenMulti.Select( aTmp, false );
+ rHiddenMulti.Select( aTmp, bSelect );
}
}
}
+}
+
+/*************************************************************************
+ * SwScriptInfo::CalcHiddenRanges()
+ *
+ * Returns a MultiSection indicating the hidden ranges.
+ *************************************************************************/
+
+void SwScriptInfo::CalcHiddenRanges( const SwTxtNode& rNode, MultiSelection& rHiddenMulti )
+{
+ selectHiddenTextProperty(rNode, rHiddenMulti);
+
+ // If there are any hidden ranges in the current text node, we have
+ // to unhide the redlining ranges:
+ selectRedLineDeleted(rNode, rHiddenMulti, false);
//
// We calculated a lot of stuff. Finally we can update the flags at the text node.
diff --git a/sw/source/core/txtnode/modeltoviewhelper.cxx b/sw/source/core/txtnode/modeltoviewhelper.cxx
index 4f8b89a..2891765 100644
--- a/sw/source/core/txtnode/modeltoviewhelper.cxx
+++ b/sw/source/core/txtnode/modeltoviewhelper.cxx
@@ -28,21 +28,15 @@
#include <modeltoviewhelper.hxx>
-namespace ModelToViewHelper
-{
-
/** Converts a model position into a view position
*/
-sal_uInt32 ConvertToViewPosition( const ConversionMap* pMap, sal_uInt32 nModelPos )
+sal_uInt32 ModelToViewHelper::ConvertToViewPosition( sal_uInt32 nModelPos ) const
{
sal_uInt32 nRet = nModelPos;
- if ( !pMap )
- return nRet;
-
- // Search for entry behind nPos:
+ // Search for entry after nPos:
ConversionMap::const_iterator aIter;
- for ( aIter = pMap->begin(); aIter != pMap->end(); ++aIter )
+ for ( aIter = m_aMap.begin(); aIter != m_aMap.end(); ++aIter )
{
if ( (*aIter).first >= nModelPos )
{
@@ -61,17 +55,14 @@ sal_uInt32 ConvertToViewPosition( const ConversionMap* pMap, sal_uInt32 nModelPo
/** Converts a view position into a model position
*/
-ModelPosition ConvertToModelPosition( const ConversionMap* pMap, sal_uInt32 nViewPos )
+ModelToViewHelper::ModelPosition ModelToViewHelper::ConvertToModelPosition( sal_uInt32 nViewPos ) const
{
ModelPosition aRet;
aRet.mnPos = nViewPos;
- if ( !pMap )
- return aRet;
-
- // Search for entry behind nPos:
+ // Search for entry after nPos:
ConversionMap::const_iterator aIter;
- for ( aIter = pMap->begin(); aIter != pMap->end(); ++aIter )
+ for ( aIter = m_aMap.begin(); aIter != m_aMap.end(); ++aIter )
{
if ( (*aIter).second > nViewPos )
{
@@ -79,7 +70,7 @@ ModelPosition ConvertToModelPosition( const ConversionMap* pMap, sal_uInt32 nVie
const sal_uInt32 nPosExpand = (*aIter).second;
// If nViewPos is in front of first field, we are finished.
- if ( aIter == pMap->begin() )
+ if ( aIter == m_aMap.begin() )
break;
--aIter;
@@ -116,6 +107,4 @@ ModelPosition ConvertToModelPosition( const ConversionMap* pMap, sal_uInt32 nVie
return aRet;
}
-} // namespace ModelToViewStringConverter end
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 46ef849..fc0a192 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -38,6 +38,7 @@
#include <svl/urihelper.hxx>
#include <svl/svstdarr.hxx>
#include <svl/ctloptions.hxx>
+#include <tools/multisel.hxx>
#include <swmodule.hxx>
#include <txtfld.hxx>
#include <txtinet.hxx>
@@ -3108,44 +3109,136 @@ sal_Bool SwTxtNode::GetExpandTxt( SwTxtNode& rDestNd, const SwIndex* pDestIdx,
return sal_True;
}
-const ModelToViewHelper::ConversionMap*
- SwTxtNode::BuildConversionMap( rtl::OUString& rRetText ) const
+struct block
{
- const rtl::OUString& rNodeText = GetTxt();
- rRetText = rNodeText;
- ModelToViewHelper::ConversionMap* pConversionMap = 0;
-
- const SwpHints* pSwpHints2 = GetpSwpHints();
- xub_StrLen nPos = 0;
-
- for ( sal_uInt16 i = 0; pSwpHints2 && i < pSwpHints2->Count(); ++i )
- {
- const SwTxtAttr* pAttr = (*pSwpHints2)[i];
- if ( RES_TXTATR_FIELD == pAttr->Which() )
- {
- const XubString aExpand(
- static_cast<SwTxtFld const*>(pAttr)->GetFld().GetFld()
- ->ExpandField(true));
- if ( aExpand.Len() > 0 )
- {
- const xub_StrLen nFieldPos = *pAttr->GetStart();
- rRetText = rRetText.replaceAt( nPos + nFieldPos, 1, aExpand );
- if ( !pConversionMap )
- pConversionMap = new ModelToViewHelper::ConversionMap;
- pConversionMap->push_back(
- ModelToViewHelper::ConversionMapEntry(
- nFieldPos, nPos + nFieldPos ) );
- nPos += ( aExpand.Len() - 1 );
+ sal_Int32 m_nStart;
+ sal_Int32 m_nLen;
+ bool m_bVisible;
+ std::vector<const SwTxtAttr*> m_aAttrs;
+ block(sal_Int32 nStart, sal_Int32 nLen, bool bVisible)
+ : m_nStart(nStart), m_nLen(nLen), m_bVisible(bVisible)
+ {
+ }
+};
+
+struct containsPos
+{
+ const sal_Int32 m_nPos;
+ containsPos(const sal_Int32 nPos)
+ : m_nPos(nPos)
+ {
+ }
+ bool operator() (const block& rIn) const
+ {
+ return m_nPos >= rIn.m_nStart && m_nPos < rIn.m_nStart + rIn.m_nLen;
+ }
+};
+
+ModelToViewHelper::ModelToViewHelper(const SwTxtNode &rNode, int eMode)
+{
+ const rtl::OUString& rNodeText = rNode.GetTxt();
+ m_aRetText = rNodeText;
+
+ if (eMode == PASSTHROUGH)
+ return;
+
+ Range aRange( 0, rNodeText.isEmpty() ? 0 : rNodeText.getLength() - 1);
+ MultiSelection aHiddenMulti(aRange);
+
+ if (eMode & HIDEINVISIBLE)
+ SwScriptInfo::selectHiddenTextProperty(rNode, aHiddenMulti);
+
+ if (eMode & HIDEREDLINED)
+ SwScriptInfo::selectRedLineDeleted(rNode, aHiddenMulti);
+
+ std::vector<block> aBlocks;
+
+ sal_Int32 nShownStart = 0;
+ for (size_t i = 0; i < aHiddenMulti.GetRangeCount(); ++i)
+ {
+ const Range& rRange = aHiddenMulti.GetRange(i);
+ sal_Int32 nHiddenStart = rRange.Min();
+ sal_Int32 nHiddenEnd = rRange.Max() + 1;
+ sal_Int32 nHiddenLen = nHiddenEnd - nHiddenStart;
+
+ sal_Int32 nShownEnd = nHiddenStart;
+ sal_Int32 nShownLen = nShownEnd - nShownStart;
+
+ if (nShownLen)
+ aBlocks.push_back(block(nShownStart, nShownLen, true));
+
+ if (nHiddenLen)
+ aBlocks.push_back(block(nHiddenStart, nHiddenLen, false));
+
+ nShownStart = nHiddenEnd;
+ }
+
+ sal_Int32 nTrailingShownLen = rNodeText.getLength() - nShownStart;
+ if (nTrailingShownLen)
+ aBlocks.push_back(block(nShownStart, nTrailingShownLen, true));
+
+ if (eMode & EXPANDFIELDS)
+ {
+ const SwpHints* pSwpHints2 = rNode.GetpSwpHints();
+ for ( sal_uInt16 i = 0; pSwpHints2 && i < pSwpHints2->Count(); ++i )
+ {
+ const SwTxtAttr* pAttr = (*pSwpHints2)[i];
+ if (pAttr->HasDummyChar())
+ {
+ xub_StrLen nDummyCharPos = *pAttr->GetStart();
+ if (aHiddenMulti.IsSelected(nDummyCharPos))
+ continue;
+ std::vector<block>::iterator aFind = std::find_if(aBlocks.begin(), aBlocks.end(), containsPos(nDummyCharPos));
+ aFind->m_aAttrs.push_back(pAttr);
}
}
}
- if ( pConversionMap && pConversionMap->size() )
- pConversionMap->push_back(
- ModelToViewHelper::ConversionMapEntry(
- rNodeText.getLength()+1, rRetText.getLength()+1 ) );
+ sal_Int32 nOffset = 0;
+ for (std::vector<block>::iterator i = aBlocks.begin(); i != aBlocks.end(); ++i)
+ {
+ if (!i->m_bVisible)
+ {
+ const sal_Int32 nHiddenStart = i->m_nStart;
+ const sal_Int32 nHiddenLen = i->m_nLen;
+
+ m_aRetText = m_aRetText.replaceAt( nOffset + nHiddenStart, nHiddenLen, rtl::OUString() );
+ m_aMap.push_back( ConversionMapEntry( nHiddenStart, nOffset + nHiddenStart ) );
+ nOffset -= nHiddenLen;
+ }
+ else
+ {
+ for (std::vector<const SwTxtAttr*>::iterator j = i->m_aAttrs.begin(); j != i->m_aAttrs.end(); ++j)
+ {
+ const SwTxtAttr* pAttr = *j;
+ xub_StrLen nFieldPos = *pAttr->GetStart();
+ rtl::OUString aExpand;
+ switch (pAttr->Which())
+ {
+ case RES_TXTATR_FIELD:
+ aExpand =
+ static_cast<SwTxtFld const*>(pAttr)->GetFld().GetFld()
+ ->ExpandField(true);
+ break;
+ case RES_TXTATR_FTN:
+ {
+ const SwFmtFtn& rFtn = static_cast<SwTxtFtn const*>(pAttr)->GetFtn();
+ const SwDoc *pDoc = rNode.GetDoc();
+ aExpand = rFtn.GetViewNumStr(*pDoc);
+ }
+ break;
+ default:
+ break;
+ }
+ m_aRetText = m_aRetText.replaceAt( nOffset + nFieldPos, 1, aExpand );
+ m_aMap.push_back( ConversionMapEntry( nFieldPos, nOffset + nFieldPos ) );
+ nOffset += ( aExpand.getLength() - 1 );
+ }
+ }
+ }
- return pConversionMap;
+ if ( !m_aMap.empty() )
+ m_aMap.push_back( ConversionMapEntry( rNodeText.getLength()+1, m_aRetText.getLength()+1 ) );
}
XubString SwTxtNode::GetRedlineTxt( xub_StrLen nIdx, xub_StrLen nLen,
diff --git a/sw/source/core/txtnode/txtedt.cxx b/sw/source/core/txtnode/txtedt.cxx
index f303138..e1e6d75 100644
--- a/sw/source/core/txtnode/txtedt.cxx
+++ b/sw/source/core/txtnode/txtedt.cxx
@@ -653,9 +653,9 @@ XubString SwTxtNode::GetCurWord( xub_StrLen nPos ) const
}
SwScanner::SwScanner( const SwTxtNode& rNd, const rtl::OUString& rTxt,
- const LanguageType* pLang, const ModelToViewHelper::ConversionMap* pConvMap,
+ const LanguageType* pLang, const ModelToViewHelper& rConvMap,
sal_uInt16 nType, sal_Int32 nStart, sal_Int32 nEnde, sal_Bool bClp )
- : rNode( rNd ), aText( rTxt), pLanguage( pLang ), pConversionMap( pConvMap ), nLen( 0 ), nWordType( nType ), bClip( bClp )
+ : rNode( rNd ), aText( rTxt), pLanguage( pLang ), rConversionMap( rConvMap ), nLen( 0 ), nWordType( nType ), bClip( bClp )
{
OSL_ENSURE( !aText.isEmpty(), "SwScanner: EmptyString" );
nStartPos = nBegin = nStart;
@@ -667,7 +667,7 @@ SwScanner::SwScanner( const SwTxtNode& rNd, const rtl::OUString& rTxt,
}
else
{
- ModelToViewHelper::ModelPosition aModelBeginPos = ModelToViewHelper::ConvertToModelPosition( pConversionMap, nBegin );
+ ModelToViewHelper::ModelPosition aModelBeginPos = rConversionMap.ConvertToModelPosition( nBegin );
const sal_Int32 nModelBeginPos = aModelBeginPos.mnPos;
aCurrLang = rNd.GetLang( nModelBeginPos );
}
@@ -729,7 +729,7 @@ sal_Bool SwScanner::NextWord()
if ( !pLanguage )
{
const sal_uInt16 nNextScriptType = pBreakIt->GetBreakIter()->getScriptType( aText, nBegin );
- ModelToViewHelper::ModelPosition aModelBeginPos = ModelToViewHelper::ConvertToModelPosition( pConversionMap, nBegin );
+ ModelToViewHelper::ModelPosition aModelBeginPos = rConversionMap.ConvertToModelPosition( nBegin );
const sal_Int32 nBeginModelPos = aModelBeginPos.mnPos;
aCurrLang = rNode.GetLang( nBeginModelPos, 1, nNextScriptType );
}
@@ -911,7 +911,7 @@ sal_uInt16 SwTxtNode::Spell(SwSpellArgs* pArgs)
// In case 2. we pass the wrong list to the scanned, because only
// the words in the wrong list have to be checked
- SwScanner aScanner( *this, m_Text, 0, 0,
+ SwScanner aScanner( *this, m_Text, 0, ModelToViewHelper(),
WordType::DICTIONARY_WORD,
nBegin, nEnd );
while( !pArgs->xSpellAlt.is() && aScanner.NextWord() )
@@ -1219,7 +1219,7 @@ SwRect SwTxtFrm::_AutoSpell( const SwCntntNode* pActNode, const SwViewOption& rV
uno::Reference< XSpellChecker1 > xSpell( ::GetSpellChecker() );
SwDoc* pDoc = pNode->GetDoc();
- SwScanner aScanner( *pNode, pNode->GetTxt(), 0, 0,
+ SwScanner aScanner( *pNode, pNode->GetTxt(), 0, ModelToViewHelper(),
WordType::DICTIONARY_WORD, nBegin, nEnd);
while( aScanner.NextWord() )
@@ -1369,13 +1369,12 @@ SwRect SwTxtFrm::SmartTagScan( SwCntntNode* /*pActNode*/, xub_StrLen /*nActPos*/
if ( nBegin < nEnd )
{
// Expand the string:
- rtl::OUString aExpandText;
- const ModelToViewHelper::ConversionMap* pConversionMap =
- pNode->BuildConversionMap( aExpandText );
+ const ModelToViewHelper aConversionMap(*pNode);
+ rtl::OUString aExpandText = aConversionMap.getViewText();
// Ownership ov ConversionMap is passed to SwXTextMarkup object!
Reference< com::sun::star::text::XTextMarkup > xTextMarkup =
- new SwXTextMarkup( *pNode, pConversionMap );
+ new SwXTextMarkup( *pNode, aConversionMap );
Reference< ::com::sun::star::frame::XController > xController = pNode->GetDoc()->GetDocShell()->GetController();
@@ -1391,8 +1390,8 @@ SwRect SwTxtFrm::SmartTagScan( SwCntntNode* /*pActNode*/, xub_StrLen /*nActPos*/
const com::sun::star::lang::Locale aLocale = pBreakIt->GetLocale( nLang );
nLangEnd = Min( nEnd, aIter.GetChgPos() );
- const sal_uInt32 nExpandBegin = ModelToViewHelper::ConvertToViewPosition( pConversionMap, nLangBegin );
- const sal_uInt32 nExpandEnd = ModelToViewHelper::ConvertToViewPosition( pConversionMap, nLangEnd );
+ const sal_uInt32 nExpandBegin = aConversionMap.ConvertToViewPosition( nLangBegin );
+ const sal_uInt32 nExpandEnd = aConversionMap.ConvertToViewPosition( nLangEnd );
rSmartTagMgr.Recognize( aExpandText, xTextMarkup, xController, aLocale, nExpandBegin, nExpandEnd - nExpandBegin );
@@ -1454,7 +1453,7 @@ void SwTxtFrm::CollectAutoCmplWrds( SwCntntNode* pActNode, xub_StrLen nActPos )
if( nBegin < nEnd )
{
sal_uInt16 nCnt = 200;
- SwScanner aScanner( *pNode, pNode->GetTxt(), 0, 0,
+ SwScanner aScanner( *pNode, pNode->GetTxt(), 0, ModelToViewHelper(),
WordType::DICTIONARY_WORD, nBegin, nEnd );
while( aScanner.NextWord() )
{
@@ -1826,6 +1825,11 @@ void SwTxtNode::ReplaceTextOnly( xub_StrLen nPos, xub_StrLen nLen,
void SwTxtNode::CountWords( SwDocStat& rStat,
xub_StrLen nStt, xub_StrLen nEnd ) const
{
+ if (IsInRedlines())
+ { //not counting txtnodes used to hold deleted redline content
+ return;
+ }
+
sal_Bool isCountAll = ( (0 == nStt) && (GetTxt().Len() == nEnd) );
++rStat.nAllPara; // #i93174#: count _all_ paragraphs
@@ -1852,13 +1856,13 @@ void SwTxtNode::CountWords( SwDocStat& rStat,
return;
}
- // expand text into pConversionMap for scanner
- rtl::OUString aExpandText;
- const ModelToViewHelper::ConversionMap* pConversionMap = BuildConversionMap( aExpandText );
+ // ConversionMap to expand fields, remove invisible and redline deleted text for scanner
+ const ModelToViewHelper aConversionMap(*this, EXPANDFIELDS | HIDEINVISIBLE | HIDEREDLINED);
+ rtl::OUString aExpandText = aConversionMap.getViewText();
// map start and end points onto the ConversionMap
- const sal_uInt32 nExpandBegin = ModelToViewHelper::ConvertToViewPosition( pConversionMap, nStt );
- const sal_uInt32 nExpandEnd = ModelToViewHelper::ConvertToViewPosition( pConversionMap, nEnd );
+ const sal_uInt32 nExpandBegin = aConversionMap.ConvertToViewPosition( nStt );
+ const sal_uInt32 nExpandEnd = aConversionMap.ConvertToViewPosition( nEnd );
if ( aExpandText.isEmpty() )
{
@@ -1866,12 +1870,6 @@ void SwTxtNode::CountWords( SwDocStat& rStat,
return;
}
- // make a copy of the expanded text for masking redlined/hidden text with ' '
- String textCopy = aExpandText;
- const xub_Unicode cChar(' ');
- const sal_uInt16 nNumOfMaskedChars = lcl_MaskRedlinesAndHiddenText( *this, textCopy, nExpandBegin, nExpandEnd, cChar, false );
- aExpandText = textCopy;
-
//do the count
// all counts exclude hidden paras and hidden+redlined within para
// definition of space/white chars in SwScanner (and BreakIter!)
@@ -1885,7 +1883,7 @@ void SwTxtNode::CountWords( SwDocStat& rStat,
if( pBreakIt->GetBreakIter().is() )
{
// zero is NULL for pLanguage -----------v last param = true for clipping
- SwScanner aScanner( *this, aExpandText, 0, pConversionMap, i18n::WordType::WORD_COUNT,
+ SwScanner aScanner( *this, aExpandText, 0, aConversionMap, i18n::WordType::WORD_COUNT,
nExpandBegin, nExpandEnd, true );
// used to filter out scanner returning almost empty strings (len=1; unichar=0x0001)
@@ -1906,7 +1904,6 @@ void SwTxtNode::CountWords( SwDocStat& rStat,
}
nTmpChars = pBreakIt->getGraphemeCount(aExpandText, nExpandBegin, nExpandEnd);
- nTmpChars -= nNumOfMaskedChars;
// no nTmpCharsExcludingSpaces adjust needed neither for blanked out MaskedChars
// nor for mid-word selection - set scanner bClip = true at creation
@@ -1922,7 +1919,7 @@ void SwTxtNode::CountWords( SwDocStat& rStat,
{
LanguageType aLanguage = GetLang( 0 );
- SwScanner aScanner( *this, aNumString, &aLanguage, 0,
+ SwScanner aScanner( *this, aNumString, &aLanguage, ModelToViewHelper(),
i18n::WordType::WORD_COUNT, 0, nNumStringLen, true );
while ( aScanner.NextWord() )
@@ -1944,8 +1941,6 @@ void SwTxtNode::CountWords( SwDocStat& rStat,
}
}
- delete pConversionMap;
-
// If counting the whole para then update cached values and mark clean
if ( isCountAll )
{
diff --git a/sw/source/core/unocore/unoflatpara.cxx b/sw/source/core/unocore/unoflatpara.cxx
index c590560..1652f9c 100644
--- a/sw/source/core/unocore/unoflatpara.cxx
+++ b/sw/source/core/unocore/unoflatpara.cxx
@@ -59,8 +59,8 @@ using namespace ::com::sun::star;
* SwXFlatParagraph
******************************************************************************/
-SwXFlatParagraph::SwXFlatParagraph( SwTxtNode& rTxtNode, rtl::OUString aExpandText, const ModelToViewHelper::ConversionMap* pMap ) :
- SwXTextMarkup( rTxtNode, pMap ),
+SwXFlatParagraph::SwXFlatParagraph( SwTxtNode& rTxtNode, rtl::OUString aExpandText, const ModelToViewHelper& rMap ) :
+ SwXTextMarkup( rTxtNode, rMap ),
maExpandText( aExpandText )
{
}
@@ -416,11 +416,10 @@ uno::Reference< text::XFlatParagraph > SwXFlatParagraphIterator::getNextPara()
if ( pRet )
{
// Expand the string:
- rtl::OUString aExpandText;
- const ModelToViewHelper::ConversionMap* pConversionMap =
- pRet->BuildConversionMap( aExpandText );
+ const ModelToViewHelper aConversionMap(*pRet);
+ rtl::OUString aExpandText = aConversionMap.getViewText();
- xRet = new SwXFlatParagraph( *pRet, aExpandText, pConversionMap );
+ xRet = new SwXFlatParagraph( *pRet, aExpandText, aConversionMap );
// keep hard references...
m_aFlatParaList.insert( xRet );
}
@@ -469,11 +468,10 @@ uno::Reference< text::XFlatParagraph > SwXFlatParagraphIterator::getParaAfter(co
if ( pNextTxtNode )
{
// Expand the string:
- rtl::OUString aExpandText;
- const ModelToViewHelper::ConversionMap* pConversionMap =
- pNextTxtNode->BuildConversionMap( aExpandText );
+ const ModelToViewHelper aConversionMap(*pNextTxtNode);
+ rtl::OUString aExpandText = aConversionMap.getViewText();
- xRet = new SwXFlatParagraph( *pNextTxtNode, aExpandText, pConversionMap );
+ xRet = new SwXFlatParagraph( *pNextTxtNode, aExpandText, aConversionMap );
// keep hard references...
m_aFlatParaList.insert( xRet );
}
@@ -516,11 +514,10 @@ uno::Reference< text::XFlatParagraph > SwXFlatParagraphIterator::getParaBefore(c
if ( pPrevTxtNode )
{
// Expand the string:
- rtl::OUString aExpandText;
- const ModelToViewHelper::ConversionMap* pConversionMap =
- pPrevTxtNode->BuildConversionMap( aExpandText );
+ const ModelToViewHelper aConversionMap(*pPrevTxtNode);
+ rtl::OUString aExpandText = aConversionMap.getViewText();
- xRet = new SwXFlatParagraph( *pPrevTxtNode, aExpandText, pConversionMap );
+ xRet = new SwXFlatParagraph( *pPrevTxtNode, aExpandText, aConversionMap );
// keep hard references...
m_aFlatParaList.insert( xRet );
}
diff --git a/sw/source/core/unocore/unotextmarkup.cxx b/sw/source/core/unocore/unotextmarkup.cxx
index 80d410e..a7cddad 100644
--- a/sw/source/core/unocore/unotextmarkup.cxx
+++ b/sw/source/core/unocore/unotextmarkup.cxx
@@ -44,8 +44,8 @@ using namespace ::com::sun::star;
/*
* SwXTextMarkup
*/
-SwXTextMarkup::SwXTextMarkup( SwTxtNode& rTxtNode, const ModelToViewHelper::ConversionMap* pMap )
- : mpTxtNode( &rTxtNode ), mpConversionMap( pMap )
+SwXTextMarkup::SwXTextMarkup( SwTxtNode& rTxtNode, const ModelToViewHelper& rMap )
+ : mpTxtNode( &rTxtNode ), maConversionMap( rMap )
{
// FME 2007-07-16 #i79641# SwXTextMarkup is allowed to be removed ...
SetIsAllowedToBeRemovedInModifyCall(true);
@@ -54,7 +54,6 @@ SwXTextMarkup::SwXTextMarkup( SwTxtNode& rTxtNode, const ModelToViewHelper::Conv
SwXTextMarkup::~SwXTextMarkup()
{
- delete mpConversionMap;
}
uno::Reference< container::XStringKeyMap > SAL_CALL SwXTextMarkup::getMarkupInfoContainer() throw (uno::RuntimeException)
@@ -133,9 +132,9 @@ void SAL_CALL SwXTextMarkup::commitTextMarkup(
const ModelToViewHelper::ModelPosition aStartPos =
- ModelToViewHelper::ConvertToModelPosition( mpConversionMap, nStart );
+ maConversionMap.ConvertToModelPosition( nStart );
const ModelToViewHelper::ModelPosition aEndPos =
- ModelToViewHelper::ConvertToModelPosition( mpConversionMap, nStart + nLength - 1);
+ maConversionMap.ConvertToModelPosition( nStart + nLength - 1);
const bool bStartInField = aStartPos.mbIsField;
const bool bEndInField = aEndPos.mbIsField;
@@ -181,8 +180,8 @@ void SAL_CALL SwXTextMarkup::commitTextMarkup(
pSubList = new SwGrammarMarkUp();
pWList->InsertSubList( nFieldPosModel, 1, nInsertPos, pSubList );
}
- const sal_uInt32 nTmpStart = ModelToViewHelper::ConvertToViewPosition( mpConversionMap, aStartPos.mnPos );
- const sal_uInt32 nTmpLen = ModelToViewHelper::ConvertToViewPosition( mpConversionMap, aStartPos.mnPos + 1 )
+ const sal_uInt32 nTmpStart = maConversionMap.ConvertToViewPosition( aStartPos.mnPos );
+ const sal_uInt32 nTmpLen = maConversionMap.ConvertToViewPosition( aStartPos.mnPos + 1 )
- nTmpStart - aStartPos.mnSubPos;
if( nTmpLen > 0 )
{
@@ -233,7 +232,7 @@ void SAL_CALL SwXTextMarkup::commitTextMarkup(
void lcl_commitGrammarMarkUp(
- const ModelToViewHelper::ConversionMap* pConversionMap,
+ const ModelToViewHelper& rConversionMap,
SwGrammarMarkUp* pWList,
::sal_Int32 nType,
const ::rtl::OUString & rIdentifier,
@@ -243,9 +242,9 @@ void lcl_commitGrammarMarkUp(
{
OSL_ENSURE( nType == text::TextMarkupType::PROOFREADING || nType == text::TextMarkupType::SENTENCE, "Wrong mark-up type" );
const ModelToViewHelper::ModelPosition aStartPos =
- ModelToViewHelper::ConvertToModelPosition( pConversionMap, nStart );
+ rConversionMap.ConvertToModelPosition( nStart );
const ModelToViewHelper::ModelPosition aEndPos =
- ModelToViewHelper::ConvertToModelPosition( pConversionMap, nStart + nLength - 1);
+ rConversionMap.ConvertToModelPosition( nStart + nLength - 1);
const bool bStartInField = aStartPos.mbIsField;
const bool bEndInField = aEndPos.mbIsField;
@@ -288,8 +287,8 @@ void lcl_commitGrammarMarkUp(
pSubList = new SwGrammarMarkUp();
pWList->InsertSubList( nFieldPosModel, 1, nInsertPos, pSubList );
}
- const sal_uInt32 nTmpStart = ModelToViewHelper::ConvertToViewPosition( pConversionMap, aStartPos.mnPos );
- const sal_uInt32 nTmpLen = ModelToViewHelper::ConvertToViewPosition( pConversionMap, aStartPos.mnPos + 1 )
+ const sal_uInt32 nTmpStart = rConversionMap.ConvertToViewPosition( aStartPos.mnPos );
+ const sal_uInt32 nTmpLen = rConversionMap.ConvertToViewPosition( aStartPos.mnPos + 1 )
- nTmpStart - aStartPos.mnSubPos;
if( nTmpLen > 0 )
pSubList->Insert( rIdentifier, xMarkupInfoContainer,
@@ -391,7 +390,7 @@ throw (lang::IllegalArgumentException, uno::RuntimeException)
if( pWList->GetBeginInv() < STRING_LEN )
{
const ModelToViewHelper::ModelPosition aSentenceEnd =
- ModelToViewHelper::ConvertToModelPosition( mpConversionMap,
+ maConversionMap.ConvertToModelPosition(
pMarkups[nSentenceMarkUpIndex].nOffset + pMarkups[nSentenceMarkUpIndex].nLength );
bAcceptGrammarError = (xub_StrLen)aSentenceEnd.mnPos > pWList->GetBeginInv();
pWList->ClearGrammarList( (xub_StrLen)aSentenceEnd.mnPos );
@@ -402,7 +401,7 @@ throw (lang::IllegalArgumentException, uno::RuntimeException)
for( i = 0; i < nLen; ++i )
{
const text::TextMarkupDescriptor &rDesc = pMarkups[i];
- lcl_commitGrammarMarkUp( mpConversionMap, pWList, rDesc.nType,
+ lcl_commitGrammarMarkUp( maConversionMap, pWList, rDesc.nType,
rDesc.aIdentifier, rDesc.nOffset, rDesc.nLength, rDesc.xMarkupInfoContainer );
}
}
@@ -411,7 +410,7 @@ throw (lang::IllegalArgumentException, uno::RuntimeException)
bRepaint = false;
i = nSentenceMarkUpIndex;
const text::TextMarkupDescriptor &rDesc = pMarkups[i];
- lcl_commitGrammarMarkUp( mpConversionMap, pWList, rDesc.nType,
+ lcl_commitGrammarMarkUp( maConversionMap, pWList, rDesc.nType,
rDesc.aIdentifier, rDesc.nOffset, rDesc.nLength, rDesc.xMarkupInfoContainer );
}
More information about the Libreoffice-commits
mailing list