Kaydet (Commit) 7907cc0e authored tarafından Miklos Vajna's avatar Miklos Vajna

fdo#59530 WW8 import of commented text ranges

Change-Id: I3e2928922ebcec8188c1b5416108373c4f26dd62
üst af1d3c83
This diff was suppressed by a .gitattributes entry.
...@@ -47,6 +47,7 @@ public: ...@@ -47,6 +47,7 @@ public:
void testN757118(); void testN757118();
void testN757905(); void testN757905();
void testAllGapsWord(); void testAllGapsWord();
void testFdo59530();
CPPUNIT_TEST_SUITE(Test); CPPUNIT_TEST_SUITE(Test);
#if !defined(MACOSX) && !defined(WNT) #if !defined(MACOSX) && !defined(WNT)
...@@ -68,6 +69,7 @@ void Test::run() ...@@ -68,6 +69,7 @@ void Test::run()
{"n757118.doc", &Test::testN757118}, {"n757118.doc", &Test::testN757118},
{"n757905.doc", &Test::testN757905}, {"n757905.doc", &Test::testN757905},
{"all_gaps_word.doc", &Test::testAllGapsWord}, {"all_gaps_word.doc", &Test::testAllGapsWord},
{"fdo59530.doc", &Test::testFdo59530},
}; };
header(); header();
for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i) for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i)
...@@ -226,6 +228,30 @@ void Test::testAllGapsWord() ...@@ -226,6 +228,30 @@ void Test::testAllGapsWord()
borderTest.testTheBorders(mxComponent); 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); CPPUNIT_TEST_SUITE_REGISTRATION(Test);
......
...@@ -1761,6 +1761,8 @@ long SwWW8ImplReader::Read_And(WW8PLCFManResult* pRes) ...@@ -1761,6 +1761,8 @@ long SwWW8ImplReader::Read_And(WW8PLCFManResult* pRes)
return 0; return 0;
String sAuthor; String sAuthor;
String sInitials;
String sName;
if( bVer67 ) if( bVer67 )
{ {
const WW67_ATRD* pDescri = (const WW67_ATRD*)pSD->GetData(); const WW67_ATRD* pDescri = (const WW67_ATRD*)pSD->GetData();
...@@ -1775,13 +1777,35 @@ long SwWW8ImplReader::Read_And(WW8PLCFManResult* pRes) ...@@ -1775,13 +1777,35 @@ long SwWW8ImplReader::Read_And(WW8PLCFManResult* pRes)
{ {
const WW8_ATRD* pDescri = (const WW8_ATRD*)pSD->GetData(); 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))) if (const String* pA = GetAnnotationAuthor(SVBT16ToShort(pDescri->ibst)))
sAuthor = *pA; sAuthor = *pA;
else 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]); sName = OUString::valueOf(sal_Int32(nTagBkmk));
for(sal_uInt16 nIdx = 1; nIdx <= nLen; ++nIdx) int nAtnIndex = GetAnnotationIndex(nTagBkmk);
sAuthor += SVBT16ToShort(pDescri->xstUsrInitl[nIdx]); 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) ...@@ -1803,9 +1827,18 @@ long SwWW8ImplReader::Read_And(WW8PLCFManResult* pRes)
this->pFmtOfJustInsertedApo = 0; this->pFmtOfJustInsertedApo = 0;
SwPostItField aPostIt( SwPostItField aPostIt(
(SwPostItFieldType*)rDoc.GetSysFldType(RES_POSTITFLD), sAuthor, (SwPostItFieldType*)rDoc.GetSysFldType(RES_POSTITFLD), sAuthor,
sTxt, aEmptyStr, aEmptyStr, aDate ); sTxt, sInitials, sName, aDate );
aPostIt.SetTextObject(pOutliner); 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)); pCtrlStck->NewAttr(*pPaM->GetPoint(), SvxCharHiddenItem(false, RES_CHRATR_HIDDEN));
rDoc.InsertPoolItem(*pPaM, SwFmtFld(aPostIt), 0); rDoc.InsertPoolItem(*pPaM, SwFmtFld(aPostIt), 0);
pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_CHRATR_HIDDEN); pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_CHRATR_HIDDEN);
...@@ -5367,6 +5400,54 @@ const String* SwWW8ImplReader::GetAnnotationAuthor(sal_uInt16 nIdx) ...@@ -5367,6 +5400,54 @@ const String* SwWW8ImplReader::GetAnnotationAuthor(sal_uInt16 nIdx)
return pRet; 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 SwWW8ImplReader::LoadDoc( SwPaM& rPaM,WW8Glossary *pGloss)
{ {
sal_uLong nErrRet = 0; sal_uLong nErrRet = 0;
......
...@@ -1101,6 +1101,9 @@ private: ...@@ -1101,6 +1101,9 @@ private:
SwMSDffManager* pMSDffManager; SwMSDffManager* pMSDffManager;
std::vector<String>* mpAtnNames; 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; sw::util::AuthorInfos m_aAuthorInfos;
String sBaseURL; String sBaseURL;
...@@ -1484,6 +1487,9 @@ private: ...@@ -1484,6 +1487,9 @@ private:
// spaeter zu ersetzen durch Aufruf in entsprechend erweiterten SvxMSDffManager // spaeter zu ersetzen durch Aufruf in entsprechend erweiterten SvxMSDffManager
const String* GetAnnotationAuthor(sal_uInt16 nIdx); 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 // Schnittstellen fuer die Toggle-Attribute
void SetToggleAttr(sal_uInt8 nAttrId, bool bOn); void SetToggleAttr(sal_uInt8 nAttrId, bool bOn);
......
...@@ -878,6 +878,14 @@ struct WW8_STRINGID ...@@ -878,6 +878,14 @@ struct WW8_STRINGID
SVBT16 reserved3; 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 struct WW8_WKB
{ {
// M.M. This is the WkbPLCF struct // M.M. This is the WkbPLCF struct
......
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