[Libreoffice-commits] .: sw/qa sw/source
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Mon Jan 21 00:29:33 PST 2013
sw/qa/extras/ww8import/data/fdo59530.doc |binary
sw/qa/extras/ww8import/ww8import.cxx | 26 +++++++++
sw/source/filter/ww8/ww8par.cxx | 89 +++++++++++++++++++++++++++++--
sw/source/filter/ww8/ww8par.hxx | 6 ++
sw/source/filter/ww8/ww8struc.hxx | 8 ++
5 files changed, 125 insertions(+), 4 deletions(-)
New commits:
commit 7907cc0ef9751d553014bd3bab49be9e7fc31bca
Author: Miklos Vajna <vmiklos at suse.cz>
Date: Mon Jan 21 09:31:26 2013 +0100
fdo#59530 WW8 import of commented text ranges
Change-Id: I3e2928922ebcec8188c1b5416108373c4f26dd62
diff --git a/sw/qa/extras/ww8import/data/fdo59530.doc b/sw/qa/extras/ww8import/data/fdo59530.doc
new file mode 100755
index 0000000..4e41cb8
Binary files /dev/null and b/sw/qa/extras/ww8import/data/fdo59530.doc differ
diff --git a/sw/qa/extras/ww8import/ww8import.cxx b/sw/qa/extras/ww8import/ww8import.cxx
index d650e11..d471b7b 100644
--- a/sw/qa/extras/ww8import/ww8import.cxx
+++ b/sw/qa/extras/ww8import/ww8import.cxx
@@ -47,6 +47,7 @@ public:
void testN757118();
void testN757905();
void testAllGapsWord();
+ void testFdo59530();
CPPUNIT_TEST_SUITE(Test);
#if !defined(MACOSX) && !defined(WNT)
@@ -68,6 +69,7 @@ void Test::run()
{"n757118.doc", &Test::testN757118},
{"n757905.doc", &Test::testN757905},
{"all_gaps_word.doc", &Test::testAllGapsWord},
+ {"fdo59530.doc", &Test::testFdo59530},
};
header();
for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i)
@@ -226,6 +228,30 @@ void Test::testAllGapsWord()
borderTest.testTheBorders(mxComponent);
}
+void Test::testFdo59530()
+{
+ // See ooxmlexport's testFdo38244().
+ // Test comment range feature.
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParaEnum->nextElement(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration();
+ xRunEnum->nextElement();
+ uno::Reference<beans::XPropertySet> xPropertySet(xRunEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("TextFieldStart"), getProperty<OUString>(xPropertySet, "TextPortionType"));
+ xRunEnum->nextElement();
+ xPropertySet.set(xRunEnum->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("TextFieldEnd"), getProperty<OUString>(xPropertySet, "TextPortionType"));
+
+ // Test initials.
+ uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
+ uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
+ xPropertySet.set(xFields->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("346376201"), getProperty<OUString>(xPropertySet, "Name"));
+ CPPUNIT_ASSERT_EQUAL(OUString("M"), getProperty<OUString>(xPropertySet, "Initials"));
+}
CPPUNIT_TEST_SUITE_REGISTRATION(Test);
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index 7705aae..acfecb2 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -1761,6 +1761,8 @@ long SwWW8ImplReader::Read_And(WW8PLCFManResult* pRes)
return 0;
String sAuthor;
+ String sInitials;
+ String sName;
if( bVer67 )
{
const WW67_ATRD* pDescri = (const WW67_ATRD*)pSD->GetData();
@@ -1775,13 +1777,35 @@ long SwWW8ImplReader::Read_And(WW8PLCFManResult* pRes)
{
const WW8_ATRD* pDescri = (const WW8_ATRD*)pSD->GetData();
+ {
+ sal_uInt16 nLen = SVBT16ToShort(pDescri->xstUsrInitl[0]);
+ for(sal_uInt16 nIdx = 1; nIdx <= nLen; ++nIdx)
+ sInitials += SVBT16ToShort(pDescri->xstUsrInitl[nIdx]);
+ }
+
if (const String* pA = GetAnnotationAuthor(SVBT16ToShort(pDescri->ibst)))
sAuthor = *pA;
else
+ sAuthor = sInitials;
+
+ // If there is a bookmark tag, a text range should be commented.
+ sal_uInt32 nTagBkmk = SVBT32ToUInt32(pDescri->ITagBkmk);
+ if (nTagBkmk != 0xFFFFFFFF)
{
- sal_uInt16 nLen = SVBT16ToShort(pDescri->xstUsrInitl[0]);
- for(sal_uInt16 nIdx = 1; nIdx <= nLen; ++nIdx)
- sAuthor += SVBT16ToShort(pDescri->xstUsrInitl[nIdx]);
+ sName = OUString::valueOf(sal_Int32(nTagBkmk));
+ int nAtnIndex = GetAnnotationIndex(nTagBkmk);
+ if (nAtnIndex != -1)
+ {
+ WW8_CP nStart = GetAnnotationStart(nAtnIndex);
+ WW8_CP nEnd = GetAnnotationEnd(nAtnIndex);
+ sal_Int32 nLen = nEnd - nStart;
+ // Don't support ranges affecting multiple SwTxtNode for now.
+ if (nLen && pPaM->GetPoint()->nContent.GetIndex() >= nLen)
+ {
+ pPaM->SetMark();
+ pPaM->GetPoint()->nContent -= nLen;
+ }
+ }
}
}
@@ -1803,9 +1827,18 @@ long SwWW8ImplReader::Read_And(WW8PLCFManResult* pRes)
this->pFmtOfJustInsertedApo = 0;
SwPostItField aPostIt(
(SwPostItFieldType*)rDoc.GetSysFldType(RES_POSTITFLD), sAuthor,
- sTxt, aEmptyStr, aEmptyStr, aDate );
+ sTxt, sInitials, sName, aDate );
aPostIt.SetTextObject(pOutliner);
+ // If this is a range, create the associated fieldmark.
+ if (pPaM->HasMark())
+ {
+ IDocumentMarkAccess* pMarksAccess = rDoc.getIDocumentMarkAccess();
+ pMarksAccess->makeFieldBookmark(*pPaM, aPostIt.GetName(), ODF_COMMENTRANGE);
+ pPaM->Exchange();
+ pPaM->DeleteMark();
+ }
+
pCtrlStck->NewAttr(*pPaM->GetPoint(), SvxCharHiddenItem(false, RES_CHRATR_HIDDEN));
rDoc.InsertPoolItem(*pPaM, SwFmtFld(aPostIt), 0);
pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_CHRATR_HIDDEN);
@@ -5367,6 +5400,54 @@ const String* SwWW8ImplReader::GetAnnotationAuthor(sal_uInt16 nIdx)
return pRet;
}
+int SwWW8ImplReader::GetAnnotationIndex(sal_uInt32 nTag)
+{
+ if (!mpAtnIndexes.get() && pWwFib->lcbSttbfAtnbkmk)
+ {
+ mpAtnIndexes.reset(new std::map<sal_uInt32, int>());
+ std::vector<String> aStrings;
+ std::vector<ww::bytes> aEntries;
+ WW8ReadSTTBF(!bVer67, *pTableStream, pWwFib->fcSttbfAtnbkmk, pWwFib->lcbSttbfAtnbkmk, sizeof(struct WW8_ATNBE), eStructCharSet, aStrings, &aEntries);
+ for (size_t i = 0; i < aStrings.size() && i < aEntries.size(); ++i)
+ {
+ ww::bytes aEntry = aEntries[i];
+ WW8_ATNBE* pAtnbeStruct = (WW8_ATNBE*)(&aEntry[0]);
+ mpAtnIndexes->insert(std::pair<sal_uInt32, int>(SVBT32ToUInt32(pAtnbeStruct->nTag), i));
+ }
+ }
+ if (mpAtnIndexes.get())
+ {
+ std::map<sal_uInt32, int>::iterator it = mpAtnIndexes->find(nTag);
+ if (it != mpAtnIndexes->end())
+ return it->second;
+ }
+ return -1;
+}
+
+WW8_CP SwWW8ImplReader::GetAnnotationStart(int nIndex)
+{
+ if (!mpAtnStarts.get() && pWwFib->lcbPlcfAtnbkf)
+ // A PLCFBKF is a PLC whose data elements are FBKF structures (4 bytes each).
+ mpAtnStarts.reset(new WW8PLCFspecial(pTableStream, pWwFib->fcPlcfAtnbkf, pWwFib->lcbPlcfAtnbkf, 4));
+
+ if (mpAtnStarts.get())
+ return mpAtnStarts->GetPos(nIndex);
+ else
+ return SAL_MAX_INT32;
+}
+
+WW8_CP SwWW8ImplReader::GetAnnotationEnd(int nIndex)
+{
+ if (!mpAtnEnds.get() && pWwFib->lcbPlcfAtnbkl)
+ // The Plcfbkl structure is a PLC that contains only CPs and no additional data.
+ mpAtnEnds.reset(new WW8PLCFspecial(pTableStream, pWwFib->fcPlcfAtnbkl, pWwFib->lcbPlcfAtnbkl, 0));
+
+ if (mpAtnEnds.get())
+ return mpAtnEnds->GetPos(nIndex);
+ else
+ return SAL_MAX_INT32;
+}
+
sal_uLong SwWW8ImplReader::LoadDoc( SwPaM& rPaM,WW8Glossary *pGloss)
{
sal_uLong nErrRet = 0;
diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx
index 31321f7..485cc34 100644
--- a/sw/source/filter/ww8/ww8par.hxx
+++ b/sw/source/filter/ww8/ww8par.hxx
@@ -1101,6 +1101,9 @@ private:
SwMSDffManager* pMSDffManager;
std::vector<String>* mpAtnNames;
+ boost::shared_ptr< std::map<sal_uInt32, int> > mpAtnIndexes;
+ boost::shared_ptr<WW8PLCFspecial> mpAtnStarts;
+ boost::shared_ptr<WW8PLCFspecial> mpAtnEnds;
sw::util::AuthorInfos m_aAuthorInfos;
String sBaseURL;
@@ -1484,6 +1487,9 @@ private:
// spaeter zu ersetzen durch Aufruf in entsprechend erweiterten SvxMSDffManager
const String* GetAnnotationAuthor(sal_uInt16 nIdx);
+ int GetAnnotationIndex(sal_uInt32 nTag);
+ WW8_CP GetAnnotationStart(int nIndex);
+ WW8_CP GetAnnotationEnd(int nIndex);
// Schnittstellen fuer die Toggle-Attribute
void SetToggleAttr(sal_uInt8 nAttrId, bool bOn);
diff --git a/sw/source/filter/ww8/ww8struc.hxx b/sw/source/filter/ww8/ww8struc.hxx
index 9bb467d..56d39d9 100644
--- a/sw/source/filter/ww8/ww8struc.hxx
+++ b/sw/source/filter/ww8/ww8struc.hxx
@@ -878,6 +878,14 @@ struct WW8_STRINGID
SVBT16 reserved3;
};
+/// The ATNBE structure contains information about an annotation bookmark in the document.
+struct WW8_ATNBE
+{
+ SVBT16 nBmc;
+ SVBT32 nTag;
+ SVBT32 nTagOld;
+};
+
struct WW8_WKB
{
// M.M. This is the WkbPLCF struct
More information about the Libreoffice-commits
mailing list