summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2014-02-06 16:04:56 +0100
committerMiklos Vajna <vmiklos@collabora.co.uk>2014-02-06 16:13:30 +0100
commit8ae90efb8a0234fb4f95e8c59a173ee8fefef782 (patch)
treedbf340a5833db3ecfa59f736dcf87df98ada0bb2 /sw
parentb37bce11cf59c6c9544e62e81f71a07e4d987a34 (diff)
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
Diffstat (limited to 'sw')
-rw-r--r--sw/qa/extras/ww8export/data/comments-nested.docbin0 -> 23552 bytes
-rw-r--r--sw/qa/extras/ww8export/ww8export.cxx9
-rw-r--r--sw/source/filter/ww8/wrtw8sty.cxx48
-rw-r--r--sw/source/filter/ww8/wrtww8.cxx2
-rw-r--r--sw/source/filter/ww8/wrtww8.hxx6
5 files changed, 46 insertions, 19 deletions
diff --git a/sw/qa/extras/ww8export/data/comments-nested.doc b/sw/qa/extras/ww8export/data/comments-nested.doc
new file mode 100644
index 000000000000..339a15b11fdb
--- /dev/null
+++ b/sw/qa/extras/ww8export/data/comments-nested.doc
Binary files differ
diff --git a/sw/qa/extras/ww8export/ww8export.cxx b/sw/qa/extras/ww8export/ww8export.cxx
index 1c4a8d738afb..4c3a0bab10e0 100644
--- a/sw/qa/extras/ww8export/ww8export.cxx
+++ b/sw/qa/extras/ww8export/ww8export.cxx
@@ -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();
diff --git a/sw/source/filter/ww8/wrtw8sty.cxx b/sw/source/filter/ww8/wrtw8sty.cxx
index 3f79db8ac02f..f631e65424f6 100644
--- a/sw/source/filter/ww8/wrtw8sty.cxx
+++ b/sw/source/filter/ww8/wrtw8sty.cxx
@@ -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
}
diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx
index 6c8289885f3c..43a1cfae14b4 100644
--- a/sw/source/filter/ww8/wrtww8.cxx
+++ b/sw/source/filter/ww8/wrtww8.cxx
@@ -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;
}
}
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index 1a781e56744c..30ee97d909bd 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -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 );