diff --git a/sfx2/source/view/classificationhelper.cxx b/sfx2/source/view/classificationhelper.cxx index e5748a61c3ab..82287da47171 100644 --- a/sfx2/source/view/classificationhelper.cxx +++ b/sfx2/source/view/classificationhelper.cxx @@ -548,6 +548,9 @@ bool SfxClassificationHelper::ShowPasteInfo(SfxClassificationCheckPasteResult eR SfxClassificationHelper::SfxClassificationHelper(const uno::Reference& xDocumentProperties, bool bUseLocalizedPolicy) : m_pImpl(o3tl::make_unique(xDocumentProperties, bUseLocalizedPolicy)) { + if (!xDocumentProperties.is()) + return; + uno::Reference xPropertyContainer = xDocumentProperties->getUserDefinedProperties(); if (!xPropertyContainer.is()) return; diff --git a/sw/source/core/edit/edfcol.cxx b/sw/source/core/edit/edfcol.cxx index ec84aec191a9..fc7ffcfa9b86 100644 --- a/sw/source/core/edit/edfcol.cxx +++ b/sw/source/core/edit/edfcol.cxx @@ -103,6 +103,8 @@ static const OUString ParagraphSignatureUsageRDFName = ":usage"; static const OUString ParagraphSignatureLastIdRDFName = "urn:bails:loext:paragraph:signature:lastid"; static const OUString ParagraphClassificationNameRDFName = "urn:bails:loext:paragraph:classification:name"; static const OUString ParagraphClassificationValueRDFName = "urn:bails:loext:paragraph:classification:value"; +static const OUString ParagraphClassificationAbbrRDFName = "urn:bails:loext:paragraph:classification:abbreviation"; +static const OUString ParagraphClassificationFieldNamesRDFName = "urn:bails:loext:paragraph:classification:fields"; static const OUString MetadataFieldServiceName = "com.sun.star.text.textfield.MetadataField"; static const OUString DocInfoServiceName = "com.sun.star.text.TextField.DocInfo.Custom"; @@ -277,11 +279,12 @@ std::pair lcl_getFieldRDFByPrefix(const uno::Reference lcl_getFieldRDF(const uno::Reference& xModel, - const uno::Reference& xField, - const OUString& sRDFName) +template +std::pair lcl_getRDF(const uno::Reference& xModel, + const T& xRef, + const OUString& sRDFName) { - const std::map aStatements = lcl_getRDFStatements(xModel, xField); + const std::map aStatements = lcl_getRDFStatements(xModel, xRef); const auto it = aStatements.find(sRDFName); return (it != aStatements.end()) ? std::make_pair(it->first, it->second) : std::make_pair(OUString(), OUString()); } @@ -291,7 +294,7 @@ std::pair lcl_getFieldRDF(const uno::Reference& xModel, const uno::Reference& xField) { - return (lcl_getFieldRDF(xModel, xField, ParagraphSignatureIdRDFName).first == ParagraphSignatureIdRDFName); + return (lcl_getRDF(xModel, xField, ParagraphSignatureIdRDFName).first == ParagraphSignatureIdRDFName); } uno::Reference lcl_findFieldByRDF(const uno::Reference& xModel, @@ -321,7 +324,7 @@ uno::Reference lcl_findFieldByRDF(const uno::Reference xField(xTextField, uno::UNO_QUERY); - std::pair pair = lcl_getFieldRDF(xModel, xField, sRDFName); + const std::pair pair = lcl_getRDF(xModel, xField, sRDFName); if (pair.first == sRDFName && (sRDFValue.isEmpty() || sRDFValue == pair.second)) return xField; } @@ -363,9 +366,8 @@ SignatureDescr lcl_getSignatureDescr(const uno::Reference& xModel const uno::Reference& xParagraph, const uno::Reference& xField) { - const std::map aStatements = lcl_getRDFStatements(xModel, xField); - const auto itId = aStatements.find(ParagraphSignatureIdRDFName); - return (itId != aStatements.end() ? lcl_getSignatureDescr(xModel, xParagraph, itId->second) : SignatureDescr()); + const std::pair pair = lcl_getRDF(xModel, xField, ParagraphSignatureIdRDFName); + return (!pair.second.isEmpty() ? lcl_getSignatureDescr(xModel, xParagraph, pair.second) : SignatureDescr()); } /// Validate and create the signature field display text from the fields. @@ -415,9 +417,8 @@ lcl_MakeParagraphSignatureFieldText(const uno::Reference& xModel, OUString lcl_getNextSignatureId(const uno::Reference& xModel, const uno::Reference& xParagraph) { - const std::map aStatements = lcl_getRDFStatements(xModel, xParagraph); - const auto it = aStatements.find(ParagraphSignatureLastIdRDFName); - return OUString::number(it != aStatements.end() ? it->second.toInt32() + 1 : 1); + const std::pair pair = lcl_getRDF(xModel, xParagraph, ParagraphSignatureLastIdRDFName); + return OUString::number(!pair.second.isEmpty() ? pair.second.toInt32() + 1 : 1); } @@ -510,7 +511,7 @@ bool lcl_IsParagraphClassificationField(const uno::Reference& xMo const uno::Reference& xField, const OUString& sKey = OUString()) { - const std::pair rdfPair = lcl_getFieldRDF(xModel, xField, ParagraphClassificationNameRDFName); + const std::pair rdfPair = lcl_getRDF(xModel, xField, ParagraphClassificationNameRDFName); return rdfPair.first == ParagraphClassificationNameRDFName && (sKey.isEmpty() || rdfPair.second == sKey); } @@ -601,8 +602,8 @@ void lcl_ValidateParagraphSignatures(SwDoc* pDoc, const uno::Reference aStatements = lcl_getRDFStatements(xModel, xParagraph); - if (aStatements.find(ParagraphSignatureLastIdRDFName) == aStatements.end()) + const std::pair pair = lcl_getRDF(xModel, xParagraph, ParagraphSignatureLastIdRDFName); + if (pair.second.isEmpty()) return; } catch (const ::css::uno::Exception&) @@ -1093,28 +1094,19 @@ void SwEditShell::SetClassification(const OUString& rName, SfxClassificationPoli } } -void SwEditShell::ApplyParagraphClassification(std::vector aResults) +void lcl_ApplyParagraphClassification(SwDoc* pDoc, + const uno::Reference& xModel, + const uno::Reference& xParent, + std::vector aResults) { - SwDocShell* pDocShell = GetDoc()->GetDocShell(); - if (!pDocShell || !GetCursor() || !GetCursor()->Start()) + css::uno::Reference xNodeSubject(xParent, uno::UNO_QUERY); + if (!xNodeSubject.is()) return; - SwTextNode* pNode = GetCursor()->Start()->nNode.GetNode().GetTextNode(); - if (pNode == nullptr) - return; - - uno::Reference xParent = SwXParagraph::CreateXParagraph(*pNode->GetDoc(), pNode); - uno::Reference xModel = pDocShell->GetBaseModel(); uno::Reference xMultiServiceFactory(xModel, uno::UNO_QUERY); sfx::ClassificationKeyCreator aKeyCreator(SfxClassificationHelper::getPolicyType()); - // Prevent recursive validation since this is triggered on node updates, which we do below. - const bool bOldValidationFlag = SetParagraphSignatureValidation(false); - comphelper::ScopeGuard const g([this, bOldValidationFlag] () { - SetParagraphSignatureValidation(bOldValidationFlag); - }); - // Remove all paragraph classification fields. for (;;) { @@ -1124,6 +1116,9 @@ void SwEditShell::ApplyParagraphClassification(std::vector aFieldNames; for (size_t nIndex = 0; nIndex < aResults.size(); ++nIndex) { const svx::ClassificationResult& rResult = aResults[nIndex]; @@ -1156,6 +1151,8 @@ void SwEditShell::ApplyParagraphClassification(std::vector aResults) +{ + SwDocShell* pDocShell = GetDoc()->GetDocShell(); + if (!pDocShell || !GetCursor() || !GetCursor()->Start()) + return; + + SwTextNode* pNode = GetCursor()->Start()->nNode.GetNode().GetTextNode(); + if (pNode == nullptr) + return; + + // Prevent recursive validation since this is triggered on node updates, which we do below. + const bool bOldValidationFlag = SetParagraphSignatureValidation(false); + comphelper::ScopeGuard const g([this, bOldValidationFlag]() { + SetParagraphSignatureValidation(bOldValidationFlag); + }); + + uno::Reference xModel = pDocShell->GetBaseModel(); + uno::Reference xParent = SwXParagraph::CreateXParagraph(*pNode->GetDoc(), pNode); + lcl_ApplyParagraphClassification(GetDoc(), xModel, xParent, aResults); } std::vector lcl_CollectParagraphClassification(const uno::Reference& xModel, const uno::Reference& xParagraph) @@ -1808,68 +1843,101 @@ void SwEditShell::RestoreMetadataFields() uno::Reference xParagraph(xParagraphs->nextElement(), uno::UNO_QUERY); std::map aSignatures; + std::vector aResults; - std::vector aResult; - - const sfx::ClassificationKeyCreator aKeyCreator(SfxClassificationHelper::getPolicyType()); - - const OUString sBlank(""); - for (const auto& pair : lcl_getRDFStatements(xModel, xParagraph)) + try { - const OUString aName = pair.first; - const OUString aValue = pair.second; + const sfx::ClassificationKeyCreator aKeyCreator(SfxClassificationHelper::getPolicyType()); + const OUString sBlank(""); - if (aKeyCreator.isMarkingTextKey(aName)) + const OUString sFieldNames = lcl_getRDF(xModel, xParagraph, ParagraphClassificationFieldNamesRDFName).second; + if (!sFieldNames.isEmpty()) { - aResult.push_back({ svx::ClassificationType::TEXT, aValue, sBlank, sBlank }); - } - else if (aKeyCreator.isCategoryNameKey(aName) || aKeyCreator.isCategoryIdentifierKey(aName)) - { - aResult.push_back({ svx::ClassificationType::CATEGORY, aValue, sBlank, sBlank }); - } - else if (aKeyCreator.isMarkingKey(aName)) - { - aResult.push_back({ svx::ClassificationType::MARKING, aValue, sBlank, sBlank }); - } - else if (aKeyCreator.isIntellectualPropertyPartKey(aName)) - { - // aResult.push_back({ svx::ClassificationType::INTELLECTUAL_PROPERTY_PART, xTextRange->getString(), sBlank, sBlank }); - } - else if (aName.startsWith(ParagraphSignatureRDFNamespace)) - { - OUString sSuffix = aName.copy(ParagraphSignatureRDFNamespace.getLength()); - sal_Int32 index = sSuffix.indexOf(":"); - if (index >= 0) + // Order the fields + sal_Int32 nIndex = 0; + do { - OUString id = sSuffix.copy(0, index); - OUString type = sSuffix.copy(index); - if (type == ParagraphSignatureDateRDFName) - aSignatures[id].msDate = aValue; - else if (type == ParagraphSignatureUsageRDFName) - aSignatures[id].msUsage = aValue; - else if (type == ParagraphSignatureDigestRDFName) - aSignatures[id].msSignature = aValue; + const OUString sCurFieldName = sFieldNames.getToken(0, '/', nIndex); + if (sCurFieldName.isEmpty()) + break; + std::pair fieldNameValue = lcl_getRDF(xModel, xParagraph, sCurFieldName); + const OUString sName = fieldNameValue.first; + const OUString sValue = fieldNameValue.second; + + if (aKeyCreator.isMarkingTextKey(sName)) + { + aResults.push_back({ svx::ClassificationType::TEXT, sValue, sValue, sBlank }); + } + else if (aKeyCreator.isCategoryNameKey(sName)) + { + const std::pair pairAbbr = lcl_getRDF(xModel, xParent, ParagraphClassificationAbbrRDFName); + const OUString sAbbreviatedName = (!pairAbbr.second.isEmpty() ? pairAbbr.second : sValue); + aResults.push_back({ svx::ClassificationType::CATEGORY, sValue, sAbbreviatedName, sBlank }); + } + else if (aKeyCreator.isCategoryIdentifierKey(sName)) + { + const std::pair pairAbbr = lcl_getRDF(xModel, xParent, ParagraphClassificationAbbrRDFName); + const OUString sAbbreviatedName = (!pairAbbr.second.isEmpty() ? pairAbbr.second : sValue); + aResults.push_back({ svx::ClassificationType::CATEGORY, sBlank, sAbbreviatedName, sValue }); + } + else if (aKeyCreator.isMarkingKey(sName)) + { + aResults.push_back({ svx::ClassificationType::MARKING, sValue, sValue, sBlank }); + } + else if (aKeyCreator.isIntellectualPropertyPartKey(sName)) + { + aResults.push_back({ svx::ClassificationType::INTELLECTUAL_PROPERTY_PART, sValue, sValue, sBlank }); + } + } + while (nIndex >= 0); + } + + lcl_ApplyParagraphClassification(GetDoc(), xModel, xParagraph, aResults); + + // Get Signatures + for (const auto& pair : lcl_getRDFStatements(xModel, xParagraph)) + { + const OUString sName = pair.first; + const OUString sValue = pair.second; + if (sName.startsWith(ParagraphSignatureRDFNamespace)) + { + OUString sSuffix = sName.copy(ParagraphSignatureRDFNamespace.getLength()); + sal_Int32 index = sSuffix.indexOf(":"); + if (index >= 0) + { + OUString id = sSuffix.copy(0, index); + OUString type = sSuffix.copy(index); + if (type == ParagraphSignatureDateRDFName) + aSignatures[id].msDate = sValue; + else if (type == ParagraphSignatureUsageRDFName) + aSignatures[id].msUsage = sValue; + else if (type == ParagraphSignatureDigestRDFName) + aSignatures[id].msSignature = sValue; + } + } + } + + for (const auto& pair : aSignatures) + { + uno::Reference xField = lcl_findFieldByRDF(xModel, xParagraph, ParagraphSignatureIdRDFName, pair.first); + if (!xField.is()) + { + uno::Reference xMultiServiceFactory(xModel, uno::UNO_QUERY); + xField = uno::Reference(xMultiServiceFactory->createInstance(MetadataFieldServiceName), uno::UNO_QUERY); + + // Add the signature at the end. + xField->attach(xParagraph->getAnchor()->getEnd()); + + const css::uno::Reference xFieldSubject(xField, uno::UNO_QUERY); + SwRDFHelper::addStatement(xModel, MetaNS, MetaFilename, xFieldSubject, ParagraphSignatureIdRDFName, pair.first); + + const OString utf8Text = lcl_getParagraphBodyText(xParagraph); + lcl_UpdateParagraphSignatureField(GetDoc(), xModel, xParagraph, xField, utf8Text); } } } - - for (const auto& pair : aSignatures) + catch (const std::exception&) { - uno::Reference xField = lcl_findFieldByRDF(xModel, xParagraph, ParagraphSignatureIdRDFName, pair.first); - if (!xField.is()) - { - uno::Reference xMultiServiceFactory(xModel, uno::UNO_QUERY); - xField = uno::Reference(xMultiServiceFactory->createInstance(MetadataFieldServiceName), uno::UNO_QUERY); - - // Add the signature at the end. - xField->attach(xParagraph->getAnchor()->getEnd()); - - const css::uno::Reference xFieldSubject(xField, uno::UNO_QUERY); - SwRDFHelper::addStatement(xModel, MetaNS, MetaFilename, xFieldSubject, ParagraphSignatureIdRDFName, pair.first); - - const OString utf8Text = lcl_getParagraphBodyText(xParagraph); - lcl_UpdateParagraphSignatureField(GetDoc(), xModel, xParagraph, xField, utf8Text); - } } } } @@ -1925,7 +1993,7 @@ OUString lcl_GetParagraphClassification(const uno::Reference& xMo if (xTextField.is()) { - const std::pair rdfValuePair = lcl_getFieldRDF(xModel, xTextField, ParagraphClassificationValueRDFName); + const std::pair rdfValuePair = lcl_getRDF(xModel, xTextField, ParagraphClassificationValueRDFName); return rdfValuePair.second; } diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx index 663036af6b70..9925dfbe24d8 100644 --- a/sw/source/filter/ww8/wrtw8nds.cxx +++ b/sw/source/filter/ww8/wrtw8nds.cxx @@ -701,8 +701,6 @@ bool SwWW8AttrIter::IsExportableAttr(sal_Int32 nSwPos) const return false; } } - else if (nSwPos > nEnd) - break; } }