vcl/source/gdi/jobset.cxx |   15 +++++++++++++++
 1 file changed, 15 insertions(+)

New commits:
commit 11cd74ade59c6b47b25a737775a541fdd6faed44
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Tue Jul 26 13:53:17 2022 +0200
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Tue Jul 26 22:37:58 2022 +0200

    tdf#150104 Store full printer/driver name in doc's JobSetup
    
    Printer and driver name have a limited length (64 chars for
    the printer name, 32 for the driver name) in the
    `ImplOldJobSetupData` struct that is part of what gets
    serialized into the "PrinterSetup" config item in
    settings.xml when saving printer settings to the document
    (s. `WriteJobSetup`). Longer printer and driver names
    get truncated, and only the truncated name got restored.
    
    At least for Windows, this scenario would result in the
    doc printer settings not getting restored properly,
    because `ImplTestSalJobSetup` (in vcl/win/gdi/salprn.cxx)
    among others checks that both printer and driver name
    match, which isn't the case when one version is truncated.
    
    ODF spec, version 1.3, section 3.1.3.5 says this on settings.xml:
    
    > 3.1.3.5 <office:document-settings>
    > The <office:document-settings> root element contains
    > implementation-dependent settings. The file within a
    > package for the <office:document-settings> element is
    > settings.xml.
    
    Since the settings are implementation-dependent,
    changing the exact format and content of
    the data in "PrinterSetup" is unproblematic,
    as long as compatibility with older application versions
    is maintained.
    
    Luckily, there is already a way to save variable-length
    key-value pairs with `JOBSET_FILE605_SYSTEM`,
    added in
    
        commit 4bd178f6ee60f641b2a6c7fcc9f6e4b6dd01df27
        Date:   Fri Sep 22 11:55:00 2000 +0000
    
            new feature in JobSetup: additional parameters
    
    Make use of this to save the full printer and
    driver name using the "PRINTER_NAME" and "DRIVER_NAME"
    keys and restore the values from those if present.
    
    For compatibility with older versions, the (potentially
    truncated) values are still written and also used as
    fallback on document open.
    
    Change-Id: I55bed58023fa7a078525add79b13f2310aa9a9dd
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137454
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>

diff --git a/vcl/source/gdi/jobset.cxx b/vcl/source/gdi/jobset.cxx
index 04bc9daf98a6..9969a6165327 100644
--- a/vcl/source/gdi/jobset.cxx
+++ b/vcl/source/gdi/jobset.cxx
@@ -30,6 +30,9 @@
 
 namespace {
 
+// used only for compatibility with older versions,
+// printer/driver name are truncated if too long,
+// device name and port name are completely unused
 struct ImplOldJobSetupData
 {
     char    cPrinterName[64];
@@ -259,6 +262,8 @@ SvStream& ReadJobSetup( SvStream& rIStream, JobSetup& 
rJobSetup )
 
             ImplJobSetup& rJobData = rJobSetup.ImplGetData();
 
+            // use (potentially truncated) printer/driver name from 
ImplOldJobSetupData as fallback,
+            // gets overwritten below if PRINTER_NAME/DRIVER_NAME keys are set
             pData->cPrinterName[std::size(pData->cPrinterName) - 1] = 0;
             rJobData.SetPrinterName( OStringToOUString(pData->cPrinterName, 
aStreamEncoding) );
             pData->cDriverName[std::size(pData->cDriverName) - 1] = 0;
@@ -327,6 +332,10 @@ SvStream& ReadJobSetup( SvStream& rIStream, JobSetup& 
rJobSetup )
                             else if( aValue == "DuplexMode::LongEdge" )
                                 rJobData.SetDuplexMode( DuplexMode::LongEdge );
                         }
+                        else if (aKey == u"PRINTER_NAME")
+                            rJobData.SetPrinterName(aValue);
+                        else if (aKey == u"DRIVER_NAME")
+                            rJobData.SetDriver(aValue);
                         else
                             rJobData.SetValueMap(aKey, aValue);
                     }
@@ -397,6 +406,12 @@ SvStream& WriteJobSetup( SvStream& rOStream, const 
JobSetup& rJobSetup )
                     write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream, 
"DuplexMode::LongEdge");
                     break;
             }
+            // write printer, driver name in full, the ones in aOldData may be 
truncated
+            write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStream, 
u"PRINTER_NAME", RTL_TEXTENCODING_UTF8);
+            write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStream, 
rJobData.GetPrinterName(), RTL_TEXTENCODING_UTF8);
+            write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStream, 
u"DRIVER_NAME", RTL_TEXTENCODING_UTF8);
+            write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStream, 
rJobData.GetDriver(), RTL_TEXTENCODING_UTF8);
+
             nLen = sal::static_int_cast<sal_uInt16>(rOStream.Tell() - nPos);
             rOStream.Seek( nPos );
             rOStream.WriteUInt16( nLen );

Reply via email to