/src/libreoffice/vcl/inc/ppdparser.hxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
11 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | | * contributor license agreements. See the NOTICE file distributed |
13 | | * with this work for additional information regarding copyright |
14 | | * ownership. The ASF licenses this file to you under the Apache |
15 | | * License, Version 2.0 (the "License"); you may not use this file |
16 | | * except in compliance with the License. You may obtain a copy of |
17 | | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | | */ |
19 | | |
20 | | #pragma once |
21 | | |
22 | | #include <sal/config.h> |
23 | | |
24 | | #include <cstddef> |
25 | | #include <memory> |
26 | | #include <string_view> |
27 | | #include <unordered_map> |
28 | | #include <vector> |
29 | | |
30 | | #include <rtl/string.hxx> |
31 | | #include <rtl/ustring.hxx> |
32 | | #include <tools/solar.h> |
33 | | #include <vcl/dllapi.h> |
34 | | |
35 | 0 | #define PRINTER_PPDDIR "driver" |
36 | | |
37 | | namespace psp { |
38 | | |
39 | | enum class orientation; |
40 | | |
41 | | class PPDCache; |
42 | | class PPDTranslator; |
43 | | |
44 | | enum class PPDValueType |
45 | | { |
46 | | Invocation, |
47 | | Quoted, |
48 | | Symbol, |
49 | | String, |
50 | | No |
51 | | }; |
52 | | |
53 | | struct VCL_DLLPUBLIC PPDValue |
54 | | { |
55 | | PPDValueType m_eType; |
56 | | //CustomOption stuff for fdo#43049 |
57 | | //see http://www.cups.org/documentation.php/spec-ppd.html#OPTIONS |
58 | | //for full specs, only the basics are implemented here |
59 | | bool m_bCustomOption; |
60 | | mutable bool m_bCustomOptionSetViaApp; |
61 | | mutable OUString m_aCustomOption; |
62 | | OUString m_aOption; |
63 | | OUString m_aValue; |
64 | | }; |
65 | | |
66 | | |
67 | | /* |
68 | | * PPDKey - a container for the available options (=values) of a PPD keyword |
69 | | */ |
70 | | |
71 | | class PPDKey |
72 | | { |
73 | | friend class PPDParser; |
74 | | friend class CPDManager; |
75 | | |
76 | | typedef std::unordered_map< OUString, PPDValue > hash_type; |
77 | | |
78 | | OUString m_aKey; |
79 | | hash_type m_aValues; |
80 | | std::vector<PPDValue*> m_aOrderedValues; |
81 | | const PPDValue* m_pDefaultValue; |
82 | | bool m_bQueryValue; |
83 | | OUString m_aGroup; |
84 | | |
85 | | private: |
86 | | |
87 | | bool m_bUIOption; |
88 | | int m_nOrderDependency; |
89 | | |
90 | | void eraseValue( const OUString& rOption ); |
91 | | public: |
92 | | PPDKey( OUString aKey ); |
93 | | ~PPDKey(); |
94 | | |
95 | | PPDValue* insertValue(const OUString& rOption, PPDValueType eType, bool bCustomOption = false); |
96 | | int countValues() const |
97 | 0 | { return m_aValues.size(); } |
98 | | // neither getValue will return the query option |
99 | | const PPDValue* getValue( int n ) const; |
100 | | const PPDValue* getValue( const OUString& rOption ) const; |
101 | | const PPDValue* getValueCaseInsensitive( const OUString& rOption ) const; |
102 | 0 | const PPDValue* getDefaultValue() const { return m_pDefaultValue; } |
103 | 0 | const OUString& getGroup() const { return m_aGroup; } |
104 | | |
105 | 0 | const OUString& getKey() const { return m_aKey; } |
106 | 0 | bool isUIKey() const { return m_bUIOption; } |
107 | 0 | int getOrderDependency() const { return m_nOrderDependency; } |
108 | | }; |
109 | | |
110 | | // define a hash for PPDKey |
111 | | struct PPDKeyhash |
112 | | { |
113 | | size_t operator()( const PPDKey * pKey) const |
114 | 0 | { return reinterpret_cast<size_t>(pKey); } |
115 | | }; |
116 | | |
117 | | /* |
118 | | * PPDParser - parses a PPD file and contains all available keys from it |
119 | | */ |
120 | | |
121 | | class PPDParser |
122 | | { |
123 | | friend class CUPSManager; |
124 | | friend class CPDManager; |
125 | | friend class PPDCache; |
126 | | |
127 | | typedef std::unordered_map< OUString, std::unique_ptr<PPDKey> > hash_type; |
128 | | |
129 | | void insertKey( std::unique_ptr<PPDKey> pKey ); |
130 | | public: |
131 | | struct PPDConstraint |
132 | | { |
133 | | const PPDKey* m_pKey1; |
134 | | const PPDValue* m_pOption1; |
135 | | const PPDKey* m_pKey2; |
136 | | const PPDValue* m_pOption2; |
137 | | |
138 | 0 | PPDConstraint() : m_pKey1( nullptr ), m_pOption1( nullptr ), m_pKey2( nullptr ), m_pOption2( nullptr ) {} |
139 | | }; |
140 | | private: |
141 | | hash_type m_aKeys; |
142 | | std::vector<PPDKey*> m_aOrderedKeys; |
143 | | ::std::vector< PPDConstraint > m_aConstraints; |
144 | | |
145 | | // the full path of the PPD file |
146 | | OUString m_aFile; |
147 | | // some basic attributes |
148 | | rtl_TextEncoding m_aFileEncoding; |
149 | | |
150 | | |
151 | | // shortcuts to important keys and their default values |
152 | | // imageable area |
153 | | const PPDKey* m_pImageableAreas; |
154 | | // paper dimensions |
155 | | const PPDValue* m_pDefaultPaperDimension; |
156 | | const PPDKey* m_pPaperDimensions; |
157 | | // paper trays |
158 | | const PPDValue* m_pDefaultInputSlot; |
159 | | // resolutions |
160 | | const PPDValue* m_pDefaultResolution; |
161 | | |
162 | | // translations |
163 | | std::unique_ptr<PPDTranslator> m_pTranslator; |
164 | | |
165 | | PPDParser( OUString aFile ); |
166 | | PPDParser(OUString aFile, const std::vector<PPDKey*>& keys); |
167 | | |
168 | | void parseOrderDependency(const OString& rLine); |
169 | | void parseOpenUI(const OString& rLine, std::string_view rPPDGroup); |
170 | | void parseConstraint(const OString& rLine); |
171 | | void parse( std::vector< OString >& rLines ); |
172 | | |
173 | | OUString handleTranslation(const OString& i_rString, bool i_bIsGlobalized); |
174 | | |
175 | | static void scanPPDDir( const OUString& rDir ); |
176 | | static void initPPDFiles(PPDCache &rPPDCache); |
177 | | static OUString getPPDFile( const OUString& rFile ); |
178 | | |
179 | | OUString matchPaperImpl(int nWidth, int nHeight, bool bSwapped, psp::orientation* pOrientation = nullptr) const; |
180 | | |
181 | | public: |
182 | | ~PPDParser(); |
183 | | static const PPDParser* getParser( const OUString& rFile ); |
184 | | |
185 | | const PPDKey* getKey( int n ) const; |
186 | | const PPDKey* getKey( const OUString& rKey ) const; |
187 | 0 | int getKeys() const { return m_aKeys.size(); } |
188 | | bool hasKey( const PPDKey* ) const; |
189 | | |
190 | 0 | const ::std::vector< PPDConstraint >& getConstraints() const { return m_aConstraints; } |
191 | | |
192 | | const OUString & getDefaultPaperDimension() const; |
193 | | void getDefaultPaperDimension( int& rWidth, int& rHeight ) const |
194 | 0 | { getPaperDimension( getDefaultPaperDimension(), rWidth, rHeight ); } |
195 | | bool getPaperDimension( std::u16string_view rPaperName, |
196 | | int& rWidth, int& rHeight ) const; |
197 | | // width and height in pt |
198 | | // returns false if paper not found |
199 | | |
200 | | // match the best paper for width and height |
201 | | OUString matchPaper( int nWidth, int nHeight, psp::orientation* pOrientation = nullptr ) const; |
202 | | |
203 | | bool getMargins( std::u16string_view rPaperName, |
204 | | int &rLeft, int& rRight, |
205 | | int &rUpper, int& rLower ) const; |
206 | | // values in pt |
207 | | // returns true if paper found |
208 | | |
209 | | // values int pt |
210 | | |
211 | | const OUString & getDefaultInputSlot() const; |
212 | | |
213 | | void getDefaultResolution( int& rXRes, int& rYRes ) const; |
214 | | // values in dpi |
215 | | static void getResolutionFromString( std::u16string_view, int&, int& ); |
216 | | // helper function |
217 | | |
218 | | OUString translateKey( const OUString& i_rKey ) const; |
219 | | OUString translateOption( std::u16string_view i_rKey, |
220 | | const OUString& i_rOption ) const; |
221 | | }; |
222 | | |
223 | | |
224 | | /* |
225 | | * PPDContext - a class to manage user definable states based on the |
226 | | * contents of a PPDParser. |
227 | | */ |
228 | | |
229 | | class PPDContext |
230 | | { |
231 | | typedef std::unordered_map< const PPDKey*, const PPDValue*, PPDKeyhash > hash_type; |
232 | | hash_type m_aCurrentValues; |
233 | | const PPDParser* m_pParser; |
234 | | |
235 | | // returns false: check failed, new value is constrained |
236 | | // true: check succeeded, new value can be set |
237 | | bool checkConstraints( const PPDKey*, const PPDValue*, bool bDoReset ); |
238 | | bool resetValue( const PPDKey*, bool bDefaultable = false ); |
239 | | public: |
240 | | PPDContext(); |
241 | 0 | PPDContext( const PPDContext& rContext ) { operator=( rContext ); } |
242 | 0 | PPDContext& operator=( const PPDContext& rContext ) = default; |
243 | | PPDContext& operator=( PPDContext&& rContext ); |
244 | | |
245 | | void setParser( const PPDParser* ); |
246 | 0 | const PPDParser* getParser() const { return m_pParser; } |
247 | | |
248 | | const PPDValue* getValue( const PPDKey* ) const; |
249 | | const PPDValue* setValue( const PPDKey*, const PPDValue*, bool bDontCareForConstraints = false ); |
250 | | |
251 | 0 | std::size_t countValuesModified() const { return m_aCurrentValues.size(); } |
252 | | const PPDKey* getModifiedKey( std::size_t n ) const; |
253 | | |
254 | | // public wrapper for the private method |
255 | | bool checkConstraints( const PPDKey*, const PPDValue* ); |
256 | | |
257 | | // for printer setup |
258 | | char* getStreamableBuffer( sal_uLong& rBytes ) const; |
259 | | void rebuildFromStreamBuffer(const std::vector<char> &rBuffer); |
260 | | |
261 | | // convenience |
262 | | int getRenderResolution() const; |
263 | | |
264 | | // width, height in points, paper will contain the name of the selected |
265 | | // paper after the call |
266 | | void getPageSize( OUString& rPaper, int& rWidth, int& rHeight ) const; |
267 | | }; |
268 | | |
269 | | } // namespace |
270 | | |
271 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |