[Libreoffice-commits] core.git: extras/source icon-themes/breeze icon-themes/galaxy include/sfx2 include/svx officecfg/registry sfx2/classification sfx2/source svx/Library_svx.mk svx/sdi svx/source svx/uiconfig svx/UIConfig_svx.mk sw/inc sw/sdi sw/source sw/uiconfig

Tomaž Vajngerl tomaz.vajngerl at collabora.co.uk
Thu Sep 21 07:49:42 UTC 2017


 extras/source/glade/libreoffice-catalog.xml.in                       |    6 
 icon-themes/breeze/links.txt                                         |    4 
 icon-themes/galaxy/links.txt                                         |    5 
 include/sfx2/classificationhelper.hxx                                |    7 
 include/svx/ClassificationDialog.hxx                                 |   63 +
 include/svx/ClassificationEditView.hxx                               |   67 ++
 include/svx/ClassificationField.hxx                                  |   67 ++
 include/svx/svxids.hrc                                               |    3 
 officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu |    5 
 sfx2/classification/baf.xsd                                          |   38 -
 sfx2/classification/baf_loext.xsd                                    |   19 
 sfx2/classification/example.xml                                      |    7 
 sfx2/classification/example_sl-SI.xml                                |    7 
 sfx2/source/view/classificationhelper.cxx                            |   53 +
 svx/Library_svx.mk                                                   |    2 
 svx/UIConfig_svx.mk                                                  |    1 
 svx/sdi/svx.sdi                                                      |   17 
 svx/source/dialog/ClassificationDialog.cxx                           |  263 ++++++++
 svx/source/dialog/ClassificationEditView.cxx                         |  172 +++++
 svx/uiconfig/ui/classificationdialog.ui                              |  321 ++++++++++
 sw/inc/editsh.hxx                                                    |    3 
 sw/sdi/_basesh.sdi                                                   |    7 
 sw/source/core/edit/edfcol.cxx                                       |  267 ++++++++
 sw/source/uibase/app/docsh2.cxx                                      |   15 
 sw/source/uibase/app/docst.cxx                                       |    3 
 sw/source/uibase/shells/basesh.cxx                                   |    5 
 sw/uiconfig/swriter/toolbar/classificationbar.xml                    |    1 
 27 files changed, 1388 insertions(+), 40 deletions(-)

New commits:
commit 71ee09947d5a71105d64fd225bb3672dfa7ce834
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Tue Sep 19 15:37:04 2017 +0200

    TSCP: add advanced classification dialog
    
    This adds a advanced classification dialog, which enables the user
    to manually construct a header/footer message from classification
    properties in cases where the user needs more control. All the
    text is inserted as fields into the end document and can be changed
    by changing the document properties. The simple classification
    still functions as it did before, which is what most users will
    want to use in this case.
    
    The BAF policy has been extended with new xml extension elements:
    - loext:Marking
    - loext:IntellectualPropertyPart
    - loext:IntellectualPropertyPartNumber
    
    They are used to fill the values in the advanced classification
    dialog.
    
    Change-Id: Ie2d638d69b8a9b0799cff9c2b785eb789f8af1d5
    Reviewed-on: https://gerrit.libreoffice.org/42474
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>
    Tested-by: Tomaž Vajngerl <quikee at gmail.com>

diff --git a/extras/source/glade/libreoffice-catalog.xml.in b/extras/source/glade/libreoffice-catalog.xml.in
index 73ef75c861af..8fb5d4c803c7 100644
--- a/extras/source/glade/libreoffice-catalog.xml.in
+++ b/extras/source/glade/libreoffice-catalog.xml.in
@@ -677,6 +677,10 @@
                         generic-name="Text View" parent="GtkTextView"
                         icon-name="widget-gtk-textentry"/>
 
+    <glade-widget-class title="Text View" name="svxlo-ClassificationEditView"
+                        generic-name="Text View" parent="GtkTextView"
+                        icon-name="widget-gtk-textentry"/>
+
     <glade-widget-class title="Combo Image Button" name="sclo-ScExtIButton"
                         generic-name="Combo Image Button" parent="GtkButton"
                         icon-name="widget-gtk-button"/>
@@ -684,7 +688,7 @@
     <glade-widget-class title="Open Document ListBox" name="dbulo-OpenDocumentListBox"
                         generic-name="Open Document ListBox" parent="GtkComboBox"
                         icon-name="widget-gtk-combobox"/>
-                        
+
     <glade-widget-class title="Fill Type ListBox" name="svxlo-SvxFillTypeBox"
                         generic-name="Fill Type ListBox" parent="GtkComboBox"
                         icon-name="widget-gtk-combobox"/>
diff --git a/icon-themes/breeze/links.txt b/icon-themes/breeze/links.txt
index 71f6d187af33..6a3a1218432b 100644
--- a/icon-themes/breeze/links.txt
+++ b/icon-themes/breeze/links.txt
@@ -889,6 +889,10 @@ cmd/sc_previousslide.png cmd/sc_prevrecord.png
 cmd/sc_nextslide.png cmd/sc_nextrecord.png
 cmd/sc_slidesetup.png cmd/sc_pagesetup.png
 
+# Classification
+cmd/lc_classificationdialog.png cmd/lc_formproperties.png
+cmd/sc_classificationdialog.png cmd/sc_formproperties.png
+
 # dbaccess
 # ==============================================
 dbaccess/res/linked_text_table.png cmd/sc_dataimport.png
diff --git a/icon-themes/galaxy/links.txt b/icon-themes/galaxy/links.txt
index a401ae66c0e0..bb6bacc26813 100644
--- a/icon-themes/galaxy/links.txt
+++ b/icon-themes/galaxy/links.txt
@@ -150,3 +150,8 @@ cmd/lc_rowoperations.png cmd/lc_entirerow.png
 cmd/sc_rowoperations.png cmd/sc_entirerow.png
 
 cmd/sc_cellprotection.png cmd/sc_protect.png
+
+# Classification
+
+cmd/lc_classificationdialog.png cmd/lc_formproperties.png
+cmd/sc_classificationdialog.png cmd/sc_formproperties.png
diff --git a/include/sfx2/classificationhelper.hxx b/include/sfx2/classificationhelper.hxx
index 3ad53c620259..7c39415c3315 100644
--- a/include/sfx2/classificationhelper.hxx
+++ b/include/sfx2/classificationhelper.hxx
@@ -57,7 +57,7 @@ public:
     /// Wrapper around CheckPaste(): informs the user if necessary and finds out if the paste can be continued or not.
     static bool ShowPasteInfo(SfxClassificationCheckPasteResult eResult);
 
-    SfxClassificationHelper(const css::uno::Reference<css::document::XDocumentProperties>& xDocumentProperties);
+    SfxClassificationHelper(const css::uno::Reference<css::document::XDocumentProperties>& xDocumentProperties, bool bUseLocalizedPolicy = true);
     ~SfxClassificationHelper();
     /// Get the currently selected category for eType.
     const OUString& GetBACName(SfxClassificationPolicyType eType);
@@ -78,6 +78,11 @@ public:
     /// The selected category has some content for the document footer.
     bool HasDocumentFooter();
     void UpdateInfobar(SfxViewFrame& rViewFrame);
+
+    const std::vector<OUString> GetMarkings();
+    const std::vector<OUString> GetIntellectualPropertyParts();
+    const std::vector<OUString> GetIntellectualPropertyPartNumbers();
+
     /// Does a best-effort conversion of rType to SfxClassificationPolicyType.
     static SfxClassificationPolicyType stringToPolicyType(const OUString& rType);
     /// Returns the string representation of a SfxClassificationPolicyType element.
diff --git a/include/svx/ClassificationDialog.hxx b/include/svx/ClassificationDialog.hxx
new file mode 100644
index 000000000000..c0612124df99
--- /dev/null
+++ b/include/svx/ClassificationDialog.hxx
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#ifndef INCLUDED_SVX_CLASSIFICATIONDIALOG_HXX
+#define INCLUDED_SVX_CLASSIFICATIONDIALOG_HXX
+
+#include <sal/config.h>
+#include <vcl/dialog.hxx>
+#include <vcl/button.hxx>
+#include <vcl/lstbox.hxx>
+#include <vcl/edit.hxx>
+#include <svx/svxdllapi.h>
+#include <svx/ClassificationEditView.hxx>
+#include <sfx2/classificationhelper.hxx>
+#include <svx/ClassificationField.hxx>
+
+namespace svx {
+
+class SVX_DLLPUBLIC ClassificationDialog : public ModalDialog
+{
+private:
+    VclPtr<ClassificationEditView> m_pEditWindow;
+    VclPtr<PushButton> m_pBoldButton;
+    VclPtr<ListBox> m_pClassificationListBox;
+    VclPtr<ListBox> m_pInternationalClassificationListBox;
+    VclPtr<ListBox> m_pMarkingListBox;
+    VclPtr<ListBox> m_pIntellectualPropertyPartListBox;
+    VclPtr<ListBox> m_pIntellectualPropertyPartNumberListBox;
+    VclPtr<PushButton> m_pIntellectualPropertyPartAddButton;
+    VclPtr<Edit> m_pIntellectualPropertyPartEdit;
+
+    SfxClassificationHelper maHelper;
+    SfxClassificationHelper maInternationalHelper;
+
+    DECL_LINK(ButtonClicked, Button*, void);
+    DECL_LINK(SelectClassificationHdl, ListBox&, void);
+    DECL_LINK(SelectMarkingHdl, ListBox&, void);
+    DECL_LINK(SelectIPPartNumbersHdl, ListBox&, void);
+    DECL_LINK(DoubleClickIPPartHdl, ListBox&, void);
+
+    void insertField(ClassificationType eType, OUString const & rString);
+
+public:
+    ClassificationDialog(vcl::Window* pParent);
+    virtual ~ClassificationDialog() override;
+    virtual void dispose() override;
+
+    std::vector<ClassificationResult> getResult();
+    void setupValues(std::vector<ClassificationResult> const & rInput);
+};
+
+} // end svx namespace
+
+#endif // INCLUDED_SVX_CLASSIFICATIONDIALOG_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/svx/ClassificationEditView.hxx b/include/svx/ClassificationEditView.hxx
new file mode 100644
index 000000000000..2231aa63eb48
--- /dev/null
+++ b/include/svx/ClassificationEditView.hxx
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#ifndef INCLUDED_SVX_CLASSIFICATIONEDITVIEW_HXX
+#define INCLUDED_SVX_CLASSIFICATIONEDITVIEW_HXX
+
+#include <sal/config.h>
+#include <svx/svxdllapi.h>
+#include <vcl/dialog.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/numitem.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
+
+namespace svx {
+
+class ClassificationEditEngine : public EditEngine
+{
+public:
+    ClassificationEditEngine(SfxItemPool* pItemPool);
+
+    virtual OUString CalcFieldValue(const SvxFieldItem& rField, sal_Int32 nPara, sal_Int32 nPos, Color*& rTxtColor, Color*& rFldColor) override;
+};
+
+class SVX_DLLPUBLIC ClassificationEditView : public Control
+{
+public:
+    ClassificationEditView(vcl::Window* pParent,  WinBits nBits);
+    virtual ~ClassificationEditView() override;
+
+    using Control::SetFont;
+    using Control::SetText;
+
+    void SetCharAttributes();
+
+    void InsertField(const SvxFieldItem& rField);
+
+    void InvertSelectionWeight();
+
+    void SetNumType(SvxNumType eNumType);
+
+    std::unique_ptr<ClassificationEditEngine> pEdEngine;
+    std::unique_ptr<EditView> pEdView;
+
+protected:
+    virtual void Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override;
+    virtual void MouseMove( const MouseEvent& rMEvt ) override;
+    virtual void MouseButtonDown( const MouseEvent& rMEvt ) override;
+    virtual void MouseButtonUp( const MouseEvent& rMEvt ) override;
+    virtual void KeyInput( const KeyEvent& rKEvt ) override;
+    virtual void Command( const CommandEvent& rCEvt ) override;
+    virtual void GetFocus() override;
+    virtual void Resize() override;
+};
+
+} // end svx namespace
+
+#endif // INCLUDED_SVX_CLASSIFICATIONEDITVIEW_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/svx/ClassificationField.hxx b/include/svx/ClassificationField.hxx
new file mode 100644
index 000000000000..53237dae1921
--- /dev/null
+++ b/include/svx/ClassificationField.hxx
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#ifndef INCLUDED_SVX_CLASSIFICATIONFIELD_HXX
+#define INCLUDED_SVX_CLASSIFICATIONFIELD_HXX
+
+#include <sal/config.h>
+#include <svx/svxdllapi.h>
+#include <editeng/flditem.hxx>
+
+namespace svx {
+
+enum class ClassificationType
+{
+    CATEGORY,
+    MARKING,
+    TEXT,
+    INTELLECTUAL_PROPERTY_PART
+};
+
+class SVX_DLLPUBLIC ClassificationField : public SvxFieldData
+{
+public:
+    ClassificationType meType;
+    OUString msDescription;
+
+    ClassificationField(ClassificationType eType, OUString const & sDescription)
+        : SvxFieldData()
+        , meType(eType)
+        , msDescription(sDescription)
+    {}
+
+    ClassificationField* Clone() const override
+    {
+        return new ClassificationField(meType, msDescription);
+    }
+
+    bool operator==(const SvxFieldData& rOther) const override
+    {
+        if (typeid(rOther) != typeid(*this))
+            return false;
+
+        const ClassificationField& rOtherField = static_cast<const ClassificationField&>(rOther);
+        return (meType == rOtherField.meType &&
+                msDescription == rOtherField.msDescription);
+    }
+};
+
+struct SVX_DLLPUBLIC ClassificationResult
+{
+    ClassificationType meType;
+    OUString msString;
+    sal_Int32 mnParagraph;
+};
+
+} // end svx namespace
+
+#endif // INCLUDED_SVX_CLASSIFICATIONFIELD_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/svx/svxids.hrc b/include/svx/svxids.hrc
index 157eb35431f1..6300b67b6b19 100644
--- a/include/svx/svxids.hrc
+++ b/include/svx/svxids.hrc
@@ -974,9 +974,10 @@
 #define SID_AUTHOR_COLOR                                ( SID_SVX_START + 1168 )
 #define SID_BMPMASK_COLOR                               ( SID_SVX_START + 1169 )
 #define SID_PARA_SIGNATURE_ADD                          ( SID_SVX_START + 1170 )
+#define SID_CLASSIFICATION_DIALOG                       ( SID_SVX_START + 1171 )
 
 // IMPORTANT NOTE: adjust SID_SVX_FIRSTFREE, when adding new slot id
-#define SID_SVX_FIRSTFREE                               ( SID_PARA_SIGNATURE_ADD + 1 )
+#define SID_SVX_FIRSTFREE                               ( SID_CLASSIFICATION_DIALOG + 1 )
 
 // Overflow check for slot IDs
 #if SID_SVX_FIRSTFREE > SID_SVX_END
diff --git a/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu b/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu
index 6e4ec8c1dd12..e1c3806b02e0 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu
@@ -6385,6 +6385,11 @@
           <value xml:lang="en-US">Apply Document Classification</value>
         </prop>
       </node>
+      <node oor:name=".uno:ClassificationDialog" oor:op="replace">
+        <prop oor:name="Label" oor:type="xs:string">
+          <value xml:lang="en-US">Classification Dialog</value>
+        </prop>
+      </node>
       <node oor:name=".uno:EditSelectMenu" oor:op="replace">
         <prop oor:name="Label" oor:type="xs:string">
           <value xml:lang="en-US">Select</value>
diff --git a/sfx2/classification/baf.xsd b/sfx2/classification/baf.xsd
index 778cfbec6036..a0bae6cc9ff1 100644
--- a/sfx2/classification/baf.xsd
+++ b/sfx2/classification/baf.xsd
@@ -1,10 +1,10 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xal="urn:oasis:names:tc:ciq:xal:3" xmlns:xnl="urn:oasis:names:tc:ciq:xnl:3" xmlns="urn:tscp:names:baf:1.1" targetNamespace="urn:tscp:names:baf:1.1">
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:xal="urn:oasis:names:tc:ciq:xal:3" xmlns:xnl="urn:oasis:names:tc:ciq:xnl:3" xmlns="urn:tscp:names:baf:1.1" targetNamespace="urn:tscp:names:baf:1.1">
   <xs:import namespace="urn:oasis:names:tc:ciq:xal:3" schemaLocation="xAL.xsd"/>
   <xs:import namespace="urn:oasis:names:tc:ciq:xnl:3" schemaLocation="xNL.xsd"/>
-  <!--
-Business Authorization
--->
+  <xs:import namespace="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" schemaLocation="baf_loext.xsd"/>
+
+  <!-- Business Authorization -->
   <xs:complexType name="BusinessAuthorization">
     <xs:sequence>
       <xs:element ref="PolicyAuthorityName"/>
@@ -31,6 +31,9 @@ Business Authorization
     <xs:complexType>
       <xs:sequence>
         <xs:element ref="BusinessAuthorizationCategory" maxOccurs="unbounded"/>
+        <xs:element ref="loext:Marking" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="loext:IntellectualPropertyPart" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="loext:IntellectualPropertyPartNumber" minOccurs="0" maxOccurs="unbounded"/>
       </xs:sequence>
     </xs:complexType>
   </xs:element>
@@ -38,6 +41,9 @@ Business Authorization
     <xs:complexType>
       <xs:sequence>
         <xs:element ref="BusinessAuthorizationCategory" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="loext:Marking" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="loext:IntellectualPropertyPart" minOccurs="0" maxOccurs="unbounded"/>
+        <xs:element ref="loext:IntellectualPropertyPartNumber" minOccurs="0" maxOccurs="unbounded"/>
       </xs:sequence>
     </xs:complexType>
   </xs:element>
@@ -51,24 +57,20 @@ Business Authorization
       <xs:restriction base="xs:date"/>
     </xs:simpleType>
   </xs:element>
-  <!--
-Business Authorization Category
--->
+  <!-- Business Authorization Category -->
   <xs:element name="BusinessAuthorizationCategory">
     <xs:complexType>
       <xs:sequence>
         <xs:element ref="AccessRules" minOccurs="0" maxOccurs="1"/>
         <xs:element ref="HandlingRules" minOccurs="0" maxOccurs="1"/>
-	<xs:element ref="LabelingRules"/>
-	<xs:element ref="ImpactLevel"/>
+        <xs:element ref="LabelingRules"/>
+        <xs:element ref="ImpactLevel"/>
       </xs:sequence>
       <xs:attribute name="Identifier" type="xs:anyURI" use="required"/>
       <xs:attribute name="Name" type="xs:string" use="optional"/>
     </xs:complexType>
   </xs:element>
-  <!--
-Impact Level
--->
+  <!-- Impact Level -->
   <xs:element name="ImpactLevel">
     <xs:complexType>
       <xs:sequence>
@@ -83,9 +85,7 @@ Impact Level
   <xs:element name="ConfidentalityValue" type="xs:string"/>
   <xs:element name="IntegrityValue" type="xs:string"/>
   <xs:element name="AvailabilityValue" type="xs:string"/>
-  <!--
-Handling Rule
--->
+  <!-- Handling Rule -->
   <xs:complexType name="HandlingRule" abstract="true"/>
   <xs:complexType name="SecureWEBTransmission">
     <xs:complexContent>
@@ -127,9 +127,7 @@ Handling Rule
       <xs:extension base="HandlingRule"/>
     </xs:complexContent>
   </xs:complexType>
-  <!--
-Labeling Rule
--->
+  <!-- Labeling Rule -->
   <xs:element name="VisualMarkingPart">
     <xs:complexType>
       <xs:sequence>
@@ -141,9 +139,7 @@ Labeling Rule
   </xs:element>
   <xs:element name="Identifier"/>
   <xs:element name="Value"/>
-  <!--
-Others
--->
+  <!-- Others -->
   <xs:element name="WorkEffortsScope">
     <xs:complexType>
       <xs:sequence>
diff --git a/sfx2/classification/baf_loext.xsd b/sfx2/classification/baf_loext.xsd
new file mode 100644
index 000000000000..593eb01173d5
--- /dev/null
+++ b/sfx2/classification/baf_loext.xsd
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" targetNamespace="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0">
+  <!-- Markings -->
+  <xs:element name="Marking">
+    <xs:complexType>
+      <xs:attribute name="Name" type="xs:string" use="optional"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="IntellectualPropertyPart">
+    <xs:complexType>
+      <xs:attribute name="Name" type="xs:string" use="optional"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="IntellectualPropertyPartNumber">
+    <xs:complexType>
+      <xs:attribute name="Name" type="xs:string" use="optional"/>
+    </xs:complexType>
+  </xs:element>
+</xs:schema>
diff --git a/sfx2/classification/example.xml b/sfx2/classification/example.xml
index f2647f903a8c..82098031ff91 100644
--- a/sfx2/classification/example.xml
+++ b/sfx2/classification/example.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<baf:BusinessAuthorization xmlns:baf="urn:tscp:names:baf:1.1">
+<baf:BusinessAuthorization xmlns:baf="urn:tscp:names:baf:1.1" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0">
     <!-- Translators: this string can be localized -->
     <baf:PolicyAuthorityName>TSCP Example Policy Authority</baf:PolicyAuthorityName>
     <!-- Translators: this string can be localized -->
@@ -78,6 +78,11 @@
                 <baf:ConfidentalityValue>3</baf:ConfidentalityValue>
             </baf:ImpactLevel>
         </baf:BusinessAuthorizationCategory>
+        <loext:Marking Name="Example Marking" />
+        <loext:IntellectualPropertyPart Name="Example First IP Part" />
+        <loext:IntellectualPropertyPart Name="Example Second IP Part" />
+        <loext:IntellectualPropertyPartNumber Name="1" />
+        <loext:IntellectualPropertyPartNumber Name="2" />
     </baf:Included>
 </baf:BusinessAuthorization>
 <!-- vim:set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/sfx2/classification/example_sl-SI.xml b/sfx2/classification/example_sl-SI.xml
index 1d1983679d83..99e04a7aab71 100644
--- a/sfx2/classification/example_sl-SI.xml
+++ b/sfx2/classification/example_sl-SI.xml
@@ -33,7 +33,7 @@
                 </baf:VisualMarkingPart>
                 <baf:VisualMarkingPart>
                     <baf:Identifier>Document: Footer</baf:Identifier>
-                    <baf:Value>Ta vsebina ima oznako zaupno. Ne razširjajte je zunaj brez  poslovne odobritve.</baf:Value>
+                    <baf:Value>Ta vsebina ima oznako zaupno. Ne razširjajte je zunaj brez poslovne odobritve.</baf:Value>
                 </baf:VisualMarkingPart>
                 <baf:VisualMarkingPart>
                     <baf:Identifier>Document: Watermark</baf:Identifier>
@@ -65,6 +65,11 @@
                 <baf:ConfidentalityValue>3</baf:ConfidentalityValue>
             </baf:ImpactLevel>
         </baf:BusinessAuthorizationCategory>
+        <loext:Marking Name="Primer oznake" />
+        <loext:IntellectualPropertyPart Name="Primer - del intelektualne lastnine ena" />
+        <loext:IntellectualPropertyPart Name="Primer - del intelektualne lastnine dve" />
+        <loext:IntellectualPropertyPartNumber Name="1" />
+        <loext:IntellectualPropertyPartNumber Name="2" />
     </baf:Included>
 </baf:BusinessAuthorization>
 <!-- vim:set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/sfx2/source/view/classificationhelper.cxx b/sfx2/source/view/classificationhelper.cxx
index 2fc02c79b80b..8a0574468c27 100644
--- a/sfx2/source/view/classificationhelper.cxx
+++ b/sfx2/source/view/classificationhelper.cxx
@@ -98,6 +98,9 @@ class SfxClassificationParser : public cppu::WeakImplHelper<xml::sax::XDocumentH
 {
 public:
     std::vector<SfxClassificationCategory> m_aCategories;
+    std::vector<OUString> m_aMarkings;
+    std::vector<OUString> m_aIPParts;
+    std::vector<OUString> m_aIPPartNumbers;
 
     OUString m_aPolicyAuthorityName;
     bool m_bInPolicyAuthorityName = false;
@@ -210,6 +213,21 @@ void SAL_CALL SfxClassificationParser::startElement(const OUString& rName, const
             m_pCategory = &rCategory;
         }
     }
+    else if (rName == "loext:Marking")
+    {
+        OUString aName = xAttribs->getValueByName("Name");
+        m_aMarkings.push_back(aName);
+    }
+    else if (rName == "loext:IntellectualPropertyPart")
+    {
+        OUString aName = xAttribs->getValueByName("Name");
+        m_aIPParts.push_back(aName);
+    }
+    else if (rName == "loext:IntellectualPropertyPartNumber")
+    {
+        OUString aName = xAttribs->getValueByName("Name");
+        m_aIPPartNumbers.push_back(aName);
+    }
     else if (rName == "baf:Scale")
     {
         m_aScale.clear();
@@ -319,9 +337,15 @@ public:
     std::map<SfxClassificationPolicyType, SfxClassificationCategory> m_aCategory;
     /// Possible categories of a policy to choose from.
     std::vector<SfxClassificationCategory> m_aCategories;
+    std::vector<OUString> m_aMarkings;
+    std::vector<OUString> m_aIPParts;
+    std::vector<OUString> m_aIPPartNumbers;
+
     uno::Reference<document::XDocumentProperties> m_xDocumentProperties;
 
-    explicit Impl(uno::Reference<document::XDocumentProperties> xDocumentProperties);
+    bool m_bUseLocalized;
+
+    explicit Impl(uno::Reference<document::XDocumentProperties> xDocumentProperties, bool bUseLocalized);
     void parsePolicy();
     /// Synchronize m_aLabels back to the document properties.
     void pushToDocumentProperties();
@@ -329,8 +353,9 @@ public:
     void setStartValidity(SfxClassificationPolicyType eType);
 };
 
-SfxClassificationHelper::Impl::Impl(uno::Reference<document::XDocumentProperties> xDocumentProperties)
+SfxClassificationHelper::Impl::Impl(uno::Reference<document::XDocumentProperties> xDocumentProperties, bool bUseLocalized)
     : m_xDocumentProperties(std::move(xDocumentProperties))
+    , m_bUseLocalized(bUseLocalized)
 {
 }
 
@@ -342,7 +367,7 @@ void SfxClassificationHelper::Impl::parsePolicy()
 
     // See if there is a localized variant next to the configured XML.
     OUString aExtension(".xml");
-    if (aPath.endsWith(aExtension))
+    if (aPath.endsWith(aExtension) && m_bUseLocalized)
     {
         OUString aBase = aPath.copy(0, aPath.getLength() - aExtension.getLength());
         const LanguageTag& rLanguageTag = Application::GetSettings().GetLanguageTag();
@@ -370,6 +395,9 @@ void SfxClassificationHelper::Impl::parsePolicy()
         SAL_WARN("sfx.view", "parsePolicy() failed: " << rException.Message);
     }
     m_aCategories = xClassificationParser->m_aCategories;
+    m_aMarkings = xClassificationParser->m_aMarkings;
+    m_aIPParts = xClassificationParser->m_aIPParts;
+    m_aIPPartNumbers = xClassificationParser->m_aIPPartNumbers;
 }
 
 bool lcl_containsProperty(const uno::Sequence<beans::Property>& rProperties, const OUString& rName)
@@ -503,8 +531,8 @@ bool SfxClassificationHelper::ShowPasteInfo(SfxClassificationCheckPasteResult eR
     return true;
 }
 
-SfxClassificationHelper::SfxClassificationHelper(const uno::Reference<document::XDocumentProperties>& xDocumentProperties)
-    : m_pImpl(o3tl::make_unique<Impl>(xDocumentProperties))
+SfxClassificationHelper::SfxClassificationHelper(const uno::Reference<document::XDocumentProperties>& xDocumentProperties, bool bUseLocalizedPolicy)
+    : m_pImpl(o3tl::make_unique<Impl>(xDocumentProperties, bUseLocalizedPolicy))
 {
     uno::Reference<beans::XPropertyContainer> xPropertyContainer = xDocumentProperties->getUserDefinedProperties();
     if (!xPropertyContainer.is())
@@ -537,6 +565,21 @@ SfxClassificationHelper::SfxClassificationHelper(const uno::Reference<document::
 
 SfxClassificationHelper::~SfxClassificationHelper() = default;
 
+const std::vector<OUString> SfxClassificationHelper::GetMarkings()
+{
+    return m_pImpl->m_aMarkings;
+}
+
+const std::vector<OUString> SfxClassificationHelper::GetIntellectualPropertyParts()
+{
+    return m_pImpl->m_aIPParts;
+}
+
+const std::vector<OUString> SfxClassificationHelper::GetIntellectualPropertyPartNumbers()
+{
+    return m_pImpl->m_aIPPartNumbers;
+}
+
 const OUString& SfxClassificationHelper::GetBACName(SfxClassificationPolicyType eType)
 {
     return m_pImpl->m_aCategory[eType].m_aName;
diff --git a/svx/Library_svx.mk b/svx/Library_svx.mk
index b24478828ff2..c04dfc8e6dc4 100644
--- a/svx/Library_svx.mk
+++ b/svx/Library_svx.mk
@@ -117,6 +117,8 @@ $(eval $(call gb_Library_add_exception_objects,svx,\
 		svx/source/dialog/crashreportdlg \
 		svx/source/dialog/crashreportui) \
     svx/source/dialog/ctredlin \
+    svx/source/dialog/ClassificationDialog \
+    svx/source/dialog/ClassificationEditView \
     svx/source/dialog/databaseregistrationui \
     svx/source/dialog/dialcontrol \
     svx/source/dialog/dlgctl3d \
diff --git a/svx/UIConfig_svx.mk b/svx/UIConfig_svx.mk
index d836697afe8b..831e1d20a27c 100644
--- a/svx/UIConfig_svx.mk
+++ b/svx/UIConfig_svx.mk
@@ -21,6 +21,7 @@ $(eval $(call gb_UIConfig_add_uifiles,svx,\
 	svx/uiconfig/ui/cellmenu \
 	svx/uiconfig/ui/chineseconversiondialog \
 	svx/uiconfig/ui/chinesedictionary \
+	svx/uiconfig/ui/classificationdialog \
 	svx/uiconfig/ui/colorwindow \
 	svx/uiconfig/ui/colsmenu \
 	svx/uiconfig/ui/compressgraphicdialog \
diff --git a/svx/sdi/svx.sdi b/svx/sdi/svx.sdi
index ead2a6047ef3..e0f3e4d378b0 100644
--- a/svx/sdi/svx.sdi
+++ b/svx/sdi/svx.sdi
@@ -4373,6 +4373,23 @@ SfxVoidItem CompressGraphic SID_COMPRESS_GRAPHIC
     GroupId = SfxGroupId::Modify;
 ]
 
+SfxVoidItem ClassificationDialog SID_CLASSIFICATION_DIALOG
+()
+[
+    AutoUpdate = TRUE,
+    FastCall = TRUE,
+    ReadOnlyDoc = FALSE,
+    Toggle = FALSE,
+    Container = FALSE,
+    RecordAbsolute = FALSE,
+    RecordPerSet;
+    Asynchron;
+
+    AccelConfig = TRUE,
+    MenuConfig = TRUE,
+    ToolBoxConfig = TRUE,
+    GroupId = SfxGroupId::Document;
+]
 
 SfxBoolItem Init3D SID_3D_INIT
 
diff --git a/svx/source/dialog/ClassificationDialog.cxx b/svx/source/dialog/ClassificationDialog.cxx
new file mode 100644
index 000000000000..e827ebc1d112
--- /dev/null
+++ b/svx/source/dialog/ClassificationDialog.cxx
@@ -0,0 +1,263 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#include <svx/ClassificationDialog.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/section.hxx>
+#include <editeng/editobj.hxx>
+#include <svl/itemset.hxx>
+
+namespace svx {
+
+namespace {
+
+const SvxFieldItem* findField(editeng::Section const & rSection)
+{
+    for (SfxPoolItem const * pPool: rSection.maAttributes)
+    {
+        if (pPool->Which() == EE_FEATURE_FIELD)
+            return static_cast<const SvxFieldItem*>(pPool);
+    }
+    return nullptr;
+}
+
+} // end anonymous namespace
+
+ClassificationDialog::ClassificationDialog(vcl::Window* pParent)
+    : ModalDialog(pParent, "AdvancedDocumentClassificationDialog", "svx/ui/classificationdialog.ui")
+    , maHelper(SfxObjectShell::Current()->getDocProperties())
+    , maInternationalHelper(SfxObjectShell::Current()->getDocProperties(), /*bUseLocalizedPolicy*/ false)
+{
+    get(m_pEditWindow, "classificationEditWindow");
+    get(m_pBoldButton, "boldButton");
+    get(m_pClassificationListBox, "classificationCB");
+    get(m_pInternationalClassificationListBox, "internationalClassificationCB");
+    get(m_pMarkingListBox, "markingCB");
+    get(m_pIntellectualPropertyPartNumberListBox, "intellectualPropertyPartNumberCB");
+    get(m_pIntellectualPropertyPartListBox, "intellectualPropertyPartLB");
+    get(m_pIntellectualPropertyPartAddButton, "intellectualPropertyPartAddButton");
+    get(m_pIntellectualPropertyPartEdit, "intellectualPropertyPartEntry");
+
+    m_pBoldButton->SetClickHdl(LINK(this, ClassificationDialog, ButtonClicked));
+    m_pIntellectualPropertyPartAddButton->SetClickHdl(LINK(this, ClassificationDialog, ButtonClicked));
+
+    m_pClassificationListBox->SetSelectHdl(LINK(this, ClassificationDialog, SelectClassificationHdl));
+    for (const OUString& rName : maHelper.GetBACNames())
+        m_pClassificationListBox->InsertEntry(rName);
+    m_pClassificationListBox->EnableAutoSize(true);
+
+    m_pInternationalClassificationListBox->SetSelectHdl(LINK(this, ClassificationDialog, SelectClassificationHdl));
+    for (const OUString& rName : maInternationalHelper.GetBACNames())
+        m_pInternationalClassificationListBox->InsertEntry(rName);
+    m_pInternationalClassificationListBox->EnableAutoSize(true);
+
+    m_pMarkingListBox->SetSelectHdl(LINK(this, ClassificationDialog, SelectMarkingHdl));
+    for (const OUString& rName : maHelper.GetMarkings())
+        m_pMarkingListBox->InsertEntry(rName);
+    m_pMarkingListBox->EnableAutoSize(true);
+
+    m_pIntellectualPropertyPartNumberListBox->SetSelectHdl(LINK(this, ClassificationDialog, SelectIPPartNumbersHdl));
+    for (const OUString& rName : maHelper.GetIntellectualPropertyPartNumbers())
+        m_pIntellectualPropertyPartNumberListBox->InsertEntry(rName);
+    m_pIntellectualPropertyPartNumberListBox->EnableAutoSize(true);
+
+    m_pIntellectualPropertyPartListBox->SetDoubleClickHdl(LINK(this, ClassificationDialog, DoubleClickIPPartHdl));
+    for (const OUString& rName : maHelper.GetIntellectualPropertyParts())
+        m_pIntellectualPropertyPartListBox->InsertEntry(rName);
+    m_pIntellectualPropertyPartListBox->EnableAutoSize(true);
+}
+
+ClassificationDialog::~ClassificationDialog()
+{
+    disposeOnce();
+}
+
+void ClassificationDialog::dispose()
+{
+    m_pEditWindow.clear();
+    m_pBoldButton.clear();
+    m_pClassificationListBox.clear();
+    m_pInternationalClassificationListBox.clear();
+    m_pMarkingListBox.clear();
+    m_pIntellectualPropertyPartListBox.clear();
+    m_pIntellectualPropertyPartNumberListBox.clear();
+    m_pIntellectualPropertyPartAddButton.clear();
+    m_pIntellectualPropertyPartEdit.clear();
+
+    ModalDialog::dispose();
+}
+
+void ClassificationDialog::insertField(ClassificationType eType, OUString const & rString)
+{
+    ClassificationField aField(eType, rString);
+    m_pEditWindow->InsertField(SvxFieldItem(aField, EE_FEATURE_FIELD));
+}
+
+void ClassificationDialog::setupValues(std::vector<ClassificationResult> const & rInput)
+{
+    for (ClassificationResult const & rClassificationResult : rInput)
+    {
+        switch (rClassificationResult.meType)
+        {
+            case svx::ClassificationType::TEXT:
+            {
+                m_pEditWindow->pEdView->InsertText(rClassificationResult.msString);
+            }
+            break;
+
+            case svx::ClassificationType::CATEGORY:
+            {
+                m_pClassificationListBox->SelectEntry(rClassificationResult.msString);
+                m_pInternationalClassificationListBox->SelectEntryPos(m_pClassificationListBox->GetSelectEntryPos());
+                insertField(rClassificationResult.meType, rClassificationResult.msString);
+            }
+            break;
+
+            case svx::ClassificationType::MARKING:
+            {
+                m_pMarkingListBox->SelectEntry(rClassificationResult.msString);
+                insertField(rClassificationResult.meType, rClassificationResult.msString);
+            }
+            break;
+
+            case svx::ClassificationType::INTELLECTUAL_PROPERTY_PART:
+            {
+                insertField(rClassificationResult.meType, rClassificationResult.msString);
+            }
+            break;
+
+            default:
+            break;
+        }
+    }
+}
+
+std::vector<ClassificationResult> ClassificationDialog::getResult()
+{
+    std::vector<ClassificationResult> aClassificationResults;
+
+    std::unique_ptr<EditTextObject> pEditText(m_pEditWindow->pEdEngine->CreateTextObject());
+
+    std::vector<editeng::Section> aSections;
+    pEditText->GetAllSections(aSections);
+
+    for (editeng::Section const & rSection : aSections)
+    {
+        const SvxFieldItem* pFieldItem = findField(rSection);
+
+        ESelection aSelection(rSection.mnParagraph, rSection.mnStart, rSection.mnParagraph, rSection.mnEnd);
+        OUString sString = m_pEditWindow->pEdEngine->GetText(aSelection);
+
+        if (pFieldItem)
+        {
+            const ClassificationField* pClassificationField = dynamic_cast<const ClassificationField*>(pFieldItem->GetField());
+            aClassificationResults.push_back({ pClassificationField->meType , sString, rSection.mnParagraph });
+        }
+        else
+        {
+            aClassificationResults.push_back({ ClassificationType::TEXT, sString, rSection.mnParagraph });
+        }
+    }
+    return aClassificationResults;
+}
+
+IMPL_LINK(ClassificationDialog, SelectClassificationHdl, ListBox&, rBox, void)
+{
+    sal_Int32 nSelected = rBox.GetSelectEntryPos();
+    if (nSelected >= 0)
+    {
+        std::unique_ptr<EditTextObject> pEditText(m_pEditWindow->pEdEngine->CreateTextObject());
+        std::vector<editeng::Section> aSections;
+        pEditText->GetAllSections(aSections);
+
+        for (editeng::Section const & rSection : aSections)
+        {
+            const SvxFieldItem* pFieldItem = findField(rSection);
+            if (pFieldItem)
+            {
+                const ClassificationField* pClassificationField = dynamic_cast<const ClassificationField*>(pFieldItem->GetField());
+                if (pClassificationField && pClassificationField->meType == ClassificationType::CATEGORY)
+                {
+                    m_pEditWindow->pEdView->SetSelection(ESelection(rSection.mnParagraph, rSection.mnStart, rSection.mnParagraph, rSection.mnEnd));
+                }
+            }
+        }
+
+        OUString aString = maHelper.GetBACNames()[nSelected];
+        insertField(ClassificationType::CATEGORY, aString);
+
+        m_pInternationalClassificationListBox->SelectEntryPos(nSelected);
+        m_pClassificationListBox->SelectEntryPos(nSelected);
+    }
+}
+
+IMPL_LINK(ClassificationDialog, SelectMarkingHdl, ListBox&, rBox, void)
+{
+    sal_Int32 nSelected = rBox.GetSelectEntryPos();
+    if (nSelected >= 0)
+    {
+        std::unique_ptr<EditTextObject> pEditText(m_pEditWindow->pEdEngine->CreateTextObject());
+        std::vector<editeng::Section> aSections;
+        pEditText->GetAllSections(aSections);
+
+        for (editeng::Section const & rSection : aSections)
+        {
+            const SvxFieldItem* pFieldItem = findField(rSection);
+            if (pFieldItem)
+            {
+                const ClassificationField* pClassificationField = dynamic_cast<const ClassificationField*>(pFieldItem->GetField());
+                if (pClassificationField && pClassificationField->meType == ClassificationType::MARKING)
+                {
+                    m_pEditWindow->pEdView->SetSelection(ESelection(rSection.mnParagraph, rSection.mnStart, rSection.mnParagraph, rSection.mnEnd));
+                }
+            }
+        }
+
+        OUString aString = maHelper.GetMarkings()[nSelected];
+        insertField(ClassificationType::MARKING, aString);
+    }
+}
+
+IMPL_LINK(ClassificationDialog, SelectIPPartNumbersHdl, ListBox&, rBox, void)
+{
+    sal_Int32 nSelected = rBox.GetSelectEntryPos();
+    if (nSelected >= 0)
+    {
+        OUString sString = maHelper.GetIntellectualPropertyPartNumbers()[nSelected];
+        m_pIntellectualPropertyPartEdit->SetText(m_pIntellectualPropertyPartEdit->GetText() + sString);
+    }
+}
+
+IMPL_LINK(ClassificationDialog, DoubleClickIPPartHdl, ListBox&, rBox, void)
+{
+    sal_Int32 nSelected = rBox.GetSelectEntryPos();
+    if (nSelected >= 0)
+    {
+        OUString sString = maHelper.GetIntellectualPropertyParts()[nSelected];
+        m_pIntellectualPropertyPartEdit->SetText(m_pIntellectualPropertyPartEdit->GetText() + sString);
+    }
+}
+
+IMPL_LINK(ClassificationDialog, ButtonClicked, Button*, pButton, void)
+{
+    if (pButton == m_pBoldButton)
+    {
+        m_pEditWindow->InvertSelectionWeight();
+    }
+    else if (pButton == m_pIntellectualPropertyPartAddButton)
+    {
+        insertField(ClassificationType::INTELLECTUAL_PROPERTY_PART, m_pIntellectualPropertyPartEdit->GetText());
+    }
+}
+
+} // end sfx2
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/dialog/ClassificationEditView.cxx b/svx/source/dialog/ClassificationEditView.cxx
new file mode 100644
index 000000000000..bfb0a159dccc
--- /dev/null
+++ b/svx/source/dialog/ClassificationEditView.cxx
@@ -0,0 +1,172 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#include <svx/ClassificationEditView.hxx>
+#include <svx/ClassificationField.hxx>
+
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <svl/itemset.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/eeitem.hxx>
+
+extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL makeClassificationEditView(VclPtr<vcl::Window> & rRet, VclPtr<vcl::Window> & pParent, VclBuilder::stringmap &)
+{
+    rRet = VclPtr<svx::ClassificationEditView>::Create(pParent, WB_BORDER|WB_TABSTOP);
+}
+
+namespace svx {
+
+ClassificationEditEngine::ClassificationEditEngine(SfxItemPool* pItemPool)
+    : EditEngine(pItemPool)
+{}
+
+OUString ClassificationEditEngine::CalcFieldValue(const SvxFieldItem& rField, sal_Int32 /*nPara*/,
+                                                  sal_Int32 /*nPos*/, Color*& /*rTxtColor*/, Color*& /*rFldColor*/)
+{
+    OUString aString;
+    const ClassificationField* pClassificationField = dynamic_cast<const ClassificationField*>(rField.GetField());
+    if (pClassificationField)
+        aString = pClassificationField->msDescription;
+    else
+        aString = "Unknown";
+    return aString;
+}
+
+ClassificationEditView::ClassificationEditView(vcl::Window* pParent, WinBits nBits)
+    : Control(pParent, nBits)
+{
+    EnableRTL(false);
+
+    const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+    Color aBgColor = rStyleSettings.GetWindowColor();
+
+    SetMapMode(MapUnit::MapTwip);
+    SetPointer(PointerStyle::Text);
+    SetBackground(aBgColor);
+
+    Size aSize(GetOutputSize());
+    aSize.Height() *= 4;
+
+    pEdEngine.reset(new ClassificationEditEngine(EditEngine::CreatePool()));
+    pEdEngine->SetPaperSize( aSize );
+    pEdEngine->SetRefDevice( this );
+
+    pEdEngine->SetControlWord(pEdEngine->GetControlWord() | EEControlBits::MARKFIELDS);
+
+    pEdView.reset(new EditView(pEdEngine.get(), this));
+    pEdView->SetOutputArea(tools::Rectangle(Point(0,0), GetOutputSize()));
+
+    pEdView->SetBackgroundColor(aBgColor);
+    pEdEngine->InsertView(pEdView.get());
+}
+
+ClassificationEditView::~ClassificationEditView()
+{
+    disposeOnce();
+}
+
+void ClassificationEditView::Resize()
+{
+    Size aOutputSize(GetOutputSize());
+    Size aSize(aOutputSize);
+    aSize.Height() *= 4;
+    pEdEngine->SetPaperSize(aSize);
+    pEdView->SetOutputArea(tools::Rectangle(Point(0,0), aOutputSize));
+    Control::Resize();
+}
+
+void ClassificationEditView::InsertField(const SvxFieldItem& rFieldItem)
+{
+    pEdView->InsertField(rFieldItem);
+    pEdView->Invalidate();
+}
+
+void ClassificationEditView::InvertSelectionWeight()
+{
+    std::unique_ptr<SfxItemSet> pSet(new SfxItemSet(pEdEngine->GetAttribs(pEdView->GetSelection())));
+    FontWeight eFontWeight = WEIGHT_BOLD;
+    if (const SfxPoolItem* pItem = pSet->GetItem(EE_CHAR_WEIGHT, true))
+    {
+        const SvxWeightItem* pWeightItem = dynamic_cast<const SvxWeightItem*>(pItem);
+        if (pWeightItem && pWeightItem->GetWeight() == WEIGHT_BOLD)
+            eFontWeight = WEIGHT_NORMAL;
+    }
+
+    SvxWeightItem aWeight(eFontWeight, EE_CHAR_WEIGHT);
+    pSet->Put(aWeight);
+    pEdEngine->QuickSetAttribs(*pSet, pEdView->GetSelection());
+    pEdView->Invalidate();
+}
+
+void ClassificationEditView::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
+{
+    const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+    Color aBgColor = rStyleSettings.GetWindowColor();
+
+    pEdView->SetBackgroundColor(aBgColor);
+
+    SetBackground(aBgColor);
+
+    Control::Paint(rRenderContext, rRect);
+
+    pEdView->Paint(rRect);
+
+    if (HasFocus())
+        pEdView->ShowCursor();
+}
+
+void ClassificationEditView::MouseMove(const MouseEvent& rMEvt)
+{
+    pEdView->MouseMove(rMEvt);
+}
+
+void ClassificationEditView::MouseButtonDown(const MouseEvent& rMEvt)
+{
+    if (!HasFocus())
+        GrabFocus();
+
+    pEdView->MouseButtonDown(rMEvt);
+}
+
+void ClassificationEditView::MouseButtonUp(const MouseEvent& rMEvt)
+{
+    pEdView->MouseButtonUp(rMEvt);
+}
+
+void ClassificationEditView::KeyInput(const KeyEvent& rKEvt)
+{
+    sal_uInt16 nKey =  rKEvt.GetKeyCode().GetModifier() + rKEvt.GetKeyCode().GetCode();
+
+    if (nKey == KEY_TAB || nKey == KEY_TAB + KEY_SHIFT)
+    {
+        Control::KeyInput( rKEvt );
+    }
+    else if (!pEdView->PostKeyEvent(rKEvt))
+    {
+        Control::KeyInput(rKEvt);
+    }
+}
+
+void ClassificationEditView::Command(const CommandEvent& rCEvt)
+{
+    pEdView->Command(rCEvt);
+}
+
+void ClassificationEditView::GetFocus()
+{
+    pEdView->ShowCursor();
+
+    Control::GetFocus();
+}
+
+} // end sfx2
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/uiconfig/ui/classificationdialog.ui b/svx/uiconfig/ui/classificationdialog.ui
new file mode 100644
index 000000000000..02d2afdb644b
--- /dev/null
+++ b/svx/uiconfig/ui/classificationdialog.ui
@@ -0,0 +1,321 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 -->
+<interface domain="sfx">
+  <requires lib="gtk+" version="3.0"/>
+  <requires lib="LibreOffice" version="1.0"/>
+  <object class="GtkDialog" id="AdvancedDocumentClassificationDialog">
+    <property name="can_focus">False</property>
+    <property name="border_width">6</property>
+    <property name="title" translatable="yes" context="classificationdialog|dialogname">Classification Dialog</property>
+    <property name="type_hint">dialog</property>
+    <child internal-child="vbox">
+      <object class="GtkBox" id="dialog-vbox1">
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">12</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action_area1">
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="ok">
+                <property name="label">gtk-ok</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="cancel">
+                <property name="label">gtk-cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="help">
+                <property name="label">gtk-help</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">2</property>
+                <property name="secondary">True</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkGrid">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="row_spacing">12</property>
+            <property name="column_spacing">12</property>
+            <child>
+              <object class="svxlo-ClassificationEditView" id="classificationEditWindow">
+                <property name="width_request">400</property>
+                <property name="height_request">400</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="hexpand">True</property>
+                <property name="vexpand">True</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes" context="classificationdialog|label-Content">Content</property>
+                <property name="xalign">0</property>
+                <property name="yalign">0</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkGrid">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="row_spacing">12</property>
+                <property name="column_spacing">12</property>
+                <child>
+                  <object class="GtkLabel">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes" context="classificationdialog|label-Classification">Classification:</property>
+                    <property name="xalign">0</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes" context="classificationdialog|label-InternationalClassification">International Classification:</property>
+                    <property name="xalign">0</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkComboBoxText" id="classificationCB">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="hexpand">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkComboBoxText" id="internationalClassificationCB">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkComboBoxText" id="markingCB">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes" context="classificationdialog|label-Marking">Marking:</property>
+                    <property name="xalign">0</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="valign">end</property>
+                    <property name="vexpand">True</property>
+                    <property name="spacing">6</property>
+                    <property name="homogeneous">True</property>
+                    <child>
+                      <object class="GtkButton" id="boldButton">
+                        <property name="label" context="classificationdialog|boldButton" translatable="yes">Bold</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">3</property>
+                    <property name="width">2</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">0</property>
+                <property name="height">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkExpander">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <child>
+                  <object class="GtkGrid">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="row_spacing">6</property>
+                    <property name="column_spacing">6</property>
+                    <child>
+                      <object class="GtkComboBoxText" id="intellectualPropertyPartNumberCB">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="active">0</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">2</property>
+                        <property name="top_attach">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes" context="classificationdialog|label-PartNumber">Part Number:</property>
+                        <property name="xalign">0</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="intellectualPropertyPartEntry">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">2</property>
+                        <property name="width">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkTreeView" id="intellectualPropertyPartLB">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="hexpand">True</property>
+                        <property name="vexpand">True</property>
+                        <child internal-child="selection">
+                          <object class="GtkTreeSelection"/>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">0</property>
+                        <property name="height">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="intellectualPropertyPartAddButton">
+                        <property name="label" translatable="yes" context="classificationdialog|intellectualPropertyPartAddButton">Add</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">2</property>
+                        <property name="top_attach">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                  </object>
+                </child>
+                <child type="label">
+                  <object class="GtkLabel">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes" context="classificationdialog|label-IntellectualProperty">Intellectual Property</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">2</property>
+                <property name="width">2</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="0">ok</action-widget>
+      <action-widget response="0">cancel</action-widget>
+      <action-widget response="0">help</action-widget>
+    </action-widgets>
+  </object>
+</interface>
diff --git a/sw/inc/editsh.hxx b/sw/inc/editsh.hxx
index f8d40ddcd0ba..bda5d3216a48 100644
--- a/sw/inc/editsh.hxx
+++ b/sw/inc/editsh.hxx
@@ -34,6 +34,7 @@
 #include <svtools/embedhlp.hxx>
 
 #include <editeng/swafopt.hxx>
+#include <svx/ClassificationField.hxx>
 
 #include <vcl/font.hxx>
 
@@ -367,6 +368,8 @@ public:
         { return static_cast<SwCharFormat*>(SwEditShell::GetFormatFromPool( nId )); }
 
     void SetClassification(const OUString& rName, SfxClassificationPolicyType eType);
+    void ApplyAdvancedClassification(std::vector<svx::ClassificationResult> const & rResult);
+    std::vector<svx::ClassificationResult> CollectAdvancedClassification();
 
     SfxWatermarkItem GetWatermark();
     void SetWatermark(const SfxWatermarkItem& rText);
diff --git a/sw/sdi/_basesh.sdi b/sw/sdi/_basesh.sdi
index 3d3a92080705..c3275e247d75 100644
--- a/sw/sdi/_basesh.sdi
+++ b/sw/sdi/_basesh.sdi
@@ -377,6 +377,12 @@ interface BaseTextSelection
         StateMethod = StateStyle ;
     ]
 
+    SID_CLASSIFICATION_DIALOG
+    [
+        ExecMethod = Execute ;
+        StateMethod = StateStyle ;
+    ]
+
     SID_WATERMARK
     [
         ExecMethod = Execute ;
@@ -546,4 +552,3 @@ interface BaseTextSelection
         StateMethod = GetState;
     ]
 }
-
diff --git a/sw/source/core/edit/edfcol.cxx b/sw/source/core/edit/edfcol.cxx
index d23828d35fa5..b413b0e290ed 100644
--- a/sw/source/core/edit/edfcol.cxx
+++ b/sw/source/core/edit/edfcol.cxx
@@ -78,25 +78,28 @@
 #include <strings.hrc>
 #include <undobj.hxx>
 
+#include <officecfg/Office/Common.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+
 #define WATERMARK_NAME "PowerPlusWaterMarkObject"
 
 namespace
 {
 
 /// Find all page styles which are currently used in the document.
-std::set<OUString> lcl_getUsedPageStyles(SwViewShell const * pShell)
+std::vector<OUString> lcl_getUsedPageStyles(SwViewShell const * pShell)
 {
-    std::set<OUString> aRet;
+    std::vector<OUString> aReturn;
 
     SwRootFrame* pLayout = pShell->GetLayout();
     for (SwFrame* pFrame = pLayout->GetLower(); pFrame; pFrame = pFrame->GetNext())
     {
         SwPageFrame* pPage = static_cast<SwPageFrame*>(pFrame);
         if (const SwPageDesc *pDesc = pPage->FindPageDesc())
-            aRet.insert(pDesc->GetName());
+            aReturn.push_back(pDesc->GetName());
     }
 
-    return aRet;
+    return aReturn;
 }
 
 /// Search for a field named rFieldName of type rServiceName in xText.
@@ -290,11 +293,259 @@ sal_uInt16 SwEditShell::GetTextFormatCollCount() const
     return GetDoc()->GetTextFormatColls()->size();
 }
 
-SwTextFormatColl& SwEditShell::GetTextFormatColl( sal_uInt16 nFormatColl) const
+SwTextFormatColl& SwEditShell::GetTextFormatColl(sal_uInt16 nFormatColl) const
 {
     return *((*(GetDoc()->GetTextFormatColls()))[nFormatColl]);
 }
 
+OUString lcl_getProperty(uno::Reference<beans::XPropertyContainer> const & rxPropertyContainer, const OUString& rName)
+{
+    uno::Reference<beans::XPropertySet> xPropertySet(rxPropertyContainer, uno::UNO_QUERY);
+    return xPropertySet->getPropertyValue(rName).get<OUString>();
+}
+
+bool lcl_containsProperty(const uno::Sequence<beans::Property> & rProperties, const OUString& rName)
+{
+    return std::find_if(rProperties.begin(), rProperties.end(), [&](const beans::Property& rProperty)
+    {
+        return rProperty.Name == rName;
+    }) != rProperties.end();
+}
+
+void lcl_removeAllProperties(uno::Reference<beans::XPropertyContainer> const & rxPropertyContainer)
+{
+    uno::Reference<beans::XPropertySet> xPropertySet(rxPropertyContainer, uno::UNO_QUERY);
+    uno::Sequence<beans::Property> aProperties = xPropertySet->getPropertySetInfo()->getProperties();
+
+    for (const beans::Property& rProperty : aProperties)
+    {
+        rxPropertyContainer->removeProperty(rProperty.Name);
+    }
+}
+
+// from classification helper
+SfxClassificationPolicyType getPolicyType()
+{
+    sal_Int32 nPolicyTypeNumber = officecfg::Office::Common::Classification::Policy::get();
+    auto eType = static_cast<SfxClassificationPolicyType>(nPolicyTypeNumber);
+    return eType;
+}
+
+bool addOrInsertDocumentProperty(uno::Reference<beans::XPropertyContainer> const & rxPropertyContainer, OUString const & rsKey, OUString const & rsValue)
+{
+    uno::Reference<beans::XPropertySet> xPropertySet(rxPropertyContainer, uno::UNO_QUERY);
+
+    try
+    {
+        if (lcl_containsProperty(xPropertySet->getPropertySetInfo()->getProperties(), rsKey))
+            xPropertySet->setPropertyValue(rsKey, uno::makeAny(rsValue));
+        else
+            rxPropertyContainer->addProperty(rsKey, beans::PropertyAttribute::REMOVABLE, uno::makeAny(rsValue));
+    }
+    catch (const uno::Exception& /*rException*/)
+    {
+        return false;
+    }
+    return true;
+}
+
+void insertFieldToDocument(uno::Reference<lang::XMultiServiceFactory> const & rxMultiServiceFactory, uno::Reference<text::XText> const & rxText, OUString const & rsKey)
+{
+    const OUString aServiceName = "com.sun.star.text.TextField.DocInfo.Custom";
+    if (!lcl_hasField(rxText, aServiceName, rsKey))
+    {
+        uno::Reference<beans::XPropertySet> xField(rxMultiServiceFactory->createInstance(aServiceName), uno::UNO_QUERY);
+        xField->setPropertyValue(UNO_NAME_NAME, uno::makeAny(rsKey));
+        uno::Reference<text::XTextContent> xTextContent(xField, uno::UNO_QUERY);
+        rxText->insertTextContent(rxText->getEnd(), xTextContent, false);
+    }
+}
+
+void SwEditShell::ApplyAdvancedClassification(std::vector<svx::ClassificationResult> const & rResults)
+{
+    SwDocShell* pDocShell = GetDoc()->GetDocShell();
+    if (!pDocShell)
+        return;
+
+    uno::Reference<frame::XModel> xModel = pDocShell->GetBaseModel();
+    uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(xModel, uno::UNO_QUERY);
+    uno::Reference<container::XNameAccess> xStyleFamilies(xStyleFamiliesSupplier->getStyleFamilies(), uno::UNO_QUERY);
+    uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName("PageStyles"), uno::UNO_QUERY);
+
+    uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(xModel, uno::UNO_QUERY);
+
+    uno::Reference<document::XDocumentProperties> xDocumentProperties = SfxObjectShell::Current()->getDocProperties();
+
+    // Clear properties
+    uno::Reference<beans::XPropertyContainer> xPropertyContainer = xDocumentProperties->getUserDefinedProperties();
+    lcl_removeAllProperties(xPropertyContainer);
+
+    SfxClassificationHelper aHelper(xDocumentProperties);
+
+    // Apply properties from the BA policy
+    for (svx::ClassificationResult const & rResult : rResults)
+    {
+        if (rResult.meType == svx::ClassificationType::CATEGORY)
+        {
+            aHelper.SetBACName(rResult.msString, getPolicyType());
+        }
+    }
+
+    OUString sPolicy = SfxClassificationHelper::policyTypeToString(getPolicyType());
+
+    std::vector<OUString> aUsedPageStyles = lcl_getUsedPageStyles(this);
+    for (const OUString& rPageStyleName : aUsedPageStyles)
+    {
+        uno::Reference<beans::XPropertySet> xPageStyle(xStyleFamily->getByName(rPageStyleName), uno::UNO_QUERY);
+
+        // HEADER
+        bool bHeaderIsOn = false;
+        xPageStyle->getPropertyValue(UNO_NAME_HEADER_IS_ON) >>= bHeaderIsOn;
+        if (!bHeaderIsOn)
+            xPageStyle->setPropertyValue(UNO_NAME_HEADER_IS_ON, uno::makeAny(true));
+        uno::Reference<text::XText> xHeaderText;
+        xPageStyle->getPropertyValue(UNO_NAME_HEADER_TEXT) >>= xHeaderText;
+
+        // FOOTER
+        bool bFooterIsOn = false;
+        xPageStyle->getPropertyValue(UNO_NAME_FOOTER_IS_ON) >>= bFooterIsOn;
+        if (!bFooterIsOn)
+            xPageStyle->setPropertyValue(UNO_NAME_FOOTER_IS_ON, uno::makeAny(true));
+        uno::Reference<text::XText> xFooterText;
+        xPageStyle->getPropertyValue(UNO_NAME_FOOTER_TEXT) >>= xFooterText;
+
+        sal_Int32 nTextNumber = 1;
+
+        for (svx::ClassificationResult const & rResult : rResults)
+        {
+            switch(rResult.meType)
+            {
+                case svx::ClassificationType::TEXT:
+                {
+                    OUString sKey = sPolicy + "Marking:Text:" + OUString::number(nTextNumber);
+                    nTextNumber++;
+
+                    addOrInsertDocumentProperty(xPropertyContainer, sKey, rResult.msString);
+                    insertFieldToDocument(xMultiServiceFactory, xHeaderText, sKey);
+                    insertFieldToDocument(xMultiServiceFactory, xFooterText, sKey);
+                }
+                break;
+
+                case svx::ClassificationType::CATEGORY:
+                {
+                    OUString sKey = sPolicy + "BusinessAuthorizationCategory:Name";
+                    insertFieldToDocument(xMultiServiceFactory, xHeaderText, sKey);
+                    insertFieldToDocument(xMultiServiceFactory, xFooterText, sKey);
+                }
+                break;
+
+                case svx::ClassificationType::MARKING:
+                {
+                    OUString sKey = sPolicy + "Extension:Marking";
+                    addOrInsertDocumentProperty(xPropertyContainer, sKey, rResult.msString);
+                    insertFieldToDocument(xMultiServiceFactory, xHeaderText, sKey);
+                    insertFieldToDocument(xMultiServiceFactory, xFooterText, sKey);
+                }
+                break;
+
+                case svx::ClassificationType::INTELLECTUAL_PROPERTY_PART:
+                {
+                    OUString sKey = sPolicy + "Extension:IntellectualPropertyPart";
+                    addOrInsertDocumentProperty(xPropertyContainer, sKey, rResult.msString);
+                    insertFieldToDocument(xMultiServiceFactory, xHeaderText, sKey);
+                    insertFieldToDocument(xMultiServiceFactory, xFooterText, sKey);
+                }
+                break;
+
+                default:
+                break;
+            }
+        }
+    }
+}
+
+std::vector<svx::ClassificationResult> SwEditShell::CollectAdvancedClassification()
+{
+    std::vector<svx::ClassificationResult> aResult;
+
+    SwDocShell* pDocShell = GetDoc()->GetDocShell();
+
+    if (!pDocShell)
+        return aResult;
+
+    uno::Reference<frame::XModel> xModel = pDocShell->GetBaseModel();
+    uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(xModel, uno::UNO_QUERY);
+    uno::Reference<container::XNameAccess> xStyleFamilies(xStyleFamiliesSupplier->getStyleFamilies(), uno::UNO_QUERY);
+    uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName("PageStyles"), uno::UNO_QUERY);
+
+    std::vector<OUString> aPageStyles = lcl_getUsedPageStyles(this);
+    OUString aPageStyleString = aPageStyles.back();
+    uno::Reference<beans::XPropertySet> xPageStyle(xStyleFamily->getByName(aPageStyleString), uno::UNO_QUERY);
+
+    bool bHeaderIsOn = false;
+    xPageStyle->getPropertyValue(UNO_NAME_HEADER_IS_ON) >>= bHeaderIsOn;
+    if (!bHeaderIsOn)
+        return aResult;
+
+    uno::Reference<text::XText> xHeaderText;
+    xPageStyle->getPropertyValue(UNO_NAME_HEADER_TEXT) >>= xHeaderText;
+
+    uno::Reference<container::XEnumerationAccess> xParagraphEnumerationAccess(xHeaderText, uno::UNO_QUERY);
+    uno::Reference<container::XEnumeration> xParagraphs = xParagraphEnumerationAccess->createEnumeration();
+
+    uno::Reference<document::XDocumentProperties> xDocumentProperties = SfxObjectShell::Current()->getDocProperties();
+    uno::Reference<beans::XPropertyContainer> xPropertyContainer = xDocumentProperties->getUserDefinedProperties();
+
+    OUString sPolicy = SfxClassificationHelper::policyTypeToString(getPolicyType());
+    sal_Int32 nParagraph = 1;
+
+    while (xParagraphs->hasMoreElements())
+    {
+        uno::Reference<container::XEnumerationAccess> xTextPortionEnumerationAccess(xParagraphs->nextElement(), uno::UNO_QUERY);
+        uno::Reference<container::XEnumeration> xTextPortions = xTextPortionEnumerationAccess->createEnumeration();
+        while (xTextPortions->hasMoreElements())
+        {
+            uno::Reference<beans::XPropertySet> xTextPortion(xTextPortions->nextElement(), uno::UNO_QUERY);
+            OUString aTextPortionType;
+            xTextPortion->getPropertyValue(UNO_NAME_TEXT_PORTION_TYPE) >>= aTextPortionType;
+            if (aTextPortionType != UNO_NAME_TEXT_FIELD)
+                continue;
+
+            uno::Reference<lang::XServiceInfo> xTextField;
+            xTextPortion->getPropertyValue(UNO_NAME_TEXT_FIELD) >>= xTextField;
+            if (!xTextField->supportsService("com.sun.star.text.TextField.DocInfo.Custom"))
+                continue;
+
+            OUString aName;
+            uno::Reference<beans::XPropertySet> xPropertySet(xTextField, uno::UNO_QUERY);
+            xPropertySet->getPropertyValue(UNO_NAME_NAME) >>= aName;
+            if (aName.startsWith(sPolicy + "Marking:Text:"))
+            {
+                OUString aValue = lcl_getProperty(xPropertyContainer, aName);
+                aResult.push_back({ svx::ClassificationType::TEXT, aValue, nParagraph });
+            }
+            else if (aName.startsWith(sPolicy + "BusinessAuthorizationCategory:Name"))
+            {
+                OUString aValue = lcl_getProperty(xPropertyContainer, aName);
+                aResult.push_back({ svx::ClassificationType::CATEGORY, aValue, nParagraph });
+            }
+            else if (aName.startsWith(sPolicy + "Extension:Marking"))
+            {
+                OUString aValue = lcl_getProperty(xPropertyContainer, aName);
+                aResult.push_back({ svx::ClassificationType::MARKING, aValue, nParagraph });
+            }
+            else if (aName.startsWith(sPolicy + "Extension:IntellectualPropertyPart"))
+            {
+                OUString aValue = lcl_getProperty(xPropertyContainer, aName);
+                aResult.push_back({ svx::ClassificationType::INTELLECTUAL_PROPERTY_PART, aValue, nParagraph });
+            }
+        }
+        nParagraph++;
+    }
+
+    return aResult;
+}
+
 void SwEditShell::SetClassification(const OUString& rName, SfxClassificationPolicyType eType)
 {
     SwDocShell* pDocShell = GetDoc()->GetDocShell();
@@ -321,7 +572,7 @@ void SwEditShell::SetClassification(const OUString& rName, SfxClassificationPoli
     uno::Reference<container::XNameAccess> xStyleFamilies(xStyleFamiliesSupplier->getStyleFamilies(), uno::UNO_QUERY);
     uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName("PageStyles"), uno::UNO_QUERY);
 
-    std::set<OUString> aUsedPageStyles = lcl_getUsedPageStyles(this);
+    std::vector<OUString> aUsedPageStyles = lcl_getUsedPageStyles(this);
     for (const OUString& rPageStyleName : aUsedPageStyles)
     {
         uno::Reference<beans::XPropertySet> xPageStyle(xStyleFamily->getByName(rPageStyleName), uno::UNO_QUERY);
@@ -414,7 +665,7 @@ SfxWatermarkItem SwEditShell::GetWatermark()
     uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(xModel, uno::UNO_QUERY);
     uno::Reference<container::XNameAccess> xStyleFamilies(xStyleFamiliesSupplier->getStyleFamilies(), uno::UNO_QUERY);
     uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName("PageStyles"), uno::UNO_QUERY);
-    std::set<OUString> aUsedPageStyles = lcl_getUsedPageStyles(this);
+    std::vector<OUString> aUsedPageStyles = lcl_getUsedPageStyles(this);
     for (const OUString& rPageStyleName : aUsedPageStyles)
     {
         uno::Reference<beans::XPropertySet> xPageStyle(xStyleFamily->getByName(rPageStyleName), uno::UNO_QUERY);
@@ -629,7 +880,7 @@ void SwEditShell::SetWatermark(const SfxWatermarkItem& rWatermark)
     uno::Reference<container::XNameAccess> xStyleFamilies(xStyleFamiliesSupplier->getStyleFamilies(), uno::UNO_QUERY);
     uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName("PageStyles"), uno::UNO_QUERY);
 
-    std::set<OUString> aUsedPageStyles = lcl_getUsedPageStyles(this);
+    std::vector<OUString> aUsedPageStyles = lcl_getUsedPageStyles(this);
     for (const OUString& rPageStyleName : aUsedPageStyles)
     {
         uno::Reference<beans::XPropertySet> xPageStyle(xStyleFamily->getByName(rPageStyleName), uno::UNO_QUERY);
diff --git a/sw/source/uibase/app/docsh2.cxx b/sw/source/uibase/app/docsh2.cxx
index dbcb99cb4bfc..eae9c158ff91 100644
--- a/sw/source/uibase/app/docsh2.cxx
+++ b/sw/source/uibase/app/docsh2.cxx
@@ -122,6 +122,7 @@
 #include <officecfg/Office/Security.hxx>
 
 #include <sfx2/fcontnr.hxx>
+#include <svx/ClassificationDialog.hxx>
 
 #include "swabstdlg.hxx"
 #include "watermarkdialog.hxx"
@@ -1163,6 +1164,20 @@ void SwDocShell::Execute(SfxRequest& rReq)
                 SAL_WARN("sw.ui", "missing parameter for SID_CLASSIFICATION_APPLY");
         }
         break;
+        case SID_CLASSIFICATION_DIALOG:
+        {
+            ScopedVclPtr<svx::ClassificationDialog> pDialog(VclPtr<svx::ClassificationDialog>::Create(nullptr));
+
+            SwWrtShell* pShell = GetWrtShell();
+            std::vector<svx::ClassificationResult> aInput = pShell->CollectAdvancedClassification();
+            pDialog->setupValues(aInput);
+
+            if (RET_OK == pDialog->Execute())
+                pShell->ApplyAdvancedClassification(pDialog->getResult());
+
+            pDialog.disposeAndClear();
+        }
+        break;
         case SID_WATERMARK:
         {
             SwWrtShell* pSh = GetWrtShell();
diff --git a/sw/source/uibase/app/docst.cxx b/sw/source/uibase/app/docst.cxx
index f78d7126faeb..a93bb5ab9ab0 100644
--- a/sw/source/uibase/app/docst.cxx
+++ b/sw/source/uibase/app/docst.cxx
@@ -272,6 +272,9 @@ void  SwDocShell::StateStyleSheet(SfxItemSet& rSet, SwWrtShell* pSh)
                 // Just trigger ClassificationCategoriesController::statusChanged().
                 rSet.InvalidateItem(nWhich);
                 break;
+            case SID_CLASSIFICATION_DIALOG:
+                rSet.InvalidateItem(nWhich);
+                break;
             case SID_STYLE_EDIT:
                 break;
             case SID_WATERMARK:
diff --git a/sw/source/uibase/shells/basesh.cxx b/sw/source/uibase/shells/basesh.cxx
index 483ee0a003a8..e2c87f6bb156 100644
--- a/sw/source/uibase/shells/basesh.cxx
+++ b/sw/source/uibase/shells/basesh.cxx
@@ -952,6 +952,11 @@ void SwBaseShell::Execute(SfxRequest &rReq)
             GetView().GetDocShell()->Execute(rReq);
         }
         break;
+        case SID_CLASSIFICATION_DIALOG:
+        {
+            GetView().GetDocShell()->Execute(rReq);
+        }
+        break;
         case SID_WATERMARK:
         {
             GetView().GetDocShell()->Execute(rReq);
diff --git a/sw/uiconfig/swriter/toolbar/classificationbar.xml b/sw/uiconfig/swriter/toolbar/classificationbar.xml
index 3ee34071e040..f176c094273a 100644
--- a/sw/uiconfig/swriter/toolbar/classificationbar.xml
+++ b/sw/uiconfig/swriter/toolbar/classificationbar.xml
@@ -9,4 +9,5 @@
 -->
 <toolbar:toolbar xmlns:toolbar="http://openoffice.org/2001/toolbar" xmlns:xlink="http://www.w3.org/1999/xlink" toolbar:id="toolbar">
   <toolbar:toolbaritem xlink:href=".uno:ClassificationApply"/>
+  <toolbar:toolbaritem xlink:href=".uno:ClassificationDialog"/>
 </toolbar:toolbar>


More information about the Libreoffice-commits mailing list