diff options
Diffstat (limited to 'vcl/unx/generic/printer/jobdata.cxx')
-rw-r--r-- | vcl/unx/generic/printer/jobdata.cxx | 306 |
1 files changed, 306 insertions, 0 deletions
diff --git a/vcl/unx/generic/printer/jobdata.cxx b/vcl/unx/generic/printer/jobdata.cxx new file mode 100644 index 000000000..362305bea --- /dev/null +++ b/vcl/unx/generic/printer/jobdata.cxx @@ -0,0 +1,306 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <officecfg/Office/Common.hxx> +#include <jobdata.hxx> +#include <printerinfomanager.hxx> +#include <tools/stream.hxx> + +#include <rtl/strbuf.hxx> +#include <memory> + +using namespace psp; + +JobData& JobData::operator=(const JobData& rRight) +{ + if(this == &rRight) + return *this; + + m_nCopies = rRight.m_nCopies; + m_bCollate = rRight.m_bCollate; + m_nLeftMarginAdjust = rRight.m_nLeftMarginAdjust; + m_nRightMarginAdjust = rRight.m_nRightMarginAdjust; + m_nTopMarginAdjust = rRight.m_nTopMarginAdjust; + m_nBottomMarginAdjust = rRight.m_nBottomMarginAdjust; + m_nColorDepth = rRight.m_nColorDepth; + m_eOrientation = rRight.m_eOrientation; + m_aPrinterName = rRight.m_aPrinterName; + m_bPapersizeFromSetup = rRight.m_bPapersizeFromSetup; + m_pParser = rRight.m_pParser; + m_aContext = rRight.m_aContext; + m_nPSLevel = rRight.m_nPSLevel; + m_nPDFDevice = rRight.m_nPDFDevice; + m_nColorDevice = rRight.m_nColorDevice; + + if( !m_pParser && !m_aPrinterName.isEmpty() ) + { + PrinterInfoManager& rMgr = PrinterInfoManager::get(); + rMgr.setupJobContextData( *this ); + } + return *this; +} + +void JobData::setCollate( bool bCollate ) +{ + if (m_nPDFDevice > 0) + { + m_bCollate = bCollate; + return; + } + const PPDParser* pParser = m_aContext.getParser(); + if( pParser ) + { + const PPDKey* pKey = pParser->getKey( "Collate" ); + if( pKey ) + { + const PPDValue* pVal = nullptr; + if( bCollate ) + pVal = pKey->getValue( "True" ); + else + { + pVal = pKey->getValue( "False" ); + if( ! pVal ) + pVal = pKey->getValue( "None" ); + } + m_aContext.setValue( pKey, pVal ); + } + } +} + +void JobData::setPaper( int i_nWidth, int i_nHeight ) +{ + if( m_pParser ) + { + OUString aPaper( m_pParser->matchPaper( i_nWidth, i_nHeight ) ); + + const PPDKey* pKey = m_pParser->getKey( "PageSize" ); + const PPDValue* pValue = pKey ? pKey->getValueCaseInsensitive( aPaper ) : nullptr; + + if (pKey && pValue) + m_aContext.setValue( pKey, pValue ); + } +} + +void JobData::setPaperBin( int i_nPaperBin ) +{ + if( m_pParser ) + { + const PPDKey* pKey = m_pParser->getKey( "InputSlot" ); + const PPDValue* pValue = pKey ? pKey->getValue( i_nPaperBin ) : nullptr; + + if (pKey && pValue) + m_aContext.setValue( pKey, pValue ); + } +} + +bool JobData::getStreamBuffer( void*& pData, sal_uInt32& bytes ) +{ + // consistency checks + if( ! m_pParser ) + m_pParser = m_aContext.getParser(); + if( m_pParser != m_aContext.getParser() || + ! m_pParser ) + return false; + + SvMemoryStream aStream; + + // write header job data + aStream.WriteLine("JobData 1"); + + OStringBuffer aLine; + + aLine.append("printer="); + aLine.append(OUStringToOString(m_aPrinterName, RTL_TEXTENCODING_UTF8)); + aStream.WriteLine(aLine.makeStringAndClear()); + + aLine.append("orientation="); + if (m_eOrientation == orientation::Landscape) + aLine.append("Landscape"); + else + aLine.append("Portrait"); + aStream.WriteLine(aLine.makeStringAndClear()); + + aLine.append("copies="); + aLine.append(static_cast<sal_Int32>(m_nCopies)); + aStream.WriteLine(aLine.makeStringAndClear()); + + if (m_nPDFDevice > 0) + { + aLine.append("collate="); + aLine.append(OString::boolean(m_bCollate)); + aStream.WriteLine(aLine.makeStringAndClear()); + } + + aLine.append("margindajustment="); + aLine.append(static_cast<sal_Int32>(m_nLeftMarginAdjust)); + aLine.append(','); + aLine.append(static_cast<sal_Int32>(m_nRightMarginAdjust)); + aLine.append(','); + aLine.append(static_cast<sal_Int32>(m_nTopMarginAdjust)); + aLine.append(','); + aLine.append(static_cast<sal_Int32>(m_nBottomMarginAdjust)); + aStream.WriteLine(aLine.makeStringAndClear()); + + aLine.append("colordepth="); + aLine.append(static_cast<sal_Int32>(m_nColorDepth)); + aStream.WriteLine(aLine.makeStringAndClear()); + + aLine.append("pslevel="); + aLine.append(static_cast<sal_Int32>(m_nPSLevel)); + aStream.WriteLine(aLine.makeStringAndClear()); + + aLine.append("pdfdevice="); + aLine.append(static_cast<sal_Int32>(m_nPDFDevice)); + aStream.WriteLine(aLine.makeStringAndClear()); + + aLine.append("colordevice="); + aLine.append(static_cast<sal_Int32>(m_nColorDevice)); + aStream.WriteLine(aLine.makeStringAndClear()); + + // now append the PPDContext stream buffer + aStream.WriteLine( "PPDContexData" ); + sal_uLong nBytes; + std::unique_ptr<char[]> pContextBuffer(m_aContext.getStreamableBuffer( nBytes )); + if( nBytes ) + aStream.WriteBytes( pContextBuffer.get(), nBytes ); + pContextBuffer.reset(); + + // success + bytes = static_cast<sal_uInt32>(aStream.Tell()); + pData = std::malloc( bytes ); + memcpy( pData, aStream.GetData(), bytes ); + return true; +} + +bool JobData::constructFromStreamBuffer( const void* pData, sal_uInt32 bytes, JobData& rJobData ) +{ + SvMemoryStream aStream( const_cast<void*>(pData), bytes, StreamMode::READ ); + OString aLine; + bool bVersion = false; + bool bPrinter = false; + bool bOrientation = false; + bool bCopies = false; + bool bContext = false; + bool bMargin = false; + bool bColorDepth = false; + bool bColorDevice = false; + bool bPSLevel = false; + bool bPDFDevice = false; + + const char printerEquals[] = "printer="; + const char orientatationEquals[] = "orientation="; + const char copiesEquals[] = "copies="; + const char collateEquals[] = "collate="; + const char margindajustmentEquals[] = "margindajustment="; + const char colordepthEquals[] = "colordepth="; + const char colordeviceEquals[] = "colordevice="; + const char pslevelEquals[] = "pslevel="; + const char pdfdeviceEquals[] = "pdfdevice="; + + while( ! aStream.eof() ) + { + aStream.ReadLine( aLine ); + if (aLine.startsWith("JobData")) + bVersion = true; + else if (aLine.startsWith(printerEquals)) + { + bPrinter = true; + rJobData.m_aPrinterName = OStringToOUString(aLine.copy(RTL_CONSTASCII_LENGTH(printerEquals)), RTL_TEXTENCODING_UTF8); + } + else if (aLine.startsWith(orientatationEquals)) + { + bOrientation = true; + rJobData.m_eOrientation = aLine.copy(RTL_CONSTASCII_LENGTH(orientatationEquals)).equalsIgnoreAsciiCase("landscape") ? orientation::Landscape : orientation::Portrait; + } + else if (aLine.startsWith(copiesEquals)) + { + bCopies = true; + rJobData.m_nCopies = aLine.copy(RTL_CONSTASCII_LENGTH(copiesEquals)).toInt32(); + } + else if (aLine.startsWith(collateEquals)) + { + rJobData.m_bCollate = aLine.copy(RTL_CONSTASCII_LENGTH(collateEquals)).toBoolean(); + } + else if (aLine.startsWith(margindajustmentEquals)) + { + bMargin = true; + sal_Int32 nIdx {RTL_CONSTASCII_LENGTH(margindajustmentEquals)}; + rJobData.m_nLeftMarginAdjust = aLine.getToken(0, ',', nIdx).toInt32(); + rJobData.m_nRightMarginAdjust = aLine.getToken(0, ',', nIdx).toInt32(); + rJobData.m_nTopMarginAdjust = aLine.getToken(0, ',', nIdx).toInt32(); + rJobData.m_nBottomMarginAdjust = aLine.getToken(0, ',', nIdx).toInt32(); + } + else if (aLine.startsWith(colordepthEquals)) + { + bColorDepth = true; + rJobData.m_nColorDepth = aLine.copy(RTL_CONSTASCII_LENGTH(colordepthEquals)).toInt32(); + } + else if (aLine.startsWith(colordeviceEquals)) + { + bColorDevice = true; + rJobData.m_nColorDevice = aLine.copy(RTL_CONSTASCII_LENGTH(colordeviceEquals)).toInt32(); + } + else if (aLine.startsWith(pslevelEquals)) + { + bPSLevel = true; + rJobData.m_nPSLevel = aLine.copy(RTL_CONSTASCII_LENGTH(pslevelEquals)).toInt32(); + } + else if (aLine.startsWith(pdfdeviceEquals)) + { + bPDFDevice = true; + rJobData.m_nPDFDevice = aLine.copy(RTL_CONSTASCII_LENGTH(pdfdeviceEquals)).toInt32(); + } + else if (aLine == "PPDContexData" && bPrinter) + { + PrinterInfoManager& rManager = PrinterInfoManager::get(); + const PrinterInfo& rInfo = rManager.getPrinterInfo( rJobData.m_aPrinterName ); + rJobData.m_pParser = PPDParser::getParser( rInfo.m_aDriverName ); + if( rJobData.m_pParser ) + { + rJobData.m_aContext.setParser( rJobData.m_pParser ); + sal_uInt64 nBytes = bytes - aStream.Tell(); + std::vector<char> aRemain(nBytes+1); + nBytes = aStream.ReadBytes(aRemain.data(), nBytes); + if (nBytes) + { + aRemain.resize(nBytes+1); + aRemain[nBytes] = 0; + rJobData.m_aContext.rebuildFromStreamBuffer(aRemain); + bContext = true; + } + } + } + } + + return bVersion && bPrinter && bOrientation && bCopies && bContext && bMargin && bPSLevel && bPDFDevice && bColorDevice && bColorDepth; +} + +void JobData::resolveDefaultBackend() +{ + if (m_nPSLevel == 0 && m_nPDFDevice == 0) + setDefaultBackend(officecfg::Office::Common::Print::Option::Printer::PDFAsStandardPrintJobFormat::get()); +} + +void JobData::setDefaultBackend(bool bUsePDF) +{ + if (bUsePDF && m_nPSLevel == 0 && m_nPDFDevice == 0) + m_nPDFDevice = 1; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |