diff options
-rw-r--r-- | filter/source/pdf/pdfexport.cxx | 12 | ||||
-rw-r--r-- | include/sfx2/dinfdlg.hxx | 32 | ||||
-rw-r--r-- | include/svl/memberid.h | 14 | ||||
-rw-r--r-- | include/vcl/pdfwriter.hxx | 8 | ||||
-rw-r--r-- | include/xmloff/xmltoken.hxx | 4 | ||||
-rw-r--r-- | offapi/UnoApi_offapi.mk | 1 | ||||
-rw-r--r-- | offapi/com/sun/star/document/XDocumentProperties2.idl | 50 | ||||
-rw-r--r-- | sfx2/source/dialog/dinfdlg.cxx | 118 | ||||
-rw-r--r-- | sfx2/source/doc/SfxDocumentMetaData.cxx | 135 | ||||
-rw-r--r-- | sfx2/uiconfig/ui/descriptioninfopage.ui | 260 | ||||
-rw-r--r-- | vcl/inc/pdf/XmpMetadata.hxx | 9 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.cxx | 28 | ||||
-rw-r--r-- | vcl/source/pdf/XmpMetadata.cxx | 79 | ||||
-rw-r--r-- | xmloff/source/core/xmltoken.cxx | 4 | ||||
-rw-r--r-- | xmloff/source/token/tokens.txt | 4 |
15 files changed, 743 insertions, 15 deletions
diff --git a/filter/source/pdf/pdfexport.cxx b/filter/source/pdf/pdfexport.cxx index 9b6523448dfb..a9a717a56cc5 100644 --- a/filter/source/pdf/pdfexport.cxx +++ b/filter/source/pdf/pdfexport.cxx @@ -49,7 +49,7 @@ #include <com/sun/star/frame/XModel.hpp> #include <com/sun/star/frame/ModuleManager.hpp> #include <com/sun/star/frame/XStorable.hpp> -#include <com/sun/star/document/XDocumentProperties.hpp> +#include <com/sun/star/document/XDocumentProperties2.hpp> #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> #include <com/sun/star/container/XNameAccess.hpp> #include <com/sun/star/view/XViewSettingsSupplier.hpp> @@ -470,7 +470,7 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >& Reference< document::XDocumentPropertiesSupplier > xDocumentPropsSupplier( mxSrcDoc, UNO_QUERY ); if ( xDocumentPropsSupplier.is() ) { - Reference< document::XDocumentProperties > xDocumentProps( xDocumentPropsSupplier->getDocumentProperties() ); + Reference< document::XDocumentProperties2 > xDocumentProps( xDocumentPropsSupplier->getDocumentProperties(), UNO_QUERY ); if ( xDocumentProps.is() ) { aContext.DocumentInfo.Title = xDocumentProps->getTitle(); @@ -481,6 +481,14 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >& = xDocumentProps->getEditingCycles() < 1 ? xDocumentProps->getCreationDate() : xDocumentProps->getModificationDate(); + aContext.DocumentInfo.Contributor = xDocumentProps->getContributor(); + aContext.DocumentInfo.Coverage = xDocumentProps->getCoverage(); + aContext.DocumentInfo.Identifier = xDocumentProps->getIdentifier(); + aContext.DocumentInfo.Publisher = xDocumentProps->getPublisher(); + aContext.DocumentInfo.Relation = xDocumentProps->getRelation(); + aContext.DocumentInfo.Rights = xDocumentProps->getRights(); + aContext.DocumentInfo.Source = xDocumentProps->getSource(); + aContext.DocumentInfo.Type = xDocumentProps->getType(); } } diff --git a/include/sfx2/dinfdlg.hxx b/include/sfx2/dinfdlg.hxx index 2acbc93cffe9..874e127f20b5 100644 --- a/include/sfx2/dinfdlg.hxx +++ b/include/sfx2/dinfdlg.hxx @@ -72,6 +72,14 @@ private: sal_Int32 m_EditingDuration; OUString m_Description; OUString m_Keywords; + OUString m_Contributor; + OUString m_Coverage; + OUString m_Identifier; + OUString m_Publisher; + OUString m_Relation; + OUString m_Rights; + OUString m_Source; + OUString m_Type; OUString m_Subject; OUString m_Title; bool m_bHasTemplate; @@ -120,6 +128,22 @@ public: void setDescription(const OUString& i_val) { m_Description = i_val; } const OUString& getKeywords() const { return m_Keywords; } void setKeywords(const OUString& i_val) { m_Keywords = i_val; } + const OUString& getContributor() const { return m_Contributor; } + void setContributor(const OUString& i_val) { m_Contributor = i_val; } + const OUString& getCoverage() const { return m_Coverage; } + void setCoverage(const OUString& i_val) { m_Coverage = i_val; } + const OUString& getIdentifier() const { return m_Identifier; } + void setIdentifier(const OUString& i_val) { m_Identifier = i_val; } + const OUString& getPublisher() const { return m_Publisher; } + void setPublisher(const OUString& i_val) { m_Publisher = i_val; } + const OUString& getRelation() const { return m_Relation; } + void setRelation(const OUString& i_val) { m_Relation = i_val; } + const OUString& getRights() const { return m_Rights; } + void setRights(const OUString& i_val) { m_Rights = i_val; } + const OUString& getSource() const { return m_Source; } + void setSource(const OUString& i_val) { m_Source = i_val; } + const OUString& getType() const { return m_Type; } + void setType(const OUString& i_val) { m_Type = i_val; } const OUString& getSubject() const { return m_Subject; } void setSubject(const OUString& i_val) { m_Subject = i_val; } const OUString& getTitle() const { return m_Title; } @@ -217,6 +241,14 @@ private: std::unique_ptr<weld::Entry> m_xTitleEd; std::unique_ptr<weld::Entry> m_xThemaEd; std::unique_ptr<weld::Entry> m_xKeywordsEd; + std::unique_ptr<weld::Entry> m_xContributorEd; + std::unique_ptr<weld::Entry> m_xCoverageEd; + std::unique_ptr<weld::Entry> m_xIdentifierEd; + std::unique_ptr<weld::Entry> m_xPublisherEd; + std::unique_ptr<weld::Entry> m_xRelationEd; + std::unique_ptr<weld::Entry> m_xRightsEd; + std::unique_ptr<weld::Entry> m_xSourceEd; + std::unique_ptr<weld::Entry> m_xTypeEd; std::unique_ptr<weld::TextView> m_xCommentEd; virtual bool FillItemSet( SfxItemSet* ) override; diff --git a/include/svl/memberid.h b/include/svl/memberid.h index afe106d41bbe..185389713814 100644 --- a/include/svl/memberid.h +++ b/include/svl/memberid.h @@ -74,11 +74,19 @@ #define MID_DOCINFO_USEUSERDATA 0x31 #define MID_DOCINFO_DELETEUSERDATA 0x32 #define MID_DOCINFO_USETHUMBNAILSAVE 0x33 +#define MID_DOCINFO_CONTRIBUTOR 0x34 +#define MID_DOCINFO_COVERAGE 0x35 +#define MID_DOCINFO_IDENTIFIER 0x38 +#define MID_DOCINFO_PUBLISHER 0x3a +#define MID_DOCINFO_RELATION 0x3b +#define MID_DOCINFO_RIGHTS 0x3c +#define MID_DOCINFO_SOURCE 0x3d +#define MID_DOCINFO_TYPE 0x3e // only for FastPropertySet -#define MID_TYPE 0x38 -#define MID_VALUE 0x39 -#define MID_VALUESET 0x40 +#define MID_TYPE 0x3f +#define MID_VALUE 0x40 +#define MID_VALUESET 0x41 #endif diff --git a/include/vcl/pdfwriter.hxx b/include/vcl/pdfwriter.hxx index 2b62b26b6ef4..f9bbf608e319 100644 --- a/include/vcl/pdfwriter.hxx +++ b/include/vcl/pdfwriter.hxx @@ -560,6 +560,14 @@ The following structure describes the permissions used in PDF security OUString Subject; // subject OUString Keywords; // keywords css::util::DateTime ModificationDate; + css::uno::Sequence<OUString> Contributor; // http://purl.org/dc/elements/1.1/contributor + OUString Coverage; // http://purl.org/dc/elements/1.1/coverage + OUString Identifier; // http://purl.org/dc/elements/1.1/identifier + css::uno::Sequence<OUString> Publisher; // http://purl.org/dc/elements/1.1/publisher + css::uno::Sequence<OUString> Relation; // http://purl.org/dc/elements/1.1/relation + OUString Rights; // http://purl.org/dc/elements/1.1/rights + OUString Source; // http://purl.org/dc/elements/1.1/source + OUString Type; // http://purl.org/dc/elements/1.1/type OUString Creator; // application that created the original document OUString Producer; // OpenOffice }; diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx index 7771577a453d..ee0c6ec57d89 100644 --- a/include/xmloff/xmltoken.hxx +++ b/include/xmloff/xmltoken.hxx @@ -518,6 +518,7 @@ namespace xmloff::token { XML_CONTOUR_PATH, XML_CONTOUR_POLYGON, XML_CONTRAST, + XML_CONTRIBUTOR, XML_CONTROL, XML_CONVERSION_MODE, XML_CONVERSION_TYPE, @@ -542,6 +543,7 @@ namespace xmloff::token { XML_COUNTRY, XML_COUNTRY_ASIAN, XML_COUNTRY_COMPLEX, + XML_COVERAGE, XML_COVERED_TABLE_CELL, XML_CREATE_DATE, XML_CREATE_DATE_STRING, @@ -1623,6 +1625,7 @@ namespace xmloff::token { XML_REL_HEIGHT_REL, XML_REL_WIDTH, XML_REL_WIDTH_REL, + XML_RELATION, XML_RELATIVE, XML_RELATIVE_TAB_STOP_POSITION, XML_RELN, @@ -1644,6 +1647,7 @@ namespace xmloff::token { XML_RIGHT_TO_LEFT, XML_RIGHTARC, XML_RIGHTCIRCLE, + XML_RIGHTS, XML_RING, XML_ROLE, XML_ROLL_FROM_BOTTOM, diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk index 7ba36b4bd065..abfbcfb8703d 100644 --- a/offapi/UnoApi_offapi.mk +++ b/offapi/UnoApi_offapi.mk @@ -2229,6 +2229,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/document,\ XDocumentInsertable \ XDocumentLanguages \ XDocumentProperties \ + XDocumentProperties2 \ XDocumentPropertiesSupplier \ XDocumentRecovery \ XDocumentRecovery2 \ diff --git a/offapi/com/sun/star/document/XDocumentProperties2.idl b/offapi/com/sun/star/document/XDocumentProperties2.idl new file mode 100644 index 000000000000..c0d2a18b4af2 --- /dev/null +++ b/offapi/com/sun/star/document/XDocumentProperties2.idl @@ -0,0 +1,50 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +module com { module sun { module star { module document { + +/** Extends XDocumentProperties interface to provide additional attributes + + @since LibreOffice 24.02 +*/ +interface XDocumentProperties2: com::sun::star::document::XDocumentProperties +{ + /** Contributors to the resource (other than the authors). */ + [attribute] sequence< string > Contributor; + + /** The extent or scope of the resource. */ + [attribute] string Coverage; + + /** Unique identifier of the resource. */ + [attribute] string Identifier; + + /** Entities responsible for making the resource available. */ + [attribute] sequence< string > Publisher; + + /** Relationships to other documents. + + Recommended practice is to identify the related resource by means of a + URI. If this is not possible or feasible, a string conforming to a + formal identification system may be provided. + */ + [attribute] sequence< string > Relation; + + /** Informal rights statement. */ + [attribute] string Rights; + + /** Unique identifier of the work from which this resource was derived */ + [attribute] string Source; + + /** The nature or genre of the resource. */ + [attribute] string Type; +}; + + +}; }; }; }; +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sfx2/source/dialog/dinfdlg.cxx b/sfx2/source/dialog/dinfdlg.cxx index 24c4f509559f..d4cb97becf5d 100644 --- a/sfx2/source/dialog/dinfdlg.cxx +++ b/sfx2/source/dialog/dinfdlg.cxx @@ -59,7 +59,7 @@ #include <com/sun/star/util/DateTimeWithTimezone.hpp> #include <com/sun/star/util/DateWithTimezone.hpp> #include <com/sun/star/util/Duration.hpp> -#include <com/sun/star/document/XDocumentProperties.hpp> +#include <com/sun/star/document/XDocumentProperties2.hpp> #include <com/sun/star/document/CmisProperty.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> @@ -215,6 +215,16 @@ SfxDocumentInfoItem::SfxDocumentInfoItem( const OUString& rFile, , m_bUseUserData( bIs ) , m_bUseThumbnailSave( _bIs ) { + Reference< document::XDocumentProperties2 > xDocProps2(i_xDocProps, UNO_QUERY); + m_Contributor = ::comphelper::string::convertCommaSeparated(xDocProps2->getContributor()); + m_Coverage = xDocProps2->getCoverage(); + m_Identifier = xDocProps2->getIdentifier(); + m_Publisher = ::comphelper::string::convertCommaSeparated(xDocProps2->getPublisher()); + m_Relation = ::comphelper::string::convertCommaSeparated(xDocProps2->getRelation()); + m_Rights = xDocProps2->getRights(); + m_Source = xDocProps2->getSource(); + m_Type = xDocProps2->getType(); + try { Reference< beans::XPropertyContainer > xContainer = i_xDocProps->getUserDefinedProperties(); @@ -260,6 +270,14 @@ SfxDocumentInfoItem::SfxDocumentInfoItem( const SfxDocumentInfoItem& rItem ) , m_EditingDuration( rItem.getEditingDuration() ) , m_Description( rItem.getDescription() ) , m_Keywords( rItem.getKeywords() ) + , m_Contributor(rItem.getContributor()) + , m_Coverage(rItem.getCoverage()) + , m_Identifier(rItem.getIdentifier()) + , m_Publisher(rItem.getPublisher()) + , m_Relation(rItem.getRelation()) + , m_Rights(rItem.getRights()) + , m_Source(rItem.getSource()) + , m_Type(rItem.getType()) , m_Subject( rItem.getSubject() ) , m_Title( rItem.getTitle() ) , m_bHasTemplate( rItem.m_bHasTemplate ) @@ -306,6 +324,14 @@ bool SfxDocumentInfoItem::operator==( const SfxPoolItem& rItem) const m_EditingDuration == rInfoItem.m_EditingDuration && m_Description == rInfoItem.m_Description && m_Keywords == rInfoItem.m_Keywords && + m_Contributor == rInfoItem.m_Contributor && + m_Coverage == rInfoItem.m_Coverage && + m_Identifier == rInfoItem.m_Identifier && + m_Publisher == rInfoItem.m_Publisher && + m_Relation == rInfoItem.m_Relation && + m_Rights == rInfoItem.m_Rights && + m_Source == rInfoItem.m_Source && + m_Type == rInfoItem.m_Type && m_Subject == rInfoItem.m_Subject && m_Title == rInfoItem.m_Title && comphelper::ContainerUniquePtrEquals(m_aCustomProperties, rInfoItem.m_aCustomProperties) && @@ -350,8 +376,18 @@ void SfxDocumentInfoItem::UpdateDocumentInfo( i_xDocProps->setDescription(getDescription()); i_xDocProps->setKeywords( ::comphelper::string::convertCommaSeparated(getKeywords())); - i_xDocProps->setSubject(getSubject()); - i_xDocProps->setTitle(getTitle()); + + Reference<document::XDocumentProperties2> xDocProps2(i_xDocProps, UNO_QUERY); + xDocProps2->setContributor(::comphelper::string::convertCommaSeparated(getContributor())); + xDocProps2->setCoverage(getCoverage()); + xDocProps2->setIdentifier(getIdentifier()); + xDocProps2->setPublisher(::comphelper::string::convertCommaSeparated(getPublisher())); + xDocProps2->setRelation(::comphelper::string::convertCommaSeparated(getRelation())); + xDocProps2->setRights(getRights()); + xDocProps2->setSource(getSource()); + xDocProps2->setType(getType()); + xDocProps2->setSubject(getSubject()); + xDocProps2->setTitle(getTitle()); // this is necessary in case of replaying a recorded macro: // in this case, the macro may contain the 4 old user-defined DocumentInfo @@ -585,6 +621,14 @@ SfxDocumentDescPage::SfxDocumentDescPage(weld::Container* pPage, weld::DialogCon , m_xTitleEd(m_xBuilder->weld_entry("title")) , m_xThemaEd(m_xBuilder->weld_entry("subject")) , m_xKeywordsEd(m_xBuilder->weld_entry("keywords")) + , m_xContributorEd(m_xBuilder->weld_entry("contributor")) + , m_xCoverageEd(m_xBuilder->weld_entry("coverage")) + , m_xIdentifierEd(m_xBuilder->weld_entry("identifier")) + , m_xPublisherEd(m_xBuilder->weld_entry("publisher")) + , m_xRelationEd(m_xBuilder->weld_entry("relation")) + , m_xRightsEd(m_xBuilder->weld_entry("rights")) + , m_xSourceEd(m_xBuilder->weld_entry("source")) + , m_xTypeEd(m_xBuilder->weld_entry("type")) , m_xCommentEd(m_xBuilder->weld_text_view("comments")) { m_xCommentEd->set_size_request(m_xKeywordsEd->get_preferred_size().Width(), @@ -606,8 +650,18 @@ bool SfxDocumentDescPage::FillItemSet(SfxItemSet *rSet) const bool bTitleMod = m_xTitleEd->get_value_changed_from_saved(); const bool bThemeMod = m_xThemaEd->get_value_changed_from_saved(); const bool bKeywordsMod = m_xKeywordsEd->get_value_changed_from_saved(); + const bool bContributorMod = m_xContributorEd->get_value_changed_from_saved(); + const bool bCoverageMod = m_xCoverageEd->get_value_changed_from_saved(); + const bool bIdentifierMod = m_xIdentifierEd->get_value_changed_from_saved(); + const bool bPublisherMod = m_xPublisherEd->get_value_changed_from_saved(); + const bool bRelationMod = m_xRelationEd->get_value_changed_from_saved(); + const bool bRightsMod = m_xRightsEd->get_value_changed_from_saved(); + const bool bSourceMod = m_xSourceEd->get_value_changed_from_saved(); + const bool bTypeMod = m_xTypeEd->get_value_changed_from_saved(); const bool bCommentMod = m_xCommentEd->get_value_changed_from_saved(); - if ( !( bTitleMod || bThemeMod || bKeywordsMod || bCommentMod ) ) + if (!(bTitleMod || bThemeMod || bKeywordsMod || bTitleMod || bThemeMod || bKeywordsMod + || bContributorMod || bCoverageMod || bIdentifierMod || bPublisherMod || bRelationMod + || bRightsMod || bSourceMod || bTypeMod || bCommentMod)) { return false; } @@ -640,6 +694,38 @@ bool SfxDocumentDescPage::FillItemSet(SfxItemSet *rSet) { pInfo->setKeywords( m_xKeywordsEd->get_text() ); } + if (bContributorMod) + { + pInfo->setContributor(m_xContributorEd->get_text()); + } + if (bCoverageMod) + { + pInfo->setCoverage(m_xCoverageEd->get_text()); + } + if (bIdentifierMod) + { + pInfo->setIdentifier(m_xIdentifierEd->get_text()); + } + if (bPublisherMod) + { + pInfo->setPublisher(m_xPublisherEd->get_text()); + } + if (bRelationMod) + { + pInfo->setRelation(m_xRelationEd->get_text()); + } + if (bRightsMod) + { + pInfo->setRights(m_xRightsEd->get_text()); + } + if (bSourceMod) + { + pInfo->setSource(m_xSourceEd->get_text()); + } + if (bTypeMod) + { + pInfo->setType(m_xTypeEd->get_text()); + } if ( bCommentMod ) { pInfo->setDescription( m_xCommentEd->get_text() ); @@ -660,11 +746,27 @@ void SfxDocumentDescPage::Reset(const SfxItemSet *rSet) m_xTitleEd->set_text(m_pInfoItem->getTitle()); m_xThemaEd->set_text(m_pInfoItem->getSubject()); m_xKeywordsEd->set_text(m_pInfoItem->getKeywords()); + m_xContributorEd->set_text(m_pInfoItem->getContributor()); + m_xCoverageEd->set_text(m_pInfoItem->getCoverage()); + m_xIdentifierEd->set_text(m_pInfoItem->getIdentifier()); + m_xPublisherEd->set_text(m_pInfoItem->getPublisher()); + m_xRelationEd->set_text(m_pInfoItem->getRelation()); + m_xRightsEd->set_text(m_pInfoItem->getRights()); + m_xSourceEd->set_text(m_pInfoItem->getSource()); + m_xTypeEd->set_text(m_pInfoItem->getType()); m_xCommentEd->set_text(m_pInfoItem->getDescription()); m_xTitleEd->save_value(); m_xThemaEd->save_value(); m_xKeywordsEd->save_value(); + m_xContributorEd->save_value(); + m_xCoverageEd->save_value(); + m_xIdentifierEd->save_value(); + m_xPublisherEd->save_value(); + m_xRelationEd->save_value(); + m_xRightsEd->save_value(); + m_xSourceEd->save_value(); + m_xTypeEd->save_value(); m_xCommentEd->save_value(); const SfxBoolItem* pROItem = SfxItemSet::GetItem<SfxBoolItem>(rSet, SID_DOC_READONLY, false); @@ -673,6 +775,14 @@ void SfxDocumentDescPage::Reset(const SfxItemSet *rSet) m_xTitleEd->set_editable(false); m_xThemaEd->set_editable(false); m_xKeywordsEd->set_editable(false); + m_xContributorEd->set_editable(false); + m_xCoverageEd->set_editable(false); + m_xIdentifierEd->set_editable(false); + m_xPublisherEd->set_editable(false); + m_xRelationEd->set_editable(false); + m_xRightsEd->set_editable(false); + m_xSourceEd->set_editable(false); + m_xTypeEd->set_editable(false); m_xCommentEd->set_editable(false); } } diff --git a/sfx2/source/doc/SfxDocumentMetaData.cxx b/sfx2/source/doc/SfxDocumentMetaData.cxx index 7d1f16c01fd9..da34b3cad2de 100644 --- a/sfx2/source/doc/SfxDocumentMetaData.cxx +++ b/sfx2/source/doc/SfxDocumentMetaData.cxx @@ -24,6 +24,7 @@ #include <cppuhelper/exc_hlp.hxx> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/document/XDocumentProperties.hpp> +#include <com/sun/star/document/XDocumentProperties2.hpp> #include <com/sun/star/lang/XInitialization.hpp> #include <com/sun/star/util/XCloneable.hpp> #include <com/sun/star/util/XModifiable.hpp> @@ -123,7 +124,7 @@ typedef std::vector<std::vector<std::pair<OUString, OUString> > > typedef ::cppu::WeakComponentImplHelper< css::lang::XServiceInfo, - css::document::XDocumentProperties, + css::document::XDocumentProperties2, css::lang::XInitialization, css::util::XCloneable, css::util::XModifiable, @@ -210,6 +211,23 @@ public: const css::uno::Sequence< css::beans::PropertyValue > & Medium) override; virtual void SAL_CALL storeToMedium(const OUString & URL, const css::uno::Sequence< css::beans::PropertyValue > & Medium) override; + virtual css::uno::Sequence< OUString > SAL_CALL getContributor() override; + virtual void SAL_CALL setContributor(const css::uno::Sequence< OUString >& the_value) override; + virtual OUString SAL_CALL getCoverage() override; + virtual void SAL_CALL setCoverage(const OUString & the_value) override; + virtual OUString SAL_CALL getIdentifier() override; + virtual void SAL_CALL setIdentifier(const OUString & the_value) override; + virtual css::uno::Sequence< OUString > SAL_CALL getPublisher() override; + virtual void SAL_CALL setPublisher(const css::uno::Sequence< OUString > & the_value) override; + virtual css::uno::Sequence< OUString > SAL_CALL getRelation() override; + virtual void SAL_CALL setRelation(const css::uno::Sequence< OUString > & the_value) override; + virtual OUString SAL_CALL getRights() override; + virtual void SAL_CALL setRights(const OUString & the_value) override; + virtual OUString SAL_CALL getSource() override; + virtual void SAL_CALL setSource(const OUString& the_value) override; + virtual OUString SAL_CALL getType() override; + virtual void SAL_CALL setType(const OUString& the_value) override; + // css::lang::XInitialization: virtual void SAL_CALL initialize( @@ -411,14 +429,25 @@ const char* s_stdMeta[] = { "meta:editing-cycles", // nonNegativeInteger "meta:editing-duration", // duration "meta:document-statistic", // ... // note: statistic is singular, no s! + "dc:coverage", + "dc:identifier", + "dc:rights", + "dc:source", + "dc:type", nullptr }; constexpr OUStringLiteral sMetaKeyword = u"meta:keyword"; constexpr OUStringLiteral sMetaUserDefined = u"meta:user-defined"; +constexpr OUStringLiteral sDCContributor = u"dc:contributor"; +constexpr OUStringLiteral sDCPublisher = u"dc:publisher"; +constexpr OUStringLiteral sDCRelation = u"dc:relation"; constexpr rtl::OUStringConstExpr s_stdMetaList[] { sMetaKeyword, // string* sMetaUserDefined, // ...* + sDCContributor, // string* + sDCPublisher, // string* + sDCRelation, // string* }; constexpr OUStringLiteral s_nsXLink = u"http://www.w3.org/1999/xlink"; @@ -1453,6 +1482,110 @@ SfxDocumentMetaData::setKeywords( } } +// css::document::XDocumentProperties2 +css::uno::Sequence<OUString> SAL_CALL SfxDocumentMetaData::getContributor() +{ + ::osl::MutexGuard g(m_aMutex); + return getMetaList("dc:contributor"); +} + +void SAL_CALL SfxDocumentMetaData::setContributor(const css::uno::Sequence<OUString>& the_value) +{ + ::osl::ClearableMutexGuard g(m_aMutex); + if (setMetaList("dc:contributor", the_value, nullptr)) + { + g.clear(); + setModified(true); + } +} + +OUString SAL_CALL SfxDocumentMetaData::getCoverage() +{ + ::osl::MutexGuard g(m_aMutex); + return getMetaText("dc:coverage"); +} + +void SAL_CALL SfxDocumentMetaData::setCoverage(const OUString& the_value) +{ + setMetaTextAndNotify("dc:coverage", the_value); +} + +OUString SAL_CALL SfxDocumentMetaData::getIdentifier() +{ + ::osl::MutexGuard g(m_aMutex); + return getMetaText("dc:identifier"); +} + +void SAL_CALL SfxDocumentMetaData::setIdentifier(const OUString& the_value) +{ + setMetaTextAndNotify("dc:identifier", the_value); +} + +css::uno::Sequence<OUString> SAL_CALL SfxDocumentMetaData::getPublisher() +{ + ::osl::MutexGuard g(m_aMutex); + return getMetaList("dc:publisher"); +} + +void SAL_CALL SfxDocumentMetaData::setPublisher(const css::uno::Sequence<OUString>& the_value) +{ + ::osl::ClearableMutexGuard g(m_aMutex); + if (setMetaList("dc:publisher", the_value, nullptr)) + { + g.clear(); + setModified(true); + } +} + +css::uno::Sequence<OUString> SAL_CALL SfxDocumentMetaData::getRelation() +{ + ::osl::MutexGuard g(m_aMutex); + return getMetaList("dc:relation"); +} + +void SAL_CALL SfxDocumentMetaData::setRelation(const css::uno::Sequence<OUString>& the_value) +{ + ::osl::ClearableMutexGuard g(m_aMutex); + if (setMetaList("dc:relation", the_value, nullptr)) + { + g.clear(); + setModified(true); + } +} + +OUString SAL_CALL SfxDocumentMetaData::getRights() +{ + ::osl::MutexGuard g(m_aMutex); + return getMetaText("dc:rights"); +} + +void SAL_CALL SfxDocumentMetaData::setRights(const OUString& the_value) +{ + setMetaTextAndNotify("dc:rights", the_value); +} + +OUString SAL_CALL SfxDocumentMetaData::getSource() +{ + ::osl::MutexGuard g(m_aMutex); + return getMetaText("dc:source"); +} + +void SAL_CALL SfxDocumentMetaData::setSource(const OUString& the_value) +{ + setMetaTextAndNotify("dc:source", the_value); +} + +OUString SAL_CALL SfxDocumentMetaData::getType() +{ + ::osl::MutexGuard g(m_aMutex); + return getMetaText("dc:type"); +} + +void SAL_CALL SfxDocumentMetaData::setType(const OUString& the_value) +{ + setMetaTextAndNotify("dc:type", the_value); +} + css::lang::Locale SAL_CALL SfxDocumentMetaData::getLanguage() { diff --git a/sfx2/uiconfig/ui/descriptioninfopage.ui b/sfx2/uiconfig/ui/descriptioninfopage.ui index 86545c576e69..d8e2523fd3fc 100644 --- a/sfx2/uiconfig/ui/descriptioninfopage.ui +++ b/sfx2/uiconfig/ui/descriptioninfopage.ui @@ -54,6 +54,126 @@ </packing> </child> <child> + <object class="GtkLabel" id="label31"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="valign">start</property> + <property name="label" translatable="yes" context="descriptioninfopage|label31">Co_ntributor:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">contributor</property> + <property name="xalign">1</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">3</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label32"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="valign">start</property> + <property name="label" translatable="yes" context="descriptioninfopage|label32">Co_verage:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">coverage</property> + <property name="xalign">1</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">4</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label37"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="valign">start</property> + <property name="label" translatable="yes" context="descriptioninfopage|label37">_Identifier:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">identifier</property> + <property name="xalign">1</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">5</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label39"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="valign">start</property> + <property name="label" translatable="yes" context="descriptioninfopage|label39">_Publisher:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">publisher</property> + <property name="xalign">1</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">6</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label40"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="valign">start</property> + <property name="label" translatable="yes" context="descriptioninfopage|label40">R_elation:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">relation</property> + <property name="xalign">1</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">7</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label41"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="valign">start</property> + <property name="label" translatable="yes" context="descriptioninfopage|label41">Ri_ghts:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">rights</property> + <property name="xalign">1</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">8</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label42"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="valign">start</property> + <property name="label" translatable="yes" context="descriptioninfopage|label42">So_urce:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">source</property> + <property name="xalign">1</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">9</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label45"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="valign">start</property> + <property name="label" translatable="yes" context="descriptioninfopage|label45">T_ype:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">type</property> + <property name="xalign">1</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">10</property> + </packing> + </child> + <child> <object class="GtkLabel" id="label30"> <property name="visible">True</property> <property name="can_focus">False</property> @@ -65,7 +185,7 @@ </object> <packing> <property name="left_attach">0</property> - <property name="top_attach">3</property> + <property name="top_attach">11</property> </packing> </child> <child> @@ -120,6 +240,142 @@ </packing> </child> <child> + <object class="GtkEntry" id="contributor"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hexpand">True</property> + <property name="truncate-multiline">True</property> + <child internal-child="accessible"> + <object class="AtkObject" id="contributor-atkobject"> + <property name="AtkObject::accessible-description" translatable="yes" context="descriptioninfopage|extended_tip|contributor">contributor accessible description</property> + </object> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">3</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="coverage"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hexpand">True</property> + <property name="truncate-multiline">True</property> + <child internal-child="accessible"> + <object class="AtkObject" id="coverage-atkobject"> + <property name="AtkObject::accessible-description" translatable="yes" context="descriptioninfopage|extended_tip|coverage"></property> + </object> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">4</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="identifier"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hexpand">True</property> + <property name="truncate-multiline">True</property> + <child internal-child="accessible"> + <object class="AtkObject" id="identifier-atkobject"> + <property name="AtkObject::accessible-description" translatable="yes" context="descriptioninfopage|extended_tip|identifier"></property> + </object> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">5</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="publisher"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hexpand">True</property> + <property name="truncate-multiline">True</property> + <child internal-child="accessible"> + <object class="AtkObject" id="publisher-atkobject"> + <property name="AtkObject::accessible-description" translatable="yes" context="descriptioninfopage|extended_tip|publisher"></property> + </object> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">6</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="relation"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hexpand">True</property> + <property name="truncate-multiline">True</property> + <child internal-child="accessible"> + <object class="AtkObject" id="relation-atkobject"> + <property name="AtkObject::accessible-description" translatable="yes" context="descriptioninfopage|extended_tip|relation"></property> + </object> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">7</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="rights"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hexpand">True</property> + <property name="truncate-multiline">True</property> + <child internal-child="accessible"> + <object class="AtkObject" id="rights-atkobject"> + <property name="AtkObject::accessible-description" translatable="yes" context="descriptioninfopage|extended_tip|rights"></property> + </object> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">8</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="source"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hexpand">True</property> + <property name="truncate-multiline">True</property> + <child internal-child="accessible"> + <object class="AtkObject" id="source-atkobject"> + <property name="AtkObject::accessible-description" translatable="yes" context="descriptioninfopage|extended_tip|source"></property> + </object> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">9</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="type"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hexpand">True</property> + <property name="truncate-multiline">True</property> + <child internal-child="accessible"> + <object class="AtkObject" id="type-atkobject"> + <property name="AtkObject::accessible-description" translatable="yes" context="descriptioninfopage|extended_tip|type"></property> + </object> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">10</property> + </packing> + </child> + <child> <object class="GtkScrolledWindow" id="scrolledwindow1"> <property name="visible">True</property> <property name="can_focus">True</property> @@ -142,7 +398,7 @@ </object> <packing> <property name="left_attach">1</property> - <property name="top_attach">3</property> + <property name="top_attach">11</property> </packing> </child> <child internal-child="accessible"> diff --git a/vcl/inc/pdf/XmpMetadata.hxx b/vcl/inc/pdf/XmpMetadata.hxx index a144266497cf..33fce97a21e3 100644 --- a/vcl/inc/pdf/XmpMetadata.hxx +++ b/vcl/inc/pdf/XmpMetadata.hxx @@ -13,6 +13,7 @@ #include <rtl/string.hxx> #include <tools/stream.hxx> #include <memory> +#include <vector> namespace vcl::pdf { @@ -29,6 +30,14 @@ public: OString msProducer; OString msPDFVersion; OString msKeywords; + std::vector<OString> maContributor; + OString msCoverage; + OString msIdentifier; + std::vector<OString> maPublisher; + std::vector<OString> maRelation; + OString msRights; + OString msSource; + OString msType; OString m_sCreatorTool; OString m_sCreateDate; diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 00b59830f048..ff2de852f4a8 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -5930,11 +5930,27 @@ static void lcl_assignMeta(std::u16string_view aValue, OString& aMeta) { if (!aValue.empty()) { - OUString aTempString = comphelper::string::encodeForXml(aValue); - aMeta = OUStringToOString(aTempString, RTL_TEXTENCODING_UTF8); + aMeta = OUStringToOString(comphelper::string::encodeForXml(aValue), RTL_TEXTENCODING_UTF8); } } +static void lcl_assignMeta(const css::uno::Sequence<OUString>& rValues, std::vector<OString>& rMeta) +{ + if (!rValues.hasElements()) + return; + + std::vector<OString> aNewMetaVector; + aNewMetaVector.reserve(rValues.getLength()); + + for (const OUString& rValue : rValues) + { + aNewMetaVector.emplace_back( + OUStringToOString(comphelper::string::encodeForXml(rValue), RTL_TEXTENCODING_UTF8)); + } + + rMeta = std::move(aNewMetaVector); +} + // emits the document metadata sal_Int32 PDFWriterImpl::emitDocumentMetadata() { @@ -5963,6 +5979,14 @@ sal_Int32 PDFWriterImpl::emitDocumentMetadata() lcl_assignMeta(m_aContext.DocumentInfo.Producer, aMetadata.msProducer); aMetadata.msPDFVersion = getPDFVersionStr(m_aContext.Version); lcl_assignMeta(m_aContext.DocumentInfo.Keywords, aMetadata.msKeywords); + lcl_assignMeta(m_aContext.DocumentInfo.Contributor, aMetadata.maContributor); + lcl_assignMeta(m_aContext.DocumentInfo.Coverage, aMetadata.msCoverage); + lcl_assignMeta(m_aContext.DocumentInfo.Identifier, aMetadata.msIdentifier); + lcl_assignMeta(m_aContext.DocumentInfo.Publisher, aMetadata.maPublisher); + lcl_assignMeta(m_aContext.DocumentInfo.Relation, aMetadata.maRelation); + lcl_assignMeta(m_aContext.DocumentInfo.Rights, aMetadata.msRights); + lcl_assignMeta(m_aContext.DocumentInfo.Source, aMetadata.msSource); + lcl_assignMeta(m_aContext.DocumentInfo.Type, aMetadata.msType); lcl_assignMeta(m_aContext.DocumentInfo.Creator, aMetadata.m_sCreatorTool); aMetadata.m_sCreateDate = m_aCreationMetaDateString; diff --git a/vcl/source/pdf/XmpMetadata.cxx b/vcl/source/pdf/XmpMetadata.cxx index 6dae3b86ebc1..7496ab26e3f5 100644 --- a/vcl/source/pdf/XmpMetadata.cxx +++ b/vcl/source/pdf/XmpMetadata.cxx @@ -65,7 +65,10 @@ void XmpMetadata::write() } // Dublin Core properties - if (!msTitle.isEmpty() || !msAuthor.isEmpty() || !msSubject.isEmpty()) + if (!msTitle.isEmpty() || !msAuthor.isEmpty() || !msSubject.isEmpty() + || !maContributor.empty() || !msCoverage.isEmpty() || !msIdentifier.isEmpty() + || !maPublisher.empty() || !maRelation.empty() || !msRights.isEmpty() + || !msSource.isEmpty() || !msType.isEmpty()) { aXmlWriter.startElement("rdf:Description"); aXmlWriter.attribute("rdf:about", OString("")); @@ -103,6 +106,80 @@ void XmpMetadata::write() aXmlWriter.endElement(); aXmlWriter.endElement(); } + if (!maContributor.empty()) + { + aXmlWriter.startElement("dc:contributor"); + aXmlWriter.startElement("rdf:Bag"); + for (const OString& rContributor : maContributor) + { + aXmlWriter.startElement("rdf:li"); + aXmlWriter.content(rContributor); + aXmlWriter.endElement(); + } + aXmlWriter.endElement(); + aXmlWriter.endElement(); + } + if (!msCoverage.isEmpty()) + { + aXmlWriter.startElement("dc:coverage"); + aXmlWriter.content(msCoverage); + aXmlWriter.endElement(); + } + if (!msIdentifier.isEmpty()) + { + aXmlWriter.startElement("dc:identifier"); + aXmlWriter.content(msIdentifier); + aXmlWriter.endElement(); + } + if (!maPublisher.empty()) + { + aXmlWriter.startElement("dc:publisher"); + aXmlWriter.startElement("rdf:Bag"); + for (const OString& rPublisher : maPublisher) + { + aXmlWriter.startElement("rdf:li"); + aXmlWriter.content(rPublisher); + aXmlWriter.endElement(); + } + aXmlWriter.endElement(); + aXmlWriter.endElement(); + } + if (!maRelation.empty()) + { + aXmlWriter.startElement("dc:relation"); + aXmlWriter.startElement("rdf:Bag"); + for (const OString& rRelation : maRelation) + { + aXmlWriter.startElement("rdf:li"); + aXmlWriter.content(rRelation); + aXmlWriter.endElement(); + } + aXmlWriter.endElement(); + aXmlWriter.endElement(); + } + if (!msRights.isEmpty()) + { + aXmlWriter.startElement("dc:rights"); + aXmlWriter.startElement("rdf:Alt"); + aXmlWriter.startElement("rdf:li"); + aXmlWriter.attribute("xml:lang", OString("x-default")); + aXmlWriter.content(msRights); + aXmlWriter.endElement(); + aXmlWriter.endElement(); + aXmlWriter.endElement(); + } + if (!msSource.isEmpty()) + { + aXmlWriter.startElement("dc:source"); + aXmlWriter.content(msSource); + aXmlWriter.endElement(); + } + if (!msType.isEmpty()) + { + aXmlWriter.startElement("dc:type"); + aXmlWriter.content(msType); + aXmlWriter.endElement(); + } aXmlWriter.endElement(); } diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx index 4f6f2223e721..eac87c5e2c63 100644 --- a/xmloff/source/core/xmltoken.cxx +++ b/xmloff/source/core/xmltoken.cxx @@ -530,6 +530,7 @@ namespace xmloff::token { TOKEN( "contour-path", XML_CONTOUR_PATH ), TOKEN( "contour-polygon", XML_CONTOUR_POLYGON ), TOKEN( "contrast", XML_CONTRAST ), + TOKEN( "contributor", XML_CONTRIBUTOR ), TOKEN( "control", XML_CONTROL ), TOKEN( "conversion-mode", XML_CONVERSION_MODE ), TOKEN( "conversion-type", XML_CONVERSION_TYPE ), @@ -554,6 +555,7 @@ namespace xmloff::token { TOKEN( "country", XML_COUNTRY ), TOKEN( "country-asian", XML_COUNTRY_ASIAN ), TOKEN( "country-complex", XML_COUNTRY_COMPLEX ), + TOKEN( "coverage", XML_COVERAGE ), TOKEN( "covered-table-cell", XML_COVERED_TABLE_CELL ), TOKEN( "create-date", XML_CREATE_DATE ), TOKEN( "create-date-string", XML_CREATE_DATE_STRING ), @@ -1636,6 +1638,7 @@ namespace xmloff::token { TOKEN( "rel-height-rel", XML_REL_HEIGHT_REL ), TOKEN( "rel-width", XML_REL_WIDTH ), TOKEN( "rel-width-rel", XML_REL_WIDTH_REL ), + TOKEN( "relation", XML_RELATION ), TOKEN( "relative", XML_RELATIVE ), TOKEN( "relative-tab-stop-position", XML_RELATIVE_TAB_STOP_POSITION ), TOKEN( "reln", XML_RELN ), @@ -1657,6 +1660,7 @@ namespace xmloff::token { TOKEN( "right-to-left", XML_RIGHT_TO_LEFT ), TOKEN( "right-arc", XML_RIGHTARC ), TOKEN( "right-circle", XML_RIGHTCIRCLE ), + TOKEN( "rights", XML_RIGHTS ), TOKEN( "ring", XML_RING ), TOKEN( "role", XML_ROLE ), TOKEN( "roll-from-bottom", XML_ROLL_FROM_BOTTOM ), diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt index 469d03645276..8bc75993eadf 100644 --- a/xmloff/source/token/tokens.txt +++ b/xmloff/source/token/tokens.txt @@ -435,6 +435,7 @@ continue-numbering contour-path contour-polygon contrast +contributor control conversion-mode conversion-type @@ -459,6 +460,7 @@ countnums country country-asian country-complex +coverage covered-table-cell create-date create-date-string @@ -1536,6 +1538,7 @@ rel-height rel-height-rel rel-width rel-width-rel +relation relative relative-tab-stop-position reln @@ -1557,6 +1560,7 @@ right-text right-to-left right-arc right-circle +rights ring role roll-from-bottom |