Kaydet (Commit) 8ae90efb authored tarafından Miklos Vajna's avatar Miklos Vajna

DOC export: fix nested comments

For one, replace m_nLastRangeStartPos with a map, so that we can keep
track of the start positions when multiple comments are open at the same
time.

For another, sort PlcfAtnBkl and PlcfAtnBkf by position as Word requires
it; with non-nested comments such explicit sorting wasn't necessary.
This also required building two maps, so that we can know what
PlcfAtnBkl index to reference in PlcfandRef, and what PlcfAtnBkf index
to reference in PlcfAtnBkl after sorting.

Change-Id: I2d7096b0c68a6b327efc4b5593ac96cdd297b3bd
üst b37bce11
This diff was suppressed by a .gitattributes entry.
......@@ -188,6 +188,15 @@ DECLARE_WW8EXPORT_TEST(testFdo59530, "fdo59530.doc")
CPPUNIT_ASSERT_EQUAL(OUString("AnnotationEnd"), getProperty<OUString>(xPropertySet, "TextPortionType"));
}
DECLARE_WW8EXPORT_TEST(testCommentsNested, "comments-nested.doc")
{
uno::Reference<beans::XPropertySet> xOuter(getProperty< uno::Reference<beans::XPropertySet> >(getRun(getParagraph(1), 2), "TextField"), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(OUString("Outer"), getProperty<OUString>(xOuter, "Content"));
uno::Reference<beans::XPropertySet> xInner(getProperty< uno::Reference<beans::XPropertySet> >(getRun(getParagraph(1), 4), "TextField"), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(OUString("Inner"), getProperty<OUString>(xInner, "Content"));
}
#endif
CPPUNIT_PLUGIN_IMPLEMENT();
......
......@@ -2087,19 +2087,19 @@ WW8_Annotation::WW8_Annotation(const SwRedlineData* pRedline)
maDateTime = pRedline->GetTimeStamp();
}
void WW8_WrPlcAnnotations::AddRangeStartPosition( WW8_CP nStartCp)
void WW8_WrPlcAnnotations::AddRangeStartPosition(const OUString& rName, WW8_CP nStartCp)
{
m_nLastRangeStartPos = nStartCp;
m_aRangeStartPositions[rName] = nStartCp;
}
void WW8_WrPlcAnnotations::Append( WW8_CP nCp, const SwPostItField *pPostIt )
{
aCps.push_back( nCp );
WW8_Annotation* p;
if( m_nLastRangeStartPos != -1 )
if( m_aRangeStartPositions.find(pPostIt->GetName()) != m_aRangeStartPositions.end() )
{
p = new WW8_Annotation(pPostIt, m_nLastRangeStartPos, nCp);
m_nLastRangeStartPos = -1;
p = new WW8_Annotation(pPostIt, m_aRangeStartPositions[pPostIt->GetName()], nCp);
m_aRangeStartPositions.erase(pPostIt->GetName());
}
else
{
......@@ -2269,6 +2269,11 @@ static bool lcl_AuthorComp( const std::pair<OUString,OUString>& aFirst, const st
return aFirst.first < aSecond.first;
}
static bool lcl_PosComp( const std::pair<WW8_CP, int>& aFirst, const std::pair<WW8_CP, int>& aSecond)
{
return aFirst.first < aSecond.first;
}
void WW8_WrPlcSubDoc::WriteGenericPlc( WW8Export& rWrt, sal_uInt8 nTTyp,
WW8_FC& rTxtStart, sal_Int32& rTxtCount, WW8_FC& rRefStart, sal_Int32& rRefCount ) const
{
......@@ -2290,8 +2295,10 @@ void WW8_WrPlcSubDoc::WriteGenericPlc( WW8Export& rWrt, sal_uInt8 nTTyp,
{
case TXT_ATN:
{
std::vector<WW8_CP> aRangeStartPos;
std::vector<WW8_CP> aRangeEndPos;
std::vector< std::pair<WW8_CP, int> > aRangeStartPos; // The second of the pair is the original index before sorting.
std::vector< std::pair<WW8_CP, int> > aRangeEndPos; // Same, so we can map between the indexes before/after sorting.
std::map<int, int> aAtnStartMap; // Maps from annotation index to start index.
std::map<int, int> aStartEndMap; // Maps from start index to end index.
// then write first the GrpXstAtnOwners
for ( i = 0; i < nLen; ++i )
{
......@@ -2299,8 +2306,8 @@ void WW8_WrPlcSubDoc::WriteGenericPlc( WW8Export& rWrt, sal_uInt8 nTTyp,
aStrArr.push_back(std::pair<OUString,OUString>(rAtn.msOwner,rAtn.m_sInitials));
if( rAtn.m_nRangeStart != rAtn.m_nRangeEnd )
{
aRangeStartPos.push_back(rAtn.m_nRangeStart);
aRangeEndPos.push_back(rAtn.m_nRangeEnd);
aRangeStartPos.push_back(std::make_pair(rAtn.m_nRangeStart, i));
aRangeEndPos.push_back(std::make_pair(rAtn.m_nRangeEnd, i));
}
}
......@@ -2309,6 +2316,17 @@ void WW8_WrPlcSubDoc::WriteGenericPlc( WW8Export& rWrt, sal_uInt8 nTTyp,
myiter aIter = ::std::unique(aStrArr.begin(), aStrArr.end());
aStrArr.erase(aIter, aStrArr.end());
// Also sort the start and end positions. We need to reference
// the start index in the annotation table and also need to
// reference the end index in the start table, so build a map
// that knows what index to reference, after sorting.
std::sort(aRangeStartPos.begin(), aRangeStartPos.end(), &lcl_PosComp);
for (i = 0; i < aRangeStartPos.size(); ++i)
aAtnStartMap[aRangeStartPos[i].second] = i;
std::sort(aRangeEndPos.begin(), aRangeEndPos.end(), &lcl_PosComp);
for (i = 0; i < aRangeEndPos.size(); ++i)
aStartEndMap[aRangeEndPos[ aAtnStartMap[i] ].second] = i;
if ( rWrt.bWrtWW8 )
{
for ( i = 0; i < aStrArr.size(); ++i )
......@@ -2343,14 +2361,14 @@ void WW8_WrPlcSubDoc::WriteGenericPlc( WW8Export& rWrt, sal_uInt8 nTTyp,
rFib.fcPlcfAtnbkf = nFcStart;
for ( i = 0; i < aRangeStartPos.size(); ++i )
{
SwWW8Writer::WriteLong( *rWrt.pTableStrm, aRangeStartPos[i] );
SwWW8Writer::WriteLong( *rWrt.pTableStrm, aRangeStartPos[i].first );
}
SwWW8Writer::WriteLong( *rWrt.pTableStrm, aRangeStartPos[i-1] + 1);
SwWW8Writer::WriteLong( *rWrt.pTableStrm, aRangeStartPos[i-1].first + 1);
// Commented text ranges additional informations (Plcfbkf.aFBKF)
for ( i = 0; i < aRangeStartPos.size(); ++i )
{
SwWW8Writer::WriteShort( *rWrt.pTableStrm, i ); // FBKF.ibkl
SwWW8Writer::WriteShort( *rWrt.pTableStrm, aStartEndMap[i] ); // FBKF.ibkl
SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 ); // FBKF.bkc
}
......@@ -2361,9 +2379,9 @@ void WW8_WrPlcSubDoc::WriteGenericPlc( WW8Export& rWrt, sal_uInt8 nTTyp,
rFib.fcPlcfAtnbkl = nFcStart;
for ( i = 0; i < aRangeEndPos.size(); ++i )
{
SwWW8Writer::WriteLong( *rWrt.pTableStrm, aRangeEndPos[i] );
SwWW8Writer::WriteLong( *rWrt.pTableStrm, aRangeEndPos[i].first );
}
SwWW8Writer::WriteLong( *rWrt.pTableStrm, aRangeEndPos[i-1] + 1);
SwWW8Writer::WriteLong( *rWrt.pTableStrm, aRangeEndPos[i-1].first + 1);
nFcStart = rWrt.pTableStrm->Tell();
rFib.lcbPlcfAtnbkl = nFcStart - rFib.fcPlcfAtnbkl;
......@@ -2379,7 +2397,7 @@ void WW8_WrPlcSubDoc::WriteGenericPlc( WW8Export& rWrt, sal_uInt8 nTTyp,
SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 ); // SttbfAtnBkmk.cchData
// One ATNBE structure for all text ranges
SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0x0100 ); // ATNBE.bmc
SwWW8Writer::WriteLong( *rWrt.pTableStrm, i ); // ATNBE.lTag
SwWW8Writer::WriteLong( *rWrt.pTableStrm, aAtnStartMap[i] ); // ATNBE.lTag
SwWW8Writer::WriteLong( *rWrt.pTableStrm, -1 ); // ATNBE.lTagOld
}
......
......@@ -1388,7 +1388,7 @@ void WW8Export::AppendAnnotationMarks(const SwTxtNode& rNode, sal_Int32 nAktPos,
const sal_Int32 nStart = pMark->GetMarkStart().nContent.GetIndex();
if (nStart == nAktPos)
{
pAtn->AddRangeStartPosition(Fc2Cp(Strm().Tell()));
pAtn->AddRangeStartPosition(pMark->GetName(), Fc2Cp(Strm().Tell()));
return;
}
}
......
......@@ -1226,12 +1226,12 @@ private:
WW8_WrPlcAnnotations& operator=(WW8_WrPlcAnnotations&);
std::set<const SwRedlineData*> maProcessedRedlines;
WW8_CP m_nLastRangeStartPos;
std::map<const OUString, WW8_CP> m_aRangeStartPositions;
public:
WW8_WrPlcAnnotations(): m_nLastRangeStartPos(-1){}
WW8_WrPlcAnnotations() {}
~WW8_WrPlcAnnotations();
void AddRangeStartPosition( WW8_CP nStartCp );
void AddRangeStartPosition(const OUString& rName, WW8_CP nStartCp);
void Append( WW8_CP nCp, const SwPostItField* pPostIt );
void Append( WW8_CP nCp, const SwRedlineData* pRedLine );
bool IsNewRedlineComment( const SwRedlineData* pRedLine );
......
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