[Libreoffice-commits] core.git: Branch 'private/thb/gpg4libre' - 1232 commits - accessibility/inc accessibility/source android/Bootstrap android/source avmedia/source basctl/inc basctl/source basctl/uiconfig basegfx/source basegfx/test basic/inc basic/qa basic/source bin/distro-install-desktop-integration bin/distro-install-sdk bin/findunusedcode bin/gbuild-to-ide bin/gbuild-to-ideNS bin/generate-bash-completion bin/generate-bash-completion.py bin/gen-iwyu-dummy-lib bin/update_pch bridges/Library_cpp_uno.mk bridges/source canvas/source chart2/CppunitTest_chart2_export.mk chart2/CppunitTest_chart2_import.mk chart2/inc chart2/Module_chart2.mk chart2/qa chart2/source chart2/uiconfig cli_ure/source codemaker/Module_codemaker.mk codemaker/source comphelper/Library_comphelper.mk comphelper/source compilerplugins/clang config_host.mk.in configmgr/source configure.ac connectivity/Configuration_writer.mk connectivity/Library_calc.mk connectivity/Library_file.mk connectivity/Library_writer.mk connectivity/ Module_connectivity.mk connectivity/registry connectivity/source cppcanvas/CppunitTest_cppcanvas_emfplus.mk cppcanvas/inc cppcanvas/source cppuhelper/source cppu/qa cppu/source cpputools/source cui/inc cui/Library_cui.mk cui/source cui/uiconfig dbaccess/inc dbaccess/Module_dbaccess.mk dbaccess/source dbaccess/uiconfig desktop/inc desktop/qa desktop/source desktop/unx dictionaries distro-configs/LibreOfficeFlatpak.conf download.lst drawinglayer/inc drawinglayer/Library_drawinglayer.mk drawinglayer/qa drawinglayer/source dtrans/source editeng/CppunitTest_editeng_core.mk editeng/inc editeng/qa editeng/source embeddedobj/Library_embobj.mk embeddedobj/source embedserv/source emfio/CppunitTest_emfio_emf_test.mk emfio/CppunitTest_emfio_wmf_test.mk emfio/emfio.component emfio/inc emfio/Library_emfio.mk emfio/Makefile emfio/Module_emfio.mk emfio/qa emfio/README emfio/source extensions/Library_abp.mk extensions/Library_dbp.mk extensions/qa extensions/source extensions/uiconfig external/boost external/coinmp external/cppunit external/expat external/fontconfig external/graphite external/harfbuzz external/hunspell external/icu external/jpeg-turbo external/lcms2 external/libatomic_ops external/libexttextcat external/libmwaw external/liborcus external/libstaroffice external/libwpd external/libwps external/libxmlsec external/lpsolve external/Module_external.mk external/pdfium external/poppler extras/source filter/CppunitTest_filter_eps_test.mk filter/qa filter/source forms/source formula/source fpicker/source fpicker/uiconfig framework/inc framework/source framework/uiconfig .gitignore helpcompiler/inc helpcompiler/source helpcontent2 hwpfilter/source i18nlangtag/qa i18nlangtag/source i18npool/inc i18npool/qa i18npool/source i18nutil/source icon-themes/breeze icon-themes/galaxy idlc/inc idlc/source idl/inc idl/source include/android include/basic include/canvas include/codemaker include/com include/comphelper include/connectivity include/cppcanvas include/cppuhelper include/d baccess include/desktop include/drawinglayer include/editeng include/filter include/formula include/framework include/i18nlangtag include/i18nutil include/linguistic include/o3tl include/oox include/osl include/registry include/rtl include/sal include/sax include/sfx2 include/sot include/svl include/svtools include/svx include/test include/toolkit include/tools include/uno include/unotools include/vbahelper include/vcl include/xmloff instsetoo_native/inc_common ios/experimental io/source javaunohelper/com jurt/com jvmfwk/plugins jvmfwk/source l10ntools/inc l10ntools/source libreofficekit/Executable_gtktiledviewer.mk libreofficekit/qa libreofficekit/README libreofficekit/source lingucomponent/source linguistic/inc linguistic/source lotuswordpro/source Makefile.fetch Makefile.in mysqlc/source odk/examples offapi/com offapi/UnoApi_offapi.mk officecfg/Configuration_officecfg.mk officecfg/registry onlineupdate/qa onlineupdate/source oovbaapi/ooo oovbaapi/UnoApi_oovbaapi.mk oox/inc oox/Li brary_oox.mk oox/qa oox/source opencl/inc opencl/source package/inc package/source postprocess/CustomTarget_registry.mk postprocess/packimages postprocess/Rdb_services.mk qadevOOo/Jar_OOoRunner.mk qadevOOo/objdsc qadevOOo/tests registry/source registry/test reportbuilder/java reportdesign/inc reportdesign/source reportdesign/uiconfig RepositoryExternal.mk Repository.mk RepositoryModule_build.mk RepositoryModule_host.mk rsc/inc rsc/source salhelper/Module_salhelper.mk sal/osl sal/qa sal/rtl sal/textenc sax/inc sax/qa sax/source sax/test scaddins/source sc/CppunitTest_sc_cellobj.mk sc/CppunitTest_sc_filters_test.mk sc/CppunitTest_sc_macros_test.mk sc/CppunitTest_sc_ucalc.mk schema/odf1.0 sc/inc sc/Library_sc.mk sc/Library_vbaobj.mk sc/Module_sc.mk

Thorsten Behrens Thorsten.Behrens at CIB.de
Sun Aug 20 01:46:42 UTC 2017


Rebased ref, commits from common ancestor:
commit 6565cb791bc18903ff3111cbf86991d72e9318dd
Author: Thorsten Behrens <Thorsten.Behrens at 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.Behrens at 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.Behrens at 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.Behrens at 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.Behrens at 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.Behrens at 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.Behrens at 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.Behrens at 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.Behrens at 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.Behrens at 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.Behrens at 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.Behrens at 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.Behrens at 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.Behrens at 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.Behrens at 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.Mehrbrodt at 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 <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at 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.grandin at 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 <ci at libreoffice.org>
    Reviewed-by: Noel Grandin <noel.grandin at 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.hallot at 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.hallot at edx.srv.br>
    Tested-by: Olivier Hallot <olivier.hallot at 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.cecchetti at 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 <ci at libreoffice.org>
    Reviewed-by: Marco Cecchetti <mrcekets at 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


More information about the Libreoffice-commits mailing list