1*c82f2877SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*c82f2877SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*c82f2877SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*c82f2877SAndrew Rist  * distributed with this work for additional information
6*c82f2877SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*c82f2877SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*c82f2877SAndrew Rist  * "License"); you may not use this file except in compliance
9*c82f2877SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*c82f2877SAndrew Rist  *
11*c82f2877SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*c82f2877SAndrew Rist  *
13*c82f2877SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*c82f2877SAndrew Rist  * software distributed under the License is distributed on an
15*c82f2877SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*c82f2877SAndrew Rist  * KIND, either express or implied.  See the License for the
17*c82f2877SAndrew Rist  * specific language governing permissions and limitations
18*c82f2877SAndrew Rist  * under the License.
19*c82f2877SAndrew Rist  *
20*c82f2877SAndrew Rist  *************************************************************/
21*c82f2877SAndrew Rist 
22*c82f2877SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_vcl.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <stdlib.h>
28cdf0e10cSrcweir #include <stdio.h>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #include <hash_map>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include "vcl/ppdparser.hxx"
33cdf0e10cSrcweir #include "vcl/strhelper.hxx"
34cdf0e10cSrcweir #include "vcl/helper.hxx"
35cdf0e10cSrcweir #include "vcl/svapp.hxx"
36cdf0e10cSrcweir #include "cupsmgr.hxx"
37cdf0e10cSrcweir #include "tools/debug.hxx"
38cdf0e10cSrcweir #include "tools/urlobj.hxx"
39cdf0e10cSrcweir #include "tools/stream.hxx"
40cdf0e10cSrcweir #include "tools/zcodec.hxx"
41cdf0e10cSrcweir #include "osl/mutex.hxx"
42cdf0e10cSrcweir #include "osl/file.hxx"
43cdf0e10cSrcweir #include "osl/process.h"
44cdf0e10cSrcweir #include "osl/thread.h"
45cdf0e10cSrcweir #include "rtl/strbuf.hxx"
46cdf0e10cSrcweir #include "rtl/ustrbuf.hxx"
47cdf0e10cSrcweir 
48cdf0e10cSrcweir #include "com/sun/star/lang/Locale.hpp"
49cdf0e10cSrcweir 
50cdf0e10cSrcweir namespace psp
51cdf0e10cSrcweir {
52cdf0e10cSrcweir     class PPDTranslator
53cdf0e10cSrcweir     {
54cdf0e10cSrcweir         struct LocaleEqual
55cdf0e10cSrcweir         {
operator ()psp::PPDTranslator::LocaleEqual56cdf0e10cSrcweir             bool operator()(const com::sun::star::lang::Locale& i_rLeft,
57cdf0e10cSrcweir                             const com::sun::star::lang::Locale& i_rRight) const
58cdf0e10cSrcweir             {
59cdf0e10cSrcweir                 return i_rLeft.Language.equals( i_rRight.Language ) &&
60cdf0e10cSrcweir                 i_rLeft.Country.equals( i_rRight.Country ) &&
61cdf0e10cSrcweir                 i_rLeft.Variant.equals( i_rRight.Variant );
62cdf0e10cSrcweir             }
63cdf0e10cSrcweir         };
64cdf0e10cSrcweir 
65cdf0e10cSrcweir         struct LocaleHash
66cdf0e10cSrcweir         {
operator ()psp::PPDTranslator::LocaleHash67cdf0e10cSrcweir             size_t operator()(const com::sun::star::lang::Locale& rLocale) const
68cdf0e10cSrcweir             { return
69cdf0e10cSrcweir                   (size_t)rLocale.Language.hashCode()
70cdf0e10cSrcweir                 ^ (size_t)rLocale.Country.hashCode()
71cdf0e10cSrcweir                 ^ (size_t)rLocale.Variant.hashCode()
72cdf0e10cSrcweir                 ;
73cdf0e10cSrcweir             }
74cdf0e10cSrcweir         };
75cdf0e10cSrcweir 
76cdf0e10cSrcweir         typedef std::hash_map< com::sun::star::lang::Locale, rtl::OUString, LocaleHash, LocaleEqual > translation_map;
77cdf0e10cSrcweir         typedef std::hash_map< rtl::OUString, translation_map, rtl::OUStringHash > key_translation_map;
78cdf0e10cSrcweir 
79cdf0e10cSrcweir         key_translation_map     m_aTranslations;
80cdf0e10cSrcweir         public:
PPDTranslator()81cdf0e10cSrcweir         PPDTranslator() {}
~PPDTranslator()82cdf0e10cSrcweir         ~PPDTranslator() {}
83cdf0e10cSrcweir 
84cdf0e10cSrcweir 
85cdf0e10cSrcweir         void insertValue(
86cdf0e10cSrcweir             const rtl::OUString& i_rKey,
87cdf0e10cSrcweir             const rtl::OUString& i_rOption,
88cdf0e10cSrcweir             const rtl::OUString& i_rValue,
89cdf0e10cSrcweir             const rtl::OUString& i_rTranslation,
90cdf0e10cSrcweir             const com::sun::star::lang::Locale& i_rLocale = com::sun::star::lang::Locale()
91cdf0e10cSrcweir             );
92cdf0e10cSrcweir 
insertOption(const rtl::OUString & i_rKey,const rtl::OUString & i_rOption,const rtl::OUString & i_rTranslation,const com::sun::star::lang::Locale & i_rLocale=com::sun::star::lang::Locale ())93cdf0e10cSrcweir         void insertOption( const rtl::OUString& i_rKey,
94cdf0e10cSrcweir                            const rtl::OUString& i_rOption,
95cdf0e10cSrcweir                            const rtl::OUString& i_rTranslation,
96cdf0e10cSrcweir                            const com::sun::star::lang::Locale& i_rLocale = com::sun::star::lang::Locale() )
97cdf0e10cSrcweir         {
98cdf0e10cSrcweir             insertValue( i_rKey, i_rOption, rtl::OUString(), i_rTranslation, i_rLocale );
99cdf0e10cSrcweir         }
100cdf0e10cSrcweir 
insertKey(const rtl::OUString & i_rKey,const rtl::OUString & i_rTranslation,const com::sun::star::lang::Locale & i_rLocale=com::sun::star::lang::Locale ())101cdf0e10cSrcweir         void insertKey( const rtl::OUString& i_rKey,
102cdf0e10cSrcweir                         const rtl::OUString& i_rTranslation,
103cdf0e10cSrcweir                         const com::sun::star::lang::Locale& i_rLocale = com::sun::star::lang::Locale() )
104cdf0e10cSrcweir         {
105cdf0e10cSrcweir             insertValue( i_rKey, rtl::OUString(), rtl::OUString(), i_rTranslation, i_rLocale );
106cdf0e10cSrcweir         }
107cdf0e10cSrcweir 
108cdf0e10cSrcweir         rtl::OUString translateValue(
109cdf0e10cSrcweir             const rtl::OUString& i_rKey,
110cdf0e10cSrcweir             const rtl::OUString& i_rOption,
111cdf0e10cSrcweir             const rtl::OUString& i_rValue,
112cdf0e10cSrcweir             const com::sun::star::lang::Locale& i_rLocale = com::sun::star::lang::Locale()
113cdf0e10cSrcweir             ) const;
114cdf0e10cSrcweir 
translateOption(const rtl::OUString & i_rKey,const rtl::OUString & i_rOption,const com::sun::star::lang::Locale & i_rLocale=com::sun::star::lang::Locale ()) const115cdf0e10cSrcweir         rtl::OUString translateOption( const rtl::OUString& i_rKey,
116cdf0e10cSrcweir                                        const rtl::OUString& i_rOption,
117cdf0e10cSrcweir                                        const com::sun::star::lang::Locale& i_rLocale = com::sun::star::lang::Locale() ) const
118cdf0e10cSrcweir         {
119cdf0e10cSrcweir             return translateValue( i_rKey, i_rOption, rtl::OUString(), i_rLocale );
120cdf0e10cSrcweir         }
121cdf0e10cSrcweir 
translateKey(const rtl::OUString & i_rKey,const com::sun::star::lang::Locale & i_rLocale=com::sun::star::lang::Locale ()) const122cdf0e10cSrcweir         rtl::OUString translateKey( const rtl::OUString& i_rKey,
123cdf0e10cSrcweir                                     const com::sun::star::lang::Locale& i_rLocale = com::sun::star::lang::Locale() ) const
124cdf0e10cSrcweir         {
125cdf0e10cSrcweir             return translateValue( i_rKey, rtl::OUString(), rtl::OUString(), i_rLocale );
126cdf0e10cSrcweir         }
127cdf0e10cSrcweir     };
128cdf0e10cSrcweir 
normalizeInputLocale(const com::sun::star::lang::Locale & i_rLocale,bool bInsertDefault=false)129cdf0e10cSrcweir     static com::sun::star::lang::Locale normalizeInputLocale(
130cdf0e10cSrcweir         const com::sun::star::lang::Locale& i_rLocale,
131cdf0e10cSrcweir         bool bInsertDefault = false
132cdf0e10cSrcweir         )
133cdf0e10cSrcweir     {
134cdf0e10cSrcweir         com::sun::star::lang::Locale aLoc( i_rLocale );
135cdf0e10cSrcweir         if( bInsertDefault && aLoc.Language.getLength() == 0 )
136cdf0e10cSrcweir         {
137cdf0e10cSrcweir             // empty locale requested, fill in application UI locale
138cdf0e10cSrcweir             aLoc = Application::GetSettings().GetUILocale();
139cdf0e10cSrcweir 
140cdf0e10cSrcweir             #if OSL_DEBUG_LEVEL > 1
141cdf0e10cSrcweir             static const char* pEnvLocale = getenv( "SAL_PPDPARSER_LOCALE" );
142cdf0e10cSrcweir             if( pEnvLocale && *pEnvLocale )
143cdf0e10cSrcweir             {
144cdf0e10cSrcweir                 rtl::OString aStr( pEnvLocale );
145cdf0e10cSrcweir                 sal_Int32 nLen = aStr.getLength();
146cdf0e10cSrcweir                 aLoc.Language = rtl::OStringToOUString( aStr.copy( 0, nLen > 2 ? 2 : nLen ), RTL_TEXTENCODING_MS_1252 );
147cdf0e10cSrcweir                 if( nLen >=5 && aStr.getStr()[2] == '_' )
148cdf0e10cSrcweir                     aLoc.Country = rtl::OStringToOUString( aStr.copy( 3, 2 ), RTL_TEXTENCODING_MS_1252 );
149cdf0e10cSrcweir                 else
150cdf0e10cSrcweir                     aLoc.Country = rtl::OUString();
151cdf0e10cSrcweir                 aLoc.Variant = rtl::OUString();
152cdf0e10cSrcweir             }
153cdf0e10cSrcweir             #endif
154cdf0e10cSrcweir         }
155cdf0e10cSrcweir         aLoc.Language = aLoc.Language.toAsciiLowerCase();
156cdf0e10cSrcweir         aLoc.Country  = aLoc.Country.toAsciiUpperCase();
157cdf0e10cSrcweir         aLoc.Variant  = aLoc.Variant.toAsciiUpperCase();
158cdf0e10cSrcweir 
159cdf0e10cSrcweir         return aLoc;
160cdf0e10cSrcweir     }
161cdf0e10cSrcweir 
insertValue(const rtl::OUString & i_rKey,const rtl::OUString & i_rOption,const rtl::OUString & i_rValue,const rtl::OUString & i_rTranslation,const com::sun::star::lang::Locale & i_rLocale)162cdf0e10cSrcweir     void PPDTranslator::insertValue(
163cdf0e10cSrcweir         const rtl::OUString& i_rKey,
164cdf0e10cSrcweir         const rtl::OUString& i_rOption,
165cdf0e10cSrcweir         const rtl::OUString& i_rValue,
166cdf0e10cSrcweir         const rtl::OUString& i_rTranslation,
167cdf0e10cSrcweir         const com::sun::star::lang::Locale& i_rLocale
168cdf0e10cSrcweir         )
169cdf0e10cSrcweir     {
170cdf0e10cSrcweir         rtl::OUStringBuffer aKey( i_rKey.getLength() + i_rOption.getLength() + i_rValue.getLength() + 2 );
171cdf0e10cSrcweir         aKey.append( i_rKey );
172cdf0e10cSrcweir         if( i_rOption.getLength() || i_rValue.getLength() )
173cdf0e10cSrcweir         {
174cdf0e10cSrcweir             aKey.append( sal_Unicode( ':' ) );
175cdf0e10cSrcweir             aKey.append( i_rOption );
176cdf0e10cSrcweir         }
177cdf0e10cSrcweir         if( i_rValue.getLength() )
178cdf0e10cSrcweir         {
179cdf0e10cSrcweir             aKey.append( sal_Unicode( ':' ) );
180cdf0e10cSrcweir             aKey.append( i_rValue );
181cdf0e10cSrcweir         }
182cdf0e10cSrcweir         if( aKey.getLength() && i_rTranslation.getLength() )
183cdf0e10cSrcweir         {
184cdf0e10cSrcweir             rtl::OUString aK( aKey.makeStringAndClear() );
185cdf0e10cSrcweir             com::sun::star::lang::Locale aLoc;
186cdf0e10cSrcweir             aLoc.Language = i_rLocale.Language.toAsciiLowerCase();
187cdf0e10cSrcweir             aLoc.Country  = i_rLocale.Country.toAsciiUpperCase();
188cdf0e10cSrcweir             aLoc.Variant  = i_rLocale.Variant.toAsciiUpperCase();
189cdf0e10cSrcweir             m_aTranslations[ aK ][ aLoc ] = i_rTranslation;
190cdf0e10cSrcweir         }
191cdf0e10cSrcweir     }
192cdf0e10cSrcweir 
translateValue(const rtl::OUString & i_rKey,const rtl::OUString & i_rOption,const rtl::OUString & i_rValue,const com::sun::star::lang::Locale & i_rLocale) const193cdf0e10cSrcweir     rtl::OUString PPDTranslator::translateValue(
194cdf0e10cSrcweir         const rtl::OUString& i_rKey,
195cdf0e10cSrcweir         const rtl::OUString& i_rOption,
196cdf0e10cSrcweir         const rtl::OUString& i_rValue,
197cdf0e10cSrcweir         const com::sun::star::lang::Locale& i_rLocale
198cdf0e10cSrcweir         ) const
199cdf0e10cSrcweir     {
200cdf0e10cSrcweir         rtl::OUString aResult;
201cdf0e10cSrcweir 
202cdf0e10cSrcweir         rtl::OUStringBuffer aKey( i_rKey.getLength() + i_rOption.getLength() + i_rValue.getLength() + 2 );
203cdf0e10cSrcweir         aKey.append( i_rKey );
204cdf0e10cSrcweir         if( i_rOption.getLength() || i_rValue.getLength() )
205cdf0e10cSrcweir         {
206cdf0e10cSrcweir             aKey.append( sal_Unicode( ':' ) );
207cdf0e10cSrcweir             aKey.append( i_rOption );
208cdf0e10cSrcweir         }
209cdf0e10cSrcweir         if( i_rValue.getLength() )
210cdf0e10cSrcweir         {
211cdf0e10cSrcweir             aKey.append( sal_Unicode( ':' ) );
212cdf0e10cSrcweir             aKey.append( i_rValue );
213cdf0e10cSrcweir         }
214cdf0e10cSrcweir         if( aKey.getLength() )
215cdf0e10cSrcweir         {
216cdf0e10cSrcweir             rtl::OUString aK( aKey.makeStringAndClear() );
217cdf0e10cSrcweir             key_translation_map::const_iterator it = m_aTranslations.find( aK );
218cdf0e10cSrcweir             if( it != m_aTranslations.end() )
219cdf0e10cSrcweir             {
220cdf0e10cSrcweir                 const translation_map& rMap( it->second );
221cdf0e10cSrcweir 
222cdf0e10cSrcweir                 com::sun::star::lang::Locale aLoc( normalizeInputLocale( i_rLocale, true ) );
223cdf0e10cSrcweir                 for( int nTry = 0; nTry < 4; nTry++ )
224cdf0e10cSrcweir                 {
225cdf0e10cSrcweir                     translation_map::const_iterator tr = rMap.find( aLoc );
226cdf0e10cSrcweir                     if( tr != rMap.end() )
227cdf0e10cSrcweir                     {
228cdf0e10cSrcweir                         aResult = tr->second;
229cdf0e10cSrcweir                         break;
230cdf0e10cSrcweir                     }
231cdf0e10cSrcweir                     switch( nTry )
232cdf0e10cSrcweir                     {
233cdf0e10cSrcweir                     case 0: aLoc.Variant  = rtl::OUString();break;
234cdf0e10cSrcweir                     case 1: aLoc.Country  = rtl::OUString();break;
235cdf0e10cSrcweir                     case 2: aLoc.Language = rtl::OUString();break;
236cdf0e10cSrcweir                     }
237cdf0e10cSrcweir                 }
238cdf0e10cSrcweir             }
239cdf0e10cSrcweir         }
240cdf0e10cSrcweir         return aResult;
241cdf0e10cSrcweir     }
242cdf0e10cSrcweir }
243cdf0e10cSrcweir 
244cdf0e10cSrcweir using namespace psp;
245cdf0e10cSrcweir using namespace rtl;
246cdf0e10cSrcweir 
247cdf0e10cSrcweir #undef DBG_ASSERT
248cdf0e10cSrcweir #if defined DBG_UTIL || (OSL_DEBUG_LEVEL > 1)
249cdf0e10cSrcweir #define BSTRING(x) ByteString( x, osl_getThreadTextEncoding() )
250cdf0e10cSrcweir #define DBG_ASSERT( x, y ) { if( ! (x) ) fprintf( stderr, (y) ); }
251cdf0e10cSrcweir #else
252cdf0e10cSrcweir #define DBG_ASSERT( x, y )
253cdf0e10cSrcweir #endif
254cdf0e10cSrcweir 
255cdf0e10cSrcweir std::list< PPDParser* > PPDParser::aAllParsers;
256cdf0e10cSrcweir std::hash_map< OUString, OUString, OUStringHash >* PPDParser::pAllPPDFiles = NULL;
257cdf0e10cSrcweir 
258cdf0e10cSrcweir class PPDDecompressStream
259cdf0e10cSrcweir {
260cdf0e10cSrcweir     SvFileStream*       mpFileStream;
261cdf0e10cSrcweir     SvMemoryStream*     mpMemStream;
262cdf0e10cSrcweir     rtl::OUString       maFileName;
263cdf0e10cSrcweir 
264cdf0e10cSrcweir     // forbid copying
265cdf0e10cSrcweir     PPDDecompressStream( const PPDDecompressStream& );
266cdf0e10cSrcweir     PPDDecompressStream& operator=(const PPDDecompressStream& );
267cdf0e10cSrcweir 
268cdf0e10cSrcweir     public:
269cdf0e10cSrcweir     PPDDecompressStream( const rtl::OUString& rFile );
270cdf0e10cSrcweir     ~PPDDecompressStream();
271cdf0e10cSrcweir 
272cdf0e10cSrcweir     bool IsOpen() const;
273cdf0e10cSrcweir     bool IsEof() const;
274cdf0e10cSrcweir     void ReadLine( ByteString& o_rLine);
275cdf0e10cSrcweir     void Open( const rtl::OUString& i_rFile );
276cdf0e10cSrcweir     void Close();
GetFileName() const277cdf0e10cSrcweir     const rtl::OUString& GetFileName() const { return maFileName; }
278cdf0e10cSrcweir };
279cdf0e10cSrcweir 
PPDDecompressStream(const rtl::OUString & i_rFile)280cdf0e10cSrcweir PPDDecompressStream::PPDDecompressStream( const rtl::OUString& i_rFile ) :
281cdf0e10cSrcweir     mpFileStream( NULL ),
282cdf0e10cSrcweir     mpMemStream( NULL )
283cdf0e10cSrcweir {
284cdf0e10cSrcweir     Open( i_rFile );
285cdf0e10cSrcweir }
286cdf0e10cSrcweir 
~PPDDecompressStream()287cdf0e10cSrcweir PPDDecompressStream::~PPDDecompressStream()
288cdf0e10cSrcweir {
289cdf0e10cSrcweir     Close();
290cdf0e10cSrcweir }
291cdf0e10cSrcweir 
Open(const rtl::OUString & i_rFile)292cdf0e10cSrcweir void PPDDecompressStream::Open( const rtl::OUString& i_rFile )
293cdf0e10cSrcweir {
294cdf0e10cSrcweir     Close();
295cdf0e10cSrcweir 
296cdf0e10cSrcweir     mpFileStream = new SvFileStream( i_rFile, STREAM_READ );
297cdf0e10cSrcweir     maFileName = mpFileStream->GetFileName();
298cdf0e10cSrcweir 
299cdf0e10cSrcweir     if( ! mpFileStream->IsOpen() )
300cdf0e10cSrcweir     {
301cdf0e10cSrcweir         Close();
302cdf0e10cSrcweir         return;
303cdf0e10cSrcweir     }
304cdf0e10cSrcweir 
305cdf0e10cSrcweir     ByteString aLine;
306cdf0e10cSrcweir     mpFileStream->ReadLine( aLine );
307cdf0e10cSrcweir     mpFileStream->Seek( 0 );
308cdf0e10cSrcweir 
309cdf0e10cSrcweir     // check for compress'ed or gzip'ed file
310cdf0e10cSrcweir     sal_uLong nCompressMethod = 0;
311cdf0e10cSrcweir     if( aLine.Len() > 1 && static_cast<unsigned char>(aLine.GetChar( 0 )) == 0x1f )
312cdf0e10cSrcweir     {
313cdf0e10cSrcweir         if( static_cast<unsigned char>(aLine.GetChar( 1 )) == 0x8b ) // check for gzip
314cdf0e10cSrcweir             nCompressMethod = ZCODEC_DEFAULT | ZCODEC_GZ_LIB;
315cdf0e10cSrcweir     }
316cdf0e10cSrcweir 
317cdf0e10cSrcweir     if( nCompressMethod != 0 )
318cdf0e10cSrcweir     {
319cdf0e10cSrcweir         // so let's try to decompress the stream
320cdf0e10cSrcweir         mpMemStream = new SvMemoryStream( 4096, 4096 );
321cdf0e10cSrcweir         ZCodec aCodec;
322cdf0e10cSrcweir         aCodec.BeginCompression( nCompressMethod );
323cdf0e10cSrcweir         long nComp = aCodec.Decompress( *mpFileStream, *mpMemStream );
324cdf0e10cSrcweir         aCodec.EndCompression();
325cdf0e10cSrcweir         if( nComp < 0 )
326cdf0e10cSrcweir         {
327cdf0e10cSrcweir             // decompression failed, must be an uncompressed stream after all
328cdf0e10cSrcweir             delete mpMemStream, mpMemStream = NULL;
329cdf0e10cSrcweir             mpFileStream->Seek( 0 );
330cdf0e10cSrcweir         }
331cdf0e10cSrcweir         else
332cdf0e10cSrcweir         {
333cdf0e10cSrcweir             // compression successfull, can get rid of file stream
334cdf0e10cSrcweir             delete mpFileStream, mpFileStream = NULL;
335cdf0e10cSrcweir             mpMemStream->Seek( 0 );
336cdf0e10cSrcweir         }
337cdf0e10cSrcweir     }
338cdf0e10cSrcweir }
339cdf0e10cSrcweir 
Close()340cdf0e10cSrcweir void PPDDecompressStream::Close()
341cdf0e10cSrcweir {
342cdf0e10cSrcweir     delete mpMemStream, mpMemStream = NULL;
343cdf0e10cSrcweir     delete mpFileStream, mpFileStream = NULL;
344cdf0e10cSrcweir }
345cdf0e10cSrcweir 
IsOpen() const346cdf0e10cSrcweir bool PPDDecompressStream::IsOpen() const
347cdf0e10cSrcweir {
348cdf0e10cSrcweir     return (mpMemStream || (mpFileStream && mpFileStream->IsOpen()));
349cdf0e10cSrcweir }
350cdf0e10cSrcweir 
IsEof() const351cdf0e10cSrcweir bool PPDDecompressStream::IsEof() const
352cdf0e10cSrcweir {
353cdf0e10cSrcweir     return ( mpMemStream ? mpMemStream->IsEof() : ( mpFileStream ? mpFileStream->IsEof() : true ) );
354cdf0e10cSrcweir }
355cdf0e10cSrcweir 
ReadLine(ByteString & o_rLine)356cdf0e10cSrcweir void PPDDecompressStream::ReadLine( ByteString& o_rLine )
357cdf0e10cSrcweir {
358cdf0e10cSrcweir     if( mpMemStream )
359cdf0e10cSrcweir         mpMemStream->ReadLine( o_rLine );
360cdf0e10cSrcweir     else if( mpFileStream )
361cdf0e10cSrcweir         mpFileStream->ReadLine( o_rLine );
362cdf0e10cSrcweir }
363cdf0e10cSrcweir 
resolveLink(const rtl::OUString & i_rURL,rtl::OUString & o_rResolvedURL,rtl::OUString & o_rBaseName,osl::FileStatus::Type & o_rType,int nLinkLevel=10)364cdf0e10cSrcweir static osl::FileBase::RC resolveLink( const rtl::OUString& i_rURL, rtl::OUString& o_rResolvedURL, rtl::OUString& o_rBaseName, osl::FileStatus::Type& o_rType, int nLinkLevel = 10 )
365cdf0e10cSrcweir {
366cdf0e10cSrcweir     osl::DirectoryItem aLinkItem;
367cdf0e10cSrcweir     osl::FileBase::RC aRet = osl::FileBase::E_None;
368cdf0e10cSrcweir 
369cdf0e10cSrcweir     if( ( aRet = osl::DirectoryItem::get( i_rURL, aLinkItem ) ) == osl::FileBase::E_None )
370cdf0e10cSrcweir     {
371cdf0e10cSrcweir         osl::FileStatus aStatus( FileStatusMask_FileName | FileStatusMask_Type | FileStatusMask_LinkTargetURL );
372cdf0e10cSrcweir         if( ( aRet = aLinkItem.getFileStatus( aStatus ) ) == osl::FileBase::E_None )
373cdf0e10cSrcweir         {
374cdf0e10cSrcweir             if( aStatus.getFileType() == osl::FileStatus::Link )
375cdf0e10cSrcweir             {
376cdf0e10cSrcweir                 if( nLinkLevel > 0 )
377cdf0e10cSrcweir                     aRet = resolveLink( aStatus.getLinkTargetURL(), o_rResolvedURL, o_rBaseName, o_rType, nLinkLevel-1 );
378cdf0e10cSrcweir                 else
379cdf0e10cSrcweir                     aRet = osl::FileBase::E_MULTIHOP;
380cdf0e10cSrcweir             }
381cdf0e10cSrcweir             else
382cdf0e10cSrcweir             {
383cdf0e10cSrcweir                 o_rResolvedURL = i_rURL;
384cdf0e10cSrcweir                 o_rBaseName = aStatus.getFileName();
385cdf0e10cSrcweir                 o_rType = aStatus.getFileType();
386cdf0e10cSrcweir             }
387cdf0e10cSrcweir         }
388cdf0e10cSrcweir     }
389cdf0e10cSrcweir     return aRet;
390cdf0e10cSrcweir }
391cdf0e10cSrcweir 
scanPPDDir(const String & rDir)392cdf0e10cSrcweir void PPDParser::scanPPDDir( const String& rDir )
393cdf0e10cSrcweir {
394cdf0e10cSrcweir     static struct suffix_t
395cdf0e10cSrcweir     {
396cdf0e10cSrcweir         const sal_Char* pSuffix;
397cdf0e10cSrcweir         const sal_Int32 nSuffixLen;
398cdf0e10cSrcweir     } const pSuffixes[] =
399cdf0e10cSrcweir     { { ".PS", 3 },  { ".PPD", 4 }, { ".PS.GZ", 6 }, { ".PPD.GZ", 7 } };
400cdf0e10cSrcweir 
401cdf0e10cSrcweir     const int nSuffixes = sizeof(pSuffixes)/sizeof(pSuffixes[0]);
402cdf0e10cSrcweir 
403cdf0e10cSrcweir     osl::Directory aDir( rDir );
404cdf0e10cSrcweir     if ( aDir.open() == osl::FileBase::E_None )
405cdf0e10cSrcweir     {
406cdf0e10cSrcweir         osl::DirectoryItem aItem;
407cdf0e10cSrcweir 
408cdf0e10cSrcweir         INetURLObject aPPDDir(rDir);
409cdf0e10cSrcweir         while( aDir.getNextItem( aItem ) == osl::FileBase::E_None )
410cdf0e10cSrcweir         {
411cdf0e10cSrcweir             osl::FileStatus aStatus( FileStatusMask_FileName );
412cdf0e10cSrcweir             if( aItem.getFileStatus( aStatus ) == osl::FileBase::E_None )
413cdf0e10cSrcweir             {
414cdf0e10cSrcweir                 rtl::OUStringBuffer aURLBuf( rDir.Len() + 64 );
415cdf0e10cSrcweir                 aURLBuf.append( rDir );
416cdf0e10cSrcweir                 aURLBuf.append( sal_Unicode( '/' ) );
417cdf0e10cSrcweir                 aURLBuf.append( aStatus.getFileName() );
418cdf0e10cSrcweir 
419cdf0e10cSrcweir                 rtl::OUString aFileURL, aFileName;
420cdf0e10cSrcweir                 osl::FileStatus::Type eType = osl::FileStatus::Unknown;
421cdf0e10cSrcweir 
422cdf0e10cSrcweir                 if( resolveLink( aURLBuf.makeStringAndClear(), aFileURL, aFileName, eType ) == osl::FileBase::E_None )
423cdf0e10cSrcweir                 {
424cdf0e10cSrcweir                     if( eType == osl::FileStatus::Regular )
425cdf0e10cSrcweir                     {
426cdf0e10cSrcweir                         INetURLObject aPPDFile = aPPDDir;
427cdf0e10cSrcweir                         aPPDFile.Append( aFileName );
428cdf0e10cSrcweir 
429cdf0e10cSrcweir                         // match extension
430cdf0e10cSrcweir                         for( int nSuffix = 0; nSuffix < nSuffixes; nSuffix++ )
431cdf0e10cSrcweir                         {
432cdf0e10cSrcweir                             if( aFileName.getLength() > pSuffixes[nSuffix].nSuffixLen )
433cdf0e10cSrcweir                             {
434cdf0e10cSrcweir                                 if( aFileName.endsWithIgnoreAsciiCaseAsciiL( pSuffixes[nSuffix].pSuffix, pSuffixes[nSuffix].nSuffixLen ) )
435cdf0e10cSrcweir                                 {
436cdf0e10cSrcweir                                     (*pAllPPDFiles)[ aFileName.copy( 0, aFileName.getLength() - pSuffixes[nSuffix].nSuffixLen ) ] = aPPDFile.PathToFileName();
437cdf0e10cSrcweir                                     break;
438cdf0e10cSrcweir                                 }
439cdf0e10cSrcweir                             }
440cdf0e10cSrcweir                         }
441cdf0e10cSrcweir                     }
442cdf0e10cSrcweir                     else if( eType == osl::FileStatus::Directory )
443cdf0e10cSrcweir                     {
444cdf0e10cSrcweir                         scanPPDDir( aFileURL );
445cdf0e10cSrcweir                     }
446cdf0e10cSrcweir                 }
447cdf0e10cSrcweir             }
448cdf0e10cSrcweir         }
449cdf0e10cSrcweir         aDir.close();
450cdf0e10cSrcweir     }
451cdf0e10cSrcweir }
452cdf0e10cSrcweir 
initPPDFiles()453cdf0e10cSrcweir void PPDParser::initPPDFiles()
454cdf0e10cSrcweir {
455cdf0e10cSrcweir     if( pAllPPDFiles )
456cdf0e10cSrcweir         return;
457cdf0e10cSrcweir 
458cdf0e10cSrcweir     pAllPPDFiles = new std::hash_map< OUString, OUString, OUStringHash >();
459cdf0e10cSrcweir 
460cdf0e10cSrcweir     // check installation directories
461cdf0e10cSrcweir     std::list< OUString > aPathList;
462cdf0e10cSrcweir     psp::getPrinterPathList( aPathList, PRINTER_PPDDIR );
463cdf0e10cSrcweir     for( std::list< OUString >::const_iterator ppd_it = aPathList.begin(); ppd_it != aPathList.end(); ++ppd_it )
464cdf0e10cSrcweir     {
465cdf0e10cSrcweir         INetURLObject aPPDDir( *ppd_it, INET_PROT_FILE, INetURLObject::ENCODE_ALL );
466cdf0e10cSrcweir         scanPPDDir( aPPDDir.GetMainURL( INetURLObject::NO_DECODE ) );
467cdf0e10cSrcweir     }
468cdf0e10cSrcweir     if( pAllPPDFiles->find( OUString( RTL_CONSTASCII_USTRINGPARAM( "SGENPRT" ) ) ) == pAllPPDFiles->end() )
469cdf0e10cSrcweir     {
470cdf0e10cSrcweir         // last try: search in directory of executable (mainly for setup)
471cdf0e10cSrcweir         OUString aExe;
472cdf0e10cSrcweir         if( osl_getExecutableFile( &aExe.pData ) == osl_Process_E_None )
473cdf0e10cSrcweir         {
474cdf0e10cSrcweir             INetURLObject aDir( aExe );
475cdf0e10cSrcweir             aDir.removeSegment();
476cdf0e10cSrcweir #ifdef DEBUG
477cdf0e10cSrcweir             fprintf( stderr, "scanning last chance dir: %s\n", OUStringToOString( aDir.GetMainURL( INetURLObject::NO_DECODE ), osl_getThreadTextEncoding() ).getStr() );
478cdf0e10cSrcweir #endif
479cdf0e10cSrcweir             scanPPDDir( aDir.GetMainURL( INetURLObject::NO_DECODE ) );
480cdf0e10cSrcweir #ifdef DEBUG
481cdf0e10cSrcweir             fprintf( stderr, "SGENPRT %s\n", pAllPPDFiles->find( OUString( RTL_CONSTASCII_USTRINGPARAM( "SGENPRT" ) ) ) == pAllPPDFiles->end() ? "not found" : "found" );
482cdf0e10cSrcweir #endif
483cdf0e10cSrcweir         }
484cdf0e10cSrcweir     }
485cdf0e10cSrcweir }
486cdf0e10cSrcweir 
getKnownPPDDrivers(std::list<rtl::OUString> & o_rDrivers,bool bRefresh)487cdf0e10cSrcweir void PPDParser::getKnownPPDDrivers( std::list< rtl::OUString >& o_rDrivers, bool bRefresh )
488cdf0e10cSrcweir {
489cdf0e10cSrcweir     if( bRefresh )
490cdf0e10cSrcweir     {
491cdf0e10cSrcweir         delete pAllPPDFiles;
492cdf0e10cSrcweir         pAllPPDFiles = NULL;
493cdf0e10cSrcweir     }
494cdf0e10cSrcweir 
495cdf0e10cSrcweir     initPPDFiles();
496cdf0e10cSrcweir     o_rDrivers.clear();
497cdf0e10cSrcweir 
498cdf0e10cSrcweir     std::hash_map< OUString, OUString, OUStringHash >::const_iterator it;
499cdf0e10cSrcweir     for( it = pAllPPDFiles->begin(); it != pAllPPDFiles->end(); ++it )
500cdf0e10cSrcweir         o_rDrivers.push_back( it->first );
501cdf0e10cSrcweir }
502cdf0e10cSrcweir 
getPPDFile(const String & rFile)503cdf0e10cSrcweir String PPDParser::getPPDFile( const String& rFile )
504cdf0e10cSrcweir {
505cdf0e10cSrcweir     INetURLObject aPPD( rFile, INET_PROT_FILE, INetURLObject::ENCODE_ALL );
506cdf0e10cSrcweir     // someone might enter a full qualified name here
507cdf0e10cSrcweir     PPDDecompressStream aStream( aPPD.PathToFileName() );
508cdf0e10cSrcweir     if( ! aStream.IsOpen() )
509cdf0e10cSrcweir     {
510cdf0e10cSrcweir         std::hash_map< OUString, OUString, OUStringHash >::const_iterator it;
511cdf0e10cSrcweir 
512cdf0e10cSrcweir         bool bRetry = true;
513cdf0e10cSrcweir         do
514cdf0e10cSrcweir         {
515cdf0e10cSrcweir             initPPDFiles();
516cdf0e10cSrcweir             // some PPD files contain dots beside the extension, so try name first
517cdf0e10cSrcweir             // and cut of points after that
518cdf0e10cSrcweir             rtl::OUString aBase( rFile );
519cdf0e10cSrcweir             sal_Int32 nLastIndex = aBase.lastIndexOf( sal_Unicode( '/' ) );
520cdf0e10cSrcweir             if( nLastIndex >= 0 )
521cdf0e10cSrcweir                 aBase = aBase.copy( nLastIndex+1 );
522cdf0e10cSrcweir             do
523cdf0e10cSrcweir             {
524cdf0e10cSrcweir                 it = pAllPPDFiles->find( aBase );
525cdf0e10cSrcweir                 nLastIndex = aBase.lastIndexOf( sal_Unicode( '.' ) );
526cdf0e10cSrcweir                 if( nLastIndex > 0 )
527cdf0e10cSrcweir                     aBase = aBase.copy( 0, nLastIndex );
528cdf0e10cSrcweir             } while( it == pAllPPDFiles->end() && nLastIndex > 0 );
529cdf0e10cSrcweir 
530cdf0e10cSrcweir             if( it == pAllPPDFiles->end() && bRetry )
531cdf0e10cSrcweir             {
532cdf0e10cSrcweir                 // a new file ? rehash
533cdf0e10cSrcweir                 delete pAllPPDFiles; pAllPPDFiles = NULL;
534cdf0e10cSrcweir                 bRetry = false;
535cdf0e10cSrcweir                 // note this is optimized for office start where
536cdf0e10cSrcweir                 // no new files occur and initPPDFiles is called only once
537cdf0e10cSrcweir             }
538cdf0e10cSrcweir         } while( ! pAllPPDFiles );
539cdf0e10cSrcweir 
540cdf0e10cSrcweir         if( it != pAllPPDFiles->end() )
541cdf0e10cSrcweir             aStream.Open( it->second );
542cdf0e10cSrcweir     }
543cdf0e10cSrcweir 
544cdf0e10cSrcweir     String aRet;
545cdf0e10cSrcweir     if( aStream.IsOpen() )
546cdf0e10cSrcweir     {
547cdf0e10cSrcweir         ByteString aLine;
548cdf0e10cSrcweir         aStream.ReadLine( aLine );
549cdf0e10cSrcweir         if( aLine.Search( "*PPD-Adobe" ) == 0 )
550cdf0e10cSrcweir             aRet = aStream.GetFileName();
551cdf0e10cSrcweir         else
552cdf0e10cSrcweir         {
553cdf0e10cSrcweir             // our *Include hack does usually not begin
554cdf0e10cSrcweir             // with *PPD-Adobe, so try some lines for *Include
555cdf0e10cSrcweir             int nLines = 10;
556cdf0e10cSrcweir             while( aLine.Search( "*Include" ) != 0 && --nLines )
557cdf0e10cSrcweir                 aStream.ReadLine( aLine );
558cdf0e10cSrcweir             if( nLines )
559cdf0e10cSrcweir                 aRet = aStream.GetFileName();
560cdf0e10cSrcweir         }
561cdf0e10cSrcweir     }
562cdf0e10cSrcweir 
563cdf0e10cSrcweir     return aRet;
564cdf0e10cSrcweir }
565cdf0e10cSrcweir 
getPPDPrinterName(const String & rFile)566cdf0e10cSrcweir String PPDParser::getPPDPrinterName( const String& rFile )
567cdf0e10cSrcweir {
568cdf0e10cSrcweir     String aPath = getPPDFile( rFile );
569cdf0e10cSrcweir     String aName;
570cdf0e10cSrcweir 
571cdf0e10cSrcweir     // read in the file
572cdf0e10cSrcweir     PPDDecompressStream aStream( aPath );
573cdf0e10cSrcweir     if( aStream.IsOpen() )
574cdf0e10cSrcweir     {
575cdf0e10cSrcweir         String aCurLine;
576cdf0e10cSrcweir         while( ! aStream.IsEof() && aStream.IsOpen() )
577cdf0e10cSrcweir         {
578cdf0e10cSrcweir             ByteString aByteLine;
579cdf0e10cSrcweir             aStream.ReadLine( aByteLine );
580cdf0e10cSrcweir             aCurLine = String( aByteLine, RTL_TEXTENCODING_MS_1252 );
581cdf0e10cSrcweir             if( aCurLine.CompareIgnoreCaseToAscii( "*include:", 9 ) == COMPARE_EQUAL )
582cdf0e10cSrcweir             {
583cdf0e10cSrcweir                 aCurLine.Erase( 0, 9 );
584cdf0e10cSrcweir                 aCurLine.EraseLeadingChars( ' ' );
585cdf0e10cSrcweir                 aCurLine.EraseTrailingChars( ' ' );
586cdf0e10cSrcweir                 aCurLine.EraseLeadingChars( '\t' );
587cdf0e10cSrcweir                 aCurLine.EraseTrailingChars( '\t' );
588cdf0e10cSrcweir                 aCurLine.EraseTrailingChars( '\r' );
589cdf0e10cSrcweir                 aCurLine.EraseTrailingChars( '\n' );
590cdf0e10cSrcweir                 aCurLine.EraseLeadingChars( '"' );
591cdf0e10cSrcweir                 aCurLine.EraseTrailingChars( '"' );
592cdf0e10cSrcweir                 aStream.Close();
593cdf0e10cSrcweir                 aStream.Open( getPPDFile( aCurLine ) );
594cdf0e10cSrcweir                 continue;
595cdf0e10cSrcweir             }
596cdf0e10cSrcweir             if( aCurLine.CompareToAscii( "*ModelName:", 11 ) == COMPARE_EQUAL )
597cdf0e10cSrcweir             {
598cdf0e10cSrcweir                 aName = aCurLine.GetToken( 1, '"' );
599cdf0e10cSrcweir                 break;
600cdf0e10cSrcweir             }
601cdf0e10cSrcweir             else if( aCurLine.CompareToAscii( "*NickName:", 10 ) == COMPARE_EQUAL )
602cdf0e10cSrcweir                 aName = aCurLine.GetToken( 1, '"' );
603cdf0e10cSrcweir         }
604cdf0e10cSrcweir     }
605cdf0e10cSrcweir     return aName;
606cdf0e10cSrcweir }
607cdf0e10cSrcweir 
getParser(const String & rFile)608cdf0e10cSrcweir const PPDParser* PPDParser::getParser( const String& rFile )
609cdf0e10cSrcweir {
610cdf0e10cSrcweir     static ::osl::Mutex aMutex;
611cdf0e10cSrcweir     ::osl::Guard< ::osl::Mutex > aGuard( aMutex );
612cdf0e10cSrcweir 
613cdf0e10cSrcweir     String aFile = rFile;
614cdf0e10cSrcweir     if( rFile.CompareToAscii( "CUPS:", 5 ) != COMPARE_EQUAL )
615cdf0e10cSrcweir         aFile = getPPDFile( rFile );
616cdf0e10cSrcweir     if( ! aFile.Len() )
617cdf0e10cSrcweir     {
618cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
619cdf0e10cSrcweir         fprintf( stderr, "Could not get printer PPD file \"%s\" !\n", OUStringToOString( rFile, osl_getThreadTextEncoding() ).getStr() );
620cdf0e10cSrcweir #endif
621cdf0e10cSrcweir         return NULL;
622cdf0e10cSrcweir     }
623cdf0e10cSrcweir 
624cdf0e10cSrcweir     for( ::std::list< PPDParser* >::const_iterator it = aAllParsers.begin(); it != aAllParsers.end(); ++it )
625cdf0e10cSrcweir         if( (*it)->m_aFile == aFile )
626cdf0e10cSrcweir             return *it;
627cdf0e10cSrcweir 
628cdf0e10cSrcweir     PPDParser* pNewParser = NULL;
629cdf0e10cSrcweir     if( aFile.CompareToAscii( "CUPS:", 5 ) != COMPARE_EQUAL )
630cdf0e10cSrcweir         pNewParser = new PPDParser( aFile );
631cdf0e10cSrcweir     else
632cdf0e10cSrcweir     {
633cdf0e10cSrcweir         PrinterInfoManager& rMgr = PrinterInfoManager::get();
634cdf0e10cSrcweir         if( rMgr.getType() == PrinterInfoManager::CUPS )
635cdf0e10cSrcweir         {
636cdf0e10cSrcweir             pNewParser = const_cast<PPDParser*>(static_cast<CUPSManager&>(rMgr).createCUPSParser( aFile ));
637cdf0e10cSrcweir         }
638cdf0e10cSrcweir     }
639cdf0e10cSrcweir     if( pNewParser )
640cdf0e10cSrcweir     {
641cdf0e10cSrcweir         // this may actually be the SGENPRT parser,
642cdf0e10cSrcweir         // so ensure uniquness here
643cdf0e10cSrcweir         aAllParsers.remove( pNewParser );
644cdf0e10cSrcweir         // insert new parser to list
645cdf0e10cSrcweir         aAllParsers.push_front( pNewParser );
646cdf0e10cSrcweir     }
647cdf0e10cSrcweir     return pNewParser;
648cdf0e10cSrcweir }
649cdf0e10cSrcweir 
freeAll()650cdf0e10cSrcweir void PPDParser::freeAll()
651cdf0e10cSrcweir {
652cdf0e10cSrcweir     while( aAllParsers.begin() != aAllParsers.end() )
653cdf0e10cSrcweir     {
654cdf0e10cSrcweir         delete aAllParsers.front();
655cdf0e10cSrcweir         aAllParsers.pop_front();
656cdf0e10cSrcweir     }
657cdf0e10cSrcweir     delete pAllPPDFiles;
658cdf0e10cSrcweir     pAllPPDFiles = NULL;
659cdf0e10cSrcweir }
660cdf0e10cSrcweir 
PPDParser(const String & rFile)661cdf0e10cSrcweir PPDParser::PPDParser( const String& rFile ) :
662cdf0e10cSrcweir         m_aFile( rFile ),
663cdf0e10cSrcweir         m_bType42Capable( false ),
664cdf0e10cSrcweir         m_aFileEncoding( RTL_TEXTENCODING_MS_1252 ),
665cdf0e10cSrcweir         m_pDefaultImageableArea( NULL ),
666cdf0e10cSrcweir         m_pImageableAreas( NULL ),
667cdf0e10cSrcweir         m_pDefaultPaperDimension( NULL ),
668cdf0e10cSrcweir         m_pPaperDimensions( NULL ),
669cdf0e10cSrcweir         m_pDefaultInputSlot( NULL ),
670cdf0e10cSrcweir         m_pInputSlots( NULL ),
671cdf0e10cSrcweir         m_pDefaultResolution( NULL ),
672cdf0e10cSrcweir         m_pResolutions( NULL ),
673cdf0e10cSrcweir         m_pDefaultDuplexType( NULL ),
674cdf0e10cSrcweir         m_pDuplexTypes( NULL ),
675cdf0e10cSrcweir         m_pFontList( NULL ),
676cdf0e10cSrcweir         m_pTranslator( new PPDTranslator() )
677cdf0e10cSrcweir {
678cdf0e10cSrcweir     // read in the file
679cdf0e10cSrcweir     std::list< ByteString > aLines;
680cdf0e10cSrcweir     PPDDecompressStream aStream( m_aFile );
681cdf0e10cSrcweir     bool bLanguageEncoding = false;
682cdf0e10cSrcweir     if( aStream.IsOpen() )
683cdf0e10cSrcweir     {
684cdf0e10cSrcweir         ByteString aCurLine;
685cdf0e10cSrcweir         while( ! aStream.IsEof() )
686cdf0e10cSrcweir         {
687cdf0e10cSrcweir             aStream.ReadLine( aCurLine );
688cdf0e10cSrcweir             if( aCurLine.GetChar( 0 ) == '*' )
689cdf0e10cSrcweir             {
690cdf0e10cSrcweir                 if( aCurLine.CompareIgnoreCaseToAscii( "*include:", 9 ) == COMPARE_EQUAL )
691cdf0e10cSrcweir                 {
692cdf0e10cSrcweir                     aCurLine.Erase( 0, 9 );
693cdf0e10cSrcweir                     aCurLine.EraseLeadingChars( ' ' );
694cdf0e10cSrcweir                     aCurLine.EraseTrailingChars( ' ' );
695cdf0e10cSrcweir                     aCurLine.EraseLeadingChars( '\t' );
696cdf0e10cSrcweir                     aCurLine.EraseTrailingChars( '\t' );
697cdf0e10cSrcweir                     aCurLine.EraseTrailingChars( '\r' );
698cdf0e10cSrcweir                     aCurLine.EraseTrailingChars( '\n' );
699cdf0e10cSrcweir                     aCurLine.EraseLeadingChars( '"' );
700cdf0e10cSrcweir                     aCurLine.EraseTrailingChars( '"' );
701cdf0e10cSrcweir                     aStream.Close();
702cdf0e10cSrcweir                     aStream.Open( getPPDFile( String( aCurLine, m_aFileEncoding ) ) );
703cdf0e10cSrcweir                     continue;
704cdf0e10cSrcweir                 }
705cdf0e10cSrcweir                 else if( ! bLanguageEncoding &&
706cdf0e10cSrcweir                          aCurLine.CompareIgnoreCaseToAscii( "*languageencoding", 17 ) == COMPARE_EQUAL )
707cdf0e10cSrcweir                 {
708cdf0e10cSrcweir                     bLanguageEncoding = true; // generally only the first one counts
709cdf0e10cSrcweir                     ByteString aLower = aCurLine;
710cdf0e10cSrcweir                     aLower.ToLowerAscii();
711cdf0e10cSrcweir                     if( aLower.Search( "isolatin1", 17 ) != STRING_NOTFOUND ||
712cdf0e10cSrcweir                         aLower.Search( "windowsansi", 17 ) != STRING_NOTFOUND )
713cdf0e10cSrcweir                         m_aFileEncoding = RTL_TEXTENCODING_MS_1252;
714cdf0e10cSrcweir                     else if( aLower.Search( "isolatin2", 17 ) != STRING_NOTFOUND )
715cdf0e10cSrcweir                         m_aFileEncoding = RTL_TEXTENCODING_ISO_8859_2;
716cdf0e10cSrcweir                     else if( aLower.Search( "isolatin5", 17 ) != STRING_NOTFOUND )
717cdf0e10cSrcweir                         m_aFileEncoding = RTL_TEXTENCODING_ISO_8859_5;
718cdf0e10cSrcweir                     else if( aLower.Search( "jis83-rksj", 17 ) != STRING_NOTFOUND )
719cdf0e10cSrcweir                         m_aFileEncoding = RTL_TEXTENCODING_SHIFT_JIS;
720cdf0e10cSrcweir                     else if( aLower.Search( "macstandard", 17 ) != STRING_NOTFOUND )
721cdf0e10cSrcweir                         m_aFileEncoding = RTL_TEXTENCODING_APPLE_ROMAN;
722cdf0e10cSrcweir                     else if( aLower.Search( "utf-8", 17 ) != STRING_NOTFOUND )
723cdf0e10cSrcweir                         m_aFileEncoding = RTL_TEXTENCODING_UTF8;
724cdf0e10cSrcweir                 }
725cdf0e10cSrcweir             }
726cdf0e10cSrcweir             aLines.push_back( aCurLine );
727cdf0e10cSrcweir         }
728cdf0e10cSrcweir     }
729cdf0e10cSrcweir     aStream.Close();
730cdf0e10cSrcweir 
731cdf0e10cSrcweir     // now get the Values
732cdf0e10cSrcweir     parse( aLines );
733cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 2
734cdf0e10cSrcweir     fprintf( stderr, "acquired %d Keys from PPD %s:\n", m_aKeys.size(), BSTRING( m_aFile ).GetBuffer() );
735cdf0e10cSrcweir     for( PPDParser::hash_type::const_iterator it = m_aKeys.begin(); it != m_aKeys.end(); ++it )
736cdf0e10cSrcweir     {
737cdf0e10cSrcweir         const PPDKey* pKey = it->second;
738cdf0e10cSrcweir         char* pSetupType = "<unknown>";
739cdf0e10cSrcweir         switch( pKey->m_eSetupType )
740cdf0e10cSrcweir         {
741cdf0e10cSrcweir             case PPDKey::ExitServer:        pSetupType = "ExitServer";break;
742cdf0e10cSrcweir             case PPDKey::Prolog:            pSetupType = "Prolog";break;
743cdf0e10cSrcweir             case PPDKey::DocumentSetup: pSetupType = "DocumentSetup";break;
744cdf0e10cSrcweir             case PPDKey::PageSetup:     pSetupType = "PageSetup";break;
745cdf0e10cSrcweir             case PPDKey::JCLSetup:          pSetupType = "JCLSetup";break;
746cdf0e10cSrcweir             case PPDKey::AnySetup:          pSetupType = "AnySetup";break;
747cdf0e10cSrcweir             default: break;
748cdf0e10cSrcweir         };
749cdf0e10cSrcweir         fprintf( stderr, "\t\"%s\" (\"%s\") (%d values) OrderDependency: %d %s\n",
750cdf0e10cSrcweir                  BSTRING( pKey->getKey() ).GetBuffer(),
751cdf0e10cSrcweir                  BSTRING( pKey->m_aUITranslation ).GetBuffer(),
752cdf0e10cSrcweir                  pKey->countValues(),
753cdf0e10cSrcweir                  pKey->m_nOrderDependency,
754cdf0e10cSrcweir                  pSetupType );
755cdf0e10cSrcweir         for( int j = 0; j < pKey->countValues(); j++ )
756cdf0e10cSrcweir         {
757cdf0e10cSrcweir             fprintf( stderr, "\t\t" );
758cdf0e10cSrcweir             const PPDValue* pValue = pKey->getValue( j );
759cdf0e10cSrcweir             if( pValue == pKey->m_pDefaultValue )
760cdf0e10cSrcweir                 fprintf( stderr, "(Default:) " );
761cdf0e10cSrcweir             char* pVType = "<unknown>";
762cdf0e10cSrcweir             switch( pValue->m_eType )
763cdf0e10cSrcweir             {
764cdf0e10cSrcweir                 case eInvocation:       pVType = "invocation";break;
765cdf0e10cSrcweir                 case eQuoted:           pVType = "quoted";break;
766cdf0e10cSrcweir                 case eString:           pVType = "string";break;
767cdf0e10cSrcweir                 case eSymbol:           pVType = "symbol";break;
768cdf0e10cSrcweir                 case eNo:               pVType = "no";break;
769cdf0e10cSrcweir                 default: break;
770cdf0e10cSrcweir             };
771cdf0e10cSrcweir             fprintf( stderr, "option: \"%s\" (\"%s\"), value: type %s \"%s\" (\"%s\")\n",
772cdf0e10cSrcweir                      BSTRING( pValue->m_aOption ).GetBuffer(),
773cdf0e10cSrcweir                      BSTRING( pValue->m_aOptionTranslation ).GetBuffer(),
774cdf0e10cSrcweir                      pVType,
775cdf0e10cSrcweir                      BSTRING( pValue->m_aValue ).GetBuffer(),
776cdf0e10cSrcweir                      BSTRING( pValue->m_aValueTranslation ).GetBuffer() );
777cdf0e10cSrcweir         }
778cdf0e10cSrcweir     }
779cdf0e10cSrcweir     fprintf( stderr, "constraints: (%d found)\n", m_aConstraints.size() );
780cdf0e10cSrcweir     for( std::list< PPDConstraint >::const_iterator cit = m_aConstraints.begin(); cit != m_aConstraints.end(); ++cit )
781cdf0e10cSrcweir     {
782cdf0e10cSrcweir         fprintf( stderr, "*\"%s\" \"%s\" *\"%s\" \"%s\"\n",
783cdf0e10cSrcweir                  BSTRING( cit->m_pKey1->getKey() ).GetBuffer(),
784cdf0e10cSrcweir                  cit->m_pOption1 ? BSTRING( cit->m_pOption1->m_aOption ).GetBuffer() : "<nil>",
785cdf0e10cSrcweir                  BSTRING( cit->m_pKey2->getKey() ).GetBuffer(),
786cdf0e10cSrcweir                  cit->m_pOption2 ? BSTRING( cit->m_pOption2->m_aOption ).GetBuffer() : "<nil>"
787cdf0e10cSrcweir                  );
788cdf0e10cSrcweir     }
789cdf0e10cSrcweir #endif
790cdf0e10cSrcweir 
791cdf0e10cSrcweir     // fill in shortcuts
792cdf0e10cSrcweir     const PPDKey* pKey;
793cdf0e10cSrcweir 
794cdf0e10cSrcweir     m_pImageableAreas = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "ImageableArea" ) ) );
795cdf0e10cSrcweir     if( m_pImageableAreas )
796cdf0e10cSrcweir         m_pDefaultImageableArea = m_pImageableAreas->getDefaultValue();
797cdf0e10cSrcweir     DBG_ASSERT( m_pImageableAreas, "Warning: no ImageableArea in PPD\n" );
798cdf0e10cSrcweir     DBG_ASSERT( m_pDefaultImageableArea, "Warning: no DefaultImageableArea in PPD\n" );
799cdf0e10cSrcweir 
800cdf0e10cSrcweir     m_pPaperDimensions = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "PaperDimension" ) ) );
801cdf0e10cSrcweir     if( m_pPaperDimensions )
802cdf0e10cSrcweir         m_pDefaultPaperDimension = m_pPaperDimensions->getDefaultValue();
803cdf0e10cSrcweir     DBG_ASSERT( m_pPaperDimensions, "Warning: no PaperDimension in PPD\n" );
804cdf0e10cSrcweir     DBG_ASSERT( m_pDefaultPaperDimension, "Warning: no DefaultPaperDimension in PPD\n" );
805cdf0e10cSrcweir 
806cdf0e10cSrcweir     m_pResolutions = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "Resolution" ) ) );
807cdf0e10cSrcweir     if( m_pResolutions )
808cdf0e10cSrcweir         m_pDefaultResolution = m_pResolutions->getDefaultValue();
809cdf0e10cSrcweir     DBG_ASSERT( m_pResolutions, "Warning: no Resolution in PPD\n" );
810cdf0e10cSrcweir     DBG_ASSERT( m_pDefaultResolution, "Warning: no DefaultResolution in PPD\n" );
811cdf0e10cSrcweir 
812cdf0e10cSrcweir     m_pInputSlots = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "InputSlot" ) ) );
813cdf0e10cSrcweir     if( m_pInputSlots )
814cdf0e10cSrcweir         m_pDefaultInputSlot = m_pInputSlots->getDefaultValue();
815cdf0e10cSrcweir     DBG_ASSERT( m_pPaperDimensions, "Warning: no InputSlot in PPD\n" );
816cdf0e10cSrcweir     DBG_ASSERT( m_pDefaultPaperDimension, "Warning: no DefaultInputSlot in PPD\n" );
817cdf0e10cSrcweir 
818cdf0e10cSrcweir     m_pDuplexTypes = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "Duplex" ) ) );
819cdf0e10cSrcweir     if( m_pDuplexTypes )
820cdf0e10cSrcweir         m_pDefaultDuplexType = m_pDuplexTypes->getDefaultValue();
821cdf0e10cSrcweir 
822cdf0e10cSrcweir     m_pFontList = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "Font" ) ) );
823cdf0e10cSrcweir     DBG_ASSERT( m_pFontList, "Warning: no Font in PPD\n" );
824cdf0e10cSrcweir 
825cdf0e10cSrcweir     // fill in direct values
826cdf0e10cSrcweir     if( (pKey = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "ModelName" ) ) )) )
827cdf0e10cSrcweir         m_aPrinterName = pKey->getValue( 0 )->m_aValue;
828cdf0e10cSrcweir     if( (pKey = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "NickName" ) ) )) )
829cdf0e10cSrcweir         m_aNickName = pKey->getValue( 0 )->m_aValue;
830cdf0e10cSrcweir     if( (pKey = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "ColorDevice" ) ) )) )
831cdf0e10cSrcweir         m_bColorDevice = pKey->getValue( 0 )->m_aValue.CompareIgnoreCaseToAscii( "true", 4 ) == COMPARE_EQUAL ? true : false;
832cdf0e10cSrcweir 
833cdf0e10cSrcweir     if( (pKey = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "LanguageLevel" ) ) )) )
834cdf0e10cSrcweir         m_nLanguageLevel = pKey->getValue( 0 )->m_aValue.ToInt32();
835cdf0e10cSrcweir     if( (pKey = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "TTRasterizer" ) ) )) )
836cdf0e10cSrcweir         m_bType42Capable = pKey->getValue( 0 )->m_aValue.EqualsIgnoreCaseAscii( "Type42" ) ? true : false;
837cdf0e10cSrcweir }
838cdf0e10cSrcweir 
~PPDParser()839cdf0e10cSrcweir PPDParser::~PPDParser()
840cdf0e10cSrcweir {
841cdf0e10cSrcweir     for( PPDParser::hash_type::iterator it = m_aKeys.begin(); it != m_aKeys.end(); ++it )
842cdf0e10cSrcweir         delete it->second;
843cdf0e10cSrcweir     delete m_pTranslator;
844cdf0e10cSrcweir }
845cdf0e10cSrcweir 
insertKey(const String & rKey,PPDKey * pKey)846cdf0e10cSrcweir void PPDParser::insertKey( const String& rKey, PPDKey* pKey )
847cdf0e10cSrcweir {
848cdf0e10cSrcweir     m_aKeys[ rKey ] = pKey;
849cdf0e10cSrcweir     m_aOrderedKeys.push_back( pKey );
850cdf0e10cSrcweir }
851cdf0e10cSrcweir 
getKey(int n) const852cdf0e10cSrcweir const PPDKey* PPDParser::getKey( int n ) const
853cdf0e10cSrcweir {
854cdf0e10cSrcweir     return ((unsigned int)n < m_aOrderedKeys.size() && n >= 0) ? m_aOrderedKeys[n] : NULL;
855cdf0e10cSrcweir }
856cdf0e10cSrcweir 
getKey(const String & rKey) const857cdf0e10cSrcweir const PPDKey* PPDParser::getKey( const String& rKey ) const
858cdf0e10cSrcweir {
859cdf0e10cSrcweir     PPDParser::hash_type::const_iterator it = m_aKeys.find( rKey );
860cdf0e10cSrcweir     return it != m_aKeys.end() ? it->second : NULL;
861cdf0e10cSrcweir }
862cdf0e10cSrcweir 
hasKey(const PPDKey * pKey) const863cdf0e10cSrcweir bool PPDParser::hasKey( const PPDKey* pKey ) const
864cdf0e10cSrcweir {
865cdf0e10cSrcweir     return
866cdf0e10cSrcweir         pKey ?
867cdf0e10cSrcweir         ( m_aKeys.find( pKey->getKey() ) != m_aKeys.end() ? true : false ) :
868cdf0e10cSrcweir         false;
869cdf0e10cSrcweir }
870cdf0e10cSrcweir 
getNibble(sal_Char cChar)871cdf0e10cSrcweir static sal_uInt8 getNibble( sal_Char cChar )
872cdf0e10cSrcweir {
873cdf0e10cSrcweir     sal_uInt8 nRet = 0;
874cdf0e10cSrcweir     if( cChar >= '0' && cChar <= '9' )
875cdf0e10cSrcweir         nRet = sal_uInt8( cChar - '0' );
876cdf0e10cSrcweir     else if( cChar >= 'A' && cChar <= 'F' )
877cdf0e10cSrcweir         nRet = 10 + sal_uInt8( cChar - 'A' );
878cdf0e10cSrcweir     else if( cChar >= 'a' && cChar <= 'f' )
879cdf0e10cSrcweir         nRet = 10 + sal_uInt8( cChar - 'a' );
880cdf0e10cSrcweir     return nRet;
881cdf0e10cSrcweir }
882cdf0e10cSrcweir 
handleTranslation(const ByteString & i_rString,bool bIsGlobalized)883cdf0e10cSrcweir String PPDParser::handleTranslation( const ByteString& i_rString, bool bIsGlobalized )
884cdf0e10cSrcweir {
885cdf0e10cSrcweir     int nOrigLen = i_rString.Len();
886cdf0e10cSrcweir     OStringBuffer aTrans( nOrigLen );
887cdf0e10cSrcweir     const sal_Char* pStr = i_rString.GetBuffer();
888cdf0e10cSrcweir     const sal_Char* pEnd = pStr + nOrigLen;
889cdf0e10cSrcweir     while( pStr < pEnd )
890cdf0e10cSrcweir     {
891cdf0e10cSrcweir         if( *pStr == '<' )
892cdf0e10cSrcweir         {
893cdf0e10cSrcweir             pStr++;
894cdf0e10cSrcweir             sal_Char cChar;
895cdf0e10cSrcweir             while( *pStr != '>' && pStr < pEnd-1 )
896cdf0e10cSrcweir             {
897cdf0e10cSrcweir                 cChar = getNibble( *pStr++ ) << 4;
898cdf0e10cSrcweir                 cChar |= getNibble( *pStr++ );
899cdf0e10cSrcweir                 aTrans.append( cChar );
900cdf0e10cSrcweir             }
901cdf0e10cSrcweir             pStr++;
902cdf0e10cSrcweir         }
903cdf0e10cSrcweir         else
904cdf0e10cSrcweir             aTrans.append( *pStr++ );
905cdf0e10cSrcweir     }
906cdf0e10cSrcweir     return OStringToOUString( aTrans.makeStringAndClear(), bIsGlobalized ? RTL_TEXTENCODING_UTF8 : m_aFileEncoding );
907cdf0e10cSrcweir }
908cdf0e10cSrcweir 
parse(::std::list<ByteString> & rLines)909cdf0e10cSrcweir void PPDParser::parse( ::std::list< ByteString >& rLines )
910cdf0e10cSrcweir {
911cdf0e10cSrcweir     std::list< ByteString >::iterator line = rLines.begin();
912cdf0e10cSrcweir     PPDParser::hash_type::const_iterator keyit;
913cdf0e10cSrcweir     while( line != rLines.end() )
914cdf0e10cSrcweir     {
915cdf0e10cSrcweir         ByteString aCurrentLine( *line );
916cdf0e10cSrcweir         ++line;
917cdf0e10cSrcweir         if( aCurrentLine.GetChar(0) != '*' )
918cdf0e10cSrcweir             continue;
919cdf0e10cSrcweir         if( aCurrentLine.GetChar(1) == '%' )
920cdf0e10cSrcweir             continue;
921cdf0e10cSrcweir 
922cdf0e10cSrcweir         ByteString aKey = GetCommandLineToken( 0, aCurrentLine.GetToken( 0, ':' ) );
923cdf0e10cSrcweir         int nPos = aKey.Search( '/' );
924cdf0e10cSrcweir         if( nPos != STRING_NOTFOUND )
925cdf0e10cSrcweir             aKey.Erase( nPos );
926cdf0e10cSrcweir         aKey.Erase( 0, 1 ); // remove the '*'
927cdf0e10cSrcweir 
928cdf0e10cSrcweir         if( aKey.Equals( "CloseUI" ) || aKey.Equals( "OpenGroup" ) || aKey.Equals( "CloseGroup" ) || aKey.Equals( "End" ) || aKey.Equals( "OpenSubGroup" ) || aKey.Equals( "CloseSubGroup" ) )
929cdf0e10cSrcweir             continue;
930cdf0e10cSrcweir 
931cdf0e10cSrcweir         if( aKey.Equals( "OpenUI" ) )
932cdf0e10cSrcweir         {
933cdf0e10cSrcweir             parseOpenUI( aCurrentLine );
934cdf0e10cSrcweir             continue;
935cdf0e10cSrcweir         }
936cdf0e10cSrcweir         else if( aKey.Equals( "OrderDependency" ) )
937cdf0e10cSrcweir         {
938cdf0e10cSrcweir             parseOrderDependency( aCurrentLine );
939cdf0e10cSrcweir             continue;
940cdf0e10cSrcweir         }
941cdf0e10cSrcweir         else if( aKey.Equals( "UIConstraints" ) || aKey.Equals( "NonUIConstraints" ) )
942cdf0e10cSrcweir             continue; // parsed in pass 2
943cdf0e10cSrcweir         else if( aKey.Equals( "CustomPageSize" ) ) // currently not handled
944cdf0e10cSrcweir             continue;
945cdf0e10cSrcweir 
946cdf0e10cSrcweir         // default values are parsed in pass 2
947cdf0e10cSrcweir         if( aKey.CompareTo( "Default", 7 ) == COMPARE_EQUAL )
948cdf0e10cSrcweir             continue;
949cdf0e10cSrcweir 
950cdf0e10cSrcweir         bool bQuery     = false;
951cdf0e10cSrcweir         if( aKey.GetChar( 0 ) == '?' )
952cdf0e10cSrcweir         {
953cdf0e10cSrcweir             aKey.Erase( 0, 1 );
954cdf0e10cSrcweir             bQuery = true;
955cdf0e10cSrcweir         }
956cdf0e10cSrcweir 
957cdf0e10cSrcweir         String aUniKey( aKey, RTL_TEXTENCODING_MS_1252 );
958cdf0e10cSrcweir         // handle CUPS extension for globalized PPDs
959cdf0e10cSrcweir         bool bIsGlobalizedLine = false;
960cdf0e10cSrcweir         com::sun::star::lang::Locale aTransLocale;
961cdf0e10cSrcweir         if( ( aUniKey.Len() > 3 && aUniKey.GetChar( 2 ) == '.' ) ||
962cdf0e10cSrcweir             ( aUniKey.Len() > 5 && aUniKey.GetChar( 2 ) == '_' && aUniKey.GetChar( 5 ) == '.' ) )
963cdf0e10cSrcweir         {
964cdf0e10cSrcweir             if( aUniKey.GetChar( 2 ) == '.' )
965cdf0e10cSrcweir             {
966cdf0e10cSrcweir                 aTransLocale.Language = aUniKey.Copy( 0, 2 );
967cdf0e10cSrcweir                 aUniKey = aUniKey.Copy( 3 );
968cdf0e10cSrcweir             }
969cdf0e10cSrcweir             else
970cdf0e10cSrcweir             {
971cdf0e10cSrcweir                 aTransLocale.Language = aUniKey.Copy( 0, 2 );
972cdf0e10cSrcweir                 aTransLocale.Country = aUniKey.Copy( 3, 2 );
973cdf0e10cSrcweir                 aUniKey = aUniKey.Copy( 6 );
974cdf0e10cSrcweir             }
975cdf0e10cSrcweir             bIsGlobalizedLine = true;
976cdf0e10cSrcweir         }
977cdf0e10cSrcweir 
978cdf0e10cSrcweir         String aOption;
979cdf0e10cSrcweir         nPos = aCurrentLine.Search( ':' );
980cdf0e10cSrcweir         if( nPos != STRING_NOTFOUND )
981cdf0e10cSrcweir         {
982cdf0e10cSrcweir             aOption = String( aCurrentLine.Copy( 1, nPos-1 ), RTL_TEXTENCODING_MS_1252 );
983cdf0e10cSrcweir             aOption = GetCommandLineToken( 1, aOption );
984cdf0e10cSrcweir             int nTransPos = aOption.Search( '/' );
985cdf0e10cSrcweir             if( nTransPos != STRING_NOTFOUND )
986cdf0e10cSrcweir                 aOption.Erase( nTransPos );
987cdf0e10cSrcweir         }
988cdf0e10cSrcweir 
989cdf0e10cSrcweir         PPDValueType eType = eNo;
990cdf0e10cSrcweir         String aValue;
991cdf0e10cSrcweir         rtl::OUString aOptionTranslation;
992cdf0e10cSrcweir         rtl::OUString aValueTranslation;
993cdf0e10cSrcweir         if( nPos != STRING_NOTFOUND )
994cdf0e10cSrcweir         {
995cdf0e10cSrcweir             // found a colon, there may be an option
996cdf0e10cSrcweir             ByteString aLine = aCurrentLine.Copy( 1, nPos-1 );
997cdf0e10cSrcweir             aLine = WhitespaceToSpace( aLine );
998cdf0e10cSrcweir             int nTransPos = aLine.Search( '/' );
999cdf0e10cSrcweir             if( nTransPos != STRING_NOTFOUND )
1000cdf0e10cSrcweir                 aOptionTranslation = handleTranslation( aLine.Copy( nTransPos+1 ), bIsGlobalizedLine );
1001cdf0e10cSrcweir 
1002cdf0e10cSrcweir             // read in more lines if necessary for multiline values
1003cdf0e10cSrcweir             aLine = aCurrentLine.Copy( nPos+1 );
1004cdf0e10cSrcweir             if( aLine.Len() )
1005cdf0e10cSrcweir             {
1006cdf0e10cSrcweir                 while( ! ( aLine.GetTokenCount( '"' ) & 1 ) &&
1007cdf0e10cSrcweir                        line != rLines.end() )
1008cdf0e10cSrcweir                     // while there is an even number of tokens; that means
1009cdf0e10cSrcweir                     // an odd number of doubleqoutes
1010cdf0e10cSrcweir                 {
1011cdf0e10cSrcweir                     // copy the newlines also
1012cdf0e10cSrcweir                     aLine += '\n';
1013cdf0e10cSrcweir                     aLine += *line;
1014cdf0e10cSrcweir                     ++line;
1015cdf0e10cSrcweir                 }
1016cdf0e10cSrcweir             }
1017cdf0e10cSrcweir             aLine = WhitespaceToSpace( aLine );
1018cdf0e10cSrcweir 
1019cdf0e10cSrcweir             // #i100644# handle a missing value (actually a broken PPD)
1020cdf0e10cSrcweir             if( ! aLine.Len() )
1021cdf0e10cSrcweir             {
1022cdf0e10cSrcweir                 if( aOption.Len() &&
1023cdf0e10cSrcweir                     aUniKey.CompareToAscii( "JCL", 3 ) != COMPARE_EQUAL )
1024cdf0e10cSrcweir                     eType = eInvocation;
1025cdf0e10cSrcweir                 else
1026cdf0e10cSrcweir                     eType = eQuoted;
1027cdf0e10cSrcweir             }
1028cdf0e10cSrcweir             // check for invocation or quoted value
1029cdf0e10cSrcweir             else if( aLine.GetChar(0) == '"' )
1030cdf0e10cSrcweir             {
1031cdf0e10cSrcweir                 aLine.Erase( 0, 1 );
1032cdf0e10cSrcweir                 nTransPos = aLine.Search( '"' );
1033cdf0e10cSrcweir                 aValue = String( aLine.Copy( 0, nTransPos ), RTL_TEXTENCODING_MS_1252 );
1034cdf0e10cSrcweir                 // after the second doublequote can follow a / and a translation
1035cdf0e10cSrcweir                 aValueTranslation = handleTranslation( aLine.Copy( nTransPos+2 ), bIsGlobalizedLine );
1036cdf0e10cSrcweir                 // check for quoted value
1037cdf0e10cSrcweir                 if( aOption.Len() &&
1038cdf0e10cSrcweir                     aUniKey.CompareToAscii( "JCL", 3 ) != COMPARE_EQUAL )
1039cdf0e10cSrcweir                     eType = eInvocation;
1040cdf0e10cSrcweir                 else
1041cdf0e10cSrcweir                     eType = eQuoted;
1042cdf0e10cSrcweir             }
1043cdf0e10cSrcweir             // check for symbol value
1044cdf0e10cSrcweir             else if( aLine.GetChar(0) == '^' )
1045cdf0e10cSrcweir             {
1046cdf0e10cSrcweir                 aLine.Erase( 0, 1 );
1047cdf0e10cSrcweir                 aValue = String( aLine, RTL_TEXTENCODING_MS_1252 );
1048cdf0e10cSrcweir                 eType = eSymbol;
1049cdf0e10cSrcweir             }
1050cdf0e10cSrcweir             else
1051cdf0e10cSrcweir             {
1052cdf0e10cSrcweir                 // must be a string value then
1053cdf0e10cSrcweir                 // strictly this is false because string values
1054cdf0e10cSrcweir                 // can contain any whitespace which is reduced
1055cdf0e10cSrcweir                 // to one space by now
1056cdf0e10cSrcweir                 // who cares ...
1057cdf0e10cSrcweir                 nTransPos = aLine.Search( '/' );
1058cdf0e10cSrcweir                 if( nTransPos == STRING_NOTFOUND )
1059cdf0e10cSrcweir                     nTransPos = aLine.Len();
1060cdf0e10cSrcweir                 aValue = String( aLine.Copy( 0, nTransPos ), RTL_TEXTENCODING_MS_1252 );
1061cdf0e10cSrcweir                 aValueTranslation = handleTranslation( aLine.Copy( nTransPos+1 ), bIsGlobalizedLine );
1062cdf0e10cSrcweir                 eType = eString;
1063cdf0e10cSrcweir             }
1064cdf0e10cSrcweir         }
1065cdf0e10cSrcweir 
1066cdf0e10cSrcweir         // handle globalized PPD entries
1067cdf0e10cSrcweir         if( bIsGlobalizedLine )
1068cdf0e10cSrcweir         {
1069cdf0e10cSrcweir             // handle main key translations of form:
1070cdf0e10cSrcweir             // *ll_CC.Translation MainKeyword/translated text: ""
1071cdf0e10cSrcweir             if( aUniKey.EqualsAscii( "Translation" ) )
1072cdf0e10cSrcweir             {
1073cdf0e10cSrcweir                 m_pTranslator->insertKey( aOption, aOptionTranslation, aTransLocale );
1074cdf0e10cSrcweir             }
1075cdf0e10cSrcweir             // handle options translations of for:
1076cdf0e10cSrcweir             // *ll_CC.MainKeyword OptionKeyword/translated text: ""
1077cdf0e10cSrcweir             else
1078cdf0e10cSrcweir             {
1079cdf0e10cSrcweir                 m_pTranslator->insertOption( aUniKey, aOption, aOptionTranslation, aTransLocale );
1080cdf0e10cSrcweir             }
1081cdf0e10cSrcweir             continue;
1082cdf0e10cSrcweir         }
1083cdf0e10cSrcweir 
1084cdf0e10cSrcweir         PPDKey* pKey = NULL;
1085cdf0e10cSrcweir         keyit = m_aKeys.find( aUniKey );
1086cdf0e10cSrcweir         if( keyit == m_aKeys.end() )
1087cdf0e10cSrcweir         {
1088cdf0e10cSrcweir             pKey = new PPDKey( aUniKey );
1089cdf0e10cSrcweir             insertKey( aUniKey, pKey );
1090cdf0e10cSrcweir         }
1091cdf0e10cSrcweir         else
1092cdf0e10cSrcweir             pKey = keyit->second;
1093cdf0e10cSrcweir 
1094cdf0e10cSrcweir         if( eType == eNo && bQuery )
1095cdf0e10cSrcweir             continue;
1096cdf0e10cSrcweir 
1097cdf0e10cSrcweir         PPDValue* pValue = pKey->insertValue( aOption );
1098cdf0e10cSrcweir         if( ! pValue )
1099cdf0e10cSrcweir             continue;
1100cdf0e10cSrcweir         pValue->m_eType = eType;
1101cdf0e10cSrcweir         pValue->m_aValue = aValue;
1102cdf0e10cSrcweir 
1103cdf0e10cSrcweir         if( aOptionTranslation.getLength() )
1104cdf0e10cSrcweir             m_pTranslator->insertOption( aUniKey, aOption, aOptionTranslation, aTransLocale );
1105cdf0e10cSrcweir         if( aValueTranslation.getLength() )
1106cdf0e10cSrcweir             m_pTranslator->insertValue( aUniKey, aOption, aValue, aValueTranslation, aTransLocale );
1107cdf0e10cSrcweir 
1108cdf0e10cSrcweir         // eventually update query and remove from option list
1109cdf0e10cSrcweir         if( bQuery && pKey->m_bQueryValue == sal_False )
1110cdf0e10cSrcweir         {
1111cdf0e10cSrcweir             pKey->m_aQueryValue = *pValue;
1112cdf0e10cSrcweir             pKey->m_bQueryValue = true;
1113cdf0e10cSrcweir             pKey->eraseValue( pValue->m_aOption );
1114cdf0e10cSrcweir         }
1115cdf0e10cSrcweir     }
1116cdf0e10cSrcweir 
1117cdf0e10cSrcweir     // second pass: fill in defaults
1118cdf0e10cSrcweir     for( line = rLines.begin(); line != rLines.end(); ++line )
1119cdf0e10cSrcweir     {
1120cdf0e10cSrcweir         ByteString aLine( *line );
1121cdf0e10cSrcweir         if( aLine.CompareTo( "*Default", 8 ) == COMPARE_EQUAL )
1122cdf0e10cSrcweir         {
1123cdf0e10cSrcweir             String aKey( aLine.Copy( 8 ), RTL_TEXTENCODING_MS_1252 );
1124cdf0e10cSrcweir             sal_uInt16 nPos = aKey.Search( ':' );
1125cdf0e10cSrcweir             if( nPos != STRING_NOTFOUND )
1126cdf0e10cSrcweir             {
1127cdf0e10cSrcweir                 aKey.Erase( nPos );
1128cdf0e10cSrcweir                 String aOption( WhitespaceToSpace( aLine.Copy( nPos+9 ) ), RTL_TEXTENCODING_MS_1252 );
1129cdf0e10cSrcweir                 keyit = m_aKeys.find( aKey );
1130cdf0e10cSrcweir                 if( keyit != m_aKeys.end() )
1131cdf0e10cSrcweir                 {
1132cdf0e10cSrcweir                     PPDKey* pKey = keyit->second;
1133cdf0e10cSrcweir                     const PPDValue* pDefValue = pKey->getValue( aOption );
1134cdf0e10cSrcweir                     if( pKey->m_pDefaultValue == NULL )
1135cdf0e10cSrcweir                         pKey->m_pDefaultValue = pDefValue;
1136cdf0e10cSrcweir                 }
1137cdf0e10cSrcweir                 else
1138cdf0e10cSrcweir                 {
1139cdf0e10cSrcweir                     // some PPDs contain defaults for keys that
1140cdf0e10cSrcweir                     // do not exist otherwise
1141cdf0e10cSrcweir                     // (example: DefaultResolution)
1142cdf0e10cSrcweir                     // so invent that key here and have a default value
1143cdf0e10cSrcweir                     PPDKey* pKey = new PPDKey( aKey );
1144cdf0e10cSrcweir                     PPDValue* pNewValue = pKey->insertValue( aOption );
1145cdf0e10cSrcweir                     pNewValue->m_eType = eInvocation; // or what ?
1146cdf0e10cSrcweir                     insertKey( aKey, pKey );
1147cdf0e10cSrcweir                 }
1148cdf0e10cSrcweir             }
1149cdf0e10cSrcweir         }
1150cdf0e10cSrcweir         else if( aLine.CompareTo( "*UIConstraints", 14 ) == COMPARE_EQUAL  ||
1151cdf0e10cSrcweir                  aLine.CompareTo( "*NonUIConstraints", 17 ) == COMPARE_EQUAL )
1152cdf0e10cSrcweir             parseConstraint( aLine );
1153cdf0e10cSrcweir 
1154cdf0e10cSrcweir     }
1155cdf0e10cSrcweir }
1156cdf0e10cSrcweir 
parseOpenUI(const ByteString & rLine)1157cdf0e10cSrcweir void PPDParser::parseOpenUI( const ByteString& rLine )
1158cdf0e10cSrcweir {
1159cdf0e10cSrcweir     String aTranslation;
1160cdf0e10cSrcweir     ByteString aKey = rLine;
1161cdf0e10cSrcweir 
1162cdf0e10cSrcweir     int nPos = aKey.Search( ':' );
1163cdf0e10cSrcweir     if( nPos != STRING_NOTFOUND )
1164cdf0e10cSrcweir         aKey.Erase( nPos );
1165cdf0e10cSrcweir     nPos = aKey.Search( '/' );
1166cdf0e10cSrcweir     if( nPos != STRING_NOTFOUND )
1167cdf0e10cSrcweir     {
1168cdf0e10cSrcweir         aTranslation = handleTranslation( aKey.Copy( nPos + 1 ), false );
1169cdf0e10cSrcweir         aKey.Erase( nPos );
1170cdf0e10cSrcweir     }
1171cdf0e10cSrcweir     aKey = GetCommandLineToken( 1, aKey );
1172cdf0e10cSrcweir     aKey.Erase( 0, 1 );
1173cdf0e10cSrcweir 
1174cdf0e10cSrcweir     String aUniKey( aKey, RTL_TEXTENCODING_MS_1252 );
1175cdf0e10cSrcweir     PPDParser::hash_type::const_iterator keyit = m_aKeys.find( aUniKey );
1176cdf0e10cSrcweir     PPDKey* pKey;
1177cdf0e10cSrcweir     if( keyit == m_aKeys.end() )
1178cdf0e10cSrcweir     {
1179cdf0e10cSrcweir         pKey = new PPDKey( aUniKey );
1180cdf0e10cSrcweir         insertKey( aUniKey, pKey );
1181cdf0e10cSrcweir     }
1182cdf0e10cSrcweir     else
1183cdf0e10cSrcweir         pKey = keyit->second;
1184cdf0e10cSrcweir 
1185cdf0e10cSrcweir     pKey->m_bUIOption = true;
1186cdf0e10cSrcweir     m_pTranslator->insertKey( pKey->getKey(), aTranslation );
1187cdf0e10cSrcweir 
1188cdf0e10cSrcweir     ByteString aValue = WhitespaceToSpace( rLine.GetToken( 1, ':' ) );
1189cdf0e10cSrcweir     if( aValue.CompareIgnoreCaseToAscii( "boolean" ) == COMPARE_EQUAL )
1190cdf0e10cSrcweir         pKey->m_eUIType = PPDKey::Boolean;
1191cdf0e10cSrcweir     else if( aValue.CompareIgnoreCaseToAscii( "pickmany" ) == COMPARE_EQUAL )
1192cdf0e10cSrcweir         pKey->m_eUIType = PPDKey::PickMany;
1193cdf0e10cSrcweir     else
1194cdf0e10cSrcweir         pKey->m_eUIType = PPDKey::PickOne;
1195cdf0e10cSrcweir }
1196cdf0e10cSrcweir 
parseOrderDependency(const ByteString & rLine)1197cdf0e10cSrcweir void PPDParser::parseOrderDependency( const ByteString& rLine )
1198cdf0e10cSrcweir {
1199cdf0e10cSrcweir     ByteString aLine( rLine );
1200cdf0e10cSrcweir     int nPos = aLine.Search( ':' );
1201cdf0e10cSrcweir     if( nPos != STRING_NOTFOUND )
1202cdf0e10cSrcweir         aLine.Erase( 0, nPos+1 );
1203cdf0e10cSrcweir 
1204cdf0e10cSrcweir     int nOrder = GetCommandLineToken( 0, aLine ).ToInt32();
1205cdf0e10cSrcweir     ByteString aSetup = GetCommandLineToken( 1, aLine );
1206cdf0e10cSrcweir     String aKey( GetCommandLineToken( 2, aLine ), RTL_TEXTENCODING_MS_1252 );
1207cdf0e10cSrcweir     if( aKey.GetChar( 0 ) != '*' )
1208cdf0e10cSrcweir         return; // invalid order depency
1209cdf0e10cSrcweir     aKey.Erase( 0, 1 );
1210cdf0e10cSrcweir 
1211cdf0e10cSrcweir     PPDKey* pKey;
1212cdf0e10cSrcweir     PPDParser::hash_type::const_iterator keyit = m_aKeys.find( aKey );
1213cdf0e10cSrcweir     if( keyit == m_aKeys.end() )
1214cdf0e10cSrcweir     {
1215cdf0e10cSrcweir         pKey = new PPDKey( aKey );
1216cdf0e10cSrcweir         insertKey( aKey, pKey );
1217cdf0e10cSrcweir     }
1218cdf0e10cSrcweir     else
1219cdf0e10cSrcweir         pKey = keyit->second;
1220cdf0e10cSrcweir 
1221cdf0e10cSrcweir     pKey->m_nOrderDependency = nOrder;
1222cdf0e10cSrcweir     if( aSetup.Equals( "ExitServer" ) )
1223cdf0e10cSrcweir         pKey->m_eSetupType = PPDKey::ExitServer;
1224cdf0e10cSrcweir     else if( aSetup.Equals( "Prolog" ) )
1225cdf0e10cSrcweir         pKey->m_eSetupType = PPDKey::Prolog;
1226cdf0e10cSrcweir     else if( aSetup.Equals( "DocumentSetup" ) )
1227cdf0e10cSrcweir         pKey->m_eSetupType = PPDKey::DocumentSetup;
1228cdf0e10cSrcweir     else if( aSetup.Equals( "PageSetup" ) )
1229cdf0e10cSrcweir         pKey->m_eSetupType = PPDKey::PageSetup;
1230cdf0e10cSrcweir     else if( aSetup.Equals( "JCLSetup" ) )
1231cdf0e10cSrcweir         pKey->m_eSetupType = PPDKey::JCLSetup;
1232cdf0e10cSrcweir     else
1233cdf0e10cSrcweir         pKey->m_eSetupType = PPDKey::AnySetup;
1234cdf0e10cSrcweir }
1235cdf0e10cSrcweir 
parseConstraint(const ByteString & rLine)1236cdf0e10cSrcweir void PPDParser::parseConstraint( const ByteString& rLine )
1237cdf0e10cSrcweir {
1238cdf0e10cSrcweir     bool bFailed = false;
1239cdf0e10cSrcweir 
1240cdf0e10cSrcweir     String aLine( rLine, RTL_TEXTENCODING_MS_1252 );
1241cdf0e10cSrcweir     aLine.Erase( 0, rLine.Search( ':' )+1 );
1242cdf0e10cSrcweir     PPDConstraint aConstraint;
1243cdf0e10cSrcweir     int nTokens = GetCommandLineTokenCount( aLine );
1244cdf0e10cSrcweir     for( int i = 0; i < nTokens; i++ )
1245cdf0e10cSrcweir     {
1246cdf0e10cSrcweir         String aToken = GetCommandLineToken( i, aLine );
1247cdf0e10cSrcweir         if( aToken.GetChar( 0 ) == '*' )
1248cdf0e10cSrcweir         {
1249cdf0e10cSrcweir             aToken.Erase( 0, 1 );
1250cdf0e10cSrcweir             if( aConstraint.m_pKey1 )
1251cdf0e10cSrcweir                 aConstraint.m_pKey2 = getKey( aToken );
1252cdf0e10cSrcweir             else
1253cdf0e10cSrcweir                 aConstraint.m_pKey1 = getKey( aToken );
1254cdf0e10cSrcweir         }
1255cdf0e10cSrcweir         else
1256cdf0e10cSrcweir         {
1257cdf0e10cSrcweir             if( aConstraint.m_pKey2 )
1258cdf0e10cSrcweir             {
1259cdf0e10cSrcweir                 if( ! ( aConstraint.m_pOption2 = aConstraint.m_pKey2->getValue( aToken ) ) )
1260cdf0e10cSrcweir                     bFailed = true;
1261cdf0e10cSrcweir             }
1262cdf0e10cSrcweir             else if( aConstraint.m_pKey1 )
1263cdf0e10cSrcweir             {
1264cdf0e10cSrcweir                 if( ! ( aConstraint.m_pOption1 = aConstraint.m_pKey1->getValue( aToken ) ) )
1265cdf0e10cSrcweir                     bFailed = true;
1266cdf0e10cSrcweir             }
1267cdf0e10cSrcweir             else
1268cdf0e10cSrcweir                 // constraint for nonexistent keys; this happens
1269cdf0e10cSrcweir                 // e.g. in HP4PLUS3 (#75636#)
1270cdf0e10cSrcweir                 bFailed = true;
1271cdf0e10cSrcweir         }
1272cdf0e10cSrcweir     }
1273cdf0e10cSrcweir     // there must be two keywords
1274cdf0e10cSrcweir     if( ! aConstraint.m_pKey1 || ! aConstraint.m_pKey2 || bFailed )
1275cdf0e10cSrcweir     {
1276cdf0e10cSrcweir #ifdef __DEBUG
1277cdf0e10cSrcweir         fprintf( stderr, "Warning: constraint \"%s\" is invalid\n", rLine.GetStr() );
1278cdf0e10cSrcweir #endif
1279cdf0e10cSrcweir     }
1280cdf0e10cSrcweir     else
1281cdf0e10cSrcweir         m_aConstraints.push_back( aConstraint );
1282cdf0e10cSrcweir }
1283cdf0e10cSrcweir 
getDefaultPaperDimension() const1284cdf0e10cSrcweir String PPDParser::getDefaultPaperDimension() const
1285cdf0e10cSrcweir {
1286cdf0e10cSrcweir     if( m_pDefaultPaperDimension )
1287cdf0e10cSrcweir         return m_pDefaultPaperDimension->m_aOption;
1288cdf0e10cSrcweir 
1289cdf0e10cSrcweir     return String();
1290cdf0e10cSrcweir }
1291cdf0e10cSrcweir 
getMargins(const String & rPaperName,int & rLeft,int & rRight,int & rUpper,int & rLower) const1292cdf0e10cSrcweir bool PPDParser::getMargins(
1293cdf0e10cSrcweir                            const String& rPaperName,
1294cdf0e10cSrcweir                            int& rLeft, int& rRight,
1295cdf0e10cSrcweir                            int& rUpper, int& rLower ) const
1296cdf0e10cSrcweir {
1297cdf0e10cSrcweir     if( ! m_pImageableAreas || ! m_pPaperDimensions )
1298cdf0e10cSrcweir         return false;
1299cdf0e10cSrcweir 
1300cdf0e10cSrcweir     int nPDim=-1, nImArea=-1, i;
1301cdf0e10cSrcweir     for( i = 0; i < m_pImageableAreas->countValues(); i++ )
1302cdf0e10cSrcweir         if( rPaperName == m_pImageableAreas->getValue( i )->m_aOption )
1303cdf0e10cSrcweir             nImArea = i;
1304cdf0e10cSrcweir     for( i = 0; i < m_pPaperDimensions->countValues(); i++ )
1305cdf0e10cSrcweir         if( rPaperName == m_pPaperDimensions->getValue( i )->m_aOption )
1306cdf0e10cSrcweir             nPDim = i;
1307cdf0e10cSrcweir     if( nPDim == -1 || nImArea == -1 )
1308cdf0e10cSrcweir         return false;
1309cdf0e10cSrcweir 
1310cdf0e10cSrcweir     double ImLLx, ImLLy, ImURx, ImURy;
1311cdf0e10cSrcweir     double PDWidth, PDHeight;
1312cdf0e10cSrcweir     String aArea = m_pImageableAreas->getValue( nImArea )->m_aValue;
1313cdf0e10cSrcweir     ImLLx = StringToDouble( GetCommandLineToken( 0, aArea ) );
1314cdf0e10cSrcweir     ImLLy = StringToDouble( GetCommandLineToken( 1, aArea ) );
1315cdf0e10cSrcweir     ImURx = StringToDouble( GetCommandLineToken( 2, aArea ) );
1316cdf0e10cSrcweir     ImURy = StringToDouble( GetCommandLineToken( 3, aArea ) );
1317cdf0e10cSrcweir //  sscanf( m_pImageableAreas->getValue( nImArea )->m_aValue.GetStr(),
1318cdf0e10cSrcweir //          "%lg%lg%lg%lg", &ImLLx, &ImLLy, &ImURx, &ImURy );
1319cdf0e10cSrcweir     aArea = m_pPaperDimensions->getValue( nPDim )->m_aValue;
1320cdf0e10cSrcweir     PDWidth     = StringToDouble( GetCommandLineToken( 0, aArea ) );
1321cdf0e10cSrcweir     PDHeight    = StringToDouble( GetCommandLineToken( 1, aArea ) );
1322cdf0e10cSrcweir //  sscanf( m_pPaperDimensions->getValue( nPDim )->m_aValue.GetStr(),
1323cdf0e10cSrcweir //          "%lg%lg", &PDWidth, &PDHeight );
1324cdf0e10cSrcweir     rLeft  = (int)(ImLLx + 0.5);
1325cdf0e10cSrcweir     rLower = (int)(ImLLy + 0.5);
1326cdf0e10cSrcweir     rUpper = (int)(PDHeight - ImURy + 0.5);
1327cdf0e10cSrcweir     rRight = (int)(PDWidth - ImURx + 0.5);
1328cdf0e10cSrcweir 
1329cdf0e10cSrcweir     return true;
1330cdf0e10cSrcweir }
1331cdf0e10cSrcweir 
getPaperDimension(const String & rPaperName,int & rWidth,int & rHeight) const1332cdf0e10cSrcweir bool PPDParser::getPaperDimension(
1333cdf0e10cSrcweir                                   const String& rPaperName,
1334cdf0e10cSrcweir                                   int& rWidth, int& rHeight ) const
1335cdf0e10cSrcweir {
1336cdf0e10cSrcweir     if( ! m_pPaperDimensions )
1337cdf0e10cSrcweir         return false;
1338cdf0e10cSrcweir 
1339cdf0e10cSrcweir     int nPDim=-1;
1340cdf0e10cSrcweir     for( int i = 0; i < m_pPaperDimensions->countValues(); i++ )
1341cdf0e10cSrcweir         if( rPaperName == m_pPaperDimensions->getValue( i )->m_aOption )
1342cdf0e10cSrcweir             nPDim = i;
1343cdf0e10cSrcweir     if( nPDim == -1 )
1344cdf0e10cSrcweir         return false;
1345cdf0e10cSrcweir 
1346cdf0e10cSrcweir     double PDWidth, PDHeight;
1347cdf0e10cSrcweir     String aArea = m_pPaperDimensions->getValue( nPDim )->m_aValue;
1348cdf0e10cSrcweir     PDWidth     = StringToDouble( GetCommandLineToken( 0, aArea ) );
1349cdf0e10cSrcweir     PDHeight    = StringToDouble( GetCommandLineToken( 1, aArea ) );
1350cdf0e10cSrcweir     rHeight = (int)(PDHeight + 0.5);
1351cdf0e10cSrcweir     rWidth  = (int)(PDWidth + 0.5);
1352cdf0e10cSrcweir 
1353cdf0e10cSrcweir     return true;
1354cdf0e10cSrcweir }
1355cdf0e10cSrcweir 
matchPaper(int nWidth,int nHeight) const1356cdf0e10cSrcweir String PPDParser::matchPaper( int nWidth, int nHeight ) const
1357cdf0e10cSrcweir {
1358cdf0e10cSrcweir     if( ! m_pPaperDimensions )
1359cdf0e10cSrcweir         return String();
1360cdf0e10cSrcweir 
1361cdf0e10cSrcweir     int nPDim = -1;
1362cdf0e10cSrcweir     double PDWidth, PDHeight;
1363cdf0e10cSrcweir     double fSort = 2e36, fNewSort;
1364cdf0e10cSrcweir 
1365cdf0e10cSrcweir     for( int i = 0; i < m_pPaperDimensions->countValues(); i++ )
1366cdf0e10cSrcweir     {
1367cdf0e10cSrcweir         String aArea =  m_pPaperDimensions->getValue( i )->m_aValue;
1368cdf0e10cSrcweir         PDWidth     = StringToDouble( GetCommandLineToken( 0, aArea ) );
1369cdf0e10cSrcweir         PDHeight    = StringToDouble( GetCommandLineToken( 1, aArea ) );
1370cdf0e10cSrcweir         PDWidth     /= (double)nWidth;
1371cdf0e10cSrcweir         PDHeight    /= (double)nHeight;
1372cdf0e10cSrcweir         if( PDWidth >= 0.9      &&  PDWidth <= 1.1      &&
1373cdf0e10cSrcweir             PDHeight >= 0.9     &&  PDHeight <= 1.1         )
1374cdf0e10cSrcweir         {
1375cdf0e10cSrcweir             fNewSort =
1376cdf0e10cSrcweir                 (1.0-PDWidth)*(1.0-PDWidth) + (1.0-PDHeight)*(1.0-PDHeight);
1377cdf0e10cSrcweir             if( fNewSort == 0.0 ) // perfect match
1378cdf0e10cSrcweir                 return m_pPaperDimensions->getValue( i )->m_aOption;
1379cdf0e10cSrcweir 
1380cdf0e10cSrcweir             if( fNewSort < fSort )
1381cdf0e10cSrcweir             {
1382cdf0e10cSrcweir                 fSort = fNewSort;
1383cdf0e10cSrcweir                 nPDim = i;
1384cdf0e10cSrcweir             }
1385cdf0e10cSrcweir         }
1386cdf0e10cSrcweir     }
1387cdf0e10cSrcweir 
1388cdf0e10cSrcweir     static bool bDontSwap = false;
1389cdf0e10cSrcweir     if( nPDim == -1 && ! bDontSwap )
1390cdf0e10cSrcweir     {
1391cdf0e10cSrcweir         // swap portrait/landscape and try again
1392cdf0e10cSrcweir         bDontSwap = true;
1393cdf0e10cSrcweir         String rRet = matchPaper( nHeight, nWidth );
1394cdf0e10cSrcweir         bDontSwap = false;
1395cdf0e10cSrcweir         return rRet;
1396cdf0e10cSrcweir     }
1397cdf0e10cSrcweir 
1398cdf0e10cSrcweir     return nPDim != -1 ? m_pPaperDimensions->getValue( nPDim )->m_aOption : String();
1399cdf0e10cSrcweir }
1400cdf0e10cSrcweir 
getDefaultInputSlot() const1401cdf0e10cSrcweir String PPDParser::getDefaultInputSlot() const
1402cdf0e10cSrcweir {
1403cdf0e10cSrcweir     if( m_pDefaultInputSlot )
1404cdf0e10cSrcweir         return m_pDefaultInputSlot->m_aValue;
1405cdf0e10cSrcweir     return String();
1406cdf0e10cSrcweir }
1407cdf0e10cSrcweir 
getSlot(int nSlot) const1408cdf0e10cSrcweir String PPDParser::getSlot( int nSlot ) const
1409cdf0e10cSrcweir {
1410cdf0e10cSrcweir     if( ! m_pInputSlots )
1411cdf0e10cSrcweir         return String();
1412cdf0e10cSrcweir 
1413cdf0e10cSrcweir     if( nSlot > 0 && nSlot < m_pInputSlots->countValues() )
1414cdf0e10cSrcweir         return m_pInputSlots->getValue( nSlot )->m_aOption;
1415cdf0e10cSrcweir     else if( m_pInputSlots->countValues() > 0 )
1416cdf0e10cSrcweir         return m_pInputSlots->getValue( (sal_uLong)0 )->m_aOption;
1417cdf0e10cSrcweir 
1418cdf0e10cSrcweir     return String();
1419cdf0e10cSrcweir }
1420cdf0e10cSrcweir 
getSlotCommand(int nSlot) const1421cdf0e10cSrcweir String PPDParser::getSlotCommand( int nSlot ) const
1422cdf0e10cSrcweir {
1423cdf0e10cSrcweir     if( ! m_pInputSlots )
1424cdf0e10cSrcweir         return String();
1425cdf0e10cSrcweir 
1426cdf0e10cSrcweir     if( nSlot > 0 && nSlot < m_pInputSlots->countValues() )
1427cdf0e10cSrcweir         return m_pInputSlots->getValue( nSlot )->m_aValue;
1428cdf0e10cSrcweir     else if( m_pInputSlots->countValues() > 0 )
1429cdf0e10cSrcweir         return m_pInputSlots->getValue( (sal_uLong)0 )->m_aValue;
1430cdf0e10cSrcweir 
1431cdf0e10cSrcweir     return String();
1432cdf0e10cSrcweir }
1433cdf0e10cSrcweir 
getSlotCommand(const String & rSlot) const1434cdf0e10cSrcweir String PPDParser::getSlotCommand( const String& rSlot ) const
1435cdf0e10cSrcweir {
1436cdf0e10cSrcweir     if( ! m_pInputSlots )
1437cdf0e10cSrcweir         return String();
1438cdf0e10cSrcweir 
1439cdf0e10cSrcweir     for( int i=0; i < m_pInputSlots->countValues(); i++ )
1440cdf0e10cSrcweir     {
1441cdf0e10cSrcweir         const PPDValue* pValue = m_pInputSlots->getValue( i );
1442cdf0e10cSrcweir         if( pValue->m_aOption == rSlot )
1443cdf0e10cSrcweir             return pValue->m_aValue;
1444cdf0e10cSrcweir     }
1445cdf0e10cSrcweir     return String();
1446cdf0e10cSrcweir }
1447cdf0e10cSrcweir 
getPaperDimension(int nPaperDimension) const1448cdf0e10cSrcweir String PPDParser::getPaperDimension( int nPaperDimension ) const
1449cdf0e10cSrcweir {
1450cdf0e10cSrcweir     if( ! m_pPaperDimensions )
1451cdf0e10cSrcweir         return String();
1452cdf0e10cSrcweir 
1453cdf0e10cSrcweir     if( nPaperDimension > 0 && nPaperDimension < m_pPaperDimensions->countValues() )
1454cdf0e10cSrcweir         return m_pPaperDimensions->getValue( nPaperDimension )->m_aOption;
1455cdf0e10cSrcweir     else if( m_pPaperDimensions->countValues() > 0 )
1456cdf0e10cSrcweir         return m_pPaperDimensions->getValue( (sal_uLong)0 )->m_aOption;
1457cdf0e10cSrcweir 
1458cdf0e10cSrcweir     return String();
1459cdf0e10cSrcweir }
1460cdf0e10cSrcweir 
getPaperDimensionCommand(int nPaperDimension) const1461cdf0e10cSrcweir String PPDParser::getPaperDimensionCommand( int nPaperDimension ) const
1462cdf0e10cSrcweir {
1463cdf0e10cSrcweir     if( ! m_pPaperDimensions )
1464cdf0e10cSrcweir         return String();
1465cdf0e10cSrcweir 
1466cdf0e10cSrcweir     if( nPaperDimension > 0 && nPaperDimension < m_pPaperDimensions->countValues() )
1467cdf0e10cSrcweir         return m_pPaperDimensions->getValue( nPaperDimension )->m_aValue;
1468cdf0e10cSrcweir     else if( m_pPaperDimensions->countValues() > 0 )
1469cdf0e10cSrcweir         return m_pPaperDimensions->getValue( (sal_uLong)0 )->m_aValue;
1470cdf0e10cSrcweir 
1471cdf0e10cSrcweir     return String();
1472cdf0e10cSrcweir }
1473cdf0e10cSrcweir 
getPaperDimensionCommand(const String & rPaperDimension) const1474cdf0e10cSrcweir String PPDParser::getPaperDimensionCommand( const String& rPaperDimension ) const
1475cdf0e10cSrcweir {
1476cdf0e10cSrcweir     if( ! m_pPaperDimensions )
1477cdf0e10cSrcweir         return String();
1478cdf0e10cSrcweir 
1479cdf0e10cSrcweir     for( int i=0; i < m_pPaperDimensions->countValues(); i++ )
1480cdf0e10cSrcweir     {
1481cdf0e10cSrcweir         const PPDValue* pValue = m_pPaperDimensions->getValue( i );
1482cdf0e10cSrcweir         if( pValue->m_aOption == rPaperDimension )
1483cdf0e10cSrcweir             return pValue->m_aValue;
1484cdf0e10cSrcweir     }
1485cdf0e10cSrcweir     return String();
1486cdf0e10cSrcweir }
1487cdf0e10cSrcweir 
getResolutionFromString(const String & rString,int & rXRes,int & rYRes) const1488cdf0e10cSrcweir void PPDParser::getResolutionFromString(
1489cdf0e10cSrcweir                                         const String& rString,
1490cdf0e10cSrcweir                                         int& rXRes, int& rYRes ) const
1491cdf0e10cSrcweir {
1492cdf0e10cSrcweir     int nPos = 0, nDPIPos;
1493cdf0e10cSrcweir 
1494cdf0e10cSrcweir     rXRes = rYRes = 300;
1495cdf0e10cSrcweir 
1496cdf0e10cSrcweir     nDPIPos = rString.SearchAscii( "dpi" );
1497cdf0e10cSrcweir     if( nDPIPos != STRING_NOTFOUND )
1498cdf0e10cSrcweir     {
1499cdf0e10cSrcweir         if( ( nPos = rString.Search( 'x' ) ) != STRING_NOTFOUND )
1500cdf0e10cSrcweir         {
1501cdf0e10cSrcweir             rXRes = rString.Copy( 0, nPos ).ToInt32();
1502cdf0e10cSrcweir             rYRes = rString.GetToken( 1, 'x' ).Erase( nDPIPos - nPos - 1 ).ToInt32();
1503cdf0e10cSrcweir         }
1504cdf0e10cSrcweir         else
1505cdf0e10cSrcweir             rXRes = rYRes = rString.Copy( 0, nDPIPos ).ToInt32();
1506cdf0e10cSrcweir     }
1507cdf0e10cSrcweir }
1508cdf0e10cSrcweir 
getDefaultResolution(int & rXRes,int & rYRes) const1509cdf0e10cSrcweir void PPDParser::getDefaultResolution( int& rXRes, int& rYRes ) const
1510cdf0e10cSrcweir {
1511cdf0e10cSrcweir     if( m_pDefaultResolution )
1512cdf0e10cSrcweir     {
1513cdf0e10cSrcweir         getResolutionFromString( m_pDefaultResolution->m_aValue, rXRes, rYRes );
1514cdf0e10cSrcweir         return;
1515cdf0e10cSrcweir     }
1516cdf0e10cSrcweir 
1517cdf0e10cSrcweir     rXRes = 300;
1518cdf0e10cSrcweir     rYRes = 300;
1519cdf0e10cSrcweir }
1520cdf0e10cSrcweir 
getResolutions() const1521cdf0e10cSrcweir int PPDParser::getResolutions() const
1522cdf0e10cSrcweir {
1523cdf0e10cSrcweir     if( ( ! m_pResolutions || m_pResolutions->countValues() == 0 ) &&
1524cdf0e10cSrcweir         m_pDefaultResolution )
1525cdf0e10cSrcweir         return 1;
1526cdf0e10cSrcweir     return m_pResolutions ? m_pResolutions->countValues() : 0;
1527cdf0e10cSrcweir }
1528cdf0e10cSrcweir 
getResolution(int nNr,int & rXRes,int & rYRes) const1529cdf0e10cSrcweir void PPDParser::getResolution( int nNr, int& rXRes, int& rYRes ) const
1530cdf0e10cSrcweir {
1531cdf0e10cSrcweir     if( ( ! m_pResolutions || m_pResolutions->countValues() == 0 ) && m_pDefaultResolution && nNr == 0 )
1532cdf0e10cSrcweir     {
1533cdf0e10cSrcweir         getDefaultResolution( rXRes, rYRes );
1534cdf0e10cSrcweir         return;
1535cdf0e10cSrcweir     }
1536cdf0e10cSrcweir     if( ! m_pResolutions )
1537cdf0e10cSrcweir         return;
1538cdf0e10cSrcweir 
1539cdf0e10cSrcweir     getResolutionFromString( m_pResolutions->getValue( nNr )->m_aOption,
1540cdf0e10cSrcweir                              rXRes, rYRes );
1541cdf0e10cSrcweir }
1542cdf0e10cSrcweir 
getResolutionCommand(int nXRes,int nYRes) const1543cdf0e10cSrcweir String PPDParser::getResolutionCommand( int nXRes, int nYRes ) const
1544cdf0e10cSrcweir {
1545cdf0e10cSrcweir     if( ( ! m_pResolutions || m_pResolutions->countValues() == 0 ) && m_pDefaultResolution )
1546cdf0e10cSrcweir         return m_pDefaultResolution->m_aValue;
1547cdf0e10cSrcweir 
1548cdf0e10cSrcweir     if( ! m_pResolutions )
1549cdf0e10cSrcweir         return String();
1550cdf0e10cSrcweir 
1551cdf0e10cSrcweir     int nX, nY;
1552cdf0e10cSrcweir     for( int i = 0; i < m_pResolutions->countValues(); i++ )
1553cdf0e10cSrcweir     {
1554cdf0e10cSrcweir         getResolutionFromString( m_pResolutions->getValue( i )->m_aOption,
1555cdf0e10cSrcweir                                  nX, nY );
1556cdf0e10cSrcweir         if( nX == nXRes && nY == nYRes )
1557cdf0e10cSrcweir             return m_pResolutions->getValue( i )->m_aValue;
1558cdf0e10cSrcweir     }
1559cdf0e10cSrcweir     return String();
1560cdf0e10cSrcweir }
1561cdf0e10cSrcweir 
getDefaultDuplexType() const1562cdf0e10cSrcweir String PPDParser::getDefaultDuplexType() const
1563cdf0e10cSrcweir {
1564cdf0e10cSrcweir     if( m_pDefaultDuplexType )
1565cdf0e10cSrcweir         return m_pDefaultDuplexType->m_aValue;
1566cdf0e10cSrcweir     return String();
1567cdf0e10cSrcweir }
1568cdf0e10cSrcweir 
getDuplex(int nDuplex) const1569cdf0e10cSrcweir String PPDParser::getDuplex( int nDuplex ) const
1570cdf0e10cSrcweir {
1571cdf0e10cSrcweir     if( ! m_pDuplexTypes )
1572cdf0e10cSrcweir         return String();
1573cdf0e10cSrcweir 
1574cdf0e10cSrcweir     if( nDuplex > 0 && nDuplex < m_pDuplexTypes->countValues() )
1575cdf0e10cSrcweir         return m_pDuplexTypes->getValue( nDuplex )->m_aOption;
1576cdf0e10cSrcweir     else if( m_pDuplexTypes->countValues() > 0 )
1577cdf0e10cSrcweir         return m_pDuplexTypes->getValue( (sal_uLong)0 )->m_aOption;
1578cdf0e10cSrcweir 
1579cdf0e10cSrcweir     return String();
1580cdf0e10cSrcweir }
1581cdf0e10cSrcweir 
getDuplexCommand(int nDuplex) const1582cdf0e10cSrcweir String PPDParser::getDuplexCommand( int nDuplex ) const
1583cdf0e10cSrcweir {
1584cdf0e10cSrcweir     if( ! m_pDuplexTypes )
1585cdf0e10cSrcweir         return String();
1586cdf0e10cSrcweir 
1587cdf0e10cSrcweir     if( nDuplex > 0 && nDuplex < m_pDuplexTypes->countValues() )
1588cdf0e10cSrcweir         return m_pDuplexTypes->getValue( nDuplex )->m_aValue;
1589cdf0e10cSrcweir     else if( m_pDuplexTypes->countValues() > 0 )
1590cdf0e10cSrcweir         return m_pDuplexTypes->getValue( (sal_uLong)0 )->m_aValue;
1591cdf0e10cSrcweir 
1592cdf0e10cSrcweir     return String();
1593cdf0e10cSrcweir }
1594cdf0e10cSrcweir 
getDuplexCommand(const String & rDuplex) const1595cdf0e10cSrcweir String PPDParser::getDuplexCommand( const String& rDuplex ) const
1596cdf0e10cSrcweir {
1597cdf0e10cSrcweir     if( ! m_pDuplexTypes )
1598cdf0e10cSrcweir         return String();
1599cdf0e10cSrcweir 
1600cdf0e10cSrcweir     for( int i=0; i < m_pDuplexTypes->countValues(); i++ )
1601cdf0e10cSrcweir     {
1602cdf0e10cSrcweir         const PPDValue* pValue = m_pDuplexTypes->getValue( i );
1603cdf0e10cSrcweir         if( pValue->m_aOption == rDuplex )
1604cdf0e10cSrcweir             return pValue->m_aValue;
1605cdf0e10cSrcweir     }
1606cdf0e10cSrcweir     return String();
1607cdf0e10cSrcweir }
1608cdf0e10cSrcweir 
getFontAttributes(int nFont,String & rEncoding,String & rCharset) const1609cdf0e10cSrcweir void PPDParser::getFontAttributes(
1610cdf0e10cSrcweir                                   int nFont,
1611cdf0e10cSrcweir                                   String& rEncoding,
1612cdf0e10cSrcweir                                   String& rCharset ) const
1613cdf0e10cSrcweir {
1614cdf0e10cSrcweir     if( m_pFontList && nFont >= 0 && nFont < m_pFontList->countValues() )
1615cdf0e10cSrcweir     {
1616cdf0e10cSrcweir         String aAttribs =
1617cdf0e10cSrcweir             WhitespaceToSpace( m_pFontList->getValue( nFont )->m_aValue );
1618cdf0e10cSrcweir         rEncoding   = GetCommandLineToken( 0, aAttribs );
1619cdf0e10cSrcweir         rCharset    = GetCommandLineToken( 2, aAttribs );
1620cdf0e10cSrcweir     }
1621cdf0e10cSrcweir }
1622cdf0e10cSrcweir 
getFontAttributes(const String & rFont,String & rEncoding,String & rCharset) const1623cdf0e10cSrcweir void PPDParser::getFontAttributes(
1624cdf0e10cSrcweir                                   const String& rFont,
1625cdf0e10cSrcweir                                   String& rEncoding,
1626cdf0e10cSrcweir                                   String& rCharset ) const
1627cdf0e10cSrcweir {
1628cdf0e10cSrcweir     if( m_pFontList )
1629cdf0e10cSrcweir     {
1630cdf0e10cSrcweir         for( int i = 0; i < m_pFontList->countValues(); i++ )
1631cdf0e10cSrcweir             if( m_pFontList->getValue( i )->m_aOption == rFont )
1632cdf0e10cSrcweir                 getFontAttributes( i, rEncoding, rCharset );
1633cdf0e10cSrcweir     }
1634cdf0e10cSrcweir }
1635cdf0e10cSrcweir 
getFont(int nFont) const1636cdf0e10cSrcweir String PPDParser::getFont( int nFont ) const
1637cdf0e10cSrcweir {
1638cdf0e10cSrcweir     if( ! m_pFontList )
1639cdf0e10cSrcweir         return String();
1640cdf0e10cSrcweir 
1641cdf0e10cSrcweir     if( nFont >=0 && nFont < m_pFontList->countValues() )
1642cdf0e10cSrcweir         return m_pFontList->getValue( nFont )->m_aOption;
1643cdf0e10cSrcweir     return String();
1644cdf0e10cSrcweir }
1645cdf0e10cSrcweir 
translateKey(const rtl::OUString & i_rKey,const com::sun::star::lang::Locale & i_rLocale) const1646cdf0e10cSrcweir rtl::OUString PPDParser::translateKey( const rtl::OUString& i_rKey,
1647cdf0e10cSrcweir                                        const com::sun::star::lang::Locale& i_rLocale ) const
1648cdf0e10cSrcweir {
1649cdf0e10cSrcweir     rtl::OUString aResult( m_pTranslator->translateKey( i_rKey, i_rLocale ) );
1650cdf0e10cSrcweir     if( aResult.getLength() == 0 )
1651cdf0e10cSrcweir         aResult = i_rKey;
1652cdf0e10cSrcweir     return aResult;
1653cdf0e10cSrcweir }
1654cdf0e10cSrcweir 
translateOption(const rtl::OUString & i_rKey,const rtl::OUString & i_rOption,const com::sun::star::lang::Locale & i_rLocale) const1655cdf0e10cSrcweir rtl::OUString PPDParser::translateOption( const rtl::OUString& i_rKey,
1656cdf0e10cSrcweir                                           const rtl::OUString& i_rOption,
1657cdf0e10cSrcweir                                           const com::sun::star::lang::Locale& i_rLocale ) const
1658cdf0e10cSrcweir {
1659cdf0e10cSrcweir     rtl::OUString aResult( m_pTranslator->translateOption( i_rKey, i_rOption, i_rLocale ) );
1660cdf0e10cSrcweir     if( aResult.getLength() == 0 )
1661cdf0e10cSrcweir         aResult = i_rOption;
1662cdf0e10cSrcweir     return aResult;
1663cdf0e10cSrcweir }
1664cdf0e10cSrcweir 
translateValue(const rtl::OUString & i_rKey,const rtl::OUString & i_rOption,const rtl::OUString & i_rValue,const com::sun::star::lang::Locale & i_rLocale) const1665cdf0e10cSrcweir rtl::OUString PPDParser::translateValue( const rtl::OUString& i_rKey,
1666cdf0e10cSrcweir                                          const rtl::OUString& i_rOption,
1667cdf0e10cSrcweir                                          const rtl::OUString& i_rValue,
1668cdf0e10cSrcweir                                          const com::sun::star::lang::Locale& i_rLocale ) const
1669cdf0e10cSrcweir {
1670cdf0e10cSrcweir     rtl::OUString aResult( m_pTranslator->translateValue( i_rKey, i_rOption, i_rValue, i_rLocale ) );
1671cdf0e10cSrcweir     if( aResult.getLength() == 0 )
1672cdf0e10cSrcweir         aResult = i_rValue;
1673cdf0e10cSrcweir     return aResult;
1674cdf0e10cSrcweir }
1675cdf0e10cSrcweir 
1676cdf0e10cSrcweir /*
1677cdf0e10cSrcweir  *  PPDKey
1678cdf0e10cSrcweir  */
1679cdf0e10cSrcweir 
PPDKey(const String & rKey)1680cdf0e10cSrcweir PPDKey::PPDKey( const String& rKey ) :
1681cdf0e10cSrcweir         m_aKey( rKey ),
1682cdf0e10cSrcweir         m_pDefaultValue( NULL ),
1683cdf0e10cSrcweir         m_bQueryValue( false ),
1684cdf0e10cSrcweir         m_bUIOption( false ),
1685cdf0e10cSrcweir         m_eUIType( PickOne ),
1686cdf0e10cSrcweir         m_nOrderDependency( 100 ),
1687cdf0e10cSrcweir         m_eSetupType( AnySetup )
1688cdf0e10cSrcweir {
1689cdf0e10cSrcweir }
1690cdf0e10cSrcweir 
1691cdf0e10cSrcweir // -------------------------------------------------------------------
1692cdf0e10cSrcweir 
~PPDKey()1693cdf0e10cSrcweir PPDKey::~PPDKey()
1694cdf0e10cSrcweir {
1695cdf0e10cSrcweir }
1696cdf0e10cSrcweir 
1697cdf0e10cSrcweir // -------------------------------------------------------------------
1698cdf0e10cSrcweir 
getValue(int n) const1699cdf0e10cSrcweir const PPDValue* PPDKey::getValue( int n ) const
1700cdf0e10cSrcweir {
1701cdf0e10cSrcweir     return ((unsigned int)n < m_aOrderedValues.size() && n >= 0) ? m_aOrderedValues[n] : NULL;
1702cdf0e10cSrcweir }
1703cdf0e10cSrcweir 
1704cdf0e10cSrcweir // -------------------------------------------------------------------
1705cdf0e10cSrcweir 
getValue(const String & rOption) const1706cdf0e10cSrcweir const PPDValue* PPDKey::getValue( const String& rOption ) const
1707cdf0e10cSrcweir {
1708cdf0e10cSrcweir     PPDKey::hash_type::const_iterator it = m_aValues.find( rOption );
1709cdf0e10cSrcweir     return it != m_aValues.end() ? &it->second : NULL;
1710cdf0e10cSrcweir }
1711cdf0e10cSrcweir 
1712cdf0e10cSrcweir // -------------------------------------------------------------------
1713cdf0e10cSrcweir 
getValueCaseInsensitive(const String & rOption) const1714cdf0e10cSrcweir const PPDValue* PPDKey::getValueCaseInsensitive( const String& rOption ) const
1715cdf0e10cSrcweir {
1716cdf0e10cSrcweir     const PPDValue* pValue = getValue( rOption );
1717cdf0e10cSrcweir     if( ! pValue )
1718cdf0e10cSrcweir     {
1719cdf0e10cSrcweir         for( size_t n = 0; n < m_aOrderedValues.size() && ! pValue; n++ )
1720cdf0e10cSrcweir             if( m_aOrderedValues[n]->m_aOption.EqualsIgnoreCaseAscii( rOption ) )
1721cdf0e10cSrcweir                 pValue = m_aOrderedValues[n];
1722cdf0e10cSrcweir     }
1723cdf0e10cSrcweir 
1724cdf0e10cSrcweir     return pValue;
1725cdf0e10cSrcweir }
1726cdf0e10cSrcweir 
1727cdf0e10cSrcweir // -------------------------------------------------------------------
1728cdf0e10cSrcweir 
eraseValue(const String & rOption)1729cdf0e10cSrcweir void PPDKey::eraseValue( const String& rOption )
1730cdf0e10cSrcweir {
1731cdf0e10cSrcweir     PPDKey::hash_type::iterator it = m_aValues.find( rOption );
1732cdf0e10cSrcweir     if( it == m_aValues.end() )
1733cdf0e10cSrcweir         return;
1734cdf0e10cSrcweir 
1735cdf0e10cSrcweir     for( PPDKey::value_type::iterator vit = m_aOrderedValues.begin(); vit != m_aOrderedValues.end(); ++vit )
1736cdf0e10cSrcweir     {
1737cdf0e10cSrcweir         if( *vit == &(it->second ) )
1738cdf0e10cSrcweir         {
1739cdf0e10cSrcweir             m_aOrderedValues.erase( vit );
1740cdf0e10cSrcweir             break;
1741cdf0e10cSrcweir         }
1742cdf0e10cSrcweir     }
1743cdf0e10cSrcweir     m_aValues.erase( it );
1744cdf0e10cSrcweir }
1745cdf0e10cSrcweir 
1746cdf0e10cSrcweir // -------------------------------------------------------------------
1747cdf0e10cSrcweir 
insertValue(const String & rOption)1748cdf0e10cSrcweir PPDValue* PPDKey::insertValue( const String& rOption )
1749cdf0e10cSrcweir {
1750cdf0e10cSrcweir     if( m_aValues.find( rOption ) != m_aValues.end() )
1751cdf0e10cSrcweir         return NULL;
1752cdf0e10cSrcweir 
1753cdf0e10cSrcweir     PPDValue aValue;
1754cdf0e10cSrcweir     aValue.m_aOption = rOption;
1755cdf0e10cSrcweir     m_aValues[ rOption ] = aValue;
1756cdf0e10cSrcweir     PPDValue* pValue = &m_aValues[rOption];
1757cdf0e10cSrcweir     m_aOrderedValues.push_back( pValue );
1758cdf0e10cSrcweir     return pValue;
1759cdf0e10cSrcweir }
1760cdf0e10cSrcweir 
1761cdf0e10cSrcweir // -------------------------------------------------------------------
1762cdf0e10cSrcweir 
1763cdf0e10cSrcweir /*
1764cdf0e10cSrcweir  * PPDContext
1765cdf0e10cSrcweir  */
1766cdf0e10cSrcweir 
PPDContext(const PPDParser * pParser)1767cdf0e10cSrcweir PPDContext::PPDContext( const PPDParser* pParser ) :
1768cdf0e10cSrcweir         m_pParser( pParser )
1769cdf0e10cSrcweir {
1770cdf0e10cSrcweir }
1771cdf0e10cSrcweir 
1772cdf0e10cSrcweir // -------------------------------------------------------------------
1773cdf0e10cSrcweir 
operator =(const PPDContext & rCopy)1774cdf0e10cSrcweir PPDContext& PPDContext::operator=( const PPDContext& rCopy )
1775cdf0e10cSrcweir {
1776cdf0e10cSrcweir     m_pParser           = rCopy.m_pParser;
1777cdf0e10cSrcweir     m_aCurrentValues    = rCopy.m_aCurrentValues;
1778cdf0e10cSrcweir     return *this;
1779cdf0e10cSrcweir }
1780cdf0e10cSrcweir 
1781cdf0e10cSrcweir // -------------------------------------------------------------------
1782cdf0e10cSrcweir 
~PPDContext()1783cdf0e10cSrcweir PPDContext::~PPDContext()
1784cdf0e10cSrcweir {
1785cdf0e10cSrcweir }
1786cdf0e10cSrcweir 
1787cdf0e10cSrcweir // -------------------------------------------------------------------
1788cdf0e10cSrcweir 
getModifiedKey(int n) const1789cdf0e10cSrcweir const PPDKey* PPDContext::getModifiedKey( int n ) const
1790cdf0e10cSrcweir {
1791cdf0e10cSrcweir     hash_type::const_iterator it;
1792cdf0e10cSrcweir     for( it = m_aCurrentValues.begin(); it != m_aCurrentValues.end() && n--; ++it )
1793cdf0e10cSrcweir         ;
1794cdf0e10cSrcweir     return it != m_aCurrentValues.end() ? it->first : NULL;
1795cdf0e10cSrcweir }
1796cdf0e10cSrcweir 
1797cdf0e10cSrcweir // -------------------------------------------------------------------
1798cdf0e10cSrcweir 
setParser(const PPDParser * pParser)1799cdf0e10cSrcweir void PPDContext::setParser( const PPDParser* pParser )
1800cdf0e10cSrcweir {
1801cdf0e10cSrcweir     if( pParser != m_pParser )
1802cdf0e10cSrcweir     {
1803cdf0e10cSrcweir         m_aCurrentValues.clear();
1804cdf0e10cSrcweir         m_pParser = pParser;
1805cdf0e10cSrcweir     }
1806cdf0e10cSrcweir }
1807cdf0e10cSrcweir 
1808cdf0e10cSrcweir // -------------------------------------------------------------------
1809cdf0e10cSrcweir 
getValue(const PPDKey * pKey) const1810cdf0e10cSrcweir const PPDValue* PPDContext::getValue( const PPDKey* pKey ) const
1811cdf0e10cSrcweir {
1812cdf0e10cSrcweir     if( ! m_pParser )
1813cdf0e10cSrcweir         return NULL;
1814cdf0e10cSrcweir 
1815cdf0e10cSrcweir     hash_type::const_iterator it;
1816cdf0e10cSrcweir     it = m_aCurrentValues.find( pKey );
1817cdf0e10cSrcweir     if( it != m_aCurrentValues.end() )
1818cdf0e10cSrcweir         return it->second;
1819cdf0e10cSrcweir 
1820cdf0e10cSrcweir     if( ! m_pParser->hasKey( pKey ) )
1821cdf0e10cSrcweir         return NULL;
1822cdf0e10cSrcweir 
1823cdf0e10cSrcweir     const PPDValue* pValue = pKey->getDefaultValue();
1824cdf0e10cSrcweir     if( ! pValue )
1825cdf0e10cSrcweir         pValue = pKey->getValue( 0 );
1826cdf0e10cSrcweir 
1827cdf0e10cSrcweir     return pValue;
1828cdf0e10cSrcweir }
1829cdf0e10cSrcweir 
1830cdf0e10cSrcweir // -------------------------------------------------------------------
1831cdf0e10cSrcweir 
setValue(const PPDKey * pKey,const PPDValue * pValue,bool bDontCareForConstraints)1832cdf0e10cSrcweir const PPDValue* PPDContext::setValue( const PPDKey* pKey, const PPDValue* pValue, bool bDontCareForConstraints )
1833cdf0e10cSrcweir {
1834cdf0e10cSrcweir     if( ! m_pParser || ! pKey )
1835cdf0e10cSrcweir         return NULL;
1836cdf0e10cSrcweir 
1837cdf0e10cSrcweir     // pValue can be NULL - it means ignore this option
1838cdf0e10cSrcweir 
1839cdf0e10cSrcweir     if( ! m_pParser->hasKey( pKey ) )
1840cdf0e10cSrcweir         return NULL;
1841cdf0e10cSrcweir 
1842cdf0e10cSrcweir     // check constraints
1843cdf0e10cSrcweir     if( pValue )
1844cdf0e10cSrcweir     {
1845cdf0e10cSrcweir         if( bDontCareForConstraints )
1846cdf0e10cSrcweir         {
1847cdf0e10cSrcweir             m_aCurrentValues[ pKey ] = pValue;
1848cdf0e10cSrcweir         }
1849cdf0e10cSrcweir         else if( checkConstraints( pKey, pValue, true ) )
1850cdf0e10cSrcweir         {
1851cdf0e10cSrcweir             m_aCurrentValues[ pKey ] = pValue;
1852cdf0e10cSrcweir 
1853cdf0e10cSrcweir             // after setting this value, check all constraints !
1854cdf0e10cSrcweir             hash_type::iterator it = m_aCurrentValues.begin();
1855cdf0e10cSrcweir             while(  it != m_aCurrentValues.end() )
1856cdf0e10cSrcweir             {
1857cdf0e10cSrcweir                 if( it->first != pKey &&
1858cdf0e10cSrcweir                     ! checkConstraints( it->first, it->second, false ) )
1859cdf0e10cSrcweir                 {
1860cdf0e10cSrcweir #ifdef __DEBUG
1861cdf0e10cSrcweir                     fprintf( stderr, "PPDContext::setValue: option %s (%s) is constrained after setting %s to %s\n",
1862cdf0e10cSrcweir                              it->first->getKey().GetStr(),
1863cdf0e10cSrcweir                              it->second->m_aOption.GetStr(),
1864cdf0e10cSrcweir                              pKey->getKey().GetStr(),
1865cdf0e10cSrcweir                              pValue->m_aOption.GetStr() );
1866cdf0e10cSrcweir #endif
1867cdf0e10cSrcweir                     resetValue( it->first, true );
1868cdf0e10cSrcweir                     it = m_aCurrentValues.begin();
1869cdf0e10cSrcweir                 }
1870cdf0e10cSrcweir                 else
1871cdf0e10cSrcweir                     ++it;
1872cdf0e10cSrcweir             }
1873cdf0e10cSrcweir         }
1874cdf0e10cSrcweir     }
1875cdf0e10cSrcweir     else
1876cdf0e10cSrcweir         m_aCurrentValues[ pKey ] = NULL;
1877cdf0e10cSrcweir 
1878cdf0e10cSrcweir     return pValue;
1879cdf0e10cSrcweir }
1880cdf0e10cSrcweir 
1881cdf0e10cSrcweir // -------------------------------------------------------------------
1882cdf0e10cSrcweir 
checkConstraints(const PPDKey * pKey,const PPDValue * pValue)1883cdf0e10cSrcweir bool PPDContext::checkConstraints( const PPDKey* pKey, const PPDValue* pValue )
1884cdf0e10cSrcweir {
1885cdf0e10cSrcweir     if( ! m_pParser || ! pKey || ! pValue )
1886cdf0e10cSrcweir         return false;
1887cdf0e10cSrcweir 
1888cdf0e10cSrcweir     // ensure that this key is already in the list if it exists at all
1889cdf0e10cSrcweir     if( m_aCurrentValues.find( pKey ) != m_aCurrentValues.end() )
1890cdf0e10cSrcweir         return checkConstraints( pKey, pValue, false );
1891cdf0e10cSrcweir 
1892cdf0e10cSrcweir     // it is not in the list, insert it temporarily
1893cdf0e10cSrcweir     bool bRet = false;
1894cdf0e10cSrcweir     if( m_pParser->hasKey( pKey ) )
1895cdf0e10cSrcweir     {
1896cdf0e10cSrcweir         const PPDValue* pDefValue = pKey->getDefaultValue();
1897cdf0e10cSrcweir         m_aCurrentValues[ pKey ] = pDefValue;
1898cdf0e10cSrcweir         bRet = checkConstraints( pKey, pValue, false );
1899cdf0e10cSrcweir         m_aCurrentValues.erase( pKey );
1900cdf0e10cSrcweir     }
1901cdf0e10cSrcweir 
1902cdf0e10cSrcweir     return bRet;
1903cdf0e10cSrcweir }
1904cdf0e10cSrcweir 
1905cdf0e10cSrcweir // -------------------------------------------------------------------
1906cdf0e10cSrcweir 
resetValue(const PPDKey * pKey,bool bDefaultable)1907cdf0e10cSrcweir bool PPDContext::resetValue( const PPDKey* pKey, bool bDefaultable )
1908cdf0e10cSrcweir {
1909cdf0e10cSrcweir     if( ! pKey || ! m_pParser || ! m_pParser->hasKey( pKey ) )
1910cdf0e10cSrcweir         return false;
1911cdf0e10cSrcweir 
1912cdf0e10cSrcweir     const PPDValue* pResetValue = pKey->getValue( String( RTL_CONSTASCII_USTRINGPARAM( "None" ) ) );
1913cdf0e10cSrcweir     if( ! pResetValue )
1914cdf0e10cSrcweir         pResetValue = pKey->getValue( String( RTL_CONSTASCII_USTRINGPARAM( "False" ) ) );
1915cdf0e10cSrcweir     if( ! pResetValue && bDefaultable )
1916cdf0e10cSrcweir         pResetValue = pKey->getDefaultValue();
1917cdf0e10cSrcweir 
1918cdf0e10cSrcweir     bool bRet = pResetValue ? ( setValue( pKey, pResetValue ) == pResetValue ? true : false ) : false;
1919cdf0e10cSrcweir 
1920cdf0e10cSrcweir     return bRet;
1921cdf0e10cSrcweir }
1922cdf0e10cSrcweir 
1923cdf0e10cSrcweir // -------------------------------------------------------------------
1924cdf0e10cSrcweir 
checkConstraints(const PPDKey * pKey,const PPDValue * pNewValue,bool bDoReset)1925cdf0e10cSrcweir bool PPDContext::checkConstraints( const PPDKey* pKey, const PPDValue* pNewValue, bool bDoReset )
1926cdf0e10cSrcweir {
1927cdf0e10cSrcweir     if( ! pNewValue )
1928cdf0e10cSrcweir         return true;
1929cdf0e10cSrcweir 
1930cdf0e10cSrcweir     // sanity checks
1931cdf0e10cSrcweir     if( ! m_pParser )
1932cdf0e10cSrcweir         return false;
1933cdf0e10cSrcweir 
1934cdf0e10cSrcweir     if( pKey->getValue( pNewValue->m_aOption ) != pNewValue )
1935cdf0e10cSrcweir         return false;
1936cdf0e10cSrcweir 
1937cdf0e10cSrcweir     // None / False and the default can always be set, but be careful !
1938cdf0e10cSrcweir     // setting them might influence constrained values
1939cdf0e10cSrcweir     if( pNewValue->m_aOption.EqualsAscii( "None" ) || pNewValue->m_aOption.EqualsAscii( "False" ) ||
1940cdf0e10cSrcweir         pNewValue == pKey->getDefaultValue() )
1941cdf0e10cSrcweir         return true;
1942cdf0e10cSrcweir 
1943cdf0e10cSrcweir     const ::std::list< PPDParser::PPDConstraint >& rConstraints( m_pParser->getConstraints() );
1944cdf0e10cSrcweir     for( ::std::list< PPDParser::PPDConstraint >::const_iterator it = rConstraints.begin(); it != rConstraints.end(); ++it )
1945cdf0e10cSrcweir     {
1946cdf0e10cSrcweir         const PPDKey* pLeft     = it->m_pKey1;
1947cdf0e10cSrcweir         const PPDKey* pRight    = it->m_pKey2;
1948cdf0e10cSrcweir         if( ! pLeft || ! pRight || ( pKey != pLeft && pKey != pRight ) )
1949cdf0e10cSrcweir             continue;
1950cdf0e10cSrcweir 
1951cdf0e10cSrcweir         const PPDKey* pOtherKey = pKey == pLeft ? pRight : pLeft;
1952cdf0e10cSrcweir         const PPDValue* pOtherKeyOption = pKey == pLeft ? it->m_pOption2 : it->m_pOption1;
1953cdf0e10cSrcweir         const PPDValue* pKeyOption = pKey == pLeft ? it->m_pOption1 : it->m_pOption2;
1954cdf0e10cSrcweir 
1955cdf0e10cSrcweir         // syntax *Key1 option1 *Key2 option2
1956cdf0e10cSrcweir         if( pKeyOption && pOtherKeyOption )
1957cdf0e10cSrcweir         {
1958cdf0e10cSrcweir             if( pNewValue != pKeyOption )
1959cdf0e10cSrcweir                 continue;
1960cdf0e10cSrcweir             if( pOtherKeyOption == getValue( pOtherKey ) )
1961cdf0e10cSrcweir             {
1962cdf0e10cSrcweir                 return false;
1963cdf0e10cSrcweir             }
1964cdf0e10cSrcweir         }
1965cdf0e10cSrcweir         // syntax *Key1 option *Key2  or  *Key1 *Key2 option
1966cdf0e10cSrcweir         else if( pOtherKeyOption || pKeyOption )
1967cdf0e10cSrcweir         {
1968cdf0e10cSrcweir             if( pKeyOption )
1969cdf0e10cSrcweir             {
1970cdf0e10cSrcweir                 if( ! ( pOtherKeyOption = getValue( pOtherKey ) ) )
1971cdf0e10cSrcweir                     continue; // this should not happen, PPD broken
1972cdf0e10cSrcweir 
1973cdf0e10cSrcweir                 if( pKeyOption == pNewValue &&
1974cdf0e10cSrcweir                     ! pOtherKeyOption->m_aOption.EqualsAscii( "None" ) &&
1975cdf0e10cSrcweir                     ! pOtherKeyOption->m_aOption.EqualsAscii( "False" ) )
1976cdf0e10cSrcweir                 {
1977cdf0e10cSrcweir                     // check if the other value can be reset and
1978cdf0e10cSrcweir                     // do so if possible
1979cdf0e10cSrcweir                     if( bDoReset && resetValue( pOtherKey ) )
1980cdf0e10cSrcweir                         continue;
1981cdf0e10cSrcweir 
1982cdf0e10cSrcweir                     return false;
1983cdf0e10cSrcweir                 }
1984cdf0e10cSrcweir             }
1985cdf0e10cSrcweir             else if( pOtherKeyOption )
1986cdf0e10cSrcweir             {
1987cdf0e10cSrcweir                 if( getValue( pOtherKey ) == pOtherKeyOption &&
1988cdf0e10cSrcweir                     ! pNewValue->m_aOption.EqualsAscii( "None" ) &&
1989cdf0e10cSrcweir                     ! pNewValue->m_aOption.EqualsAscii( "False" ) )
1990cdf0e10cSrcweir                     return false;
1991cdf0e10cSrcweir             }
1992cdf0e10cSrcweir             else
1993cdf0e10cSrcweir             {
1994cdf0e10cSrcweir                 // this should not happen, PPD is broken
1995cdf0e10cSrcweir             }
1996cdf0e10cSrcweir         }
1997cdf0e10cSrcweir         // syntax *Key1 *Key2
1998cdf0e10cSrcweir         else
1999cdf0e10cSrcweir         {
2000cdf0e10cSrcweir             const PPDValue* pOtherValue = getValue( pOtherKey );
2001cdf0e10cSrcweir             if( ! pOtherValue->m_aOption.EqualsAscii( "None" )  &&
2002cdf0e10cSrcweir                 ! pOtherValue->m_aOption.EqualsAscii( "False" )     &&
2003cdf0e10cSrcweir                 ! pNewValue->m_aOption.EqualsAscii( "None" )        &&
2004cdf0e10cSrcweir                 ! pNewValue->m_aOption.EqualsAscii( "False" ) )
2005cdf0e10cSrcweir                 return false;
2006cdf0e10cSrcweir         }
2007cdf0e10cSrcweir     }
2008cdf0e10cSrcweir     return true;
2009cdf0e10cSrcweir }
2010cdf0e10cSrcweir 
2011cdf0e10cSrcweir // -------------------------------------------------------------------
2012cdf0e10cSrcweir 
getUnconstrainedValues(const PPDKey * pKey,::std::list<const PPDValue * > & rValues)2013cdf0e10cSrcweir void PPDContext::getUnconstrainedValues( const PPDKey* pKey, ::std::list< const PPDValue* >& rValues )
2014cdf0e10cSrcweir {
2015cdf0e10cSrcweir     rValues.clear();
2016cdf0e10cSrcweir 
2017cdf0e10cSrcweir     if( ! m_pParser || ! pKey || ! m_pParser->hasKey( pKey ) )
2018cdf0e10cSrcweir         return;
2019cdf0e10cSrcweir 
2020cdf0e10cSrcweir     int nValues = pKey->countValues();
2021cdf0e10cSrcweir     for( int i = 0; i < nValues; i++ )
2022cdf0e10cSrcweir     {
2023cdf0e10cSrcweir         const PPDValue* pValue = pKey->getValue( i );
2024cdf0e10cSrcweir         if( checkConstraints( pKey, pValue ) )
2025cdf0e10cSrcweir             rValues.push_back( pValue );
2026cdf0e10cSrcweir     }
2027cdf0e10cSrcweir }
2028cdf0e10cSrcweir 
2029cdf0e10cSrcweir 
2030cdf0e10cSrcweir // -------------------------------------------------------------------
2031cdf0e10cSrcweir 
getStreamableBuffer(sal_uLong & rBytes) const2032cdf0e10cSrcweir void* PPDContext::getStreamableBuffer( sal_uLong& rBytes ) const
2033cdf0e10cSrcweir {
2034cdf0e10cSrcweir     rBytes = 0;
2035cdf0e10cSrcweir     if( ! m_aCurrentValues.size() )
2036cdf0e10cSrcweir         return NULL;
2037cdf0e10cSrcweir     hash_type::const_iterator it;
2038cdf0e10cSrcweir     for( it = m_aCurrentValues.begin(); it != m_aCurrentValues.end(); ++it )
2039cdf0e10cSrcweir     {
2040cdf0e10cSrcweir         ByteString aCopy( it->first->getKey(), RTL_TEXTENCODING_MS_1252 );
2041cdf0e10cSrcweir         rBytes += aCopy.Len();
2042cdf0e10cSrcweir         rBytes += 1; // for ':'
2043cdf0e10cSrcweir         if( it->second )
2044cdf0e10cSrcweir         {
2045cdf0e10cSrcweir             aCopy = ByteString( it->second->m_aOption, RTL_TEXTENCODING_MS_1252 );
2046cdf0e10cSrcweir             rBytes += aCopy.Len();
2047cdf0e10cSrcweir         }
2048cdf0e10cSrcweir         else
2049cdf0e10cSrcweir             rBytes += 4;
2050cdf0e10cSrcweir         rBytes += 1; // for '\0'
2051cdf0e10cSrcweir     }
2052cdf0e10cSrcweir     rBytes += 1;
2053cdf0e10cSrcweir     void* pBuffer = new char[ rBytes ];
2054cdf0e10cSrcweir     memset( pBuffer, 0, rBytes );
2055cdf0e10cSrcweir     char* pRun = (char*)pBuffer;
2056cdf0e10cSrcweir     for( it = m_aCurrentValues.begin(); it != m_aCurrentValues.end(); ++it )
2057cdf0e10cSrcweir     {
2058cdf0e10cSrcweir         ByteString aCopy( it->first->getKey(), RTL_TEXTENCODING_MS_1252 );
2059cdf0e10cSrcweir         int nBytes = aCopy.Len();
2060cdf0e10cSrcweir         memcpy( pRun, aCopy.GetBuffer(), nBytes );
2061cdf0e10cSrcweir         pRun += nBytes;
2062cdf0e10cSrcweir         *pRun++ = ':';
2063cdf0e10cSrcweir         if( it->second )
2064cdf0e10cSrcweir             aCopy = ByteString( it->second->m_aOption, RTL_TEXTENCODING_MS_1252 );
2065cdf0e10cSrcweir         else
2066cdf0e10cSrcweir             aCopy = "*nil";
2067cdf0e10cSrcweir         nBytes = aCopy.Len();
2068cdf0e10cSrcweir         memcpy( pRun, aCopy.GetBuffer(), nBytes );
2069cdf0e10cSrcweir         pRun += nBytes;
2070cdf0e10cSrcweir 
2071cdf0e10cSrcweir         *pRun++ = 0;
2072cdf0e10cSrcweir     }
2073cdf0e10cSrcweir     return pBuffer;
2074cdf0e10cSrcweir }
2075cdf0e10cSrcweir 
2076cdf0e10cSrcweir // -------------------------------------------------------------------
2077cdf0e10cSrcweir 
rebuildFromStreamBuffer(void * pBuffer,sal_uLong nBytes)2078cdf0e10cSrcweir void PPDContext::rebuildFromStreamBuffer( void* pBuffer, sal_uLong nBytes )
2079cdf0e10cSrcweir {
2080cdf0e10cSrcweir     if( ! m_pParser )
2081cdf0e10cSrcweir         return;
2082cdf0e10cSrcweir 
2083cdf0e10cSrcweir     m_aCurrentValues.clear();
2084cdf0e10cSrcweir 
2085cdf0e10cSrcweir     char* pRun = (char*)pBuffer;
2086cdf0e10cSrcweir     while( nBytes && *pRun )
2087cdf0e10cSrcweir     {
2088cdf0e10cSrcweir         ByteString aLine( pRun );
2089cdf0e10cSrcweir         int nPos = aLine.Search( ':' );
2090cdf0e10cSrcweir         if( nPos != STRING_NOTFOUND )
2091cdf0e10cSrcweir         {
2092cdf0e10cSrcweir             const PPDKey* pKey = m_pParser->getKey( String( aLine.Copy( 0, nPos ), RTL_TEXTENCODING_MS_1252 ) );
2093cdf0e10cSrcweir             if( pKey )
2094cdf0e10cSrcweir             {
2095cdf0e10cSrcweir                 const PPDValue* pValue = NULL;
2096cdf0e10cSrcweir                 String aOption( aLine.Copy( nPos+1 ), RTL_TEXTENCODING_MS_1252 );
2097cdf0e10cSrcweir                 if( ! aOption.EqualsAscii( "*nil" ) )
2098cdf0e10cSrcweir                     pValue = pKey->getValue( aOption );
2099cdf0e10cSrcweir                 m_aCurrentValues[ pKey ] = pValue;
2100cdf0e10cSrcweir #ifdef __DEBUG
2101cdf0e10cSrcweir                 fprintf( stderr, "PPDContext::rebuildFromStreamBuffer: read PPDKeyValue { %s, %s }\n", pKV->m_pKey->getKey().GetStr(), pKV->m_pCurrentValue ? pKV->m_pCurrentValue->m_aOption.GetStr() : "<nil>" );
2102cdf0e10cSrcweir #endif
2103cdf0e10cSrcweir             }
2104cdf0e10cSrcweir         }
2105cdf0e10cSrcweir         nBytes -= aLine.Len()+1;
2106cdf0e10cSrcweir         pRun += aLine.Len()+1;
2107cdf0e10cSrcweir     }
2108cdf0e10cSrcweir }
2109cdf0e10cSrcweir 
2110cdf0e10cSrcweir // -------------------------------------------------------------------
2111cdf0e10cSrcweir 
getRenderResolution() const2112cdf0e10cSrcweir int PPDContext::getRenderResolution() const
2113cdf0e10cSrcweir {
2114cdf0e10cSrcweir     // initialize to reasonable default, if parser is not set
2115cdf0e10cSrcweir     int nDPI = 300;
2116cdf0e10cSrcweir     if( m_pParser )
2117cdf0e10cSrcweir     {
2118cdf0e10cSrcweir         int nDPIx = 300, nDPIy = 300;
2119cdf0e10cSrcweir         const PPDKey* pKey = m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "Resolution" ) ) );
2120cdf0e10cSrcweir         if( pKey )
2121cdf0e10cSrcweir         {
2122cdf0e10cSrcweir             const PPDValue* pValue = getValue( pKey );
2123cdf0e10cSrcweir             if( pValue )
2124cdf0e10cSrcweir                 m_pParser->getResolutionFromString( pValue->m_aOption, nDPIx, nDPIy );
2125cdf0e10cSrcweir             else
2126cdf0e10cSrcweir                 m_pParser->getDefaultResolution( nDPIx, nDPIy );
2127cdf0e10cSrcweir         }
2128cdf0e10cSrcweir         else
2129cdf0e10cSrcweir             m_pParser->getDefaultResolution( nDPIx, nDPIy );
2130cdf0e10cSrcweir 
2131cdf0e10cSrcweir         nDPI = (nDPIx > nDPIy) ? nDPIx : nDPIy;
2132cdf0e10cSrcweir     }
2133cdf0e10cSrcweir     return  nDPI;
2134cdf0e10cSrcweir }
2135cdf0e10cSrcweir 
2136cdf0e10cSrcweir // -------------------------------------------------------------------
2137cdf0e10cSrcweir 
getPageSize(String & rPaper,int & rWidth,int & rHeight) const2138cdf0e10cSrcweir void PPDContext::getPageSize( String& rPaper, int& rWidth, int& rHeight ) const
2139cdf0e10cSrcweir {
2140cdf0e10cSrcweir     // initialize to reasonable default, if parser is not set
2141cdf0e10cSrcweir     rPaper  = String( RTL_CONSTASCII_USTRINGPARAM( "A4" ) );
2142cdf0e10cSrcweir     rWidth  = 595;
2143cdf0e10cSrcweir     rHeight = 842;
2144cdf0e10cSrcweir     if( m_pParser )
2145cdf0e10cSrcweir     {
2146cdf0e10cSrcweir         const PPDKey* pKey = m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "PageSize" ) ) );
2147cdf0e10cSrcweir         if( pKey )
2148cdf0e10cSrcweir         {
2149cdf0e10cSrcweir             const PPDValue* pValue = getValue( pKey );
2150cdf0e10cSrcweir             if( pValue )
2151cdf0e10cSrcweir             {
2152cdf0e10cSrcweir                 rPaper = pValue->m_aOption;
2153cdf0e10cSrcweir                 m_pParser->getPaperDimension( rPaper, rWidth, rHeight );
2154cdf0e10cSrcweir             }
2155cdf0e10cSrcweir             else
2156cdf0e10cSrcweir             {
2157cdf0e10cSrcweir                 rPaper = m_pParser->getDefaultPaperDimension();
2158cdf0e10cSrcweir                 m_pParser->getDefaultPaperDimension( rWidth, rHeight );
2159cdf0e10cSrcweir             }
2160cdf0e10cSrcweir         }
2161cdf0e10cSrcweir     }
2162cdf0e10cSrcweir }
2163