[Libreoffice-commits] core.git: 4 commits - include/sfx2 sc/source sd/source sfx2/source sw/inc sw/qa sw/source writerfilter/source
Miklos Vajna
vmiklos at collabora.co.uk
Thu Mar 10 13:33:44 UTC 2016
include/sfx2/classificationhelper.hxx | 11 -
sc/source/ui/view/formatsh.cxx | 2
sd/source/ui/view/drviews2.cxx | 2
sfx2/source/view/classificationcontroller.cxx | 2
sfx2/source/view/classificationhelper.cxx | 40 ++--
sfx2/source/view/viewfrm.cxx | 4
sw/inc/fmtmeta.hxx | 10 +
sw/qa/extras/rtfimport/data/classification-confidential.rtf | 11 +
sw/qa/extras/rtfimport/data/classification-no.rtf | 1
sw/qa/extras/rtfimport/data/classification-yes.rtf | 11 +
sw/qa/extras/rtfimport/rtfimport.cxx | 29 +++
sw/qa/extras/uiwriter/uiwriter.cxx | 16 +
sw/source/core/edit/edfcol.cxx | 2
sw/source/core/txtnode/fmtatr2.cxx | 18 ++
sw/source/filter/ww8/rtfexport.cxx | 7
sw/source/uibase/dochdl/swdtflvr.cxx | 5
writerfilter/source/rtftok/rtfdocumentimpl.cxx | 102 ++++++++++--
writerfilter/source/rtftok/rtflistener.hxx | 3
18 files changed, 230 insertions(+), 46 deletions(-)
New commits:
commit b1f9369b8181b4f135bfc8a0f1fdf1be7609fd0f
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Thu Mar 10 11:23:51 2016 +0100
RTF import: handle classification during copy&paste
With this, it can't happen that "paste" returns an error, but "paste as
rtf" succeeds (from a classification point of view).
Change-Id: Ia6807e5a6c065557cdd735a574ea858d29a97160
diff --git a/sw/qa/extras/rtfimport/data/classification-confidential.rtf b/sw/qa/extras/rtfimport/data/classification-confidential.rtf
new file mode 100644
index 0000000..c7207f9
--- /dev/null
+++ b/sw/qa/extras/rtfimport/data/classification-confidential.rtf
@@ -0,0 +1,11 @@
+{\rtf1{\*\userprops
+{\propname urn:bails:IntellectualProperty:Authorization:StartValidity}\proptype30{\staticval 2016-03-08T10:55:18,531376147}{\propname urn:bails:IntellectualProperty:Authorization:StopValidity}\proptype30{\staticval None}{\propname urn:bails:IntellectualPr
+operty:BusinessAuthorization:Identifier}\proptype30{\staticval urn:example:tscp:1}{\propname urn:bails:IntellectualProperty:BusinessAuthorization:Locator}\proptype30{\staticval None}{\propname urn:bails:IntellectualProperty:BusinessAuthorization:Name}
+\proptype30{\staticval None}{\propname urn:bails:IntellectualProperty:BusinessAuthorizationCategory:Identifier}\proptype30{\staticval urn:example:tscp:1:internal-only}{\propname urn:bails:IntellectualProperty:BusinessAuthorizationCategory:Identifier:OID}
+\proptype30{\staticval None}{\propname urn:bails:IntellectualProperty:BusinessAuthorizationCategory:Locator}\proptype30{\staticval None}{\propname urn:bails:IntellectualProperty:BusinessAuthorizationCategory:Name}\proptype30{\staticval Confidential}
+{\propname urn:bails:IntellectualProperty:Impact:Level:Availability}\proptype30{\staticval 2}{\propname urn:bails:IntellectualProperty:Impact:Level:Confidentiality}\proptype30{\staticval 2}{\propname urn:bails:IntellectualProperty:Impact:Level:Integrity}
+\proptype30{\staticval 2}{\propname urn:bails:IntellectualProperty:Impact:Scale}\proptype30{\staticval UK-Cabinet}{\propname urn:bails:IntellectualProperty:Marking:document-footer}\proptype30{\staticval This content is marked Internal Only. Do not distrib
+ute it outside of the business.}{\propname urn:bails:IntellectualProperty:Marking:document-header}\proptype30{\staticval Classification: Internal Only}{\propname urn:bails:IntellectualProperty:Marking:document-watermark}\proptype30{\staticval Internal Onl
+y}{\propname urn:bails:IntellectualProperty:MarkingPrecedence}\proptype30{\staticval None}{\propname urn:bails:IntellectualProperty:Policy:Identifier}\proptype30{\staticval None}{\propname urn:bails:IntellectualProperty:Policy:Name}\proptype30{\staticval
+TSCP Example Policy}{\propname urn:bails:IntellectualProperty:PolicyAuthority:Country}\proptype30{\staticval None}{\propname urn:bails:IntellectualProperty:PolicyAuthority:Identifier}\proptype30{\staticval None}{\propname urn:bails:IntellectualProperty:Po
+licyAuthority:Name}\proptype30{\staticval TSCP Example Policy Authority}}\par classification-yes\par}
diff --git a/sw/qa/extras/rtfimport/data/classification-no.rtf b/sw/qa/extras/rtfimport/data/classification-no.rtf
new file mode 100644
index 0000000..7c773d1
--- /dev/null
+++ b/sw/qa/extras/rtfimport/data/classification-no.rtf
@@ -0,0 +1 @@
+{\rtf1 \par classification-no\par}
diff --git a/sw/qa/extras/rtfimport/data/classification-yes.rtf b/sw/qa/extras/rtfimport/data/classification-yes.rtf
new file mode 100644
index 0000000..a40c3d1
--- /dev/null
+++ b/sw/qa/extras/rtfimport/data/classification-yes.rtf
@@ -0,0 +1,11 @@
+{\rtf1{\*\userprops
+{\propname urn:bails:IntellectualProperty:Authorization:StartValidity}\proptype30{\staticval 2016-03-08T10:55:18,531376147}{\propname urn:bails:IntellectualProperty:Authorization:StopValidity}\proptype30{\staticval None}{\propname urn:bails:IntellectualPr
+operty:BusinessAuthorization:Identifier}\proptype30{\staticval urn:example:tscp:1}{\propname urn:bails:IntellectualProperty:BusinessAuthorization:Locator}\proptype30{\staticval None}{\propname urn:bails:IntellectualProperty:BusinessAuthorization:Name}
+\proptype30{\staticval None}{\propname urn:bails:IntellectualProperty:BusinessAuthorizationCategory:Identifier}\proptype30{\staticval urn:example:tscp:1:internal-only}{\propname urn:bails:IntellectualProperty:BusinessAuthorizationCategory:Identifier:OID}
+\proptype30{\staticval None}{\propname urn:bails:IntellectualProperty:BusinessAuthorizationCategory:Locator}\proptype30{\staticval None}{\propname urn:bails:IntellectualProperty:BusinessAuthorizationCategory:Name}\proptype30{\staticval Internal Only}
+{\propname urn:bails:IntellectualProperty:Impact:Level:Availability}\proptype30{\staticval 3}{\propname urn:bails:IntellectualProperty:Impact:Level:Confidentiality}\proptype30{\staticval 3}{\propname urn:bails:IntellectualProperty:Impact:Level:Integrity}
+\proptype30{\staticval 3}{\propname urn:bails:IntellectualProperty:Impact:Scale}\proptype30{\staticval UK-Cabinet}{\propname urn:bails:IntellectualProperty:Marking:document-footer}\proptype30{\staticval This content is marked Internal Only. Do not distrib
+ute it outside of the business.}{\propname urn:bails:IntellectualProperty:Marking:document-header}\proptype30{\staticval Classification: Internal Only}{\propname urn:bails:IntellectualProperty:Marking:document-watermark}\proptype30{\staticval Internal Onl
+y}{\propname urn:bails:IntellectualProperty:MarkingPrecedence}\proptype30{\staticval None}{\propname urn:bails:IntellectualProperty:Policy:Identifier}\proptype30{\staticval None}{\propname urn:bails:IntellectualProperty:Policy:Name}\proptype30{\staticval
+TSCP Example Policy}{\propname urn:bails:IntellectualProperty:PolicyAuthority:Country}\proptype30{\staticval None}{\propname urn:bails:IntellectualProperty:PolicyAuthority:Identifier}\proptype30{\staticval None}{\propname urn:bails:IntellectualProperty:Po
+licyAuthority:Name}\proptype30{\staticval TSCP Example Policy Authority}}\par classification-yes\par}
diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx
index f8193cd..a8c8f79 100644
--- a/sw/qa/extras/rtfimport/rtfimport.cxx
+++ b/sw/qa/extras/rtfimport/rtfimport.cxx
@@ -2525,6 +2525,35 @@ DECLARE_RTFIMPORT_TEST(testTdf87034, "tdf87034.rtf")
CPPUNIT_ASSERT_EQUAL(OUString("A1B3C4D"), getParagraph(1)->getString());
}
+DECLARE_RTFIMPORT_TEST(testClassificatonPaste, "hello.rtf")
+{
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<text::XTextRange> xText(xTextDocument->getText(), uno::UNO_QUERY);
+ uno::Reference<text::XTextRange> xEnd = xText->getEnd();
+
+ // Not classified source, not classified destination: OK.
+ paste("classification-no.rtf", xEnd);
+ CPPUNIT_ASSERT_EQUAL(OUString("classification-no"), getParagraph(2)->getString());
+
+ // Classified source, not classified destination: nothing should happen.
+ OUString aOld = xText->getString();
+ paste("classification-yes.rtf", xEnd);
+ CPPUNIT_ASSERT_EQUAL(aOld, xText->getString());
+}
+
+DECLARE_RTFIMPORT_TEST(testClassificatonPasteLevels, "classification-confidential.rtf")
+{
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<text::XTextRange> xText(xTextDocument->getText(), uno::UNO_QUERY);
+ uno::Reference<text::XTextRange> xEnd = xText->getEnd();
+
+ // Classified source and classified destination, but internal only has a
+ // higher level than confidential: nothing should happen.
+ OUString aOld = xText->getString();
+ paste("classification-yes.rtf", xEnd);
+ CPPUNIT_ASSERT_EQUAL(aOld, xText->getString());
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 6bea01f..1c83e66 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -22,6 +22,7 @@
#include <unotools/streamwrap.hxx>
#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
#include <vcl/wmf.hxx>
+#include <vcl/layout.hxx>
#include <filter/msfilter/util.hxx>
#include <comphelper/string.hxx>
#include <tools/globname.hxx>
@@ -31,6 +32,9 @@
#include <comphelper/sequenceashashmap.hxx>
#include <comphelper/sequence.hxx>
#include <sfx2/sfxbasemodel.hxx>
+#include <sfx2/classificationhelper.hxx>
+#include <sfx2/sfx.hrc>
+#include <sfx2/sfxresid.hxx>
#include <oox/mathml/import.hxx>
#include <ooxml/resourceids.hxx>
#include <oox/token/namespaces.hxx>
@@ -741,6 +745,9 @@ void RTFDocumentImpl::resolve(Stream& rMapper)
case RTFError::CHAR_OVER:
SAL_INFO("writerfilter", "RTFDocumentImpl::resolve: characters after last '}'");
break;
+ case RTFError::CLASSIFICATION:
+ SAL_INFO("writerfilter", "RTFDocumentImpl::resolve: classification prevented paste");
+ break;
}
}
@@ -5124,6 +5131,39 @@ bool lcl_containsProperty(const uno::Sequence<beans::Property>& rProperties, con
}) != rProperties.end();
}
+namespace
+{
+
+RTFError lcl_checkClassification(const uno::Reference<document::XDocumentProperties>& xSource, const uno::Reference<document::XDocumentProperties>& xDestination)
+{
+ switch (SfxClassificationHelper::CheckPaste(xSource, xDestination))
+ {
+ case SfxClassificationCheckPasteResult::None:
+ {
+ return RTFError::OK;
+ }
+ break;
+ case SfxClassificationCheckPasteResult::TargetDocNotClassified:
+ {
+ if (!Application::IsHeadlessModeEnabled())
+ ScopedVclPtrInstance<MessageDialog>::Create(nullptr, SfxResId(STR_TARGET_DOC_NOT_CLASSIFIED), VCL_MESSAGE_INFO)->Execute();
+ return RTFError::CLASSIFICATION;
+ }
+ break;
+ case SfxClassificationCheckPasteResult::DocClassificationTooLow:
+ {
+ if (!Application::IsHeadlessModeEnabled())
+ ScopedVclPtrInstance<MessageDialog>::Create(nullptr, SfxResId(STR_DOC_CLASSIFICATION_TOO_LOW), VCL_MESSAGE_INFO)->Execute();
+ return RTFError::CLASSIFICATION;
+ }
+ break;
+ }
+
+ return RTFError::OK;
+}
+
+}
+
RTFError RTFDocumentImpl::popState()
{
//SAL_INFO("writerfilter", OSL_THIS_FUNC << " before pop: m_pTokenizer->getGroup() " << m_pTokenizer->getGroup() <<
@@ -5943,6 +5983,14 @@ RTFError RTFDocumentImpl::popState()
if (m_xDocumentProperties.is())
{
+ if (!m_bIsNewDoc)
+ {
+ // Check classification.
+ RTFError nError = lcl_checkClassification(xDocumentProperties, m_xDocumentProperties);
+ if (nError != RTFError::OK)
+ return nError;
+ }
+
uno::Reference<beans::XPropertyContainer> xClipboardPropertyContainer = xDocumentProperties->getUserDefinedProperties();
uno::Reference<beans::XPropertyContainer> xDocumentPropertyContainer = m_xDocumentProperties->getUserDefinedProperties();
uno::Reference<beans::XPropertySet> xClipboardPropertySet(xClipboardPropertyContainer, uno::UNO_QUERY);
@@ -5958,7 +6006,11 @@ RTFError RTFDocumentImpl::popState()
try
{
if (lcl_containsProperty(aDocumentProperties, rKey))
- xDocumentPropertySet->setPropertyValue(rKey, aValue);
+ {
+ // When pasting, don't update existing properties.
+ if (!m_bIsNewDoc)
+ xDocumentPropertySet->setPropertyValue(rKey, aValue);
+ }
else
xDocumentPropertyContainer->addProperty(rKey, beans::PropertyAttribute::REMOVABLE, aValue);
}
diff --git a/writerfilter/source/rtftok/rtflistener.hxx b/writerfilter/source/rtftok/rtflistener.hxx
index dbce218..ea3d9e2 100644
--- a/writerfilter/source/rtftok/rtflistener.hxx
+++ b/writerfilter/source/rtftok/rtflistener.hxx
@@ -30,7 +30,8 @@ enum class RTFError
GROUP_OVER,
UNEXPECTED_EOF,
HEX_INVALID,
- CHAR_OVER
+ CHAR_OVER,
+ CLASSIFICATION
};
/**
commit e75f6e549eb825c310d16d11babf0fba5ee7fd7a
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Thu Mar 10 08:58:00 2016 +0100
sfx2: make SfxClassificationHelper not require a full doc shell
So that input filters can build their own doc properties and can also
use CheckPaste() without having the full original document around.
Change-Id: I0b8a63702f73ce04e8728a360b56ab9d1ca67af1
diff --git a/include/sfx2/classificationhelper.hxx b/include/sfx2/classificationhelper.hxx
index 5a58fcc..9ce8933 100644
--- a/include/sfx2/classificationhelper.hxx
+++ b/include/sfx2/classificationhelper.hxx
@@ -13,6 +13,8 @@
#include <memory>
#include <vector>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+
#include <rtl/ustring.hxx>
#include <sfx2/dllapi.h>
@@ -39,11 +41,12 @@ class SFX2_DLLPUBLIC SfxClassificationHelper
public:
/// Does the document have any BAILS properties?
- static bool IsClassified(SfxObjectShell& rObjectShell);
- /// Checks if pasting from rSource to rDestination would leak information.
- static SfxClassificationCheckPasteResult CheckPaste(SfxObjectShell& rSource, SfxObjectShell& rDestination);
+ static bool IsClassified(const css::uno::Reference<css::document::XDocumentProperties>& xDocumentProperties);
+ /// Checks if pasting from xSource to xDestination would leak information.
+ static SfxClassificationCheckPasteResult CheckPaste(const css::uno::Reference<css::document::XDocumentProperties>& xSource,
+ const css::uno::Reference<css::document::XDocumentProperties>& xDestination);
- SfxClassificationHelper(SfxObjectShell& rObjectShell);
+ SfxClassificationHelper(const css::uno::Reference<css::document::XDocumentProperties>& xDocumentProperties);
~SfxClassificationHelper();
const OUString& GetBACName();
/// Return all possible valid category names, based on the policy.
diff --git a/sc/source/ui/view/formatsh.cxx b/sc/source/ui/view/formatsh.cxx
index b4114b9..71434872 100644
--- a/sc/source/ui/view/formatsh.cxx
+++ b/sc/source/ui/view/formatsh.cxx
@@ -974,7 +974,7 @@ void ScFormatShell::ExecuteStyle( SfxRequest& rReq )
if (pArgs && pArgs->GetItemState(nSlotId, false, &pItem) == SfxItemState::SET)
{
const OUString& rName = static_cast<const SfxStringItem*>(pItem)->GetValue();
- SfxClassificationHelper aHelper(*pDocSh);
+ SfxClassificationHelper aHelper(pDocSh->getDocProperties());
aHelper.SetBACName(rName);
}
else
diff --git a/sd/source/ui/view/drviews2.cxx b/sd/source/ui/view/drviews2.cxx
index ab17cd6..e7d431c 100644
--- a/sd/source/ui/view/drviews2.cxx
+++ b/sd/source/ui/view/drviews2.cxx
@@ -1153,7 +1153,7 @@ void DrawViewShell::FuTemporary(SfxRequest& rReq)
{
if (SfxObjectShell* pObjectShell = pViewFrame->GetObjectShell())
{
- SfxClassificationHelper aHelper(*pObjectShell);
+ SfxClassificationHelper aHelper(pObjectShell->getDocProperties());
aHelper.SetBACName(rName);
}
}
diff --git a/sfx2/source/view/classificationcontroller.cxx b/sfx2/source/view/classificationcontroller.cxx
index 1dc8134..788eddf 100644
--- a/sfx2/source/view/classificationcontroller.cxx
+++ b/sfx2/source/view/classificationcontroller.cxx
@@ -164,7 +164,7 @@ void ClassificationCategoriesController::statusChanged(const frame::FeatureState
if (!pObjectShell)
return;
- SfxClassificationHelper aHelper(*pObjectShell);
+ SfxClassificationHelper aHelper(pObjectShell->getDocProperties());
if (m_pCategories->GetEntryCount() == 0)
{
std::vector<OUString> aNames = aHelper.GetBACNames();
diff --git a/sfx2/source/view/classificationhelper.cxx b/sfx2/source/view/classificationhelper.cxx
index 6950048..2abcff8 100644
--- a/sfx2/source/view/classificationhelper.cxx
+++ b/sfx2/source/view/classificationhelper.cxx
@@ -321,18 +321,18 @@ public:
SfxClassificationCategory m_aCategory;
/// Possible categories of a policy to choose from.
std::vector<SfxClassificationCategory> m_aCategories;
- SfxObjectShell& m_rObjectShell;
+ const uno::Reference<document::XDocumentProperties>& m_xDocumentProperties;
- Impl(SfxObjectShell& rObjectShell);
+ Impl(const uno::Reference<document::XDocumentProperties>& xDocumentProperties);
void parsePolicy();
- /// Synchronize m_aLabels back to the object shell.
- void pushToObjectShell();
+ /// Synchronize m_aLabels back to the document properties.
+ void pushToDocumentProperties();
/// Set the classification start date to the system time.
void setStartValidity();
};
-SfxClassificationHelper::Impl::Impl(SfxObjectShell& rObjectShell)
- : m_rObjectShell(rObjectShell)
+SfxClassificationHelper::Impl::Impl(const uno::Reference<document::XDocumentProperties>& xDocumentProperties)
+ : m_xDocumentProperties(xDocumentProperties)
{
}
@@ -384,10 +384,9 @@ void SfxClassificationHelper::Impl::setStartValidity()
}
}
-void SfxClassificationHelper::Impl::pushToObjectShell()
+void SfxClassificationHelper::Impl::pushToDocumentProperties()
{
- uno::Reference<document::XDocumentProperties> xDocumentProperties = m_rObjectShell.getDocProperties();
- uno::Reference<beans::XPropertyContainer> xPropertyContainer = xDocumentProperties->getUserDefinedProperties();
+ uno::Reference<beans::XPropertyContainer> xPropertyContainer = m_xDocumentProperties->getUserDefinedProperties();
uno::Reference<beans::XPropertySet> xPropertySet(xPropertyContainer, uno::UNO_QUERY);
uno::Sequence<beans::Property> aProperties = xPropertySet->getPropertySetInfo()->getProperties();
std::map<OUString, OUString> aLabels = m_aCategory.m_aLabels;
@@ -403,14 +402,13 @@ void SfxClassificationHelper::Impl::pushToObjectShell()
}
catch (const uno::Exception& rException)
{
- SAL_WARN("sfx.view", "pushToObjectShell() failed for property " << rLabel.first << ": " << rException.Message);
+ SAL_WARN("sfx.view", "pushDocumentProperties() failed for property " << rLabel.first << ": " << rException.Message);
}
}
}
-bool SfxClassificationHelper::IsClassified(SfxObjectShell& rObjectShell)
+bool SfxClassificationHelper::IsClassified(const uno::Reference<document::XDocumentProperties>& xDocumentProperties)
{
- uno::Reference<document::XDocumentProperties> xDocumentProperties = rObjectShell.getDocProperties();
uno::Reference<beans::XPropertyContainer> xPropertyContainer = xDocumentProperties->getUserDefinedProperties();
if (!xPropertyContainer.is())
return false;
@@ -426,15 +424,16 @@ bool SfxClassificationHelper::IsClassified(SfxObjectShell& rObjectShell)
return false;
}
-SfxClassificationCheckPasteResult SfxClassificationHelper::CheckPaste(SfxObjectShell& rSource, SfxObjectShell& rDestination)
+SfxClassificationCheckPasteResult SfxClassificationHelper::CheckPaste(const uno::Reference<document::XDocumentProperties>& xSource,
+ const uno::Reference<document::XDocumentProperties>& xDestination)
{
- bool bSourceClassified = SfxClassificationHelper::IsClassified(rSource);
+ bool bSourceClassified = SfxClassificationHelper::IsClassified(xSource);
if (!bSourceClassified)
// No classification on the source side. Return early, regardless the
// state of the destination side.
return SfxClassificationCheckPasteResult::None;
- bool bDestinationClassified = SfxClassificationHelper::IsClassified(rDestination);
+ bool bDestinationClassified = SfxClassificationHelper::IsClassified(xDestination);
if (bSourceClassified && !bDestinationClassified)
{
// Paste from a classified document to a non-classified one -> deny.
@@ -442,8 +441,8 @@ SfxClassificationCheckPasteResult SfxClassificationHelper::CheckPaste(SfxObjectS
}
// Remaining case: paste between two classified documents.
- SfxClassificationHelper aSource(rSource);
- SfxClassificationHelper aDestination(rDestination);
+ SfxClassificationHelper aSource(xSource);
+ SfxClassificationHelper aDestination(xDestination);
if (aSource.GetImpactScale() != aDestination.GetImpactScale())
// It's possible to compare them if they have the same scale.
return SfxClassificationCheckPasteResult::None;
@@ -455,10 +454,9 @@ SfxClassificationCheckPasteResult SfxClassificationHelper::CheckPaste(SfxObjectS
return SfxClassificationCheckPasteResult::None;
}
-SfxClassificationHelper::SfxClassificationHelper(SfxObjectShell& rObjectShell)
- : m_pImpl(o3tl::make_unique<Impl>(rObjectShell))
+SfxClassificationHelper::SfxClassificationHelper(const uno::Reference<document::XDocumentProperties>& xDocumentProperties)
+ : m_pImpl(o3tl::make_unique<Impl>(xDocumentProperties))
{
- uno::Reference<document::XDocumentProperties> xDocumentProperties = rObjectShell.getDocProperties();
uno::Reference<beans::XPropertyContainer> xPropertyContainer = xDocumentProperties->getUserDefinedProperties();
if (!xPropertyContainer.is())
return;
@@ -660,7 +658,7 @@ void SfxClassificationHelper::SetBACName(const OUString& rName)
m_pImpl->m_aCategory = *it;
m_pImpl->setStartValidity();
- m_pImpl->pushToObjectShell();
+ m_pImpl->pushToDocumentProperties();
SfxViewFrame* pViewFrame = SfxViewFrame::Current();
if (!pViewFrame)
return;
diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx
index bea3126..9775ff0 100644
--- a/sfx2/source/view/viewfrm.cxx
+++ b/sfx2/source/view/viewfrm.cxx
@@ -1343,10 +1343,10 @@ void SfxViewFrame::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
}
}
- if (SfxClassificationHelper::IsClassified(*xObjSh.get()))
+ if (SfxClassificationHelper::IsClassified(xObjSh->getDocProperties()))
{
// Document has BAILS properties, display an infobar accordingly.
- SfxClassificationHelper aHelper(*xObjSh.get());
+ SfxClassificationHelper aHelper(xObjSh->getDocProperties());
aHelper.UpdateInfobar(*this);
}
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index 69a7827..77e8069 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -3249,6 +3249,16 @@ void SwUiWriterTest::testTdf96961()
CPPUNIT_ASSERT(nLast > nOther);
}
+namespace
+{
+
+int checkShells(SwDocShell* pSource, SwDocShell* pDestination)
+{
+ return int(SfxClassificationHelper::CheckPaste(pSource->getDocProperties(), pDestination->getDocProperties()));
+}
+
+}
+
void SwUiWriterTest::testClassificationPaste()
{
SwDocShell* pSourceShell = createDoc()->GetDocShell();
@@ -3258,17 +3268,17 @@ void SwUiWriterTest::testClassificationPaste()
SwDocShell* pDestinationShell = createDoc()->GetDocShell();
// Not classified source, not classified destination.
- CPPUNIT_ASSERT_EQUAL(int(SfxClassificationCheckPasteResult::None), int(SfxClassificationHelper::CheckPaste(*pSourceShell, *pDestinationShell)));
+ CPPUNIT_ASSERT_EQUAL(int(SfxClassificationCheckPasteResult::None), checkShells(pSourceShell, pDestinationShell));
// Classified source, not classified destination.
uno::Sequence<beans::PropertyValue> aInternalOnly = comphelper::InitPropertySequence({{"Name", uno::makeAny(OUString("Internal Only"))}});
lcl_dispatchCommand(xSourceComponent, ".uno:ClassificationApply", aInternalOnly);
- CPPUNIT_ASSERT_EQUAL(int(SfxClassificationCheckPasteResult::TargetDocNotClassified), int(SfxClassificationHelper::CheckPaste(*pSourceShell, *pDestinationShell)));
+ CPPUNIT_ASSERT_EQUAL(int(SfxClassificationCheckPasteResult::TargetDocNotClassified), checkShells(pSourceShell, pDestinationShell));
// Classified source and classified destination -- internal only has a higher level than confidential.
uno::Sequence<beans::PropertyValue> aConfidential = comphelper::InitPropertySequence({{"Name", uno::makeAny(OUString("Confidential"))}});
lcl_dispatchCommand(mxComponent, ".uno:ClassificationApply", aConfidential);
- CPPUNIT_ASSERT_EQUAL(int(SfxClassificationCheckPasteResult::DocClassificationTooLow), int(SfxClassificationHelper::CheckPaste(*pSourceShell, *pDestinationShell)));
+ CPPUNIT_ASSERT_EQUAL(int(SfxClassificationCheckPasteResult::DocClassificationTooLow), checkShells(pSourceShell, pDestinationShell));
xSourceComponent->dispose();
}
diff --git a/sw/source/core/edit/edfcol.cxx b/sw/source/core/edit/edfcol.cxx
index c5cadf9..86b2883 100644
--- a/sw/source/core/edit/edfcol.cxx
+++ b/sw/source/core/edit/edfcol.cxx
@@ -177,7 +177,7 @@ void SwEditShell::SetClassification(const OUString& rName)
if (!pDocShell)
return;
- SfxClassificationHelper aHelper(*pDocShell);
+ SfxClassificationHelper aHelper(pDocShell->getDocProperties());
bool bHadWatermark = !aHelper.GetDocumentWatermark().isEmpty();
diff --git a/sw/source/uibase/dochdl/swdtflvr.cxx b/sw/source/uibase/dochdl/swdtflvr.cxx
index 0e2b838..6d47e8f 100644
--- a/sw/source/uibase/dochdl/swdtflvr.cxx
+++ b/sw/source/uibase/dochdl/swdtflvr.cxx
@@ -3226,7 +3226,7 @@ bool lcl_checkClassification(SwDoc* pSourceDoc, SwDoc* pDestinationDoc)
if (!pSourceShell || !pDestinationShell)
return true;
- switch (SfxClassificationHelper::CheckPaste(*pSourceShell, *pDestinationShell))
+ switch (SfxClassificationHelper::CheckPaste(pSourceShell->getDocProperties(), pDestinationShell->getDocProperties()))
{
case SfxClassificationCheckPasteResult::None:
{
commit b84f5a0efa4a24a3e8074bc27fb21529b9c4d3a6
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Thu Mar 10 08:23:37 2016 +0100
RTF import: set user-defined metadata only after parsing all of them
This helps setting all or no metadata in case an error would happen in
the middle of parsing metadata entries.
Change-Id: I349f53148627dd07f1304ebe00f0664bd23e26ea
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 6dd561b..6bea01f 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -8,6 +8,7 @@
*/
#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/document/DocumentProperties.hpp>
#include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
#include <com/sun/star/graphic/GraphicProvider.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
@@ -2056,6 +2057,9 @@ RTFError RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword)
case RTF_USERPROPS:
// Container of all user-defined properties.
m_aStates.top().eDestination = Destination::USERPROPS;
+ if (m_xDocumentProperties.is())
+ // Create a custom document properties to be able to process them later all at once.
+ m_xDocumentProperties = document::DocumentProperties::create(m_xContext);
break;
case RTF_PROPNAME:
m_aStates.top().eDestination = Destination::PROPNAME;
@@ -5924,20 +5928,48 @@ RTFError RTFDocumentImpl::popState()
if (m_aStates.top().aPropType == cppu::UnoType<OUString>::get())
aAny = uno::makeAny(aStaticVal);
- // Set it.
- try
- {
- if (lcl_containsProperty(aProperties, rKey))
- xPropertySet->setPropertyValue(rKey, aAny);
- else
- xPropertyContainer->addProperty(rKey, beans::PropertyAttribute::REMOVABLE, aAny);
- }
- catch (const uno::Exception& rException)
+ xPropertyContainer->addProperty(rKey, beans::PropertyAttribute::REMOVABLE, aAny);
+ }
+ break;
+ case Destination::USERPROPS:
+ {
+ // These are the imported properties.
+ uno::Reference<document::XDocumentProperties> xDocumentProperties = m_xDocumentProperties;
+
+ // These are the real document properties.
+ uno::Reference<document::XDocumentPropertiesSupplier> xDocumentPropertiesSupplier(m_xDstDoc, uno::UNO_QUERY);
+ if (xDocumentPropertiesSupplier.is())
+ m_xDocumentProperties.set(xDocumentPropertiesSupplier->getDocumentProperties(), uno::UNO_QUERY);
+
+ if (m_xDocumentProperties.is())
+ {
+ uno::Reference<beans::XPropertyContainer> xClipboardPropertyContainer = xDocumentProperties->getUserDefinedProperties();
+ uno::Reference<beans::XPropertyContainer> xDocumentPropertyContainer = m_xDocumentProperties->getUserDefinedProperties();
+ uno::Reference<beans::XPropertySet> xClipboardPropertySet(xClipboardPropertyContainer, uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xDocumentPropertySet(xDocumentPropertyContainer, uno::UNO_QUERY);
+ uno::Sequence<beans::Property> aClipboardProperties = xClipboardPropertySet->getPropertySetInfo()->getProperties();
+ uno::Sequence<beans::Property> aDocumentProperties = xDocumentPropertySet->getPropertySetInfo()->getProperties();
+
+ for (const beans::Property& rProperty : aClipboardProperties)
{
- SAL_WARN("writerfilter", "failed to set property " << rKey << ": " << rException.Message);
+ const OUString& rKey = rProperty.Name;
+ uno::Any aValue = xClipboardPropertySet->getPropertyValue(rKey);
+
+ try
+ {
+ if (lcl_containsProperty(aDocumentProperties, rKey))
+ xDocumentPropertySet->setPropertyValue(rKey, aValue);
+ else
+ xDocumentPropertyContainer->addProperty(rKey, beans::PropertyAttribute::REMOVABLE, aValue);
+ }
+ catch (const uno::Exception& rException)
+ {
+ SAL_WARN("writerfilter", "failed to set property " << rKey << ": " << rException.Message);
+ }
}
}
- break;
+ }
+ break;
default:
break;
}
commit 6a114b8ffaac52322c318d2dba543a2ad52cc892
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Thu Mar 10 08:18:41 2016 +0100
sw: make metadata available in copy result
The "copy" part of copy&paste works in sw by creating a separate SwDoc,
then copying the selection of the original SwDoc into it, so filters can
easily just export the whole clipboard document. A side effect of this
is that the clipboard document has no documnent shell, that would
contain the metadata.
Add a new member to MetaFieldManager that can store metadata in the
clipboard case, let SwTransferable::GetData() write metadata there, and
finally adapt the RTF export to look for metadata there as well.
Change-Id: Icfe32abca4290af8bf5b24a34160c43d4c87c04a
diff --git a/sw/inc/fmtmeta.hxx b/sw/inc/fmtmeta.hxx
index ab1ac82..eb276df 100644
--- a/sw/inc/fmtmeta.hxx
+++ b/sw/inc/fmtmeta.hxx
@@ -31,6 +31,9 @@
#include <vector>
namespace com { namespace sun { namespace star {
+ namespace document {
+ class XDocumentProperties;
+ }
namespace text {
class XTextField;
}
@@ -190,12 +193,14 @@ public:
};
/// knows all meta-fields in the document.
-class MetaFieldManager
+class SW_DLLPUBLIC MetaFieldManager
: private ::boost::noncopyable
{
private:
typedef ::std::vector< std::weak_ptr<MetaField> > MetaFieldList_t;
MetaFieldList_t m_MetaFields;
+ /// Document properties of a clipboard document, empty for non-clipboard documents.
+ css::uno::Reference<css::document::XDocumentProperties> m_xDocumentProperties;
public:
MetaFieldManager();
@@ -205,6 +210,9 @@ public:
const bool bIsFixedLanguage = false );
/// get all meta fields
::std::vector< css::uno::Reference<css::text::XTextField> > getMetaFields();
+ /// Copy document properties from rSource to m_xDocumentProperties.
+ void copyDocumentProperties(const SwDoc& rSource);
+ css::uno::Reference<css::document::XDocumentProperties> getDocumentProperties();
};
} // namespace sw
diff --git a/sw/source/core/txtnode/fmtatr2.cxx b/sw/source/core/txtnode/fmtatr2.cxx
index d709111..d4a4812 100644
--- a/sw/source/core/txtnode/fmtatr2.cxx
+++ b/sw/source/core/txtnode/fmtatr2.cxx
@@ -36,6 +36,8 @@
#include <unostyle.hxx>
#include <unoevent.hxx>
#include <com/sun/star/text/RubyAdjust.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/util/XCloneable.hpp>
#include <cmdid.h>
#include <com/sun/star/uno/Any.h>
@@ -827,6 +829,22 @@ MetaFieldManager::getMetaFields()
return ret;
}
+void MetaFieldManager::copyDocumentProperties(const SwDoc& rSource)
+{
+ const SwDocShell* pDocShell = rSource.GetDocShell();
+ if (!pDocShell)
+ return;
+
+ uno::Reference<document::XDocumentPropertiesSupplier> xDocumentPropertiesSupplier(pDocShell->GetModel(), uno::UNO_QUERY);
+ uno::Reference<util::XCloneable> xCloneable(xDocumentPropertiesSupplier->getDocumentProperties(), uno::UNO_QUERY);
+ m_xDocumentProperties.set(xCloneable->createClone(), uno::UNO_QUERY);
+}
+
+uno::Reference<document::XDocumentProperties> MetaFieldManager::getDocumentProperties()
+{
+ return m_xDocumentProperties;
+}
+
} // namespace sw
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/ww8/rtfexport.cxx b/sw/source/filter/ww8/rtfexport.cxx
index 2c3c88b..6ce1099 100644
--- a/sw/source/filter/ww8/rtfexport.cxx
+++ b/sw/source/filter/ww8/rtfexport.cxx
@@ -46,6 +46,7 @@
#endif
#include <svx/xflclit.hxx>
#include <editeng/hyphenzoneitem.hxx>
+#include <fmtmeta.hxx>
using namespace ::com::sun::star;
@@ -485,6 +486,12 @@ void RtfExport::WriteUserProps()
uno::Reference<document::XDocumentPropertiesSupplier> xDPS(pDocShell->GetModel(), uno::UNO_QUERY);
xDocProps.set(xDPS->getDocumentProperties());
}
+ else
+ {
+ // Clipboard document, read metadata from the meta field manager.
+ sw::MetaFieldManager& rManager = m_pDoc->GetMetaFieldManager();
+ xDocProps.set(rManager.getDocumentProperties());
+ }
if (xDocProps.is())
{
diff --git a/sw/source/uibase/dochdl/swdtflvr.cxx b/sw/source/uibase/dochdl/swdtflvr.cxx
index 76ffde6..0e2b838 100644
--- a/sw/source/uibase/dochdl/swdtflvr.cxx
+++ b/sw/source/uibase/dochdl/swdtflvr.cxx
@@ -123,6 +123,7 @@
#include <vcl/svapp.hxx>
#include <swserv.hxx>
#include <calbck.hxx>
+#include <fmtmeta.hxx>
#include <vcl/GraphicNativeTransform.hxx>
#include <vcl/GraphicNativeMetadata.hxx>
@@ -380,6 +381,8 @@ namespace
rDest.ReplaceStyles(rSrc, false);
rSrcWrtShell.Copy(&rDest);
+
+ rDest.GetMetaFieldManager().copyDocumentProperties(rSrc);
}
void lclCheckAndPerformRotation(Graphic& aGraphic)
More information about the Libreoffice-commits
mailing list