Rebased ref, commits from common ancestor: commit 6565cb791bc18903ff3111cbf86991d72e9318dd Author: Thorsten Behrens <thorsten.behr...@cib.de> Date: Sun Aug 20 03:43:20 2017 +0200
gpg4libre: pass down OpenPGP encryption info to package code Change-Id: Ie67c9927efdad4a027b14ed6a37a188b85eaf077 diff --git a/package/inc/PackageConstants.hxx b/package/inc/PackageConstants.hxx index df7bebcf6bd4..78736736d05a 100644 --- a/package/inc/PackageConstants.hxx +++ b/package/inc/PackageConstants.hxx @@ -34,6 +34,10 @@ const sal_Int32 n_ConstDigestDecrypt = 1056; // 1024 + 32 #define PKG_MNFST_VERSION 1 //Version #define PKG_MNFST_MEDIATYPE 2 //MediaType +#define PKG_MNFST_KEYID 3 //PGP Key ID +#define PKG_MNFST_KEYPACKET 4 //PGP Key packet +#define PKG_MNFST_CIPHERVAL 5 //PGP session key cipher value + #define PKG_MNFST_INIVECTOR 3 //InitialisationVector #define PKG_MNFST_SALT 4 //Salt #define PKG_MNFST_ITERATION 5 //IterationCount @@ -44,13 +48,15 @@ const sal_Int32 n_ConstDigestDecrypt = 1056; // 1024 + 32 #define PKG_MNFST_DIGESTALG 10 //DigestAlgorithm #define PKG_MNFST_DERKEYSIZE 11 //DerivedKeySize -#define PKG_SIZE_NOENCR_MNFST 3 -#define PKG_SIZE_ENCR_MNFST 12 +#define PKG_SIZE_NOENCR_MNFST 3 +#define PKG_SIZE_GPG_ENCR_MNFST 6 +#define PKG_SIZE_ENCR_MNFST 12 // the properties related constants #define ENCRYPTION_KEY_PROPERTY "EncryptionKey" #define STORAGE_ENCRYPTION_KEYS_PROPERTY "StorageEncryptionKeys" #define ENCRYPTION_ALGORITHMS_PROPERTY "EncryptionAlgorithms" +#define ENCRYPTION_GPG_PROPERTIES "EncryptionGpGProperties" #define HAS_ENCRYPTED_ENTRIES_PROPERTY "HasEncryptedEntries" #define HAS_NONENCRYPTED_ENTRIES_PROPERTY "HasNonEncryptedEntries" #define IS_INCONSISTENT_PROPERTY "IsInconsistent" diff --git a/package/inc/ZipPackage.hxx b/package/inc/ZipPackage.hxx index cd5a8caba757..b8f9cc69f7f2 100644 --- a/package/inc/ZipPackage.hxx +++ b/package/inc/ZipPackage.hxx @@ -73,6 +73,7 @@ protected: css::uno::Sequence< css::beans::NamedValue > m_aStorageEncryptionKeys; css::uno::Sequence< sal_Int8 > m_aEncryptionKey; + css::uno::Sequence< css::beans::NamedValue > m_aGpgProps; FolderHash m_aRecent; OUString m_aURL; diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx index ba9e705d76bb..c80f0c6b7a85 100644 --- a/package/source/zippackage/ZipPackage.cxx +++ b/package/source/zippackage/ZipPackage.cxx @@ -1197,7 +1197,9 @@ uno::Reference< io::XInputStream > ZipPackage::writeTempFile() if ( m_nFormat == embed::StorageFormats::PACKAGE ) { - uno::Sequence < PropertyValue > aPropSeq( PKG_SIZE_NOENCR_MNFST ); + static bool bGpgEncrypt = true; + uno::Sequence < PropertyValue > aPropSeq( + bGpgEncrypt ? PKG_SIZE_ENCR_MNFST : PKG_SIZE_GPG_ENCR_MNFST ); aPropSeq [PKG_MNFST_MEDIATYPE].Name = sMediaType; aPropSeq [PKG_MNFST_MEDIATYPE].Value <<= m_xRootFolder->GetMediaType(); aPropSeq [PKG_MNFST_VERSION].Name = sVersion; @@ -1205,6 +1207,14 @@ uno::Reference< io::XInputStream > ZipPackage::writeTempFile() aPropSeq [PKG_MNFST_FULLPATH].Name = sFullPath; aPropSeq [PKG_MNFST_FULLPATH].Value <<= OUString("/"); + if( bGpgEncrypt ) + { + for ( sal_Int32 nInd = 0; nInd < m_aGpgProps.getLength(); nInd++ ) + { + aPropSeq[PKG_MNFST_KEYID+nInd].Name = m_aGpgProps[nInd].Name; + aPropSeq[PKG_MNFST_KEYID+nInd].Value = m_aGpgProps[nInd].Value; + } + } aManList.push_back( aPropSeq ); } @@ -1732,6 +1742,17 @@ void SAL_CALL ZipPackage::setPropertyValue( const OUString& aPropertyName, const } } } + else if ( aPropertyName == ENCRYPTION_GPG_PROPERTIES ) + { + uno::Sequence< beans::NamedValue > aGpgProps; + if ( m_pZipFile || !( aValue >>= aGpgProps ) || aGpgProps.getLength() == 0 ) + { + // the algorithms can not be changed if the file has a persistence based on the algorithms ( m_pZipFile ) + throw IllegalArgumentException(THROW_WHERE "unexpected algorithms list is provided.", uno::Reference< uno::XInterface >(), 2 ); + } + + m_aGpgProps = aGpgProps; + } else throw UnknownPropertyException(THROW_WHERE ); } diff --git a/package/source/zippackage/ZipPackageStream.cxx b/package/source/zippackage/ZipPackageStream.cxx index e7f4e88f55c7..39b5c543d2df 100644 --- a/package/source/zippackage/ZipPackageStream.cxx +++ b/package/source/zippackage/ZipPackageStream.cxx @@ -518,6 +518,9 @@ bool ZipPackageStream::saveChild( const OUString sStartKeyAlgProperty ("StartKeyAlgorithm"); const OUString sDigestAlgProperty ("DigestAlgorithm"); const OUString sDerivedKeySizeProperty ("DerivedKeySize"); + const OUString sPgpKeyIDProperty ( "KeyId" ); + const OUString sPgpKeyPacketProperty ( "KeyPacket" ); + const OUString sCipherValueProperty ( "CipherValue" ); uno::Sequence < beans::PropertyValue > aPropSet (PKG_SIZE_NOENCR_MNFST); @@ -662,7 +665,8 @@ bool ZipPackageStream::saveChild( // last property is digest, which is inserted later if we didn't have // a magic header - aPropSet.realloc(PKG_SIZE_ENCR_MNFST); + static bool bGpgEncrypt = true; + aPropSet.realloc(bGpgEncrypt ? PKG_SIZE_ENCR_MNFST : PKG_SIZE_GPG_ENCR_MNFST); aPropSet[PKG_MNFST_INIVECTOR].Name = sInitialisationVectorProperty; aPropSet[PKG_MNFST_INIVECTOR].Value <<= m_xBaseEncryptionData->m_aInitVector; @@ -670,6 +674,15 @@ bool ZipPackageStream::saveChild( aPropSet[PKG_MNFST_SALT].Value <<= m_xBaseEncryptionData->m_aSalt; aPropSet[PKG_MNFST_ITERATION].Name = sIterationCountProperty; aPropSet[PKG_MNFST_ITERATION].Value <<= m_xBaseEncryptionData->m_nIterationCount; + if( bGpgEncrypt ) + { + aPropSet[PKG_MNFST_KEYID].Name = sPgpKeyIDProperty; + aPropSet[PKG_MNFST_KEYID].Value <<= m_xBaseEncryptionData->m_aSalt; + aPropSet[PKG_MNFST_KEYPACKET].Name = sPgpKeyPacketProperty; + aPropSet[PKG_MNFST_KEYPACKET].Value <<= m_xBaseEncryptionData->m_aSalt; + aPropSet[PKG_MNFST_CIPHERVAL].Name = sCipherValueProperty; + aPropSet[PKG_MNFST_CIPHERVAL].Value <<= m_xBaseEncryptionData->m_aSalt; + } // Need to store the uncompressed size in the manifest OSL_ENSURE( m_nOwnStreamOrigSize >= 0, "The stream size was not correctly initialized!" ); diff --git a/sfx2/source/dialog/filedlghelper.cxx b/sfx2/source/dialog/filedlghelper.cxx index ad2c469e1fdd..0fa1c7e7e67e 100644 --- a/sfx2/source/dialog/filedlghelper.cxx +++ b/sfx2/source/dialog/filedlghelper.cxx @@ -1513,8 +1513,9 @@ ErrCode FileDialogHelper_Impl::execute( std::vector<OUString>& rpURLList, } catch( const IllegalArgumentException& ){} } + // check, whether or not we have to display a key selection box - else if ( pCurrentFilter && mbHasPassword && mbIsGpgEnabled && xCtrlAccess.is() ) + if ( pCurrentFilter && mbHasPassword && mbIsGpgEnabled && xCtrlAccess.is() ) { try { @@ -1524,11 +1525,7 @@ ErrCode FileDialogHelper_Impl::execute( std::vector<OUString>& rpURLList, { // ask for a key OUString aDocName(rpURLList[0]); - // ErrCode errCode = RequestKey(pCurrentFilter, aDocName, rpSet); - //if (errCode != ERRCODE_NONE) - rpSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( ::comphelper::OStorageHelper::CreatePackageEncryptionData( keyId ) ) ) ); - - return ERRCODE_IO_NOTSUPPORTED; //errCode; + rpSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( ::comphelper::OStorageHelper::CreateGpgPackageEncryptionData(aDocName) ) ) ); } } catch( const IllegalArgumentException& ){} diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx index 1f05b72bde83..78a6cb4888cb 100644 --- a/sfx2/source/doc/objstor.cxx +++ b/sfx2/source/doc/objstor.cxx @@ -391,7 +391,17 @@ void SfxObjectShell::SetupStorage( const uno::Reference< embed::XStorage >& xSto catch( uno::Exception& ) { } + } + // if gpg -> force AES + if ( true ) + { + aEncryptionAlgs[0].Value <<= xml::crypto::DigestID::SHA256; + aEncryptionAlgs[1].Value <<= xml::crypto::CipherID::AES_CBC_W3C_PADDING; + aEncryptionAlgs[2].Value <<= xml::crypto::DigestID::SHA256_1K; + } + else if ( nDefVersion >= SvtSaveOptions::ODFVER_012 ) + { if ( !bUseSHA1InODF12 && nDefVersion != SvtSaveOptions::ODFVER_012_EXT_COMPAT ) { aEncryptionAlgs[0].Value <<= xml::crypto::DigestID::SHA256; commit ea87a60cdce4b847e1b5fd669361c8356996144e Author: Thorsten Behrens <thorsten.behr...@cib.de> Date: Sun Aug 20 03:42:47 2017 +0200 fixup add manifest entries for gpg encruption Change-Id: Ic14b603d33e87bb839d1a533eec59993da70a60e diff --git a/package/source/manifest/ManifestExport.cxx b/package/source/manifest/ManifestExport.cxx index 7c0491009beb..88762d272021 100644 --- a/package/source/manifest/ManifestExport.cxx +++ b/package/source/manifest/ManifestExport.cxx @@ -297,6 +297,7 @@ ManifestExport::ManifestExport( uno::Reference< xml::sax::XDocumentHandler > con "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" ); xHandler->startElement( sEncryptionMethodElement, xNewAttrList ); xHandler->ignorableWhitespace ( sWhiteSpace ); + xHandler->endElement( sEncryptionMethodElement ); xHandler->startElement( sKeyInfoElement, nullptr ); xHandler->ignorableWhitespace ( sWhiteSpace ); @@ -334,6 +335,9 @@ ManifestExport::ManifestExport( uno::Reference< xml::sax::XDocumentHandler > con xHandler->endElement( sCipherValueElement ); xHandler->ignorableWhitespace ( sWhiteSpace ); + xHandler->endElement( sCipherDataElement ); + xHandler->ignorableWhitespace ( sWhiteSpace ); + xHandler->endElement( sEncryptedKeyElement ); xHandler->ignorableWhitespace ( sWhiteSpace ); commit 15010e65458333052aac5d6b14c8b541cf3ad199 Author: Thorsten Behrens <thorsten.behr...@cib.de> Date: Sun Aug 20 03:38:05 2017 +0200 comphelper: add storage helper for GPG encryption data gpg4libre needs to pass down slightly different meta data to package / zip storage. Change-Id: Idba9ad7a821cb33070cf5e5a0f79ae55db99b276 diff --git a/comphelper/source/misc/storagehelper.cxx b/comphelper/source/misc/storagehelper.cxx index c4cc8178e298..7df94b276e8a 100644 --- a/comphelper/source/misc/storagehelper.cxx +++ b/comphelper/source/misc/storagehelper.cxx @@ -19,6 +19,7 @@ #include <com/sun/star/embed/ElementModes.hpp> #include <com/sun/star/embed/XEncryptionProtectedSource2.hpp> +#include <com/sun/star/embed/XEncryptionProtectedStorage.hpp> #include <com/sun/star/embed/XStorage.hpp> #include <com/sun/star/embed/XTransactedObject.hpp> #include <com/sun/star/embed/StorageFactory.hpp> @@ -38,6 +39,8 @@ #include <vector> #include <rtl/digest.h> +#include <rtl/random.h> +#include <osl/time.h> #include <osl/diagnose.h> #include <ucbhelper/content.hxx> @@ -190,11 +193,21 @@ void OStorageHelper::SetCommonStorageEncryptionData( const uno::Reference< embed::XStorage >& xStorage, const uno::Sequence< beans::NamedValue >& aEncryptionData ) { - uno::Reference< embed::XEncryptionProtectedSource2 > xEncrSet( xStorage, uno::UNO_QUERY ); + uno::Reference< embed::XEncryptionProtectedStorage > xEncrSet( xStorage, uno::UNO_QUERY ); if ( !xEncrSet.is() ) throw io::IOException(); // TODO - xEncrSet->setEncryptionData( aEncryptionData ); + if ( aEncryptionData.getLength() == 2 && + aEncryptionData[0].Name == "GpgInfos" && + aEncryptionData[1].Name == "EncryptionKey" ) + { + xEncrSet->setGpgProperties( + aEncryptionData[0].Value.get< uno::Sequence< beans::NamedValue > >() ); + xEncrSet->setEncryptionData( + aEncryptionData[1].Value.get< uno::Sequence< beans::NamedValue > >() ); + } + else + xEncrSet->setEncryptionData( aEncryptionData ); } @@ -403,6 +416,47 @@ uno::Sequence< beans::NamedValue > OStorageHelper::CreatePackageEncryptionData( return aEncryptionData; } +uno::Sequence< beans::NamedValue > OStorageHelper::CreateGpgPackageEncryptionData( const OUString& aDocName ) +{ + // generate session key + // -------------------- + + // Get a random number generator and seed it with current timestamp + TimeValue aTime; + osl_getSystemTime( &aTime ); + rtlRandomPool aRandomPool = rtl_random_createPool(); + rtl_random_addBytes(aRandomPool, &aTime, 8); + + // get 16 random chars out of it + uno::Sequence < sal_Int8 > aVector(16); + rtl_random_getBytes( aRandomPool, aVector.getArray(), aVector.getLength() ); + + rtl_random_destroyPool(aRandomPool); + + uno::Sequence< beans::NamedValue > aContainer(2); + uno::Sequence< beans::NamedValue > aGpgEncryptionData(3); + uno::Sequence< beans::NamedValue > aEncryptionData(1); + + // TODO perhaps rename that one - bit misleading name ... + aGpgEncryptionData[0].Name = "KeyId"; + aGpgEncryptionData[0].Value <<= OUString("jypAUdH0E9c="); + aGpgEncryptionData[0].Name = "KeyPacket"; + aGpgEncryptionData[0].Value <<= OUString("LS0tLS1CRUdJTiBQR1AgUFJJVkFURSBLRVkgQkxPQ0stLS0tLQpWZXJzaW9uOiBHbnVQRyB2MQoKbFFJR0JGY3J4V3NCQkFDM1VBdko4Sk9PZWZZcVVYQVNzVHkrUHBjNHp3cU9YZlRZT2VTSk45V3RZWDVBdU9RNgpjdzZUTmhhbExwT1hLNlhLcUpoMklqSVh6cE1jUzEvQzg1QlNSK0V6dm51VXlhUCtZTXI4VzkyalZwNGo2OWJFCkR1Mnd2Nm5wTnFvRDhqY3NBMHJLeUFoVEg0c3lNL2RMcm1FOThEVXJibGRscE11R0VDUFg0L2tVSHdBUkFRQUIKL2djREFqbjhxQXJpdllBVVlLVGtxd1U5dTRseUdhUEFzOFZNc0ltWTRYUksxd1hOWHNmVC9vaG44QWh4OHJWWQp3eCtQUnFVemxrS2xiNFhkcjBzL0VKSWp0bmx4c3ZPYWlsY1VFaFpEL0VkaHM5WEI2MUl0UFdSWm1OMW1lbGt0Ck1lZDBLL1hCdzVxejJUemZGcFBaaGIxdjZMY0IwRmZnSjY2K1JBWW9EZXVmRGdGNllNcmhrc3kvVnNwM1MrYTYKNE4rclBuNWlkcTVPOU5lb09MVCt5RGRBVTlFeFAxVnd1SFY5V01UT3JvcUtKZUYyT1lvSW05V2dzTGd6ZEU1OQpuSXFVNC9FcWQxYUpCbTgrRTBtbnhFd0VuS2JJNEtOa0tzdDAwRXFmTmIzVXA4RlFJV3hVRnlaclplL2JmeTNCCnVrM2IzZ0xRUlRqUHJvR0JNS3B2UWQvd2xVVTVESS92OUdHMWtpT2duV1dnZGFWWjBFazdzTWhaY1R3aWpHNFYKaUVaOEE1bVZRWXBMTlFwY29jRGdoM0lyRzBkSFVkNVorRUVaQkRSbElaRklKVnVyak9XempzM2lsd3ZhYWpmUwppSFdiZUw 4Nmh2bFVWV2hCTCtqMUhsTDRZWjg2SmJNc0kzQ0ZmaEJXT1pqbEFMMTRvc1NHNUVLMEhGUmxjM1FnClZYTmxjaUE4ZEdWemRFQmxlR0Z0Y0d4bExtTnZiVDZJdmdRVEFRSUFLQVVDVnl2RmF3SWJBd1VKQUFGUmdBWUwKQ1FnSEF3SUdGUWdDQ1FvTEJCWUNBd0VDSGdFQ0Y0QUFDZ2tRanlwQVVkSDBFOWVwTGdQOUcxLytPU0pkVWVzKwp3ZDMvQmdwbUxqdWRsWEVXQVZjZnh2UlpHbmVjY2VwOXl5ay90WHRSc3lnNjMyTnV5REFlUk5EWmRDVEFHNGNUCmQxY1crWnJsQzM5T1MrOFUrQUFVUi82QlVic3JXT0RrMTVzN2VOOUs3NmE2SU9Lb2RKRHd1QkVkZDJQcUdCd3YKQ1Qwam5pT0pXUFVZdjJzOHBPMGFndzdVV0dNUzdmU2RBZ1lFVnl2RmF3RUVBTU04aVZnMERNbEpPSlQwbmhFQgp2dFR3ZUpIeFB2akpnTHNmUlFsdkNlQWs1U2taV1pNTllxRnRxbTl6NmJqMkJobnlYU0tFMENBem4xTXhsc1o2CjlJWkJPQ3ZURlRRY1pZQ3V2N1UwY3prU0xzMlBvN1VMeXJKMFNpSS9OS2NSdVhIR3ZDSzdWUHdpK2RROTNITUEKWUxOZ2FyblJ1cVUzbHd1NU1yaHROZVpOQUJFQkFBSCtCd01DT2Z5b0N1SzlnQlJnZm1XUmlRc1VzU1BkRTlDRwptaGpRcDdKOWRNQTIrWDhsK0NnaU8yU2J3SG5idmwrWEtLaElzaGNRSWp2UitMdHZnRFFoZkN6TlJwNTBnRlRUCkZNZER6RlVJakVhYVRleDh2cUFkV1lQcjl5SitVSGdUVWhTdVB5eG41UHYrVmR1MmhTai9pVzJpeEVUQ2J5ZkUKOWt6R2FsMGJaQWRiWFZEcHFoam1rbHAzVXlkQm1xRzVoMmJ4cS9Z eFRKYmZ4S01RQm03Ukw4MDBHbjYwUWhsUwpDTkNmWVFRa290cmlnMzNzWHl4Q1RSZDQ3Ymk1Zmlta2JoOVllcnU5Q29sUDVqQUQwSm43NjBxYk5MZjcveFNCCnJRRENzL0k4R1lYMmtkQllrOUxpYm03Y1FhNjRrRDVaMzZtdGdNNERGQjEwbUMxaDVRZVpuRUJtczdKei9PUTMKdWtUWU1JYTBUT1VnY25jTG40K0pKckZQTkxYak9rNVdid0FzN0hYKzEyVitXb05oSmhVdlhMYXFHTTcrUWtUUwplMERJazVCZFZxUlp4VURJRDM0OEhQR0Ntc21VUlRGRDcxbEZKMy91Zkg3a2FHTmVzUnBnZFplSmFGUlFybS93CkpLQ1c2SXJJbEt1cWNpNDRMdkpBYTRpbEJCZ0JBZ0FQQlFKWEs4VnJBaHNNQlFrQUFWR0FBQW9KRUk4cVFGSFIKOUJQWHdVVUQvaTh5eStTOVpjdWhWcUxuTmNXNkxzSHhUaHE2MXVMRysxcTg3aFBYVGxLMmt3M0M5QTI2OUlqOApBUkhRaGpBSUFSSkM3MHNCaWVKK0xMMlZWa1ZYakVnYnpqdlNHTUE3dkRXRlBJOHovdHVxSnBKeW1zR0tEbFJ4CkptSVBkRFFOVlJtZGV6cnd1WlNlaVJabE43SjNNNnQvenJCNzFHVU9CakhLS2Jua2pKdUQKPXpyZG4KLS0tLS1FTkQgUEdQIFBSSVZBVEUgS0VZIEJMT0NLLS0tLS0K"); + aGpgEncryptionData[0].Name = "CipherValue"; + aGpgEncryptionData[0].Value <<= OUString("FAm4BDOfQRJ66/ecfIByCck3JxaKYYEWwms7z+Vsb+iqPWyPGdbgJNkRBAWH4V92JvMoc/QcD/1+z+iRvR6PMGdDHAyprIh5uGHs7mo+dqabJU0qOhHb16InW2XO1GqhmjzMDUw+q4ot28jpfIVSMKPlf6b8vnNUICMJjXn+aB8="); + + aEncryptionData[0].Name = PACKAGE_ENCRYPTIONDATA_SHA256UTF8; + aEncryptionData[0].Value <<= aVector; + + aContainer[0].Name = "GpgInfos"; + aContainer[0].Value = makeAny(aGpgEncryptionData); + aContainer[1].Name = "EncryptionKey"; + aContainer[1].Value = makeAny(aEncryptionData); + + (void)aDocName; + + return aContainer; +} bool OStorageHelper::IsValidZipEntryFileName( const OUString& aName, bool bSlashAllowed ) { diff --git a/include/comphelper/storagehelper.hxx b/include/comphelper/storagehelper.hxx index 84c958fb1f23..2b8b6cab9e3d 100644 --- a/include/comphelper/storagehelper.hxx +++ b/include/comphelper/storagehelper.hxx @@ -172,6 +172,10 @@ public: CreatePackageEncryptionData( const OUString& aPassword ); + static css::uno::Sequence< css::beans::NamedValue > + CreateGpgPackageEncryptionData( + const OUString& aDocName ); + static bool IsValidZipEntryFileName( const OUString& aName, bool bSlashAllowed ); static bool IsValidZipEntryFileName( const sal_Unicode *pChar, sal_Int32 nLength, bool bSlashAllowed ); diff --git a/offapi/com/sun/star/embed/XEncryptionProtectedStorage.idl b/offapi/com/sun/star/embed/XEncryptionProtectedStorage.idl index 5ddcc6831844..5ed2524daf81 100644 --- a/offapi/com/sun/star/embed/XEncryptionProtectedStorage.idl +++ b/offapi/com/sun/star/embed/XEncryptionProtectedStorage.idl @@ -84,6 +84,11 @@ interface XEncryptionProtectedStorage: XEncryptionProtectedSource2 /** allows to get the encryption algorithms of the object. */ sequence< ::com::sun::star::beans::NamedValue > getEncryptionAlgorithms(); + + /** set OpenPGP-specific encryption properties + */ + void setGpgProperties( [in] sequence< ::com::sun::star::beans::NamedValue > aProps ) + raises( ::com::sun::star::lang::IllegalArgumentException ); }; diff --git a/package/source/xstor/xstorage.cxx b/package/source/xstor/xstorage.cxx index 9586bcbdc433..194ec00a67b9 100644 --- a/package/source/xstor/xstorage.cxx +++ b/package/source/xstor/xstorage.cxx @@ -4216,6 +4216,66 @@ void SAL_CALL OStorage::setEncryptionAlgorithms( const uno::Sequence< beans::Nam } } +void SAL_CALL OStorage::setGpgProperties( const uno::Sequence< beans::NamedValue >& aProps ) +{ + ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() ); + + if ( !m_pImpl ) + { + SAL_INFO("package.xstor", THROW_WHERE "Disposed!"); + throw lang::DisposedException( THROW_WHERE ); + } + + if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE ) + throw uno::RuntimeException( THROW_WHERE ); // the interface must be visible only for package storage + + if ( !aProps.getLength() ) + throw uno::RuntimeException( THROW_WHERE "Unexpected empty encryption algorithms list!" ); + + SAL_WARN_IF( !m_pData->m_bIsRoot, "package.xstor", "setEncryptionAlgorithms() method is not available for nonroot storages!" ); + if ( m_pData->m_bIsRoot ) + { + try { + m_pImpl->ReadContents(); + } + catch ( const uno::RuntimeException& aRuntimeException ) + { + SAL_INFO("package.xstor", "Rethrow: " << aRuntimeException.Message); + throw; + } + catch ( const uno::Exception& aException ) + { + SAL_INFO("package.xstor", "Rethrow: " << aException.Message); + + uno::Any aCaught( ::cppu::getCaughtException() ); + throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open package!", + static_cast< OWeakObject* >( this ), + aCaught ); + } + + uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW ); + try + { + xPackPropSet->setPropertyValue( ENCRYPTION_GPG_PROPERTIES, + uno::makeAny( aProps ) ); + } + catch ( const uno::RuntimeException& aRuntimeException ) + { + SAL_INFO("package.xstor", "Rethrow: " << aRuntimeException.Message); + throw; + } + catch( const uno::Exception& aException ) + { + SAL_INFO("package.xstor", "Rethrow: " << aException.Message); + + uno::Any aCaught( ::cppu::getCaughtException() ); + throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open package!", + static_cast< OWeakObject* >( this ), + aCaught ); + } + } +} + uno::Sequence< beans::NamedValue > SAL_CALL OStorage::getEncryptionAlgorithms() { ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() ); diff --git a/package/source/xstor/xstorage.hxx b/package/source/xstor/xstorage.hxx index 5bd4d654f7b9..2b798a502fcd 100644 --- a/package/source/xstor/xstorage.hxx +++ b/package/source/xstor/xstorage.hxx @@ -457,6 +457,7 @@ public: // XEncryptionProtectedStorage virtual void SAL_CALL setEncryptionAlgorithms( const css::uno::Sequence< css::beans::NamedValue >& aAlgorithms ) override; + virtual void SAL_CALL setGpgProperties( const css::uno::Sequence< css::beans::NamedValue >& aAlgorithms ) override; virtual css::uno::Sequence< css::beans::NamedValue > SAL_CALL getEncryptionAlgorithms() override; commit 33cc1a6fcd33aac68492d3fa0f500733c8633ab0 Author: Thorsten Behrens <thorsten.behr...@cib.de> Date: Sun Aug 20 03:18:09 2017 +0200 package: get rid of requirement for plain passwords Change-Id: I36d41d9166ae2b2ea287af82c87b5f2ea86bd564 diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx index 66e40cb9d410..ba9e705d76bb 100644 --- a/package/source/zippackage/ZipPackage.cxx +++ b/package/source/zippackage/ZipPackage.cxx @@ -1664,9 +1664,8 @@ void SAL_CALL ZipPackage::setPropertyValue( const OUString& aPropertyName, const // this property is only necessary to support raw passwords in storage API; // because of this support the storage has to operate with more than one key dependent on storage generation algorithm; // when this support is removed, the storage will get only one key from outside - // TODO/LATER: Get rid of this property as well as of support of raw passwords in storages uno::Sequence< beans::NamedValue > aKeys; - if ( !( aValue >>= aKeys ) || ( aKeys.getLength() && aKeys.getLength() < 2 ) ) + if ( !( aValue >>= aKeys ) || ( aKeys.getLength() && aKeys.getLength() < 1 ) ) throw IllegalArgumentException(THROW_WHERE, uno::Reference< uno::XInterface >(), 2 ); if ( aKeys.getLength() ) @@ -1681,7 +1680,7 @@ void SAL_CALL ZipPackage::setPropertyValue( const OUString& aPropertyName, const bHasSHA1 = true; } - if ( !bHasSHA256 || !bHasSHA1 ) + if ( !bHasSHA256 && !bHasSHA1 ) throw IllegalArgumentException(THROW_WHERE "Expected keys are not provided!", uno::Reference< uno::XInterface >(), 2 ); } commit cf9a61a09754ad1aa4c20ecad586360b86e92391 Author: Thorsten Behrens <thorsten.behr...@cib.de> Date: Sat Aug 19 22:27:36 2017 +0200 fixup bubli ui patches Change-Id: I8bc092fa286c2ab7c941e0fe5d2c014636b0c759 diff --git a/fpicker/source/office/OfficeControlAccess.cxx b/fpicker/source/office/OfficeControlAccess.cxx index 6d8543044cbc..d550ddb8bc79 100644 --- a/fpicker/source/office/OfficeControlAccess.cxx +++ b/fpicker/source/office/OfficeControlAccess.cxx @@ -405,6 +405,7 @@ namespace svt { case CHECKBOX_AUTOEXTENSION: case CHECKBOX_PASSWORD: + case CHECKBOX_GPG: case CHECKBOX_FILTEROPTIONS: case CHECKBOX_READONLY: case CHECKBOX_LINK: diff --git a/fpicker/source/office/iodlg.cxx b/fpicker/source/office/iodlg.cxx index df21d5f00d7f..f61ba454b948 100644 --- a/fpicker/source/office/iodlg.cxx +++ b/fpicker/source/office/iodlg.cxx @@ -556,6 +556,7 @@ void SvtFileDialog::Init_Impl get(pImpl->_pBtnConnectToServer, "connect_to_server"); get(pImpl->_pBtnNewFolder, "new_folder"); get(pImpl->_pCbPassword, "password"); + get(pImpl->_pCbGPGEncrypt, "gpgencrypt"); get(pImpl->_pCbAutoExtension, "extension"); get(pImpl->_pFtFileVersion, "shared_label"); get(pImpl->_pLbFileVersion, "shared"); @@ -639,6 +640,11 @@ void SvtFileDialog::Init_Impl pImpl->_pCbPassword->SetClickHdl( LINK( this, SvtFileDialog, ClickHdl_Impl ) ); pImpl->_pCbPassword->Show(); } + if ( nStyle & PickerFlags::Password ) + { + pImpl->_pCbGPGEncrypt->SetClickHdl( LINK( this, SvtFileDialog, ClickHdl_Impl ) ); + pImpl->_pCbGPGEncrypt->Show(); + } // set the ini file for extracting the size pImpl->_aIniKey = "FileDialog"; @@ -1530,6 +1536,8 @@ IMPL_LINK( SvtFileDialog, ClickHdl_Impl, Button*, pCheckBox, void ) nId = CHECKBOX_READONLY; else if ( pCheckBox == pImpl->_pCbPassword ) nId = CHECKBOX_PASSWORD; + else if ( pCheckBox == pImpl->_pCbGPGEncrypt ) + nId = CHECKBOX_GPG; else if ( pCheckBox == _pCbLinkBox ) nId = CHECKBOX_LINK; else if ( pCheckBox == _pCbPreviewBox ) @@ -2319,6 +2327,10 @@ Control* SvtFileDialog::getControl( sal_Int16 _nControlId, bool _bLabelControl ) pReturn = pImpl->_pCbPassword; break; + case CHECKBOX_GPG: + pReturn = pImpl->_pCbGPGEncrypt; + break; + case CHECKBOX_FILTEROPTIONS: pReturn = pImpl->_pCbOptions; break; diff --git a/fpicker/uiconfig/ui/explorerfiledialog.ui b/fpicker/uiconfig/ui/explorerfiledialog.ui index 95dc9216ae2c..deb706e349c0 100644 --- a/fpicker/uiconfig/ui/explorerfiledialog.ui +++ b/fpicker/uiconfig/ui/explorerfiledialog.ui @@ -437,7 +437,7 @@ </packing> </child> <child> - <object class="GtkCheckButton" id="selection1"> + <object class="GtkCheckButton" id="selection"> <property name="label"> </property> <property name="use_action_appearance">False</property> commit b8c020120f350d1e173f444ce416bd0f7899eb53 Author: Thorsten Behrens <thorsten.behr...@cib.de> Date: Fri Aug 18 22:01:13 2017 +0200 request key from filepicker Change-Id: I3a20f293bd12fc3de76fb1e846452c0a574e8794 diff --git a/offapi/com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.idl b/offapi/com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.idl index f213b0344cd9..40f8d5591a70 100644 --- a/offapi/com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.idl +++ b/offapi/com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.idl @@ -49,6 +49,7 @@ published constants ExtendedFilePickerElementIds const short LISTBOX_TEMPLATE_LABEL = 208; const short LISTBOX_IMAGE_TEMPLATE_LABEL = 209; const short LISTBOX_FILTER_SELECTOR = 210; + const short CHECKBOX_GPG = 211; }; diff --git a/sfx2/source/dialog/filedlghelper.cxx b/sfx2/source/dialog/filedlghelper.cxx index 3cd8ef520f64..ad2c469e1fdd 100644 --- a/sfx2/source/dialog/filedlghelper.cxx +++ b/sfx2/source/dialog/filedlghelper.cxx @@ -881,6 +881,7 @@ FileDialogHelper_Impl::FileDialogHelper_Impl( mbHasPassword = false; m_bHaveFilterOptions = false; mbIsPwdEnabled = true; + mbIsGpgEnabled = true; mbHasVersions = false; mbHasPreview = false; mbShowPreview = false; @@ -1512,6 +1513,26 @@ ErrCode FileDialogHelper_Impl::execute( std::vector<OUString>& rpURLList, } catch( const IllegalArgumentException& ){} } + // check, whether or not we have to display a key selection box + else if ( pCurrentFilter && mbHasPassword && mbIsGpgEnabled && xCtrlAccess.is() ) + { + try + { + Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_GPG, 0 ); + bool bGpg = false; + if ( ( aValue >>= bGpg ) && bGpg ) + { + // ask for a key + OUString aDocName(rpURLList[0]); + // ErrCode errCode = RequestKey(pCurrentFilter, aDocName, rpSet); + //if (errCode != ERRCODE_NONE) + rpSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( ::comphelper::OStorageHelper::CreatePackageEncryptionData( keyId ) ) ) ); + + return ERRCODE_IO_NOTSUPPORTED; //errCode; + } + } + catch( const IllegalArgumentException& ){} + } SaveLastUsedFilter(); return ERRCODE_NONE; diff --git a/sfx2/source/dialog/filedlgimpl.hxx b/sfx2/source/dialog/filedlgimpl.hxx index 736d00d41e10..595afd2fca39 100644 --- a/sfx2/source/dialog/filedlgimpl.hxx +++ b/sfx2/source/dialog/filedlgimpl.hxx @@ -76,6 +76,7 @@ namespace sfx2 bool mbHasPassword : 1; bool mbIsPwdEnabled : 1; + bool mbIsGpgEnabled : 1; bool m_bHaveFilterOptions : 1; bool mbHasVersions : 1; bool mbHasAutoExt : 1; commit a523297b93b7481abb4028bb692cf0889c881b58 Author: Katarina Behrens <katarina.behr...@cib.de> Date: Thu Aug 17 17:56:45 2017 +0200 gpg4libre: Add flag for filters that support GPG encryption Change-Id: I48518f26a3ccbe430d36fb6657bdeff0943492d3 diff --git a/filter/source/config/cache/constant.hxx b/filter/source/config/cache/constant.hxx index 7e8cc0218a9a..66b47dc304df 100644 --- a/filter/source/config/cache/constant.hxx +++ b/filter/source/config/cache/constant.hxx @@ -106,6 +106,7 @@ #define FLAGNAME_DEFAULT "DEFAULT" #define FLAGNAME_ENCRYPTION "ENCRYPTION" #define FLAGNAME_EXPORT "EXPORT" +#define FLAGNAME_GPGENCRYPTION "GPGENCRYPTION" #define FLAGNAME_IMPORT "IMPORT" #define FLAGNAME_INTERNAL "INTERNAL" #define FLAGNAME_NOTINFILEDIALOG "NOTINFILEDIALOG" diff --git a/filter/source/config/cache/filtercache.cxx b/filter/source/config/cache/filtercache.cxx index 09a136af4120..05b7e52ad8e2 100644 --- a/filter/source/config/cache/filtercache.cxx +++ b/filter/source/config/cache/filtercache.cxx @@ -1879,6 +1879,7 @@ css::uno::Sequence< OUString > FilterCache::impl_convertFlagField2FlagNames(SfxF if (nFlags & SfxFilterFlags::TEMPLATEPATH ) lFlagNames.push_back(FLAGNAME_TEMPLATEPATH ); if (nFlags & SfxFilterFlags::COMBINED ) lFlagNames.push_back(FLAGNAME_COMBINED ); if (nFlags & SfxFilterFlags::SUPPORTSSIGNING) lFlagNames.push_back(FLAGNAME_SUPPORTSSIGNING); + if (nFlags & SfxFilterFlags::GPGENCRYPTION) lFlagNames.push_back(FLAGNAME_GPGENCRYPTION); return comphelper::containerToSequence(lFlagNames); } @@ -1924,6 +1925,11 @@ SfxFilterFlags FilterCache::impl_convertFlagNames2FlagField(const css::uno::Sequ nField |= SfxFilterFlags::EXPORT; continue; } + if (pNames[i] == FLAGNAME_GPGENCRYPTION) + { + nField |= SfxFilterFlags::GPGENCRYPTION; + continue; + } if (pNames[i] == FLAGNAME_IMPORT) { nField |= SfxFilterFlags::IMPORT; diff --git a/filter/source/config/fragments/filters/writer8.xcu b/filter/source/config/fragments/filters/writer8.xcu index 410b3a77e717..def9d57d532f 100644 --- a/filter/source/config/fragments/filters/writer8.xcu +++ b/filter/source/config/fragments/filters/writer8.xcu @@ -16,7 +16,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . --> <node oor:name="writer8" oor:op="replace"> - <prop oor:name="Flags"><value>IMPORT EXPORT TEMPLATE OWN DEFAULT PREFERRED ENCRYPTION PASSWORDTOMODIFY</value></prop> + <prop oor:name="Flags"><value>IMPORT EXPORT TEMPLATE OWN DEFAULT PREFERRED ENCRYPTION PASSWORDTOMODIFY GPGENCRYPTION</value></prop> <prop oor:name="UIComponent"/> <prop oor:name="FilterService"/> <prop oor:name="UserData"><value>CXML</value></prop> diff --git a/include/comphelper/documentconstants.hxx b/include/comphelper/documentconstants.hxx index 75418535c80f..9447a7b17fc6 100644 --- a/include/comphelper/documentconstants.hxx +++ b/include/comphelper/documentconstants.hxx @@ -110,13 +110,15 @@ enum class SfxFilterFlags ENCRYPTION = 0x01000000L, PASSWORDTOMODIFY = 0x02000000L, + GPGENCRYPTION = 0x04000000L, PREFERED = 0x10000000L, STARTPRESENTATION = 0x20000000L, SUPPORTSSIGNING = 0x40000000L, }; + namespace o3tl { - template<> struct typed_flags<SfxFilterFlags> : is_typed_flags<SfxFilterFlags, 0x739f157fL> {}; + template<> struct typed_flags<SfxFilterFlags> : is_typed_flags<SfxFilterFlags, 0x779f157fL> {}; } #define SFX_FILTER_NOTINSTALLED (SfxFilterFlags::MUSTINSTALL | SfxFilterFlags::CONSULTSERVICE) diff --git a/include/sfx2/docfilt.hxx b/include/sfx2/docfilt.hxx index 47454f90e742..75b889f451d3 100644 --- a/include/sfx2/docfilt.hxx +++ b/include/sfx2/docfilt.hxx @@ -78,6 +78,7 @@ public: bool IsOwnFormat() const { return bool(nFormatType & SfxFilterFlags::OWN); } /// If the filter supports digital signatures. bool GetSupportsSigning() const { return bool(nFormatType & SfxFilterFlags::SUPPORTSSIGNING); } + bool GetGpgEncryption() const { return bool(nFormatType & SfxFilterFlags::GPGENCRYPTION); } bool IsOwnTemplateFormat() const { return bool(nFormatType & SfxFilterFlags::TEMPLATEPATH); } bool IsAlienFormat() const { return bool(nFormatType & SfxFilterFlags::ALIEN); } bool CanImport() const { return bool(nFormatType & SfxFilterFlags::IMPORT); } commit 185a6cf9ff88526dc6c7df6957940fd32629bff4 Author: Katarina Behrens <katarina.behr...@cib.de> Date: Fri Aug 18 15:51:38 2017 +0200 gpg4libre: Encrypt with GPG checkbox in SaveAs file dialog, 1st stab LibO's own file dialog only so far Change-Id: Ic5f6c180afb5d4e0fc151ad57d769b99ad7fbdf3 diff --git a/fpicker/source/office/iodlgimp.cxx b/fpicker/source/office/iodlgimp.cxx index e45764e7782e..3a9963c813d6 100644 --- a/fpicker/source/office/iodlgimp.cxx +++ b/fpicker/source/office/iodlgimp.cxx @@ -222,6 +222,7 @@ SvtExpFileDlg_Impl::SvtExpFileDlg_Impl() : _pBtnUp ( nullptr ), _pBtnNewFolder ( nullptr ), _pCbPassword ( nullptr ), + _pCbGPGEncrypt ( nullptr ), _pEdCurrentPath ( nullptr ), _pCbAutoExtension ( nullptr ), _pCbOptions ( nullptr ), diff --git a/fpicker/source/office/iodlgimp.hxx b/fpicker/source/office/iodlgimp.hxx index 521871d2473f..233beb856491 100644 --- a/fpicker/source/office/iodlgimp.hxx +++ b/fpicker/source/office/iodlgimp.hxx @@ -145,6 +145,7 @@ public: VclPtr<SvtUpButton_Impl> _pBtnUp; VclPtr<PushButton> _pBtnNewFolder; VclPtr<CheckBox> _pCbPassword; + VclPtr<CheckBox> _pCbGPGEncrypt; VclPtr<SvtURLBox> _pEdCurrentPath; VclPtr<CheckBox> _pCbAutoExtension; VclPtr<CheckBox> _pCbOptions; diff --git a/fpicker/uiconfig/ui/explorerfiledialog.ui b/fpicker/uiconfig/ui/explorerfiledialog.ui index 04c4f824d692..95dc9216ae2c 100644 --- a/fpicker/uiconfig/ui/explorerfiledialog.ui +++ b/fpicker/uiconfig/ui/explorerfiledialog.ui @@ -433,11 +433,11 @@ </object> <packing> <property name="left_attach">0</property> - <property name="top_attach">1</property> + <property name="top_attach">2</property> </packing> </child> <child> - <object class="GtkCheckButton" id="selection"> + <object class="GtkCheckButton" id="selection1"> <property name="label"> </property> <property name="use_action_appearance">False</property> @@ -448,9 +448,25 @@ </object> <packing> <property name="left_attach">1</property> + <property name="top_attach">2</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="gpgencrypt"> + <property name="label" translatable="yes">Encrypt with GPG key</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="left_attach">0</property> <property name="top_attach">1</property> </packing> </child> + <child> + <placeholder/> + </child> </object> <packing> <property name="left_attach">0</property> commit 0aa6193f526f72168019b685a16c5e15a9e11c3f Author: Thorsten Behrens <thorsten.behr...@cib.de> Date: Fri Aug 18 21:34:11 2017 +0200 add manifest entries for gpg encruption Change-Id: I71bd7e2c6c73d997fa1ed5bb36fdc2873daca10c diff --git a/package/source/manifest/ManifestDefines.hxx b/package/source/manifest/ManifestDefines.hxx index 968aed648e6a..42ff1ceeadbc 100644 --- a/package/source/manifest/ManifestDefines.hxx +++ b/package/source/manifest/ManifestDefines.hxx @@ -24,8 +24,10 @@ #define MANIFEST_NSPREFIX "manifest:" #define ELEMENT_MANIFEST "manifest:manifest" #define ATTRIBUTE_XMLNS "xmlns:manifest" +#define ATTRIBUTE_XMLNS_LOEXT "xmlns:loext" #define MANIFEST_NAMESPACE "http://openoffice.org/2001/manifest" #define MANIFEST_OASIS_NAMESPACE "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" +#define MANIFEST_LOEXT_NAMESPACE "urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" #define MANIFEST_DOCTYPE "<!DOCTYPE manifest:manifest PUBLIC \"-//OpenOffice.org//DTD Manifest 1.0//EN\" \"Manifest.dtd\">" #define ATTRIBUTE_CDATA "CDATA" @@ -34,6 +36,15 @@ #define ATTRIBUTE_VERSION "manifest:version" #define ATTRIBUTE_MEDIA_TYPE "manifest:media-type" #define ATTRIBUTE_SIZE "manifest:size" +#define ELEMENT_KEYINFO "loext:KeyInfo" +#define ELEMENT_ENCRYPTEDKEY "loext:EncryptedKey" +#define ELEMENT_ENCRYPTIONMETHOD "loext:EncryptionMethod" +#define ELEMENT_PGPDATA "loext:PGPData" +#define ELEMENT_PGPKEYID "loext:PGPKeyID" +#define ELEMENT_PGPKEYPACKET "loext:PGPKeyPacket" +#define ATTRIBUTE_ALGORITHM "loext:Algorithm" +#define ELEMENT_CIPHERDATA "loext:CipherData" +#define ELEMENT_CIPHERVALUE "loext:CipherValue" #define ELEMENT_ENCRYPTION_DATA "manifest:encryption-data" #define ATTRIBUTE_CHECKSUM_TYPE "manifest:checksum-type" diff --git a/package/source/manifest/ManifestExport.cxx b/package/source/manifest/ManifestExport.cxx index 915c8f243bd7..7c0491009beb 100644 --- a/package/source/manifest/ManifestExport.cxx +++ b/package/source/manifest/ManifestExport.cxx @@ -66,11 +66,23 @@ ManifestExport::ManifestExport( uno::Reference< xml::sax::XDocumentHandler > con const OUString sChecksumTypeAttribute ( ATTRIBUTE_CHECKSUM_TYPE ); const OUString sChecksumAttribute ( ATTRIBUTE_CHECKSUM); + const OUString sKeyInfoElement ( ELEMENT_KEYINFO ); + const OUString sEncryptedKeyElement ( ELEMENT_ENCRYPTEDKEY ); + const OUString sEncryptionMethodElement ( ELEMENT_ENCRYPTIONMETHOD ); + const OUString sPgpDataElement ( ELEMENT_PGPDATA ); + const OUString sPgpKeyIDElement ( ELEMENT_PGPKEYID ); + const OUString sPGPKeyPacketElement ( ELEMENT_PGPKEYPACKET ); + const OUString sAlgorithmAttribute ( ATTRIBUTE_ALGORITHM ); + const OUString sCipherDataElement ( ELEMENT_CIPHERDATA ); + const OUString sCipherValueElement ( ELEMENT_CIPHERVALUE ); + const OUString sPgpKeyIDProperty ( "KeyId" ); + const OUString sPgpKeyPacketProperty ( "KeyPacket" ); + const OUString sCipherValueProperty ( "CipherValue" ); const OUString sFullPathProperty ( "FullPath" ); const OUString sVersionProperty ( "Version" ); const OUString sMediaTypeProperty ( "MediaType" ); const OUString sIterationCountProperty ( "IterationCount" ); - const OUString sDerivedKeySizeProperty ( "DerivedKeySize" ); + const OUString sDerivedKeySizeProperty ( "DerivedKeySize" ); const OUString sSaltProperty ( "Salt" ); const OUString sInitialisationVectorProperty( "InitialisationVector" ); const OUString sSizeProperty ( "Size" ); @@ -159,14 +171,19 @@ ManifestExport::ManifestExport( uno::Reference< xml::sax::XDocumentHandler > con { // oasis format pRootAttrList->AddAttribute ( ATTRIBUTE_XMLNS, - sCdataAttribute, - MANIFEST_OASIS_NAMESPACE ); + sCdataAttribute, + MANIFEST_OASIS_NAMESPACE ); bAcceptNonemptyVersion = true; if ( aDocVersion.compareTo( ODFVER_012_TEXT ) >= 0 ) { - // this is ODF12 generation, let encrypted streams contain start-key-generation entry + // this is ODF12 or later generation, let encrypted + // streams contain start-key-generation entry bStoreStartKeyGeneration = true; pRootAttrList->AddAttribute ( sVersionAttribute, sCdataAttribute, aDocVersion ); + // plus gpg4libre extensions - loext NS for that + pRootAttrList->AddAttribute ( ATTRIBUTE_XMLNS_LOEXT, + sCdataAttribute, + MANIFEST_LOEXT_NAMESPACE ); } } else @@ -174,8 +191,8 @@ ManifestExport::ManifestExport( uno::Reference< xml::sax::XDocumentHandler > con // even if it is no SO6 format the namespace must be specified // thus SO6 format is used as default one pRootAttrList->AddAttribute ( ATTRIBUTE_XMLNS, - sCdataAttribute, - MANIFEST_NAMESPACE ); + sCdataAttribute, + MANIFEST_NAMESPACE ); bProvideDTD = true; } @@ -198,7 +215,12 @@ ManifestExport::ManifestExport( uno::Reference< xml::sax::XDocumentHandler > con ::comphelper::AttributeList *pAttrList = new ::comphelper::AttributeList; const beans::PropertyValue *pValue = pSequence[i].getConstArray(); OUString aString; - const uno::Any *pVector = nullptr, *pSalt = nullptr, *pIterationCount = nullptr, *pDigest = nullptr, *pDigestAlg = nullptr, *pEncryptAlg = nullptr, *pStartKeyAlg = nullptr, *pDerivedKeySize = nullptr; + const uno::Any *pVector = nullptr, *pSalt = nullptr, + *pIterationCount = nullptr, *pDigest = nullptr, + *pDigestAlg = nullptr, *pEncryptAlg = nullptr, + *pStartKeyAlg = nullptr, *pDerivedKeySize = nullptr, + *pPgpKeyIDProperty = nullptr, *pPgpKeyPacketProperty = nullptr, + *pCipherValueProperty = nullptr; for (sal_uInt32 j = 0, nNum = pSequence[i].getLength(); j < nNum; j++, pValue++) { if (pValue->Name == sMediaTypeProperty ) @@ -242,11 +264,82 @@ ManifestExport::ManifestExport( uno::Reference< xml::sax::XDocumentHandler > con pStartKeyAlg = &pValue->Value; else if (pValue->Name == sDerivedKeySizeProperty ) pDerivedKeySize = &pValue->Value; + else if (pValue->Name == sPgpKeyIDProperty ) + pPgpKeyIDProperty = &pValue->Value; + else if (pValue->Name == sPgpKeyPacketProperty ) + pPgpKeyPacketProperty = &pValue->Value; + else if (pValue->Name == sCipherValueProperty ) + pCipherValueProperty = &pValue->Value; } xHandler->ignorableWhitespace ( sWhiteSpace ); uno::Reference < xml::sax::XAttributeList > xAttrList ( pAttrList ); xHandler->startElement( sFileEntryElement , xAttrList); + if ( pPgpKeyIDProperty && pPgpKeyPacketProperty && pCipherValueProperty ) + { + // TODO make this work for multiple recipients + // ==== OpenPGP - encryped session data + ::comphelper::AttributeList * pNewAttrList = new ::comphelper::AttributeList; + uno::Reference < xml::sax::XAttributeList > xNewAttrList (pNewAttrList); + OUStringBuffer aBuffer; + uno::Sequence < sal_Int8 > aSequence; + + xHandler->ignorableWhitespace ( sWhiteSpace ); + + // ==== KeyInfo & children + xHandler->startElement( sKeyInfoElement, nullptr ); + xHandler->ignorableWhitespace ( sWhiteSpace ); + xHandler->startElement( sEncryptedKeyElement, nullptr ); + xHandler->ignorableWhitespace ( sWhiteSpace ); + + // TODO this should rather be configurable + pNewAttrList->AddAttribute ( sAlgorithmAttribute, sCdataAttribute, + "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" ); + xHandler->startElement( sEncryptionMethodElement, xNewAttrList ); + xHandler->ignorableWhitespace ( sWhiteSpace ); + + xHandler->startElement( sKeyInfoElement, nullptr ); + xHandler->ignorableWhitespace ( sWhiteSpace ); + + xHandler->startElement( sPgpDataElement, nullptr ); + xHandler->ignorableWhitespace ( sWhiteSpace ); + + xHandler->startElement( sPgpKeyIDElement, nullptr ); + *pPgpKeyIDProperty >>= aSequence; + ::sax::Converter::encodeBase64(aBuffer, aSequence); + xHandler->characters( aBuffer.makeStringAndClear() ); + xHandler->endElement( sPgpKeyIDElement ); + xHandler->ignorableWhitespace ( sWhiteSpace ); + + xHandler->startElement( sPGPKeyPacketElement, nullptr ); + *pPgpKeyPacketProperty >>= aSequence; + ::sax::Converter::encodeBase64(aBuffer, aSequence); + xHandler->characters( aBuffer.makeStringAndClear() ); + xHandler->endElement( sPGPKeyPacketElement ); + xHandler->ignorableWhitespace ( sWhiteSpace ); + + xHandler->endElement( sPgpDataElement ); + xHandler->ignorableWhitespace ( sWhiteSpace ); + + xHandler->endElement( sKeyInfoElement ); + xHandler->ignorableWhitespace ( sWhiteSpace ); + + xHandler->startElement( sCipherDataElement, nullptr ); + xHandler->ignorableWhitespace ( sWhiteSpace ); + + xHandler->startElement( sCipherValueElement, nullptr ); + *pCipherValueProperty >>= aSequence; + ::sax::Converter::encodeBase64(aBuffer, aSequence); + xHandler->characters( aBuffer.makeStringAndClear() ); + xHandler->endElement( sCipherValueElement ); + xHandler->ignorableWhitespace ( sWhiteSpace ); + + xHandler->endElement( sEncryptedKeyElement ); + xHandler->ignorableWhitespace ( sWhiteSpace ); + + xHandler->endElement( sKeyInfoElement ); + xHandler->ignorableWhitespace ( sWhiteSpace ); + } if ( pVector && pSalt && pIterationCount && pDigest && pDigestAlg && pEncryptAlg && pStartKeyAlg && pDerivedKeySize ) { // ==== Encryption Data commit 2a0600922751275165363a370afd7fb021370e11 Author: Thorsten Behrens <thorsten.behr...@cib.de> Date: Mon Aug 14 16:44:42 2017 +0200 wip diff --git a/oox/source/shape/WpgContext.cxx b/oox/source/shape/WpgContext.cxx index faf1f0ff3dcf..8aa00cbdbde0 100644 --- a/oox/source/shape/WpgContext.cxx +++ b/oox/source/shape/WpgContext.cxx @@ -35,7 +35,7 @@ oox::core::ContextHandlerRef WpgContext::onCreateContext(sal_Int32 nElementToken switch (getBaseToken(nElementToken)) { case XML_wgp: - break; + return this; case XML_cNvGrpSpPr: break; case XML_grpSpPr: diff --git a/sax/source/fastparser/fastparser.cxx b/sax/source/fastparser/fastparser.cxx index 4cdd3b034962..e4348d407851 100644 --- a/sax/source/fastparser/fastparser.cxx +++ b/sax/source/fastparser/fastparser.cxx @@ -238,13 +238,6 @@ public: void callbackEndElement(); void callbackCharacters( const xmlChar* s, int nLen ); void callbackProcessingInstruction( const xmlChar *target, const xmlChar *data ); -#if 0 - bool callbackExternalEntityRef( XML_Parser parser, const xmlChar *openEntityNames, const xmlChar *base, const xmlChar *systemId, const xmlChar *publicId); - void callbackEntityDecl(const xmlChar *entityName, int is_parameter_entity, - const xmlChar *value, int value_length, const xmlChar *base, - const xmlChar *systemId, const xmlChar *publicId, - const xmlChar *notationName); -#endif void pushEntity( const Entity& rEntity ); void popEntity(); @@ -268,9 +261,6 @@ private: void DefineNamespace( const OString& rPrefix, const OUString& namespaceURL ); private: -#if 0 - FastSaxParser* mpFront; -#endif osl::Mutex maMutex; ///< Protecting whole parseStream() execution ::rtl::Reference< FastLocatorImpl > mxDocumentLocator; NamespaceMap maNamespaceMap; @@ -334,24 +324,6 @@ static void call_callbackProcessingInstruction( void *userData, const xmlChar *t pFastParser->callbackProcessingInstruction( target, data ); } -#if 0 -static void call_callbackEntityDecl(void *userData, const xmlChar *entityName, - int is_parameter_entity, const xmlChar *value, int value_length, - const xmlChar *base, const xmlChar *systemId, - const xmlChar *publicId, const xmlChar *notationName) -{ - FastSaxParserImpl* pFastParser = reinterpret_cast<FastSaxParserImpl*>(userData); - pFastParser->callbackEntityDecl(entityName, is_parameter_entity, value, - value_length, base, systemId, publicId, notationName); -} - -static int call_callbackExternalEntityRef( XML_Parser parser, - const xmlChar *openEntityNames, const xmlChar *base, const xmlChar *systemId, const xmlChar *publicId ) -{ - FastSaxParserImpl* pFastParser = reinterpret_cast<FastSaxParserImpl*>( XML_GetUserData( parser ) ); - return pFastParser->callbackExternalEntityRef( parser, openEntityNames, base, systemId, publicId ); -} -#endif } class FastLocatorImpl : public WeakImplHelper< XLocator > @@ -463,6 +435,7 @@ void Entity::startElement( Event *pEvent ) if( nElementToken == FastToken::DONTKNOW ) { + SAL_DEBUG("fastparser: unknown element: " << aElementName); if( pParentContext ) xContext = pParentContext->createUnknownChildContext( aNamespace, aElementName, xAttr ); else if( mxDocumentHandler.is() ) @@ -476,10 +449,13 @@ void Entity::startElement( Event *pEvent ) else { if( pParentContext ) + { xContext = pParentContext->createFastChildContext( nElementToken, xAttr ); + } else if( mxDocumentHandler.is() ) + { xContext = mxDocumentHandler->createFastChildContext( nElementToken, xAttr ); - + } if( xContext.is() ) xContext->startFastElement( nElementToken, xAttr ); } @@ -651,9 +627,6 @@ void Entity::saveException( const Any & e ) namespace sax_fastparser { FastSaxParserImpl::FastSaxParserImpl() : -#if 0 - mpFront(pFront), -#endif m_bIgnoreMissingNSDecl(false), mpTop(nullptr) { @@ -790,7 +763,8 @@ void FastSaxParserImpl::parseStream(const InputSource& maStructSource) rEntity.mxDocumentHandler->startDocument(); } - rEntity.mbEnableThreads = (rEntity.maStructSource.aInputStream->available() > 10000); + rEntity.mbEnableThreads = false; + //(rEntity.maStructSource.aInputStream->available() > 10000); if (rEntity.mbEnableThreads) { @@ -1040,10 +1014,6 @@ void FastSaxParserImpl::parse() callbacks.characters = call_callbackCharacters; callbacks.processingInstruction = call_callbackProcessingInstruction; callbacks.initialized = XML_SAX2_MAGIC; -#if 0 - XML_SetEntityDeclHandler(entity.mpParser, call_callbackEntityDecl); - XML_SetExternalEntityRefHandler( entity.mpParser, call_callbackExternalEntityRef ); -#endif int nRead = 0; do { @@ -1234,7 +1204,10 @@ void FastSaxParserImpl::callbackStartElement(const xmlChar *localName , const xm if (rEntity.mbEnableThreads) produce(); else + { + SAL_DEBUG("fastparser: created child context from doc handler for: " << localName); rEntity.startElement( &rEvent ); + } } catch (const Exception&) { @@ -1305,106 +1278,6 @@ void FastSaxParserImpl::callbackProcessingInstruction( const xmlChar *target, co rEntity.processingInstruction( rEvent.msNamespace, rEvent.msElementName ); } -#if 0 -void FastSaxParserImpl::callbackEntityDecl( - SAL_UNUSED_PARAMETER const xmlChar * /*entityName*/, - SAL_UNUSED_PARAMETER int /*is_parameter_entity*/, - const xmlChar *value, SAL_UNUSED_PARAMETER int /*value_length*/, - SAL_UNUSED_PARAMETER const xmlChar * /*base*/, - SAL_UNUSED_PARAMETER const xmlChar * /*systemId*/, - SAL_UNUSED_PARAMETER const xmlChar * /*publicId*/, - SAL_UNUSED_PARAMETER const xmlChar * /*notationName*/) -{ - if (value) { // value != 0 means internal entity - SAL_INFO("sax", "FastSaxParser: internal entity declaration, stopping"); - XML_StopParser(getEntity().mpParser, XML_FALSE); - getEntity().saveException( SAXParseException( - "FastSaxParser: internal entity declaration, stopping", - static_cast<OWeakObject*>(mpFront), Any(), - mxDocumentLocator->getPublicId(), - mxDocumentLocator->getSystemId(), - mxDocumentLocator->getLineNumber(), - mxDocumentLocator->getColumnNumber() ) ); - } else { - SAL_INFO("sax", "FastSaxParser: ignoring external entity declaration"); - } -} - -bool FastSaxParserImpl::callbackExternalEntityRef( - XML_Parser parser, const xmlChar *context, - SAL_UNUSED_PARAMETER const xmlChar * /*base*/, const xmlChar *systemId, - const xmlChar *publicId ) -{ - bool bOK = true; - InputSource source; - - Entity& rCurrEntity = getEntity(); - Entity aNewEntity( rCurrEntity ); - - if( rCurrEntity.mxEntityResolver.is() ) try - { - aNewEntity.maStructSource = rCurrEntity.mxEntityResolver->resolveEntity( - OUString( publicId, strlen( publicId ), RTL_TEXTENCODING_UTF8 ) , - OUString( systemId, strlen( systemId ), RTL_TEXTENCODING_UTF8 ) ); - } - catch (const SAXParseException & e) - { - rCurrEntity.saveException( e ); - bOK = false; - } - catch (const SAXException& e) - { - rCurrEntity.saveException( SAXParseException( - e.Message, e.Context, e.WrappedException, - mxDocumentLocator->getPublicId(), - mxDocumentLocator->getSystemId(), - mxDocumentLocator->getLineNumber(), - mxDocumentLocator->getColumnNumber() ) ); - bOK = false; - } - - if( aNewEntity.maStructSource.aInputStream.is() ) - { - aNewEntity.mpParser = XML_ExternalEntityParserCreate( parser, context, 0 ); - if( !aNewEntity.mpParser ) - { - return false; - } - - aNewEntity.maConverter.setInputStream( aNewEntity.maStructSource.aInputStream ); - pushEntity( aNewEntity ); - try - { - parse(); - } - catch (const SAXParseException& e) - { - rCurrEntity.saveException( e ); - bOK = false; - } - catch (const IOException& e) - { - SAXException aEx; - aEx.WrappedException <<= e; - rCurrEntity.saveException( aEx ); - bOK = false; - } - catch (const RuntimeException& e) - { - SAXException aEx; - aEx.WrappedException <<= e; - rCurrEntity.saveException( aEx ); - bOK = false; - } - - popEntity(); - XML_ParserFree( aNewEntity.mpParser ); - } - - return bOK; -} -#endif - FastSaxParser::FastSaxParser() : mpImpl(new FastSaxParserImpl) {} FastSaxParser::~FastSaxParser() diff --git a/writerfilter/source/ooxml/OOXMLFactory.cxx b/writerfilter/source/ooxml/OOXMLFactory.cxx index 12f6237ea996..310b304684d4 100644 --- a/writerfilter/source/ooxml/OOXMLFactory.cxx +++ b/writerfilter/source/ooxml/OOXMLFactory.cxx @@ -151,6 +151,7 @@ OOXMLFactory::createFastChildContext(OOXMLFastContextHandler * pHandler, void OOXMLFactory::characters(OOXMLFastContextHandler * pHandler, const OUString & rString) { + SAL_DEBUG("characters gotten: " << rString); Id nDefine = pHandler->getDefine(); OOXMLFactory_ns::Pointer_t pFactory = getFactoryForNamespace(nDefine); commit 8ce78206061f26c22bd9d163df16a6abc75f2d98 Author: Thorsten Behrens <thorsten.behr...@cib.de> Date: Fri Aug 11 09:47:15 2017 +0200 WIP: tdf#100074 handle wpg:wgp-shapes in writerfilter Change-Id: Icf7130f2ca808c05c11ae21f5f2900dce90786c1 diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx index 1bf94413caa6..6676f9ce6416 100644 --- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx +++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx @@ -1709,8 +1709,8 @@ OOXMLFastContextHandlerShape::lcl_createFastChildContext uno::Reference< xml::sax::XFastContextHandler > xContextHandler; bool bGroupShape = Element == Token_t(NMSP_vml | XML_group); - // drawingML version also counts as a group shape. - bGroupShape |= mrShapeContext->getStartToken() == Token_t(NMSP_wpg | XML_wgp); + // // drawingML version also counts as a group shape. + // bGroupShape |= mrShapeContext->getStartToken() == Token_t(NMSP_wpg | XML_wgp); switch (oox::getNamespace(Element)) { diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml index 92e8677a8ecb..8da1a6404574 100644 --- a/writerfilter/source/ooxml/model.xml +++ b/writerfilter/source/ooxml/model.xml @@ -3993,8 +3993,49 @@ <namespace name="dml-graphicalObject"> <start name="graphic"/> <grammar xmlns="http://relaxng.org/ns/structure/1.0" ns="http://schemas.openxmlformats.org/drawingml/2006/main"> + <include href="dml-documentProperties"/> + <include href="dml-shapeProperties"/> + <include href="vml-main"/> <!-- ISO RELAX NG Schema --> <!-- start = graphic --> + <define name="CT_WordprocessingShape"> + <element name="wps:cNvSpPr"> + <ref name="CT_NonVisualDrawingShapeProps"/> + </element> + <element name="wps:cNvPr"> + <ref name="CT_NonVisualDrawingProps"/> + </element> + <element name="wps:spPr"> + <ref name="CT_ShapeProperties"/> + </element> + <element name="wps:txbx"> + <ref name="CT_Textbox"/> + </element> + <element name="wps:bodyPr"> + <ref name="BUILT_IN_ANY_TYPE"/> + </element> + </define> + <define name="CT_WordprocessingGroup"> + <element name="wpg:cNvGrpSpPr"> + <ref name="CT_NonVisualGroupDrawingShapeProps"/> + </element> + <element name="wpg:grpSpPr"> + <ref name="CT_WordprocessingGroup"/> + </element> + <element name="wps:wsp"> + <ref name="CT_WordprocessingShape"/> + </element> + </define> + <define name="wgp"> + <element name="wpg:wgp"> + <ref name="CT_WordprocessingGroup"/> + </element> + </define> + <define name="wsp"> + <element name="wps:wsp"> + <ref name="CT_WordprocessingShape"/> + </element> + </define> <define name="CT_GraphicalObjectData"> <ref name="pic"/> <ref name="relIds"/> @@ -4025,8 +4066,8 @@ <element name="relIds" tokenid="ooxml:CT_GraphicalObjectData_relIds"/> <element name="lockedCanvas" tokenid="ooxml:CT_GraphicalObjectData_lockedCanvas"/> <element name="chart" tokenid="ooxml:CT_GraphicalObjectData_chart"/> - <element name="wsp" tokenid="ooxml:CT_GraphicalObjectData_wsp"/> - <element name="wgp" tokenid="ooxml:CT_GraphicalObjectData_wgp"/> + <element name="wps:wsp" tokenid="ooxml:CT_GraphicalObjectData_wsp"/> + <element name="wpg:wgp" tokenid="ooxml:CT_GraphicalObjectData_wgp"/> <attribute name="uri" tokenid="ooxml:CT_GraphicalObjectData_uri"/> </resource> <resource name="CT_GraphicalObject" resource="Properties"> @@ -4035,6 +4076,20 @@ <resource name="graphic" resource="Properties"> <element name="graphic" tokenid="ooxml:graphic_graphic"/> </resource> + <resource name="CT_WordprocessingShape" resource="Shape"> + <element name="wps:cNvSpPr" tokenid="ooxml:CT_WordprocessingShape_cNvSpPr"/> + <element name="wps:spPr" tokenid="ooxml:CT_WordprocessingShape_spPr"/> + </resource> + <resource name="wsp" resource="Shape"> + <element name="wps:wsp" tokenid="ooxml:wps_wsp"/> + </resource> + <resource name="CT_WordprocessingGroup" resource="Shape"> + <element name="wpg:cNvGrpSpPr" tokenid="ooxml:CT_WordprocessingGroup_cNvGrpSpPr"/> + <element name="wpg:grpSpPr" tokenid="ooxml:CT_WordprocessingGroup_grpSpPr"/> + </resource> + <resource name="wgp" resource="Shape"> + <element name="wpg:wgp" tokenid="ooxml:wpg_wgp"/> + </resource> </namespace> <namespace name="wp14"> <start name="sizeRelH"/> commit 5ebab4e5473fa986ae15fb6e894e8b7890e19219 Author: Thorsten Behrens <thorsten.behr...@cib.de> Date: Wed Aug 9 23:22:01 2017 +0200 Revert "wip" This reverts commit 63a4f9af5c2ff9d8f0b71918aa4c6a8dcd492b6a. diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml index d6ee090cfecb..92e8677a8ecb 100644 --- a/writerfilter/source/ooxml/model.xml +++ b/writerfilter/source/ooxml/model.xml @@ -30,7 +30,6 @@ xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" - xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture" xmlns:wvml="urn:schemas-microsoft-com:office:word" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:xml="http://www.w3.org/XML/1998/namespace"> @@ -8373,15 +8372,12 @@ </element> </define> <define name="CT_WordprocessingShape"> - <element name="wps:cNvSpPr"> + <element name="cNvSpPr"> <ref name="CT_NonVisualDrawingShapeProps"/> </element> - <element name="wps:spPr"> + <element name="spPr"> <ref name="CT_ShapeProperties"/> </element> - <element name="wps:txbx"> - <ref name="CT_Textbox"/> - </element> </define> <define name="wsp"> <element name="wps:wsp"> @@ -8392,18 +8388,9 @@ <element name="cNvGrpSpPr"> <ref name="CT_NonVisualGroupDrawingShapeProps"/> </element> - <!-- oneOrMore --> - <choice> - <element name="wps:wsp"> - <ref name="CT_WordprocessingShape"/> - </element> - <element name="wpg:grpSpPr"> - <ref name="CT_WordprocessingGroup"/> - </element> - <element name="pic:pic"> - <ref name="CT_Picture"/> - </element> - </choice> + <element name="grpSpPr"> + <ref name="CT_WordprocessingGroup"/> + </element> </define> <define name="wgp"> <element name="wpg:wgp"> @@ -8455,8 +8442,6 @@ <resource name="CT_WordprocessingGroup" resource="Shape"> <element name="wpg:cNvGrpSpPr" tokenid="ooxml:CT_WordprocessingGroup_cNvGrpSpPr"/> <element name="wpg:grpSpPr" tokenid="ooxml:CT_WordprocessingGroup_grpSpPr"/> - <element name="wps:wsp" tokenid="ooxml:CT_WordprocessingGroup_wsp"/> - <element name="pic:pic" tokenid="ooxml:CT_WordprocessingGroup_pic"/> </resource> <resource name="wgp" resource="Shape"> <element name="wpg:wgp" tokenid="ooxml:wpg_wgp"/> commit 63a4f9af5c2ff9d8f0b71918aa4c6a8dcd492b6a Author: Thorsten Behrens <thorsten.behr...@cib.de> Date: Wed Aug 9 23:18:25 2017 +0200 wip Change-Id: I36f6b5cce7baa68917b4792bf8cdc500ca10d9ce diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml index 6b9dccd7d0ce..d6ee090cfecb 100644 --- a/writerfilter/source/ooxml/model.xml +++ b/writerfilter/source/ooxml/model.xml @@ -8373,12 +8373,15 @@ </element> </define> <define name="CT_WordprocessingShape"> - <element name="cNvSpPr"> + <element name="wps:cNvSpPr"> <ref name="CT_NonVisualDrawingShapeProps"/> </element> - <element name="spPr"> + <element name="wps:spPr"> <ref name="CT_ShapeProperties"/> </element> + <element name="wps:txbx"> + <ref name="CT_Textbox"/> + </element> </define> <define name="wsp"> <element name="wps:wsp"> @@ -8394,7 +8397,7 @@ <element name="wps:wsp"> <ref name="CT_WordprocessingShape"/> </element> - <element name="grpSpPr"> + <element name="wpg:grpSpPr"> <ref name="CT_WordprocessingGroup"/> </element> <element name="pic:pic"> commit 1408f77a14a5cf4932a9ff1ca8b54d26b8275631 Author: Thorsten Behrens <thorsten.behr...@cib.de> Date: Wed Aug 9 01:47:14 2017 +0200 new model foo Change-Id: I255d38c264e8ee76d18d7e37eaadf68a3f8d4330 diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml index 92e8677a8ecb..6b9dccd7d0ce 100644 --- a/writerfilter/source/ooxml/model.xml +++ b/writerfilter/source/ooxml/model.xml @@ -30,6 +30,7 @@ xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" + xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture" xmlns:wvml="urn:schemas-microsoft-com:office:word" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:xml="http://www.w3.org/XML/1998/namespace"> @@ -8388,9 +8389,18 @@ <element name="cNvGrpSpPr"> <ref name="CT_NonVisualGroupDrawingShapeProps"/> </element> - <element name="grpSpPr"> - <ref name="CT_WordprocessingGroup"/> - </element> + <!-- oneOrMore --> + <choice> + <element name="wps:wsp"> + <ref name="CT_WordprocessingShape"/> + </element> + <element name="grpSpPr"> + <ref name="CT_WordprocessingGroup"/> + </element> + <element name="pic:pic"> + <ref name="CT_Picture"/> + </element> + </choice> </define> <define name="wgp"> <element name="wpg:wgp"> @@ -8442,6 +8452,8 @@ <resource name="CT_WordprocessingGroup" resource="Shape"> <element name="wpg:cNvGrpSpPr" tokenid="ooxml:CT_WordprocessingGroup_cNvGrpSpPr"/> <element name="wpg:grpSpPr" tokenid="ooxml:CT_WordprocessingGroup_grpSpPr"/> + <element name="wps:wsp" tokenid="ooxml:CT_WordprocessingGroup_wsp"/> + <element name="pic:pic" tokenid="ooxml:CT_WordprocessingGroup_pic"/> </resource> <resource name="wgp" resource="Shape"> <element name="wpg:wgp" tokenid="ooxml:wpg_wgp"/> commit 5376dcc88788dd5a88cbd7166a6605b2bdce5e9c Author: Thorsten Behrens <thorsten.behr...@cib.de> Date: Tue Aug 1 03:07:17 2017 +0200 kill redundant breaks Change-Id: I18aadb7b6b2fa50159624df1b4a7de9270473785 diff --git a/oox/source/shape/WpgContext.cxx b/oox/source/shape/WpgContext.cxx index 2ae26fedb84c..faf1f0ff3dcf 100644 --- a/oox/source/shape/WpgContext.cxx +++ b/oox/source/shape/WpgContext.cxx @@ -40,7 +40,6 @@ oox::core::ContextHandlerRef WpgContext::onCreateContext(sal_Int32 nElementToken break; case XML_grpSpPr: return new oox::drawingml::ShapePropertiesContext(*this, *mpShape); - break; case XML_wsp: { // Don't set default character height, Writer has its own way to set @@ -49,15 +48,12 @@ oox::core::ContextHandlerRef WpgContext::onCreateContext(sal_Int32 nElementToken oox::drawingml::ShapePtr pShape(new oox::drawingml::Shape("com.sun.star.drawing.CustomShape", /*bDefaultHeight=*/false)); return new oox::drawingml::ShapeContext(*this, mpShape, pShape); } - break; case XML_pic: return new oox::drawingml::GraphicShapeContext(*this, mpShape, std::make_shared<oox::drawingml::Shape>("com.sun.star.drawing.GraphicObjectShape")); - break; case XML_grpSp: { return new oox::drawingml::ShapeGroupContext(*this, mpShape, std::make_shared<oox::drawingml::Shape>("com.sun.star.drawing.GroupShape")); } - break; case XML_graphicFrame: break; default: diff --git a/oox/source/shape/WpsContext.cxx b/oox/source/shape/WpsContext.cxx index b26ce06562b0..81050762cc79 100644 --- a/oox/source/shape/WpsContext.cxx +++ b/oox/source/shape/WpsContext.cxx @@ -55,10 +55,8 @@ oox::core::ContextHandlerRef WpsContext::onCreateContext(sal_Int32 nElementToken break; case XML_spPr: return new oox::drawingml::ShapePropertiesContext(*this, *mpShape); - break; case XML_style: return new oox::drawingml::ShapeStyleContext(*this, *mpShape); - break; case XML_bodyPr: if (mxShape.is()) { commit 9f1e3ad35abfbf060b4fe0a48f46e6cf4d90dc03 Author: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> Date: Wed Jul 26 10:50:05 2017 +0200 tdf#107723 Import font name from text portions in shapes Change-Id: Ib9b73b5c05ec2e6846ea3adc950ccab5d1c0a9b0 Reviewed-on: https://gerrit.libreoffice.org/40439 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> diff --git a/include/oox/vml/vmltextbox.hxx b/include/oox/vml/vmltextbox.hxx index 0f0828c88797..8b32713c1dae 100644 --- a/include/oox/vml/vmltextbox.hxx +++ b/include/oox/vml/vmltextbox.hxx @@ -49,6 +49,8 @@ struct TextParagraphModel struct OOX_DLLPUBLIC TextFontModel { OptValue< OUString > moName; ///< Font name. + OptValue< OUString > moNameAsian; ///< Asian font name. + OptValue< OUString > moNameComplex; ///< Complex font name. OptValue< OUString > moColor; ///< Font color, HTML encoded, sort of. OptValue< sal_Int32 > monSize; ///< Font size in twips. OptValue< sal_Int32 > monUnderline; ///< Single or double underline. diff --git a/oox/source/vml/vmltextbox.cxx b/oox/source/vml/vmltextbox.cxx index ac8c51273d77..cfa07b0546db 100644 --- a/oox/source/vml/vmltextbox.cxx +++ b/oox/source/vml/vmltextbox.cxx @@ -82,6 +82,20 @@ void TextBox::convert(const uno::Reference<drawing::XShape>& xShape) const std::vector<beans::PropertyValue> aPropVec; const TextParagraphModel& rParagraph = aIt->maParagraph; const TextFontModel& rFont = aIt->maFont; + if (rFont.moName.has()) + { + aPropertyValue.Name = "CharFontName"; + aPropertyValue.Value <<= rFont.moName.get(); + aPropVec.push_back(aPropertyValue); + + aPropertyValue.Name = "CharFontNameAsian"; + aPropertyValue.Value <<= rFont.moNameAsian.get(); + aPropVec.push_back(aPropertyValue); + + aPropertyValue.Name = "CharFontNameComplex"; + aPropertyValue.Value <<= rFont.moNameComplex.get(); + aPropVec.push_back(aPropertyValue); + } if (rFont.mobBold.has()) { aPropertyValue.Name = "CharWeight"; diff --git a/oox/source/vml/vmltextboxcontext.cxx b/oox/source/vml/vmltextboxcontext.cxx index 239e53c3a655..c46ff71b98a5 100644 --- a/oox/source/vml/vmltextboxcontext.cxx +++ b/oox/source/vml/vmltextboxcontext.cxx @@ -139,6 +139,12 @@ void TextPortionContext::onStartElement(const AttributeList& rAttribs) case W_TOKEN(rPr): case W_TOKEN(t): break; + case W_TOKEN(rFonts): + // See https://msdn.microsoft.com/en-us/library/documentformat.openxml.wordprocessing.runfonts(v=office.14).aspx + maFont.moName = rAttribs.getString(W_TOKEN(ascii)); + maFont.moNameAsian = rAttribs.getString(W_TOKEN(eastAsia)); + maFont.moNameComplex = rAttribs.getString(W_TOKEN(cs)); + break; default: SAL_INFO("oox", "unhandled: 0x" << std::hex<< getCurrentElement()); break; diff --git a/sw/qa/extras/ooxmlimport/data/groupshape-fontname.docx b/sw/qa/extras/ooxmlimport/data/groupshape-fontname.docx new file mode 100644 index 000000000000..025f737e0556 Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/groupshape-fontname.docx differ diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx index 384e0e09a053..ccad25052c5a 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -1405,6 +1405,42 @@ DECLARE_OOXMLIMPORT_TEST(testTdf108849, "tdf108849.docx") CPPUNIT_ASSERT_EQUAL_MESSAGE("Misplaced body-level sectPr's create extra sections!", 2, getPages()); } +DECLARE_OOXMLIMPORT_TEST(testTdf109306, "tdf109306.docx") +{ + uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY); + // Both types of relative width specification (pct): simple integers (in fiftieths of percent) + // and floats with "%" unit specification must be treated correctly + CPPUNIT_ASSERT_EQUAL(true, bool(getProperty<bool>(xTables->getByIndex(0), "IsWidthRelative"))); + CPPUNIT_ASSERT_EQUAL(sal_Int16(90), getProperty<sal_Int16>(xTables->getByIndex(0), "RelativeWidth")); + + CPPUNIT_ASSERT_EQUAL(true, bool(getProperty<bool>(xTables->getByIndex(1), "IsWidthRelative"))); + CPPUNIT_ASSERT_EQUAL(sal_Int16(80), getProperty<sal_Int16>(xTables->getByIndex(1), "RelativeWidth")); +} + +DECLARE_OOXMLIMPORT_TEST(testTdf109524, "tdf109524.docx") +{ + uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY); + // The table should have a small width (just to hold the short text in its single cell). + // Until it's correctly implemented, we assign it 100% relative width. + // Previously, the table (without explicitly set width) had huge actual width + // and extended far outside of page's right border. + CPPUNIT_ASSERT_EQUAL(true, bool(getProperty<bool>(xTables->getByIndex(0), "IsWidthRelative"))); + CPPUNIT_ASSERT_EQUAL(sal_Int16(100), getProperty<sal_Int16>(xTables->getByIndex(0), "RelativeWidth")); +} + +DECLARE_OOXMLIMPORT_TEST(testGroupShapeFontName, "groupshape-fontname.docx") +{ + // Font names inside a group shape were not imported + uno::Reference<container::XIndexAccess> xGroup(getShape(1), uno::UNO_QUERY); + uno::Reference<text::XText> xText = uno::Reference<text::XTextRange>(xGroup->getByIndex(1), uno::UNO_QUERY)->getText(); + + CPPUNIT_ASSERT_EQUAL(OUString("Calibri"), getProperty<OUString>(getRun(getParagraphOfText(1, xText), 1), "CharFontName")); + CPPUNIT_ASSERT_EQUAL(OUString("Calibri"), getProperty<OUString>(getRun(getParagraphOfText(1, xText), 1), "CharFontNameComplex")); + CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(getRun(getParagraphOfText(1, xText), 1), "CharFontNameAsian")); +} + // tests should only be added to ooxmlIMPORT *if* they fail round-tripping in ooxmlEXPORT CPPUNIT_PLUGIN_IMPLEMENT(); commit 5b5995c05a17b1b16617ef8b477a657ce2a9406c Author: Noel Grandin <noel.gran...@collabora.co.uk> Date: Thu Jul 20 10:15:07 2017 +0200 loplugin:unusedfields in writerfilter Change-Id: I7831da8cccfa730c8615ef770d0add95cbde396b Reviewed-on: https://gerrit.libreoffice.org/40215 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/compilerplugins/clang/unusedfields.readonly.results b/compilerplugins/clang/unusedfields.readonly.results index 9f621908c89c..f573cfec970b 100644 --- a/compilerplugins/clang/unusedfields.readonly.results +++ b/compilerplugins/clang/unusedfields.readonly.results @@ -1870,18 +1870,6 @@ writerfilter/source/dmapper/DomainMapper_Impl.cxx:165 writerfilter::dmapper::FieldConversion cFieldServiceName const sal_Char * writerfilter/source/dmapper/DomainMapper_Impl.cxx:166 writerfilter::dmapper::FieldConversion eFieldId enum writerfilter::dmapper::FieldId -writerfilter/source/dmapper/GraphicImport.cxx:160 - writerfilter::dmapper::GraphicBorderLine nLineColor sal_Int32 -writerfilter/source/dmapper/GraphicImport.cxx:190 - writerfilter::dmapper::GraphicImport_Impl nRightPosition sal_Int32 -writerfilter/source/dmapper/PropertyMap.hxx:214 - writerfilter::dmapper::SectionPropertyMap m_bPageNoRestart _Bool -writerfilter/source/dmapper/PropertyMap.hxx:229 - writerfilter::dmapper::SectionPropertyMap m_nDzaGutter sal_Int32 -writerfilter/source/dmapper/TDefTableHandler.hxx:44 - writerfilter::dmapper::TDefTableHandler m_aCellBorderPositions ::std::vector<sal_Int32> -writerfilter/source/dmapper/TDefTableHandler.hxx:45 - writerfilter::dmapper::TDefTableHandler m_aCellVertAlign ::std::vector<sal_Int32> writerfilter/source/ooxml/OOXMLFactory.hxx:60 writerfilter::ooxml::AttributeInfo m_nToken writerfilter::Token_t writerfilter/source/ooxml/OOXMLFactory.hxx:61 diff --git a/writerfilter/source/dmapper/GraphicImport.cxx b/writerfilter/source/dmapper/GraphicImport.cxx index c242d0b9d023..37e48daf0c80 100644 --- a/writerfilter/source/dmapper/GraphicImport.cxx +++ b/writerfilter/source/dmapper/GraphicImport.cxx @@ -157,18 +157,16 @@ void XInputStreamHelper::closeInput( ) struct GraphicBorderLine { sal_Int32 nLineWidth; - sal_Int32 nLineColor; bool bHasShadow; GraphicBorderLine() : nLineWidth(0) - ,nLineColor(0) ,bHasShadow(false) {} bool isEmpty() { - return nLineWidth == 0 && nLineColor == 0 && !bHasShadow; + return nLineWidth == 0 && !bHasShadow; } }; @@ -187,7 +185,6 @@ public: sal_Int32 nLeftPosition; sal_Int32 nTopPosition; - sal_Int32 nRightPosition; bool bUseSimplePos; sal_Int32 zOrder; @@ -259,7 +256,6 @@ public: ,rDomainMapper( rDMapper ) ,nLeftPosition(0) ,nTopPosition(0) - ,nRightPosition(0) ,bUseSimplePos(false) ,zOrder(-1) ,nHoriOrient( text::HoriOrientation::NONE ) @@ -1156,7 +1152,7 @@ uno::Reference< text::XTextContent > GraphicImport::createGraphicObject( const b } else { - aBorderLine.Color = rBorderLine.nLineColor; + aBorderLine.Color = 0; aBorderLine.InnerLineWidth = 0; aBorderLine.OuterLineWidth = (sal_Int16)rBorderLine.nLineWidth; aBorderLine.LineDistance = 0; @@ -1212,7 +1208,7 @@ uno::Reference< text::XTextContent > GraphicImport::createGraphicObject( const b xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_SIZE_PROTECTED ), uno::makeAny(true)); - sal_Int32 nWidth = m_pImpl->nRightPosition - m_pImpl->nLeftPosition; + sal_Int32 nWidth = - m_pImpl->nLeftPosition; if (m_pImpl->eGraphicImportType == IMPORT_AS_DETECTED_ANCHOR) { //adjust margins diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx index 577815ceff96..2c5ece45dc2f 100644 --- a/writerfilter/source/dmapper/PropertyMap.cxx +++ b/writerfilter/source/dmapper/PropertyMap.cxx @@ -370,7 +370,6 @@ SectionPropertyMap::SectionPropertyMap( bool bIsFirstSection ) , m_xColumnContainer( nullptr ) , m_bSeparatorLineIsOn( false ) , m_bEvenlySpaced( false ) - , m_bPageNoRestart( false ) , m_nPageNumber( -1 ) , m_nPageNumberType( -1 ) , m_nBreakType( -1 ) @@ -382,7 +381,6 @@ SectionPropertyMap::SectionPropertyMap( bool bIsFirstSection ) , m_nBottomMargin( 2540 ) , m_nHeaderTop( 1270 ) // 720 twip , m_nHeaderBottom( 1270 ) // 720 twip - , m_nDzaGutter( 0 ) , m_nGridType( 0 ) , m_nGridLinePitch( 1 ) , m_nDxtCharSpace( 0 ) @@ -989,11 +987,6 @@ uno::Reference< beans::XPropertySet > lcl_GetRangeProperties( bool bIsFirstSecti void SectionPropertyMap::HandleMarginsHeaderFooter( bool bFirstPage, DomainMapper_Impl& rDM_Impl ) { - if ( m_nDzaGutter > 0 ) - { - //todo: iGutterPos from DocProperties are missing - m_nLeftMargin += m_nDzaGutter; - } Insert( PROP_LEFT_MARGIN, uno::makeAny( m_nLeftMargin ) ); Insert( PROP_RIGHT_MARGIN, uno::makeAny( m_nRightMargin ) ); @@ -1397,7 +1390,7 @@ void SectionPropertyMap::CloseSectionGroup( DomainMapper_Impl& rDM_Impl ) uno::makeAny( m_bTitlePage ? m_sFirstPageStyleName : m_sFollowPageStyleName ) ); - if (m_bPageNoRestart || 0 <= m_nPageNumber) + if (0 <= m_nPageNumber) { sal_Int16 nPageNumber = m_nPageNumber >= 0 ? static_cast< sal_Int16 >(m_nPageNumber) : 1; xRangeProperties->setPropertyValue(getPropertyName(PROP_PAGE_NUMBER_OFFSET), diff --git a/writerfilter/source/dmapper/PropertyMap.hxx b/writerfilter/source/dmapper/PropertyMap.hxx index 1cc7050713dd..d7f416f79607 100644 --- a/writerfilter/source/dmapper/PropertyMap.hxx +++ b/writerfilter/source/dmapper/PropertyMap.hxx @@ -211,7 +211,6 @@ private: bool m_bSeparatorLineIsOn; bool m_bEvenlySpaced; - bool m_bPageNoRestart; sal_Int32 m_nPageNumber; // Page number type is a value from css::style::NumberingType. sal_Int16 m_nPageNumberType; @@ -226,8 +225,6 @@ private: sal_Int32 m_nHeaderTop; sal_Int32 m_nHeaderBottom; - sal_Int32 m_nDzaGutter; - sal_Int32 m_nGridType; sal_Int32 m_nGridLinePitch; sal_Int32 m_nDxtCharSpace; diff --git a/writerfilter/source/dmapper/TDefTableHandler.cxx b/writerfilter/source/dmapper/TDefTableHandler.cxx index a77b40d7fde5..75b7bbb4be02 100644 --- a/writerfilter/source/dmapper/TDefTableHandler.cxx +++ b/writerfilter/source/dmapper/TDefTableHandler.cxx @@ -415,17 +415,6 @@ void TDefTableHandler::lcl_sprm(Sprm & rSprm) void TDefTableHandler::fillCellProperties( size_t nCell, const ::std::shared_ptr< TablePropertyMap >& pCellProperties ) const { - if( m_aCellBorderPositions.size() > nCell ) - { - sal_Int16 nVertOrient = text::VertOrientation::NONE; - switch( m_aCellVertAlign[nCell] ) //0 - top 1 - center 2 - bottom - { - case 1: nVertOrient = text::VertOrientation::CENTER; break; - case 2: nVertOrient = text::VertOrientation::BOTTOM; break; - default:; - } - pCellProperties->Insert( PROP_VERT_ORIENT, uno::makeAny( nVertOrient ) ); - } if( m_aTopBorderLines.size() > nCell ) pCellProperties->Insert( PROP_TOP_BORDER, uno::makeAny( m_aTopBorderLines[nCell] ) ); if( m_aLeftBorderLines.size() > nCell ) diff --git a/writerfilter/source/dmapper/TDefTableHandler.hxx b/writerfilter/source/dmapper/TDefTableHandler.hxx index c3186bb28a98..18a52cf9de88 100644 --- a/writerfilter/source/dmapper/TDefTableHandler.hxx +++ b/writerfilter/source/dmapper/TDefTableHandler.hxx @@ -38,12 +38,6 @@ class PropertyMap; class TablePropertyMap; class TDefTableHandler : public LoggedProperties { -public: - -private: - ::std::vector<sal_Int32> m_aCellBorderPositions; - ::std::vector<sal_Int32> m_aCellVertAlign; - std::vector<css::table::BorderLine2> m_aLeftBorderLines; std::vector<css::table::BorderLine2> m_aRightBorderLines; std::vector<css::table::BorderLine2> m_aTopBorderLines; commit 7f21d0fe4143ce66778ce2eeea1623cd9d6dd638 Author: Olivier Hallot <olivier.hal...@libreoffice.org> Date: Mon Jul 17 18:02:43 2017 -0300 Updated core Project: help e3187aa9dd2a80972b8aded1fb8f2270caa70438 Mute some l10n strings Change-Id: I3e263434d9881d3a7a6a20bbe0a5a85878fd1081 Reviewed-on: https://gerrit.libreoffice.org/40103 Reviewed-by: Olivier Hallot <olivier.hal...@edx.srv.br> Tested-by: Olivier Hallot <olivier.hal...@edx.srv.br> diff --git a/helpcontent2 b/helpcontent2 index 96683c90c8fa..e3187aa9dd2a 160000 --- a/helpcontent2 +++ b/helpcontent2 @@ -1 +1 @@ -Subproject commit 96683c90c8faf8af6bcee5a149f3a7a6acefcf26 +Subproject commit e3187aa9dd2a80972b8aded1fb8f2270caa70438 commit f715c6cfa41ad5a552181bad5e36e8e03f96f480 Author: Marco Cecchetti <marco.cecche...@collabora.com> Date: Thu Jul 20 12:18:37 2017 +0200 support for filter dialog when an image is exported from context menu When user save the selected image in a non-vector format the filter dialog used in Draw pops up for filter setting. Change-Id: Ic98b48a47322e807627b7a2ccd8044ec0db30efc Reviewed-on: https://gerrit.libreoffice.org/40223 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Marco Cecchetti <mrcek...@gmail.com> diff --git a/include/svx/xoutbmp.hxx b/include/svx/xoutbmp.hxx index cad11de73161..7a2962c18ec2 100644 --- a/include/svx/xoutbmp.hxx +++ b/include/svx/xoutbmp.hxx @@ -60,7 +60,8 @@ public: static Animation MirrorAnimation( const Animation& rAnimation, bool bHMirr, bool bVMirr ); static ErrCode WriteGraphic( const Graphic& rGraphic, OUString& rFileName, const OUString& rFilterName, const XOutFlags nFlags, - const Size* pMtfSize_100TH_MM = nullptr ); + const Size* pMtfSize_100TH_MM = nullptr, + const css::uno::Sequence< css::beans::PropertyValue >* pFilterData = nullptr); static bool GraphicToBase64(const Graphic& rGraphic, OUString& rOUString); static ErrCode ExportGraphic( const Graphic& rGraphic, const INetURLObject& rURL, diff --git a/svtools/source/filter/SvFilterOptionsDialog.cxx b/svtools/source/filter/SvFilterOptionsDialog.cxx index b3303392bb00..134a09ee1fdc 100644 --- a/svtools/source/filter/SvFilterOptionsDialog.cxx +++ b/svtools/source/filter/SvFilterOptionsDialog.cxx @@ -34,6 +34,7 @@ #include <com/sun/star/document/XExporter.hpp> #include <com/sun/star/document/XViewDataSupplier.hpp> #include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/graphic/XGraphic.hpp> #include <com/sun/star/lang/XInitialization.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/uno/Sequence.h> @@ -187,10 +188,12 @@ sal_Int16 SvFilterOptionsDialog::execute() sal_Int16 nRet = ui::dialogs::ExecutableDialogResults::CANCEL; OUString aInternalFilterName; + uno::Reference<graphic::XGraphic> xGraphic; sal_Int32 j, nCount = maMediaDescriptor.getLength(); for ( j = 0; j < nCount; j++ ) { - if ( maMediaDescriptor[ j ].Name == "FilterName" ) + const OUString& rName = maMediaDescriptor[ j ].Name; + if ( rName == "FilterName" ) { OUString aStr; maMediaDescriptor[ j ].Value >>= aStr; @@ -199,6 +202,10 @@ sal_Int16 SvFilterOptionsDialog::execute() aInternalFilterName = aInternalFilterName.replaceAll( "impress_", "" ); break; } + else if ( rName == "Graphic" ) + { + maMediaDescriptor[ j ].Value >>= xGraphic; + } } if ( !aInternalFilterName.isEmpty() ) { @@ -216,7 +223,7 @@ sal_Int16 SvFilterOptionsDialog::execute() aFltCallDlgPara.aFilterData = maFilterDataSequence; aFltCallDlgPara.aFilterExt = aGraphicFilter.GetExportFormatShortName( nFormat ); bool bIsPixelFormat( aGraphicFilter.IsExportPixelFormat( nFormat ) ); - if ( ScopedVclPtrInstance<ExportDialog>( aFltCallDlgPara, mxContext, mxSourceDocument, mbExportSelection, bIsPixelFormat )->Execute() == RET_OK ) + if ( ScopedVclPtrInstance<ExportDialog>( aFltCallDlgPara, mxContext, mxSourceDocument, mbExportSelection, bIsPixelFormat, xGraphic )->Execute() == RET_OK ) nRet = ui::dialogs::ExecutableDialogResults::OK; // taking the out parameter from the dialog diff --git a/svtools/source/filter/exportdialog.cxx b/svtools/source/filter/exportdialog.cxx index 49c4fd8621b6..ca47490e3816 100644 --- a/svtools/source/filter/exportdialog.cxx +++ b/svtools/source/filter/exportdialog.cxx @@ -352,6 +352,9 @@ awt::Size ExportDialog::GetOriginalSize() void ExportDialog::GetGraphicSource() { + if (mxGraphic.is()) + return; + if ( mxSourceDocument.is() ) { uno::Reference< frame::XModel > xModel( mxSourceDocument, uno::UNO_QUERY ); @@ -414,38 +417,76 @@ void ExportDialog::GetGraphicStream() mpTempStream = new SvMemoryStream(); maBitmap = Bitmap(); - uno::Reference < io::XStream > xStream( new utl::OStreamWrapper( *mpTempStream ) ); - uno::Reference < io::XOutputStream > xOutputStream( xStream->getOutputStream() ); - - uno::Reference< drawing::XGraphicExportFilter > xGraphicExporter = - drawing::GraphicExportFilter::create( mxContext ); - - OUString sFormat( maExt ); - uno::Sequence< beans::PropertyValue > aDescriptor( 3 ); - aDescriptor[0].Name = "OutputStream"; - aDescriptor[0].Value <<= xOutputStream; - aDescriptor[1].Name = "FilterName"; - aDescriptor[1].Value <<= sFormat; - aDescriptor[2].Name = "FilterData"; - aDescriptor[2].Value <<= aNewFilterData; - - uno::Reference< lang::XComponent > xSourceDoc; - if ( mxPage.is() ) - xSourceDoc.set( mxPage, uno::UNO_QUERY_THROW ); - else if ( mxShapes.is() ) - xSourceDoc.set( mxShapes, uno::UNO_QUERY_THROW ); - else if ( mxShape.is() ) - xSourceDoc.set( mxShape, uno::UNO_QUERY_THROW ); - if ( xSourceDoc.is() ) + if ( mxGraphic.is() ) { - xGraphicExporter->setSourceDocument( xSourceDoc ); - xGraphicExporter->filter( aDescriptor ); + SvMemoryStream* pTempStream = dynamic_cast<SvMemoryStream*>( mpTempStream ); + Graphic aGraphic( mxGraphic ); - if ( mnFormat == FORMAT_JPG ) + if ( aGraphic.GetType() == GraphicType::Bitmap ) { - mpTempStream->Seek( STREAM_SEEK_TO_BEGIN ); - maBitmap = GetGraphicBitmap( *mpTempStream ); - mpTempStream->Seek( STREAM_SEEK_TO_END ); + Size aSizePixel( aGraphic.GetSizePixel() ); + if( maSize.Width && maSize.Height && + ( ( maSize.Width != aSizePixel.Width() ) || + ( maSize.Height != aSizePixel.Height() ) ) ) + { + BitmapEx aBmpEx( aGraphic.GetBitmapEx() ); + // export: use highest quality + aBmpEx.Scale( Size( maSize.Width, maSize.Height ), BmpScaleFlag::Lanczos ); + aGraphic = aBmpEx; + } + } + + GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter(); + const sal_uInt16 nFilter = rFilter.GetExportFormatNumberForShortName( maExt ); + if ( rFilter.IsExportPixelFormat( nFilter ) ) + { + pTempStream->SetResizeOffset(1024); + pTempStream->SetStreamSize(1024); + rFilter.ExportGraphic( aGraphic, "", *pTempStream, nFilter, &aNewFilterData ); + + if ( mnFormat == FORMAT_JPG ) + { + mpTempStream->Seek( STREAM_SEEK_TO_BEGIN ); + maBitmap = GetGraphicBitmap( *mpTempStream ); + mpTempStream->Seek( STREAM_SEEK_TO_END ); + } + } + } + else + { + uno::Reference < io::XStream > xStream( new utl::OStreamWrapper( *mpTempStream ) ); + uno::Reference < io::XOutputStream > xOutputStream( xStream->getOutputStream() ); + + uno::Reference< drawing::XGraphicExportFilter > xGraphicExporter = + drawing::GraphicExportFilter::create( mxContext ); + + OUString sFormat( maExt ); + uno::Sequence< beans::PropertyValue > aDescriptor( 3 ); + aDescriptor[0].Name = "OutputStream"; + aDescriptor[0].Value <<= xOutputStream; + aDescriptor[1].Name = "FilterName"; + aDescriptor[1].Value <<= sFormat; + aDescriptor[2].Name = "FilterData"; + aDescriptor[2].Value <<= aNewFilterData; + + uno::Reference< lang::XComponent > xSourceDoc; + if ( mxPage.is() ) + xSourceDoc.set( mxPage, uno::UNO_QUERY_THROW ); + else if ( mxShapes.is() ) + xSourceDoc.set( mxShapes, uno::UNO_QUERY_THROW ); + else if ( mxShape.is() ) + xSourceDoc.set( mxShape, uno::UNO_QUERY_THROW ); + if ( xSourceDoc.is() ) + { + xGraphicExporter->setSourceDocument( xSourceDoc ); + xGraphicExporter->filter( aDescriptor ); + + if ( mnFormat == FORMAT_JPG ) + { + mpTempStream->Seek( STREAM_SEEK_TO_BEGIN ); + maBitmap = GetGraphicBitmap( *mpTempStream ); + mpTempStream->Seek( STREAM_SEEK_TO_END ); + } } } } @@ -514,11 +555,13 @@ bool ExportDialog::IsTempExportAvailable() const ExportDialog::ExportDialog(FltCallDialogParameter& rPara, const css::uno::Reference< css::uno::XComponentContext >& rxContext, const css::uno::Reference< css::lang::XComponent >& rxSourceDocument, - bool bExportSelection, bool bIsPixelFormat) + bool bExportSelection, bool bIsPixelFormat, + const css::uno::Reference< css::graphic::XGraphic >& rxGraphic) : ModalDialog(rPara.pWindow, "GraphicExportDialog", "svt/ui/graphicexport.ui") , mrFltCallPara(rPara) , mxContext(rxContext) , mxSourceDocument(rxSourceDocument) + , mxGraphic(rxGraphic) , mpSbCompression(nullptr) , mpNfCompression(nullptr) , msEstimatedSizePix1(SvtResId(STR_SVT_ESTIMATED_SIZE_PIX_1)) @@ -603,18 +646,31 @@ ExportDialog::ExportDialog(FltCallDialogParameter& rPara, Size aResolution( Application::GetDefaultDevice()->LogicToPixel( Size( 100, 100 ), MapUnit::MapCM ) ); maResolution.Width = aResolution.Width(); maResolution.Height= aResolution.Height(); - maOriginalSize = GetOriginalSize(); - if ( bIsPixelFormat ) + + if ( mxGraphic.is() ) { - double fPixelsPer100thmm = static_cast< double >( maResolution.Width ) / 100000.0; - maSize = awt::Size( static_cast< sal_Int32 >( ( fPixelsPer100thmm * maOriginalSize.Width ) + 0.5 ), - static_cast< sal_Int32 >( ( fPixelsPer100thmm * maOriginalSize.Height ) + 0.5 ) ); + Graphic aGraphic(mxGraphic); + Size aSize = aGraphic.GetSizePixel(); ... etc. - the rest is truncated _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits