summaryrefslogtreecommitdiff
path: root/writerfilter
diff options
context:
space:
mode:
authorSerge Krot <Serge.Krot@cib.de>2017-10-09 12:15:05 +0200
committerThorsten Behrens <Thorsten.Behrens@CIB.de>2017-10-10 19:35:28 +0200
commitf5c266695a4a88da7db971a21915e2bbf758d48e (patch)
treeb11516ba17e51898a66152e4e75eb2ff34244ef3 /writerfilter
parent9c4d690b73b30aa144828935ad4e87eb13442d0c (diff)
tdf#66398 Parse and output permissions for DOCX using bookmarks
Change-Id: Id08998ae775c5f383edc4bf0410d16f88c70dfd6 Reviewed-on: https://gerrit.libreoffice.org/43275 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
Diffstat (limited to 'writerfilter')
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx25
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx117
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.hxx53
-rw-r--r--writerfilter/source/ooxml/model.xml70
4 files changed, 231 insertions, 34 deletions
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index f492c2c2d033..227f55935ee3 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -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
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index be16a2307eaf..8e1423cf1380 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -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)
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 208318c81c12..df22413a8cbd 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -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 );
diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml
index 81cdc3ff9c77..a9ffbdfa6c65 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -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"/>