Kaydet (Commit) f5c26669 authored tarafından Serge Krot's avatar Serge Krot Kaydeden (comit) Thorsten Behrens

tdf#66398 Parse and output permissions for DOCX using bookmarks

Change-Id: Id08998ae775c5f383edc4bf0410d16f88c70dfd6
Reviewed-on: https://gerrit.libreoffice.org/43275Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarThorsten Behrens <Thorsten.Behrens@CIB.de>
üst 9c4d690b
......@@ -695,7 +695,16 @@ protected:
private:
void DoWriteBookmarks( );
void DoWriteBookmarkTagStart(const OUString & bookmarkName);
void DoWriteBookmarkTagEnd(const OUString & bookmarkName);
void DoWriteBookmarksStart();
void DoWriteBookmarksEnd();
void DoWritePermissionTagStart(const OUString & permission);
void DoWritePermissionTagEnd(const OUString & permission);
void DoWritePermissionsStart();
void DoWritePermissionsEnd();
void DoWriteAnnotationMarks( );
void WritePostponedGraphic();
void WritePostponedMath(const SwOLENode* pObject);
......@@ -776,6 +785,10 @@ private:
std::vector<OUString> m_rBookmarksStart;
std::vector<OUString> m_rBookmarksEnd;
/// Permissions to output
std::vector<OUString> m_rPermissionsStart;
std::vector<OUString> m_rPermissionsEnd;
/// Annotation marks to output
std::vector<OString> m_rAnnotationMarksStart;
std::vector<OString> m_rAnnotationMarksEnd;
......
......@@ -1125,6 +1125,26 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
}
break;
}
case NS_ooxml::LN_CT_PermStart_ed:
{
m_pImpl->setPermissionRangeEd(sStringValue);
break;
}
case NS_ooxml::LN_CT_PermStart_edGrp:
{
m_pImpl->setPermissionRangeEdGrp(sStringValue);
break;
}
case NS_ooxml::LN_CT_PermStart_id:
{
m_pImpl->startOrEndPermissionRange(nIntValue);
break;
}
case NS_ooxml::LN_CT_PermEnd_id:
{
m_pImpl->startOrEndPermissionRange(nIntValue);
break;
}
default:
SAL_WARN("writerfilter", "DomainMapper::lcl_attribute: unhandled token: " << nName);
}
......@@ -2816,11 +2836,6 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext )
pProperties->resolve(*this);
}
break;
case NS_ooxml::LN_EG_RunLevelElts_permStart: // 93164
case NS_ooxml::LN_EG_RunLevelElts_permEnd: // 93165
{
break;
}
default:
{
#ifdef DEBUG_WRITERFILTER
......
......@@ -202,6 +202,7 @@ DomainMapper_Impl::DomainMapper_Impl(
m_bStartBibliography(false),
m_bStartGenericField(false),
m_bTextInserted(false),
m_sCurrentPermId(0),
m_pLastSectionContext( ),
m_pLastCharacterContext(),
m_sCurrentParaStyleId(),
......@@ -4791,6 +4792,7 @@ void DomainMapper_Impl::SetBookmarkName( const OUString& rBookmarkName )
m_sCurrentBkmkName = rBookmarkName;
}
// This method was used as-is for DomainMapper_Impl::startOrEndPermissionRange() implementation.
void DomainMapper_Impl::StartOrEndBookmark( const OUString& rId )
{
/*
......@@ -4869,6 +4871,121 @@ void DomainMapper_Impl::StartOrEndBookmark( const OUString& rId )
}
}
void DomainMapper_Impl::setPermissionRangeEd(const OUString& user)
{
PermMap_t::iterator aPremIter = m_aPermMap.find(m_sCurrentPermId);
if (aPremIter != m_aPermMap.end())
aPremIter->second.m_Ed = user;
else
m_sCurrentPermEd = user;
}
void DomainMapper_Impl::setPermissionRangeEdGrp(const OUString& group)
{
PermMap_t::iterator aPremIter = m_aPermMap.find(m_sCurrentPermId);
if (aPremIter != m_aPermMap.end())
aPremIter->second.m_EdGrp = group;
else
m_sCurrentPermEdGrp = group;
}
// This method is based on implementation from DomainMapper_Impl::StartOrEndBookmark()
void DomainMapper_Impl::startOrEndPermissionRange(sal_Int32 permissinId)
{
/*
* Add the dummy paragraph to handle section properties
* if the first element in the section is a table. If the dummy para is not added yet, then add it;
* So permission is not attached to the wrong paragraph.
*/
if (getTableManager().isInCell() && m_nTableDepth == 0 && GetIsFirstParagraphInSection()
&& !GetIsDummyParaAddedForTableInSection() && !GetIsTextFrameInserted())
{
AddDummyParaForTableInSection();
}
if (m_aTextAppendStack.empty())
return;
const bool bIsAfterDummyPara = GetIsDummyParaAddedForTableInSection() && GetIsFirstParagraphInSection();
uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend;
PermMap_t::iterator aPermIter = m_aPermMap.find(permissinId);
//is the bookmark name already registered?
try
{
if (aPermIter == m_aPermMap.end())
{
//otherwise insert a text range as marker
bool bIsStart = true;
uno::Reference< text::XTextRange > xCurrent;
if (xTextAppend.is())
{
uno::Reference< text::XTextCursor > xCursor = xTextAppend->createTextCursorByRange(xTextAppend->getEnd());
if (!bIsAfterDummyPara)
bIsStart = !xCursor->goLeft(1, false);
xCurrent = xCursor->getStart();
}
// register the start of the new permission
m_sCurrentPermId = permissinId;
m_aPermMap.emplace(permissinId, PermInsertPosition(bIsStart, permissinId, m_sCurrentPermEd, m_sCurrentPermEdGrp, xCurrent));
// clean up
m_sCurrentPermEd.clear();
m_sCurrentPermEdGrp.clear();
}
else
{
if (m_xTextFactory.is())
{
uno::Reference< text::XTextCursor > xCursor;
uno::Reference< text::XText > xText = aPermIter->second.m_xTextRange->getText();
if (aPermIter->second.m_bIsStartOfText && !bIsAfterDummyPara)
{
xCursor = xText->createTextCursorByRange(xText->getStart());
}
else
{
xCursor = xText->createTextCursorByRange(aPermIter->second.m_xTextRange);
xCursor->goRight(1, false);
}
xCursor->gotoRange(xTextAppend->getEnd(), true);
// A Paragraph was recently finished, and a new Paragraph has not been started as yet
// then move the bookmark-End to the earlier paragraph
if (IsOutsideAParagraph())
{
xCursor->goLeft(1, false);
}
// create a new bookmark using specific bookmark name pattern for permissions
uno::Reference< text::XTextContent > xPerm(m_xTextFactory->createInstance("com.sun.star.text.Bookmark"), uno::UNO_QUERY_THROW);
uno::Reference< container::XNamed > xPermNamed(xPerm, uno::UNO_QUERY_THROW);
xPermNamed->setName(aPermIter->second.createBookmarkName());
// add new bookmark
const bool bAbsorb = !xCursor->isCollapsed();
uno::Reference< text::XTextRange > xCurrent = uno::Reference< text::XTextRange >(xCursor, uno::UNO_QUERY_THROW);
xTextAppend->insertTextContent(xCurrent, xPerm, bAbsorb);
}
// remove proccessed permission
m_aPermMap.erase(aPermIter);
// clean up
m_sCurrentPermId = 0;
m_sCurrentPermEd.clear();
m_sCurrentPermEdGrp.clear();
}
}
catch (const uno::Exception&)
{
//TODO: What happens to bookmarks where start and end are at different XText objects?
}
}
void DomainMapper_Impl::AddAnnotationPosition(
const bool bStart,
const sal_Int32 nAnnotationId)
......
......@@ -258,6 +258,49 @@ struct BookmarkInsertPosition
{}
};
struct PermInsertPosition
{
bool m_bIsStartOfText;
sal_Int32 m_Id;
OUString m_Ed;
OUString m_EdGrp;
css::uno::Reference<css::text::XTextRange> m_xTextRange;
PermInsertPosition(bool bIsStartOfText, sal_Int32 id, const OUString& ed, const OUString& edGrp, css::uno::Reference<css::text::XTextRange> const& xTextRange)
: m_bIsStartOfText(bIsStartOfText)
, m_Id(id)
, m_Ed(ed)
, m_EdGrp(edGrp)
, m_xTextRange(xTextRange)
{}
OUString createBookmarkName() const
{
OUString bookmarkName;
assert((!m_Ed.isEmpty()) || (!m_EdGrp.isEmpty()));
if (m_Ed.isEmpty())
{
bookmarkName += "permission-for-group:";
bookmarkName += OUString::number(m_Id);
bookmarkName += ":";
bookmarkName += m_EdGrp;
}
else
{
bookmarkName += "permission-for-user:";
bookmarkName += OUString::number(m_Id);
bookmarkName += ":";
bookmarkName += m_Ed;
}
//todo: make sure the name is not used already!
return bookmarkName;
}
};
/// Stores the start/end positions of an annotation before its insertion.
struct AnnotationPosition
{
......@@ -334,6 +377,7 @@ class DomainMapper_Impl final
{
public:
typedef std::map < OUString, BookmarkInsertPosition > BookmarkMap_t;
typedef std::map < sal_Int32, PermInsertPosition > PermMap_t;
private:
SourceDocumentType m_eDocumentType;
......@@ -375,6 +419,11 @@ private:
OUString m_sCurrentBkmkId;
OUString m_sCurrentBkmkName;
PermMap_t m_aPermMap;
sal_Int32 m_sCurrentPermId;
OUString m_sCurrentPermEd;
OUString m_sCurrentPermEdGrp;
PageMar m_aPageMargins;
SymbolData m_aSymbolData;
......@@ -705,6 +754,10 @@ public:
void SetBookmarkName( const OUString& rBookmarkName );
void StartOrEndBookmark( const OUString& rId );
void setPermissionRangeEd(const OUString& user);
void setPermissionRangeEdGrp(const OUString& group);
void startOrEndPermissionRange(sal_Int32 permissinId);
void AddAnnotationPosition(
const bool bStart,
const sal_Int32 nAnnotationId );
......
......@@ -12126,6 +12126,9 @@
</attribute>
<ref name="CT_MarkupRange"/>
</define>
<define name="CT_MarkupRangePerm">
<ref name="CT_MarkupRange"/>
</define>
<define name="CT_MarkupRangeCommentStart">
<ref name="CT_Markup"/>
</define>
......@@ -12166,6 +12169,24 @@
<ref name="ST_String"/>
</attribute>
</define>
<define name="CT_PermStart">
<ref name="CT_MarkupRangePerm"/>
<attribute name="ed">
<data type="string"/>
</attribute>
<attribute name="edGrp">
<data type="string"/>
</attribute>
<attribute name="colFirst">
<data type="ST_DecimalNumber"/>
</attribute>
<attribute name="colLast">
<data type="ST_DecimalNumber"/>
</attribute>
</define>
<define name="CT_PermEnd">
<ref name="CT_MarkupRangePerm"/>
</define>
<define name="CT_TrackChangeNumbering">
<ref name="CT_TrackChange"/>
<attribute name="original">
......@@ -12254,6 +12275,12 @@
<element name="bookmarkEnd">
<ref name="CT_MarkupRangeBookmark"/>
</element>
<element name="permStart">
<ref name="CT_PermStart"/>
</element>
<element name="permEnd">
<ref name="CT_PermEnd"/>
</element>
<element name="moveFromRangeStart">
<ref name="CT_MoveBookmark"/>
</element>
......@@ -13279,29 +13306,6 @@
<data type="string"/>
</attribute>
</define>
<define name="CT_Perm">
<attribute name="id">
<data type="string"/>
</attribute>
<attribute name="displacedByCustomXml">
<data type="string"/>
</attribute>
</define>
<define name="CT_PermStart">
<ref name="CT_Perm"/>
<attribute name="edGrp">
<data type="string"/>
</attribute>
<attribute name="ed">
<data type="string"/>
</attribute>
<attribute name="colFirst">
<data type="string"/>
</attribute>
<attribute name="colLast">
<data type="string"/>
</attribute>
</define>
<define name="CT_Text">
<ref name="ST_String"/>
<attribute name="xml:space">
......@@ -16291,12 +16295,6 @@
<element name="proofErr">
<ref name="CT_ProofErr"/>
</element>
<element name="permStart">
<ref name="CT_PermStart"/>
</element>
<element name="permEnd">
<ref name="CT_Perm"/>
</element>
<ref name="EG_RangeMarkupElements"/>
<element name="ins">
<ref name="CT_RunTrackChange"/>
......@@ -17363,6 +17361,18 @@
<resource name="CT_MarkupRangeBookmark" resource="Properties">
<attribute name="id" tokenid="ooxml:CT_MarkupRangeBookmark_id"/>
</resource>
<resource name="CT_PermStart" resource="Properties">
<attribute name="id" tokenid="ooxml:CT_PermStart_id"/>
<attribute name="colFirst" tokenid="ooxml:CT_PermStart_colFirst"/>
<attribute name="colLast" tokenid="ooxml:CT_PermStart_colLast"/>
<attribute name="ed" tokenid="ooxml:CT_PermStart_ed"/>
<attribute name="edGrp" tokenid="ooxml:CT_PermStart_edGrp"/>
<attribute name="displacedByCustomXml" tokenid="ooxml:CT_PermStart_displacedByCustomXml"/>
</resource>
<resource name="CT_PermEnd" resource="Properties">
<attribute name="id" tokenid="ooxml:CT_PermEnd_id"/>
<attribute name="displacedByCustomXml" tokenid="ooxml:CT_PermEnd_displacedByCustomXml"/>
</resource>
<resource name="CT_MarkupRangeCommentStart" resource="Properties">
<attribute name="id" tokenid="ooxml:EG_RangeMarkupElements_commentRangeStart"/>
</resource>
......@@ -17425,6 +17435,8 @@
<resource name="EG_RangeMarkupElements" resource="Properties">
<element name="bookmarkStart" tokenid="ooxml:EG_RangeMarkupElements_bookmarkStart"/>
<element name="bookmarkEnd" tokenid="ooxml:EG_RangeMarkupElements_bookmarkEnd"/>
<element name="permStart" tokenid="ooxml:EG_RangeMarkupElements_PermStart"/>
<element name="permEnd" tokenid="ooxml:EG_RangeMarkupElements_PermEnd"/>
<element name="moveFromRangeStart" tokenid="ooxml:EG_RangeMarkupElements_moveFromRangeStart"/>
<element name="moveFromRangeEnd" tokenid="ooxml:EG_RangeMarkupElements_moveFromRangeEnd"/>
<element name="moveToRangeStart" tokenid="ooxml:EG_RangeMarkupElements_moveToRangeStart"/>
......
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