/* -*- 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 .
*/
#ifndef INCLUDED_VCL_PPDPARSER_HXX
#define INCLUDED_VCL_PPDPARSER_HXX
#include <sal/config.h>
#include <cstddef>
#include <memory>
#include <string_view>
#include <unordered_map>
#include <vector>
#include <rtl/string.hxx>
#include <rtl/ustring.hxx>
#include <tools/solar.h>
#include <vcl/dllapi.h>
#define PRINTER_PPDDIR "driver"
namespace psp {
enum class orientation;
class PPDCache;
class PPDTranslator;
enum PPDValueType { eInvocation, eQuoted, eSymbol, eString, eNo };
struct VCL_DLLPUBLIC PPDValue
{
PPDValueType m_eType;
//CustomOption stuff for fdo#43049
//see http://www.cups.org/documentation.php/spec-ppd.html#OPTIONS
//for full specs, only the basics are implemented here
bool m_bCustomOption;
mutable bool m_bCustomOptionSetViaApp;
mutable OUString m_aCustomOption;
OUString m_aOption;
OUString m_aValue;
};
/*
* PPDKey - a container for the available options (=values) of a PPD keyword
*/
class PPDKey
{
friend class PPDParser;
friend class CPDManager;
typedef std::unordered_map< OUString, PPDValue > hash_type;
OUString m_aKey;
hash_type m_aValues;
std::vector<PPDValue*> m_aOrderedValues;
const PPDValue* m_pDefaultValue;
bool m_bQueryValue;
OUString m_aGroup;
private:
bool m_bUIOption;
int m_nOrderDependency;
void eraseValue( const OUString& rOption );
public:
PPDKey( OUString aKey );
~PPDKey();
PPDValue* insertValue(const OUString& rOption, PPDValueType eType, bool bCustomOption = false);
int countValues() const
{ return m_aValues.size(); }
// neither getValue will return the query option
const PPDValue* getValue( int n ) const;
const PPDValue* getValue( const OUString& rOption ) const;
const PPDValue* getValueCaseInsensitive( const OUString& rOption ) const;
const PPDValue* getDefaultValue() const { return m_pDefaultValue; }
const OUString& getGroup() const { return m_aGroup; }
const OUString& getKey() const { return m_aKey; }
bool isUIKey() const { return m_bUIOption; }
int getOrderDependency() const { return m_nOrderDependency; }
};
// define a hash for PPDKey
struct PPDKeyhash
{
size_t operator()( const PPDKey * pKey) const
{ return reinterpret_cast<size_t>(pKey); }
};
/*
* PPDParser - parses a PPD file and contains all available keys from it
*/
class PPDParser
{
friend class PPDContext;
friend class CUPSManager;
friend class CPDManager;
friend class PPDCache;
typedef std::unordered_map< OUString, std::unique_ptr<PPDKey> > hash_type;
void insertKey( std::unique_ptr<PPDKey> pKey );
public:
struct PPDConstraint
{
const PPDKey* m_pKey1;
const PPDValue* m_pOption1;
const PPDKey* m_pKey2;
const PPDValue* m_pOption2;
PPDConstraint() : m_pKey1( nullptr ), m_pOption1( nullptr ), m_pKey2( nullptr ), m_pOption2( nullptr ) {}
};
private:
hash_type m_aKeys;
std::vector<PPDKey*> m_aOrderedKeys;
::std::vector< PPDConstraint > m_aConstraints;
// the full path of the PPD file
OUString m_aFile;
// some basic attributes
rtl_TextEncoding m_aFileEncoding;
// shortcuts to important keys and their default values
// imageable area
const PPDKey* m_pImageableAreas;
// paper dimensions
const PPDValue* m_pDefaultPaperDimension;
const PPDKey* m_pPaperDimensions;
// paper trays
const PPDValue* m_pDefaultInputSlot;
// resolutions
const PPDValue* m_pDefaultResolution;
// translations
std::unique_ptr<PPDTranslator> m_pTranslator;
PPDParser( OUString aFile );
PPDParser(OUString aFile, const std::vector<PPDKey*>& keys);
void parseOrderDependency(const OString& rLine);
void parseOpenUI(const OString& rLine, std::string_view rPPDGroup);
void parseConstraint(const OString& rLine);
void parse( std::vector< OString >& rLines );
OUString handleTranslation(const OString& i_rString, bool i_bIsGlobalized);
static void scanPPDDir( const OUString& rDir );
static void initPPDFiles(PPDCache &rPPDCache);
static OUString getPPDFile( const OUString& rFile );
OUString matchPaperImpl(int nWidth, int nHeight, bool bSwapped, psp::orientation* pOrientation = nullptr) const;
public:
~PPDParser();
static const PPDParser* getParser( const OUString& rFile );
const PPDKey* getKey( int n ) const;
const PPDKey* getKey( const OUString& rKey ) const;
int getKeys() const { return m_aKeys.size(); }
bool hasKey( const PPDKey* ) const;
const ::std::vector< PPDConstraint >& getConstraints() const { return m_aConstraints; }
const OUString & getDefaultPaperDimension() const;
void getDefaultPaperDimension( int& rWidth, int& rHeight ) const
{ getPaperDimension( getDefaultPaperDimension(), rWidth, rHeight ); }
bool getPaperDimension( std::u16string_view rPaperName,
int& rWidth, int& rHeight ) const;
// width and height in pt
// returns false if paper not found
// match the best paper for width and height
OUString matchPaper( int nWidth, int nHeight, psp::orientation* pOrientation = nullptr ) const;
bool getMargins( std::u16string_view rPaperName,
int &rLeft, int& rRight,
int &rUpper, int& rLower ) const;
// values in pt
// returns true if paper found
// values int pt
const OUString & getDefaultInputSlot() const;
void getDefaultResolution( int& rXRes, int& rYRes ) const;
// values in dpi
static void getResolutionFromString( std::u16string_view, int&, int& );
// helper function
OUString translateKey( const OUString& i_rKey ) const;
OUString translateOption( std::u16string_view i_rKey,
const OUString& i_rOption ) const;
};
/*
* PPDContext - a class to manage user definable states based on the
* contents of a PPDParser.
*/
class PPDContext
{
typedef std::unordered_map< const PPDKey*, const PPDValue*, PPDKeyhash > hash_type;
hash_type m_aCurrentValues;
const PPDParser* m_pParser;
// returns false: check failed, new value is constrained
// true: check succeeded, new value can be set
bool checkConstraints( const PPDKey*, const PPDValue*, bool bDoReset );
bool resetValue( const PPDKey*, bool bDefaultable = false );
public:
PPDContext();
PPDContext( const PPDContext& rContext ) { operator=( rContext ); }
PPDContext& operator=( const PPDContext& rContext ) = default;
PPDContext& operator=( PPDContext&& rContext );
void setParser( const PPDParser* );
const PPDParser* getParser() const { return m_pParser; }
const PPDValue* getValue( const PPDKey* ) const;
const PPDValue* setValue( const PPDKey*, const PPDValue*, bool bDontCareForConstraints = false );
std::size_t countValuesModified() const { return m_aCurrentValues.size(); }
const PPDKey* getModifiedKey( std::size_t n ) const;
// public wrapper for the private method
bool checkConstraints( const PPDKey*, const PPDValue* );
// for printer setup
char* getStreamableBuffer( sal_uLong& rBytes ) const;
void rebuildFromStreamBuffer(const std::vector<char> &rBuffer);
// convenience
int getRenderResolution() const;
// width, height in points, paper will contain the name of the selected
// paper after the call
void getPageSize( OUString& rPaper, int& rWidth, int& rHeight ) const;
};
} // namespace
#endif // INCLUDED_VCL_PPDPARSER_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
↑ V690 The 'PPDContext' class implements a copy constructor, but lacks the copy assignment operator. It is dangerous to use such a class.
↑ V690 The 'PPDContext' class implements the move assignment operator, but lacks a move constructor. It is dangerous to use such a class.