Kaydet (Commit) 5a816823 authored tarafından Caolán McNamara's avatar Caolán McNamara Kaydeden (comit) Andras Timar

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

Change-Id: If70e34fec1c0819f827f483d3d7ac4f19b3caef8
(cherry picked from commit cc596d8d)
Reviewed-on: https://gerrit.libreoffice.org/17983Reviewed-by: 's avatarDavid Tardon <dtardon@redhat.com>
Tested-by: 's avatarDavid Tardon <dtardon@redhat.com>
üst 9ce688e3
This diff was suppressed by a .gitattributes entry.
...@@ -443,23 +443,23 @@ SdrObject* SwWW8ImplReader::ReadPolyLine(WW8_DPHEAD* pHd, SfxAllItemSet &rSet) ...@@ -443,23 +443,23 @@ SdrObject* SwWW8ImplReader::ReadPolyLine(WW8_DPHEAD* pHd, SfxAllItemSet &rSet)
return pObj; return pObj;
} }
ESelection SwWW8ImplReader::GetESelection( long nCpStart, long nCpEnd ) ESelection GetESelection(EditEngine &rDrawEditEngine, long nCpStart, long nCpEnd)
{ {
sal_Int32 nPCnt = m_pDrawEditEngine->GetParagraphCount(); sal_Int32 nPCnt = rDrawEditEngine.GetParagraphCount();
sal_Int32 nSP = 0; sal_Int32 nSP = 0;
sal_Int32 nEP = 0; sal_Int32 nEP = 0;
while( (nSP < nPCnt) while( (nSP < nPCnt)
&& (nCpStart >= m_pDrawEditEngine->GetTextLen( nSP ) + 1) ) && (nCpStart >= rDrawEditEngine.GetTextLen( nSP ) + 1) )
{ {
nCpStart -= m_pDrawEditEngine->GetTextLen( nSP ) + 1; nCpStart -= rDrawEditEngine.GetTextLen( nSP ) + 1;
nSP++; nSP++;
} }
// Beim Ende erst 1 Zeichen spaeter auf naechste Zeile umschalten, // Beim Ende erst 1 Zeichen spaeter auf naechste Zeile umschalten,
// da sonst Zeilenattribute immer eine Zeile zu weit reichen. // da sonst Zeilenattribute immer eine Zeile zu weit reichen.
while( (nEP < nPCnt) while( (nEP < nPCnt)
&& (nCpEnd > m_pDrawEditEngine->GetTextLen( nEP ) + 1) ) && (nCpEnd > rDrawEditEngine.GetTextLen( nEP ) + 1) )
{ {
nCpEnd -= m_pDrawEditEngine->GetTextLen( nEP ) + 1; nCpEnd -= rDrawEditEngine.GetTextLen( nEP ) + 1;
nEP++; nEP++;
} }
return ESelection( nSP, nCpStart, nEP, nCpEnd ); return ESelection( nSP, nCpStart, nEP, nCpEnd );
...@@ -641,7 +641,7 @@ void SwWW8ImplReader::InsertAttrsAsDrawingAttrs(long nStartCp, long nEndCp, ...@@ -641,7 +641,7 @@ void SwWW8ImplReader::InsertAttrsAsDrawingAttrs(long nStartCp, long nEndCp,
comphelper::string::padToLength(sTemp, comphelper::string::padToLength(sTemp,
nTextStart - nStartReplace, cReplaceSymbol); nTextStart - nStartReplace, cReplaceSymbol);
m_pDrawEditEngine->QuickInsertText(sTemp.makeStringAndClear(), m_pDrawEditEngine->QuickInsertText(sTemp.makeStringAndClear(),
GetESelection(nStartReplace - nStartCp, GetESelection(*m_pDrawEditEngine, nStartReplace - nStartCp,
nTextStart - nStartCp ) ); nTextStart - nStartCp ) );
} }
} }
...@@ -718,7 +718,7 @@ void SwWW8ImplReader::InsertAttrsAsDrawingAttrs(long nStartCp, long nEndCp, ...@@ -718,7 +718,7 @@ void SwWW8ImplReader::InsertAttrsAsDrawingAttrs(long nStartCp, long nEndCp,
if( pS->Count() ) if( pS->Count() )
{ {
m_pDrawEditEngine->QuickSetAttribs( *pS, m_pDrawEditEngine->QuickSetAttribs( *pS,
GetESelection( nTextStart - nStartCp, nEnd - nStartCp ) ); GetESelection(*m_pDrawEditEngine, nTextStart - nStartCp, nEnd - nStartCp ) );
delete pS; delete pS;
pS = new SfxItemSet(m_pDrawEditEngine->GetEmptyItemSet()); pS = new SfxItemSet(m_pDrawEditEngine->GetEmptyItemSet());
} }
...@@ -736,7 +736,7 @@ void SwWW8ImplReader::InsertAttrsAsDrawingAttrs(long nStartCp, long nEndCp, ...@@ -736,7 +736,7 @@ void SwWW8ImplReader::InsertAttrsAsDrawingAttrs(long nStartCp, long nEndCp,
myIter aEnd = aChunks.end(); myIter aEnd = aChunks.end();
for (myIter aIter = aChunks.begin(); aIter != aEnd; ++aIter) for (myIter aIter = aChunks.begin(); aIter != aEnd; ++aIter)
{ {
ESelection aSel(GetESelection(aIter->GetStartPos()-nStartCp, ESelection aSel(GetESelection(*m_pDrawEditEngine, aIter->GetStartPos()-nStartCp,
aIter->GetEndPos()-nStartCp)); aIter->GetEndPos()-nStartCp));
OUString aString(m_pDrawEditEngine->GetText(aSel)); OUString aString(m_pDrawEditEngine->GetText(aSel));
const sal_Int32 nOrigLen = aString.getLength(); const sal_Int32 nOrigLen = aString.getLength();
...@@ -891,6 +891,47 @@ sal_Int32 SwWW8ImplReader::GetRangeAsDrawingString(OUString& rString, long nStar ...@@ -891,6 +891,47 @@ sal_Int32 SwWW8ImplReader::GetRangeAsDrawingString(OUString& rString, long nStar
return 0; 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* SwWW8ImplReader::ImportAsOutliner(OUString &rString, WW8_CP nStartCp, WW8_CP nEndCp, ManTypes eType)
{ {
OutlinerParaObject* pRet = 0; OutlinerParaObject* pRet = 0;
...@@ -901,8 +942,16 @@ OutlinerParaObject* SwWW8ImplReader::ImportAsOutliner(OUString &rString, WW8_CP ...@@ -901,8 +942,16 @@ OutlinerParaObject* SwWW8ImplReader::ImportAsOutliner(OUString &rString, WW8_CP
if (!m_pDrawEditEngine) if (!m_pDrawEditEngine)
m_pDrawEditEngine = new EditEngine(0); m_pDrawEditEngine = new EditEngine(0);
m_pDrawEditEngine->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));
m_pDrawEditEngine->SetText(sEEString);
InsertAttrsAsDrawingAttrs(nStartCp, nStartCp+nLen, eType); InsertAttrsAsDrawingAttrs(nStartCp, nStartCp+nLen, eType);
//remove any superfluous placeholders of replaceDosLineEndsButPreserveLength
//after attributes have been inserted
removePositions(*m_pDrawEditEngine, aDosLineEnds);
// Annotations typically begin with a (useless) 0x5 // Annotations typically begin with a (useless) 0x5
if ((eType == MAN_AND) && m_pDrawEditEngine->GetTextLen()) if ((eType == MAN_AND) && m_pDrawEditEngine->GetTextLen())
......
...@@ -1580,7 +1580,6 @@ private: ...@@ -1580,7 +1580,6 @@ private:
SdrObject *ReadElipse(WW8_DPHEAD* pHd, SfxAllItemSet &rSet); SdrObject *ReadElipse(WW8_DPHEAD* pHd, SfxAllItemSet &rSet);
SdrObject *ReadArc(WW8_DPHEAD* pHd, SfxAllItemSet &rSet); SdrObject *ReadArc(WW8_DPHEAD* pHd, SfxAllItemSet &rSet);
SdrObject *ReadPolyLine(WW8_DPHEAD* pHd, SfxAllItemSet &rSet); SdrObject *ReadPolyLine(WW8_DPHEAD* pHd, SfxAllItemSet &rSet);
ESelection GetESelection( long nCpStart, long nCpEnd );
void InsertTxbxStyAttrs( SfxItemSet& rS, sal_uInt16 nColl ); void InsertTxbxStyAttrs( SfxItemSet& rS, sal_uInt16 nColl );
void InsertAttrsAsDrawingAttrs(long nStartCp, long nEndCp, ManTypes eType, bool bONLYnPicLocFc=false); void InsertAttrsAsDrawingAttrs(long nStartCp, long nEndCp, ManTypes eType, bool bONLYnPicLocFc=false);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment