summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2015-08-25 10:48:12 +0100
committerDavid Tardon <dtardon@redhat.com>2015-08-26 15:42:25 +0000
commit0c689034cf65d5b65d32e00e2f0b0567c51df866 (patch)
tree2b2d7261b018058cfdc690d5e3ed48d6fa4224ff
parent299dfbdaeb752af1879b7df05b53b802d1d485cd (diff)
ensure editeng str len is in sync with attributes
for the duration of inserting attributes, and excess dos newline chars can be removed safely afterwards (cherry picked from commit cc596d8d0f2f896d000833ffcba0035e3812c657) Change-Id: If70e34fec1c0819f827f483d3d7ac4f19b3caef8 Reviewed-on: https://gerrit.libreoffice.org/17988 Reviewed-by: David Tardon <dtardon@redhat.com> Tested-by: David Tardon <dtardon@redhat.com>
-rw-r--r--sw/qa/core/data/ww5/pass/crash-3.docbin0 -> 3938 bytes
-rw-r--r--sw/source/filter/ww8/ww8graf.cxx69
-rw-r--r--sw/source/filter/ww8/ww8par.hxx1
3 files changed, 59 insertions, 11 deletions
diff --git a/sw/qa/core/data/ww5/pass/crash-3.doc b/sw/qa/core/data/ww5/pass/crash-3.doc
new file mode 100644
index 000000000000..54931a28206d
--- /dev/null
+++ b/sw/qa/core/data/ww5/pass/crash-3.doc
Binary files differ
diff --git a/sw/source/filter/ww8/ww8graf.cxx b/sw/source/filter/ww8/ww8graf.cxx
index 6562bc7a13fa..6bdbabfeea86 100644
--- a/sw/source/filter/ww8/ww8graf.cxx
+++ b/sw/source/filter/ww8/ww8graf.cxx
@@ -460,23 +460,23 @@ SdrObject* SwWW8ImplReader::ReadPolyLine( WW8_DPHEAD* pHd, const WW8_DO* pDo,
return pObj;
}
-ESelection SwWW8ImplReader::GetESelection( long nCpStart, long nCpEnd )
+ESelection GetESelection(EditEngine &rDrawEditEngine, long nCpStart, long nCpEnd)
{
- sal_Int32 nPCnt = mpDrawEditEngine->GetParagraphCount();
+ sal_Int32 nPCnt = rDrawEditEngine.GetParagraphCount();
sal_Int32 nSP = 0;
sal_Int32 nEP = 0;
while( (nSP < nPCnt)
- && (nCpStart >= mpDrawEditEngine->GetTextLen( nSP ) + 1) )
+ && (nCpStart >= rDrawEditEngine.GetTextLen( nSP ) + 1) )
{
- nCpStart -= mpDrawEditEngine->GetTextLen( nSP ) + 1;
+ nCpStart -= rDrawEditEngine.GetTextLen( nSP ) + 1;
nSP++;
}
// Beim Ende erst 1 Zeichen spaeter auf naechste Zeile umschalten,
// da sonst Zeilenattribute immer eine Zeile zu weit reichen.
while( (nEP < nPCnt)
- && (nCpEnd > mpDrawEditEngine->GetTextLen( nEP ) + 1) )
+ && (nCpEnd > rDrawEditEngine.GetTextLen( nEP ) + 1) )
{
- nCpEnd -= mpDrawEditEngine->GetTextLen( nEP ) + 1;
+ nCpEnd -= rDrawEditEngine.GetTextLen( nEP ) + 1;
nEP++;
}
return ESelection( nSP, nCpStart, nEP, nCpEnd );
@@ -657,7 +657,7 @@ void SwWW8ImplReader::InsertAttrsAsDrawingAttrs(long nStartCp, long nEndCp,
comphelper::string::padToLength(sTemp,
nTxtStart - nStartReplace, cReplaceSymbol);
mpDrawEditEngine->QuickInsertText(sTemp.makeStringAndClear(),
- GetESelection(nStartReplace - nStartCp,
+ GetESelection(*mpDrawEditEngine, nStartReplace - nStartCp,
nTxtStart - nStartCp ) );
}
}
@@ -734,7 +734,7 @@ void SwWW8ImplReader::InsertAttrsAsDrawingAttrs(long nStartCp, long nEndCp,
if( pS->Count() )
{
mpDrawEditEngine->QuickSetAttribs( *pS,
- GetESelection( nTxtStart - nStartCp, nEnd - nStartCp ) );
+ GetESelection(*mpDrawEditEngine, nTxtStart - nStartCp, nEnd - nStartCp) );
delete pS;
pS = new SfxItemSet(mpDrawEditEngine->GetEmptyItemSet());
}
@@ -752,7 +752,7 @@ void SwWW8ImplReader::InsertAttrsAsDrawingAttrs(long nStartCp, long nEndCp,
myIter aEnd = aChunks.end();
for (myIter aIter = aChunks.begin(); aIter != aEnd; ++aIter)
{
- ESelection aSel(GetESelection(aIter->GetStartPos()-nStartCp,
+ ESelection aSel(GetESelection(*mpDrawEditEngine, aIter->GetStartPos()-nStartCp,
aIter->GetEndPos()-nStartCp));
OUString aString(mpDrawEditEngine->GetText(aSel));
const sal_Int32 nOrigLen = aString.getLength();
@@ -907,6 +907,47 @@ sal_Int32 SwWW8ImplReader::GetRangeAsDrawingString(OUString& rString, long nStar
return 0;
}
+//EditEngine::InsertText will replace dos lines resulting in a shorter
+//string than is passed in, so inserting attributes based on the original
+//string len can fail. So here replace the dos line ends similar to
+//how EditEngine does it, but preserve the length and replace the extra
+//chars with placeholders, record the position of the placeholders and
+//remove those extra chars after attributes have been inserted
+std::vector<sal_Int32> replaceDosLineEndsButPreserveLength(OUString &rIn)
+{
+ OUStringBuffer aNewData(rIn);
+ std::vector<sal_Int32> aDosLineEndDummies;
+ sal_Int32 i = 0;
+ sal_Int32 nStrLen = rIn.getLength();
+ while (i < nStrLen)
+ {
+ // \r or \n causes linebreak
+ if (rIn[i] == '\r' || rIn[i] == '\n')
+ {
+ // skip char if \r\n or \n\r
+ if ( (i+1) < nStrLen && ((rIn[i+1] == '\r') || (rIn[i+1] == '\n')) &&
+ (rIn[i] != rIn[i+1]) )
+ {
+ ++i;
+ aDosLineEndDummies.push_back(i);
+ aNewData[i] = 0;
+ }
+ }
+ ++i;
+ }
+ rIn = aNewData.makeStringAndClear();
+ return aDosLineEndDummies;
+}
+
+void removePositions(EditEngine &rDrawEditEngine, const std::vector<sal_Int32>& rDosLineEndDummies)
+{
+ for (auto aIter = rDosLineEndDummies.rbegin(); aIter != rDosLineEndDummies.rend(); ++aIter)
+ {
+ sal_Int32 nCharPos(*aIter);
+ rDrawEditEngine.QuickDelete(GetESelection(rDrawEditEngine, nCharPos, nCharPos+1));
+ }
+}
+
OutlinerParaObject* SwWW8ImplReader::ImportAsOutliner(OUString &rString, WW8_CP nStartCp, WW8_CP nEndCp, ManTypes eType)
{
OutlinerParaObject* pRet = 0;
@@ -917,8 +958,16 @@ OutlinerParaObject* SwWW8ImplReader::ImportAsOutliner(OUString &rString, WW8_CP
if (!mpDrawEditEngine)
mpDrawEditEngine = new EditEngine(0);
- mpDrawEditEngine->SetText(rString);
+ //replace dos line endings with editeng ones, replace any extra chars with
+ //placeholders to keep the inserted string len in sync with the attribute cps
+ //and record in aDosLineEnds the superfluous positions
+ OUString sEEString(rString);
+ std::vector<sal_Int32> aDosLineEnds(replaceDosLineEndsButPreserveLength(sEEString));
+ mpDrawEditEngine->SetText(sEEString);
InsertAttrsAsDrawingAttrs(nStartCp, nStartCp+nLen, eType);
+ //remove any superfluous placeholders of replaceDosLineEndsButPreserveLength
+ //after attributes have been inserted
+ removePositions(*mpDrawEditEngine, aDosLineEnds);
// Annotations typically begin with a (useless) 0x5
if ((eType == MAN_AND) && mpDrawEditEngine->GetTextLen())
diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx
index 179e05f22662..475c70ce0453 100644
--- a/sw/source/filter/ww8/ww8par.hxx
+++ b/sw/source/filter/ww8/ww8par.hxx
@@ -1602,7 +1602,6 @@ private:
SfxAllItemSet &rSet);
SdrObject *ReadPolyLine(WW8_DPHEAD* pHd, const WW8_DO* pDo,
SfxAllItemSet &rSet);
- ESelection GetESelection( long nCpStart, long nCpEnd );
void InsertTxbxStyAttrs( SfxItemSet& rS, sal_uInt16 nColl );
void InsertAttrsAsDrawingAttrs(long nStartCp, long nEndCp, ManTypes eType, bool bONLYnPicLocFc=false);