1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_vcl.hxx"
26*b1cdbd2cSJim Jagielski 
27*b1cdbd2cSJim Jagielski #include <unistd.h>
28*b1cdbd2cSJim Jagielski #include <sys/wait.h>
29*b1cdbd2cSJim Jagielski #include <signal.h>
30*b1cdbd2cSJim Jagielski 
31*b1cdbd2cSJim Jagielski #include "cupsmgr.hxx"
32*b1cdbd2cSJim Jagielski #include "vcl/fontmanager.hxx"
33*b1cdbd2cSJim Jagielski #include "vcl/strhelper.hxx"
34*b1cdbd2cSJim Jagielski 
35*b1cdbd2cSJim Jagielski #include "unx/saldata.hxx"
36*b1cdbd2cSJim Jagielski 
37*b1cdbd2cSJim Jagielski #include "tools/urlobj.hxx"
38*b1cdbd2cSJim Jagielski #include "tools/stream.hxx"
39*b1cdbd2cSJim Jagielski #include "tools/debug.hxx"
40*b1cdbd2cSJim Jagielski #include "tools/config.hxx"
41*b1cdbd2cSJim Jagielski 
42*b1cdbd2cSJim Jagielski #include "i18npool/paper.hxx"
43*b1cdbd2cSJim Jagielski 
44*b1cdbd2cSJim Jagielski #include "rtl/strbuf.hxx"
45*b1cdbd2cSJim Jagielski 
46*b1cdbd2cSJim Jagielski #include "osl/thread.hxx"
47*b1cdbd2cSJim Jagielski #include "osl/mutex.hxx"
48*b1cdbd2cSJim Jagielski #include "osl/process.h"
49*b1cdbd2cSJim Jagielski 
50*b1cdbd2cSJim Jagielski // filename of configuration files
51*b1cdbd2cSJim Jagielski #define PRINT_FILENAME  "psprint.conf"
52*b1cdbd2cSJim Jagielski // the group of the global defaults
53*b1cdbd2cSJim Jagielski #define GLOBAL_DEFAULTS_GROUP "__Global_Printer_Defaults__"
54*b1cdbd2cSJim Jagielski 
55*b1cdbd2cSJim Jagielski #include <hash_set>
56*b1cdbd2cSJim Jagielski 
57*b1cdbd2cSJim Jagielski using namespace psp;
58*b1cdbd2cSJim Jagielski using namespace rtl;
59*b1cdbd2cSJim Jagielski using namespace osl;
60*b1cdbd2cSJim Jagielski 
61*b1cdbd2cSJim Jagielski namespace psp
62*b1cdbd2cSJim Jagielski {
63*b1cdbd2cSJim Jagielski     class SystemQueueInfo : public Thread
64*b1cdbd2cSJim Jagielski     {
65*b1cdbd2cSJim Jagielski         mutable Mutex               m_aMutex;
66*b1cdbd2cSJim Jagielski         bool                        m_bChanged;
67*b1cdbd2cSJim Jagielski         std::list< PrinterInfoManager::SystemPrintQueue >
68*b1cdbd2cSJim Jagielski                                     m_aQueues;
69*b1cdbd2cSJim Jagielski         OUString                    m_aCommand;
70*b1cdbd2cSJim Jagielski 
71*b1cdbd2cSJim Jagielski         virtual void run();
72*b1cdbd2cSJim Jagielski 
73*b1cdbd2cSJim Jagielski         public:
74*b1cdbd2cSJim Jagielski         SystemQueueInfo();
75*b1cdbd2cSJim Jagielski         ~SystemQueueInfo();
76*b1cdbd2cSJim Jagielski 
77*b1cdbd2cSJim Jagielski         bool hasChanged() const;
78*b1cdbd2cSJim Jagielski         OUString getCommand() const;
79*b1cdbd2cSJim Jagielski 
80*b1cdbd2cSJim Jagielski         // sets changed status to false; therefore not const
81*b1cdbd2cSJim Jagielski         void getSystemQueues( std::list< PrinterInfoManager::SystemPrintQueue >& rQueues );
82*b1cdbd2cSJim Jagielski     };
83*b1cdbd2cSJim Jagielski } // namespace
84*b1cdbd2cSJim Jagielski 
85*b1cdbd2cSJim Jagielski /*
86*b1cdbd2cSJim Jagielski *  class PrinterInfoManager
87*b1cdbd2cSJim Jagielski */
88*b1cdbd2cSJim Jagielski 
89*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------
90*b1cdbd2cSJim Jagielski 
get()91*b1cdbd2cSJim Jagielski PrinterInfoManager& PrinterInfoManager::get()
92*b1cdbd2cSJim Jagielski {
93*b1cdbd2cSJim Jagielski     SalData* pSalData = GetSalData();
94*b1cdbd2cSJim Jagielski 
95*b1cdbd2cSJim Jagielski     if( ! pSalData->m_pPIManager )
96*b1cdbd2cSJim Jagielski     {
97*b1cdbd2cSJim Jagielski         pSalData->m_pPIManager = CUPSManager::tryLoadCUPS();
98*b1cdbd2cSJim Jagielski         if( ! pSalData->m_pPIManager )
99*b1cdbd2cSJim Jagielski             pSalData->m_pPIManager = new PrinterInfoManager();
100*b1cdbd2cSJim Jagielski 
101*b1cdbd2cSJim Jagielski         pSalData->m_pPIManager->initialize();
102*b1cdbd2cSJim Jagielski         #if OSL_DEBUG_LEVEL > 1
103*b1cdbd2cSJim Jagielski         fprintf( stderr, "PrinterInfoManager::get create Manager of type %d\n", pSalData->m_pPIManager->getType() );
104*b1cdbd2cSJim Jagielski         #endif
105*b1cdbd2cSJim Jagielski     }
106*b1cdbd2cSJim Jagielski 
107*b1cdbd2cSJim Jagielski     return *pSalData->m_pPIManager;
108*b1cdbd2cSJim Jagielski }
109*b1cdbd2cSJim Jagielski 
release()110*b1cdbd2cSJim Jagielski void PrinterInfoManager::release()
111*b1cdbd2cSJim Jagielski {
112*b1cdbd2cSJim Jagielski     SalData* pSalData = GetSalData();
113*b1cdbd2cSJim Jagielski     delete pSalData->m_pPIManager;
114*b1cdbd2cSJim Jagielski     pSalData->m_pPIManager = NULL;
115*b1cdbd2cSJim Jagielski }
116*b1cdbd2cSJim Jagielski 
117*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------
118*b1cdbd2cSJim Jagielski 
PrinterInfoManager(Type eType)119*b1cdbd2cSJim Jagielski PrinterInfoManager::PrinterInfoManager( Type eType ) :
120*b1cdbd2cSJim Jagielski     m_pQueueInfo( NULL ),
121*b1cdbd2cSJim Jagielski     m_eType( eType ),
122*b1cdbd2cSJim Jagielski     m_bUseIncludeFeature( false ),
123*b1cdbd2cSJim Jagielski     m_bUseJobPatch( true ),
124*b1cdbd2cSJim Jagielski     m_aSystemDefaultPaper( RTL_CONSTASCII_USTRINGPARAM( "A4" ) ),
125*b1cdbd2cSJim Jagielski     m_bDisableCUPS( false )
126*b1cdbd2cSJim Jagielski {
127*b1cdbd2cSJim Jagielski     if( eType == Default )
128*b1cdbd2cSJim Jagielski         m_pQueueInfo = new SystemQueueInfo();
129*b1cdbd2cSJim Jagielski     initSystemDefaultPaper();
130*b1cdbd2cSJim Jagielski }
131*b1cdbd2cSJim Jagielski 
132*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------
133*b1cdbd2cSJim Jagielski 
~PrinterInfoManager()134*b1cdbd2cSJim Jagielski PrinterInfoManager::~PrinterInfoManager()
135*b1cdbd2cSJim Jagielski {
136*b1cdbd2cSJim Jagielski     delete m_pQueueInfo;
137*b1cdbd2cSJim Jagielski     #if OSL_DEBUG_LEVEL > 1
138*b1cdbd2cSJim Jagielski     fprintf( stderr, "PrinterInfoManager: destroyed Manager of type %d\n", getType() );
139*b1cdbd2cSJim Jagielski     #endif
140*b1cdbd2cSJim Jagielski }
141*b1cdbd2cSJim Jagielski 
142*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------
143*b1cdbd2cSJim Jagielski 
isCUPSDisabled() const144*b1cdbd2cSJim Jagielski bool PrinterInfoManager::isCUPSDisabled() const
145*b1cdbd2cSJim Jagielski {
146*b1cdbd2cSJim Jagielski     return m_bDisableCUPS;
147*b1cdbd2cSJim Jagielski }
148*b1cdbd2cSJim Jagielski 
149*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------
150*b1cdbd2cSJim Jagielski 
setCUPSDisabled(bool bDisable)151*b1cdbd2cSJim Jagielski void PrinterInfoManager::setCUPSDisabled( bool bDisable )
152*b1cdbd2cSJim Jagielski {
153*b1cdbd2cSJim Jagielski     m_bDisableCUPS = bDisable;
154*b1cdbd2cSJim Jagielski     writePrinterConfig();
155*b1cdbd2cSJim Jagielski     // actually we know the printers changed
156*b1cdbd2cSJim Jagielski     // however this triggers reinitialization the right way
157*b1cdbd2cSJim Jagielski     checkPrintersChanged( true );
158*b1cdbd2cSJim Jagielski }
159*b1cdbd2cSJim Jagielski 
160*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------
161*b1cdbd2cSJim Jagielski 
initSystemDefaultPaper()162*b1cdbd2cSJim Jagielski void PrinterInfoManager::initSystemDefaultPaper()
163*b1cdbd2cSJim Jagielski {
164*b1cdbd2cSJim Jagielski     m_aSystemDefaultPaper = rtl::OStringToOUString(
165*b1cdbd2cSJim Jagielski         PaperInfo::toPSName(PaperInfo::getSystemDefaultPaper().getPaper()),
166*b1cdbd2cSJim Jagielski         RTL_TEXTENCODING_UTF8);
167*b1cdbd2cSJim Jagielski }
168*b1cdbd2cSJim Jagielski 
169*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------
170*b1cdbd2cSJim Jagielski 
checkPrintersChanged(bool bWait)171*b1cdbd2cSJim Jagielski bool PrinterInfoManager::checkPrintersChanged( bool bWait )
172*b1cdbd2cSJim Jagielski {
173*b1cdbd2cSJim Jagielski     // check if files were created, deleted or modified since initialize()
174*b1cdbd2cSJim Jagielski     ::std::list< WatchFile >::const_iterator it;
175*b1cdbd2cSJim Jagielski     bool bChanged = false;
176*b1cdbd2cSJim Jagielski     for( it = m_aWatchFiles.begin(); it != m_aWatchFiles.end() && ! bChanged; ++it )
177*b1cdbd2cSJim Jagielski     {
178*b1cdbd2cSJim Jagielski         DirectoryItem aItem;
179*b1cdbd2cSJim Jagielski         if( DirectoryItem::get( it->m_aFilePath, aItem ) )
180*b1cdbd2cSJim Jagielski         {
181*b1cdbd2cSJim Jagielski             if( it->m_aModified.Seconds != 0 )
182*b1cdbd2cSJim Jagielski                 bChanged = true; // file probably has vanished
183*b1cdbd2cSJim Jagielski         }
184*b1cdbd2cSJim Jagielski         else
185*b1cdbd2cSJim Jagielski         {
186*b1cdbd2cSJim Jagielski             FileStatus aStatus( FileStatusMask_ModifyTime );
187*b1cdbd2cSJim Jagielski             if( aItem.getFileStatus( aStatus ) )
188*b1cdbd2cSJim Jagielski                 bChanged = true; // unlikely but not impossible
189*b1cdbd2cSJim Jagielski             else
190*b1cdbd2cSJim Jagielski             {
191*b1cdbd2cSJim Jagielski                 TimeValue aModified = aStatus.getModifyTime();
192*b1cdbd2cSJim Jagielski                 if( aModified.Seconds != it->m_aModified.Seconds )
193*b1cdbd2cSJim Jagielski                     bChanged = true;
194*b1cdbd2cSJim Jagielski             }
195*b1cdbd2cSJim Jagielski         }
196*b1cdbd2cSJim Jagielski     }
197*b1cdbd2cSJim Jagielski 
198*b1cdbd2cSJim Jagielski     if( bWait && m_pQueueInfo )
199*b1cdbd2cSJim Jagielski     {
200*b1cdbd2cSJim Jagielski         #if OSL_DEBUG_LEVEL > 1
201*b1cdbd2cSJim Jagielski         fprintf( stderr, "syncing printer discovery thread\n" );
202*b1cdbd2cSJim Jagielski         #endif
203*b1cdbd2cSJim Jagielski         m_pQueueInfo->join();
204*b1cdbd2cSJim Jagielski         #if OSL_DEBUG_LEVEL > 1
205*b1cdbd2cSJim Jagielski         fprintf( stderr, "done: syncing printer discovery thread\n" );
206*b1cdbd2cSJim Jagielski         #endif
207*b1cdbd2cSJim Jagielski     }
208*b1cdbd2cSJim Jagielski 
209*b1cdbd2cSJim Jagielski     if( ! bChanged && m_pQueueInfo )
210*b1cdbd2cSJim Jagielski         bChanged = m_pQueueInfo->hasChanged();
211*b1cdbd2cSJim Jagielski     if( bChanged )
212*b1cdbd2cSJim Jagielski     {
213*b1cdbd2cSJim Jagielski         initialize();
214*b1cdbd2cSJim Jagielski     }
215*b1cdbd2cSJim Jagielski 
216*b1cdbd2cSJim Jagielski     return bChanged;
217*b1cdbd2cSJim Jagielski }
218*b1cdbd2cSJim Jagielski 
219*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------
220*b1cdbd2cSJim Jagielski 
initialize()221*b1cdbd2cSJim Jagielski void PrinterInfoManager::initialize()
222*b1cdbd2cSJim Jagielski {
223*b1cdbd2cSJim Jagielski     m_bUseIncludeFeature = false;
224*b1cdbd2cSJim Jagielski     rtl_TextEncoding aEncoding = gsl_getSystemTextEncoding();
225*b1cdbd2cSJim Jagielski     m_aPrinters.clear();
226*b1cdbd2cSJim Jagielski     m_aWatchFiles.clear();
227*b1cdbd2cSJim Jagielski     OUString aDefaultPrinter;
228*b1cdbd2cSJim Jagielski 
229*b1cdbd2cSJim Jagielski     // first initialize the global defaults
230*b1cdbd2cSJim Jagielski     // have to iterate over all possible files
231*b1cdbd2cSJim Jagielski     // there should be only one global setup section in all
232*b1cdbd2cSJim Jagielski     // available config files
233*b1cdbd2cSJim Jagielski     m_aGlobalDefaults = PrinterInfo();
234*b1cdbd2cSJim Jagielski 
235*b1cdbd2cSJim Jagielski     // need a parser for the PPDContext. generic printer should do.
236*b1cdbd2cSJim Jagielski     m_aGlobalDefaults.m_pParser = PPDParser::getParser( String( RTL_CONSTASCII_USTRINGPARAM( "SGENPRT" ) ) );
237*b1cdbd2cSJim Jagielski     m_aGlobalDefaults.m_aContext.setParser( m_aGlobalDefaults.m_pParser );
238*b1cdbd2cSJim Jagielski     m_aGlobalDefaults.m_bPerformFontSubstitution = true;
239*b1cdbd2cSJim Jagielski     m_bDisableCUPS = false;
240*b1cdbd2cSJim Jagielski 
241*b1cdbd2cSJim Jagielski     if( ! m_aGlobalDefaults.m_pParser )
242*b1cdbd2cSJim Jagielski     {
243*b1cdbd2cSJim Jagielski         #if OSL_DEBUG_LEVEL > 1
244*b1cdbd2cSJim Jagielski         fprintf( stderr, "Error: no default PPD file SGENPRT available, shutting down psprint...\n" );
245*b1cdbd2cSJim Jagielski         #endif
246*b1cdbd2cSJim Jagielski         return;
247*b1cdbd2cSJim Jagielski     }
248*b1cdbd2cSJim Jagielski 
249*b1cdbd2cSJim Jagielski     std::list< OUString > aDirList;
250*b1cdbd2cSJim Jagielski     psp::getPrinterPathList( aDirList, NULL );
251*b1cdbd2cSJim Jagielski     std::list< OUString >::const_iterator print_dir_it;
252*b1cdbd2cSJim Jagielski     for( print_dir_it = aDirList.begin(); print_dir_it != aDirList.end(); ++print_dir_it )
253*b1cdbd2cSJim Jagielski     {
254*b1cdbd2cSJim Jagielski         INetURLObject aFile( *print_dir_it, INET_PROT_FILE, INetURLObject::ENCODE_ALL );
255*b1cdbd2cSJim Jagielski         aFile.Append( String( RTL_CONSTASCII_USTRINGPARAM( PRINT_FILENAME ) ) );
256*b1cdbd2cSJim Jagielski         Config aConfig( aFile.PathToFileName() );
257*b1cdbd2cSJim Jagielski         if( aConfig.HasGroup( GLOBAL_DEFAULTS_GROUP ) )
258*b1cdbd2cSJim Jagielski         {
259*b1cdbd2cSJim Jagielski             #if OSL_DEBUG_LEVEL > 1
260*b1cdbd2cSJim Jagielski             fprintf( stderr, "found global defaults in %s\n", OUStringToOString( aFile.PathToFileName(), RTL_TEXTENCODING_ISO_8859_1 ).getStr() );
261*b1cdbd2cSJim Jagielski             #endif
262*b1cdbd2cSJim Jagielski             aConfig.SetGroup( GLOBAL_DEFAULTS_GROUP );
263*b1cdbd2cSJim Jagielski 
264*b1cdbd2cSJim Jagielski             ByteString aValue( aConfig.ReadKey( "Copies" ) );
265*b1cdbd2cSJim Jagielski             if( aValue.Len() )
266*b1cdbd2cSJim Jagielski                 m_aGlobalDefaults.m_nCopies = aValue.ToInt32();
267*b1cdbd2cSJim Jagielski 
268*b1cdbd2cSJim Jagielski             aValue = aConfig.ReadKey( "Orientation" );
269*b1cdbd2cSJim Jagielski             if( aValue.Len() )
270*b1cdbd2cSJim Jagielski                 m_aGlobalDefaults.m_eOrientation = aValue.EqualsIgnoreCaseAscii( "Landscape" ) ? orientation::Landscape : orientation::Portrait;
271*b1cdbd2cSJim Jagielski 
272*b1cdbd2cSJim Jagielski             aValue = aConfig.ReadKey( "MarginAdjust" );
273*b1cdbd2cSJim Jagielski             if( aValue.Len() )
274*b1cdbd2cSJim Jagielski             {
275*b1cdbd2cSJim Jagielski                 m_aGlobalDefaults.m_nLeftMarginAdjust   = aValue.GetToken( 0, ',' ).ToInt32();
276*b1cdbd2cSJim Jagielski                 m_aGlobalDefaults.m_nRightMarginAdjust  = aValue.GetToken( 1, ',' ).ToInt32();
277*b1cdbd2cSJim Jagielski                 m_aGlobalDefaults.m_nTopMarginAdjust    = aValue.GetToken( 2, ',' ).ToInt32();
278*b1cdbd2cSJim Jagielski                 m_aGlobalDefaults.m_nBottomMarginAdjust = aValue.GetToken( 3, ',' ).ToInt32();
279*b1cdbd2cSJim Jagielski             }
280*b1cdbd2cSJim Jagielski 
281*b1cdbd2cSJim Jagielski             aValue = aConfig.ReadKey( "ColorDepth", "24" );
282*b1cdbd2cSJim Jagielski             if( aValue.Len() )
283*b1cdbd2cSJim Jagielski                 m_aGlobalDefaults.m_nColorDepth = aValue.ToInt32();
284*b1cdbd2cSJim Jagielski 
285*b1cdbd2cSJim Jagielski             aValue = aConfig.ReadKey( "ColorDevice" );
286*b1cdbd2cSJim Jagielski             if( aValue.Len() )
287*b1cdbd2cSJim Jagielski                 m_aGlobalDefaults.m_nColorDevice = aValue.ToInt32();
288*b1cdbd2cSJim Jagielski 
289*b1cdbd2cSJim Jagielski             aValue = aConfig.ReadKey( "PSLevel" );
290*b1cdbd2cSJim Jagielski             if( aValue.Len() )
291*b1cdbd2cSJim Jagielski                 m_aGlobalDefaults.m_nPSLevel = aValue.ToInt32();
292*b1cdbd2cSJim Jagielski 
293*b1cdbd2cSJim Jagielski             aValue = aConfig.ReadKey( "PDFDevice" );
294*b1cdbd2cSJim Jagielski             if( aValue.Len() )
295*b1cdbd2cSJim Jagielski                 m_aGlobalDefaults.m_nPDFDevice = aValue.ToInt32();
296*b1cdbd2cSJim Jagielski 
297*b1cdbd2cSJim Jagielski             aValue = aConfig.ReadKey( "PerformFontSubstitution" );
298*b1cdbd2cSJim Jagielski             if( aValue.Len() )
299*b1cdbd2cSJim Jagielski             {
300*b1cdbd2cSJim Jagielski                 if( ! aValue.Equals( "0" ) && ! aValue.EqualsIgnoreCaseAscii( "false" ) )
301*b1cdbd2cSJim Jagielski                     m_aGlobalDefaults.m_bPerformFontSubstitution = true;
302*b1cdbd2cSJim Jagielski                 else
303*b1cdbd2cSJim Jagielski                     m_aGlobalDefaults.m_bPerformFontSubstitution = false;
304*b1cdbd2cSJim Jagielski             }
305*b1cdbd2cSJim Jagielski 
306*b1cdbd2cSJim Jagielski             aValue = aConfig.ReadKey( "DisableCUPS" );
307*b1cdbd2cSJim Jagielski             if( aValue.Len() )
308*b1cdbd2cSJim Jagielski             {
309*b1cdbd2cSJim Jagielski                 if( aValue.Equals( "1" ) || aValue.EqualsIgnoreCaseAscii( "true" ) )
310*b1cdbd2cSJim Jagielski                     m_bDisableCUPS = true;
311*b1cdbd2cSJim Jagielski                 else
312*b1cdbd2cSJim Jagielski                     m_bDisableCUPS = false;
313*b1cdbd2cSJim Jagielski             }
314*b1cdbd2cSJim Jagielski 
315*b1cdbd2cSJim Jagielski             // get the PPDContext of global JobData
316*b1cdbd2cSJim Jagielski             for( int nKey = 0; nKey < aConfig.GetKeyCount(); nKey++ )
317*b1cdbd2cSJim Jagielski             {
318*b1cdbd2cSJim Jagielski                 ByteString aKey( aConfig.GetKeyName( nKey ) );
319*b1cdbd2cSJim Jagielski                 if( aKey.CompareTo( "PPD_", 4 ) == COMPARE_EQUAL )
320*b1cdbd2cSJim Jagielski                 {
321*b1cdbd2cSJim Jagielski                     aValue = aConfig.ReadKey( aKey );
322*b1cdbd2cSJim Jagielski                     const PPDKey* pKey = m_aGlobalDefaults.m_pParser->getKey( String( aKey.Copy( 4 ), RTL_TEXTENCODING_ISO_8859_1 ) );
323*b1cdbd2cSJim Jagielski                     if( pKey )
324*b1cdbd2cSJim Jagielski                     {
325*b1cdbd2cSJim Jagielski                         m_aGlobalDefaults.m_aContext.
326*b1cdbd2cSJim Jagielski                         setValue( pKey,
327*b1cdbd2cSJim Jagielski                         aValue.Equals( "*nil" ) ? NULL : pKey->getValue( String( aValue, RTL_TEXTENCODING_ISO_8859_1 ) ),
328*b1cdbd2cSJim Jagielski                         sal_True );
329*b1cdbd2cSJim Jagielski                     }
330*b1cdbd2cSJim Jagielski                 }
331*b1cdbd2cSJim Jagielski                 else if( aKey.Len() > 10 && aKey.CompareTo("SubstFont_", 10 ) == COMPARE_EQUAL )
332*b1cdbd2cSJim Jagielski                 {
333*b1cdbd2cSJim Jagielski                     aValue = aConfig.ReadKey( aKey );
334*b1cdbd2cSJim Jagielski                     m_aGlobalDefaults.m_aFontSubstitutes[ OStringToOUString( aKey.Copy( 10 ), RTL_TEXTENCODING_ISO_8859_1 ) ] = OStringToOUString( aValue, RTL_TEXTENCODING_ISO_8859_1 );
335*b1cdbd2cSJim Jagielski                 }
336*b1cdbd2cSJim Jagielski             }
337*b1cdbd2cSJim Jagielski             #if OSL_DEBUG_LEVEL > 1
338*b1cdbd2cSJim Jagielski             fprintf( stderr, "global settings: fontsubst = %s, %d substitutes\n", m_aGlobalDefaults.m_bPerformFontSubstitution ? "true" : "false", (int)m_aGlobalDefaults.m_aFontSubstitutes.size() );
339*b1cdbd2cSJim Jagielski             #endif
340*b1cdbd2cSJim Jagielski         }
341*b1cdbd2cSJim Jagielski     }
342*b1cdbd2cSJim Jagielski     setDefaultPaper( m_aGlobalDefaults.m_aContext );
343*b1cdbd2cSJim Jagielski     fillFontSubstitutions( m_aGlobalDefaults );
344*b1cdbd2cSJim Jagielski 
345*b1cdbd2cSJim Jagielski     // now collect all available printers
346*b1cdbd2cSJim Jagielski     for( print_dir_it = aDirList.begin(); print_dir_it != aDirList.end(); ++print_dir_it )
347*b1cdbd2cSJim Jagielski     {
348*b1cdbd2cSJim Jagielski         INetURLObject aDir( *print_dir_it, INET_PROT_FILE, INetURLObject::ENCODE_ALL );
349*b1cdbd2cSJim Jagielski         INetURLObject aFile( aDir );
350*b1cdbd2cSJim Jagielski         aFile.Append( String( RTL_CONSTASCII_USTRINGPARAM( PRINT_FILENAME ) ) );
351*b1cdbd2cSJim Jagielski 
352*b1cdbd2cSJim Jagielski         // check directory validity
353*b1cdbd2cSJim Jagielski         OUString aUniPath;
354*b1cdbd2cSJim Jagielski         FileBase::getFileURLFromSystemPath( aDir.PathToFileName(), aUniPath );
355*b1cdbd2cSJim Jagielski         Directory aDirectory( aUniPath );
356*b1cdbd2cSJim Jagielski         if( aDirectory.open() )
357*b1cdbd2cSJim Jagielski             continue;
358*b1cdbd2cSJim Jagielski         aDirectory.close();
359*b1cdbd2cSJim Jagielski 
360*b1cdbd2cSJim Jagielski 
361*b1cdbd2cSJim Jagielski         FileBase::getFileURLFromSystemPath( aFile.PathToFileName(), aUniPath );
362*b1cdbd2cSJim Jagielski         FileStatus aStatus( FileStatusMask_ModifyTime );
363*b1cdbd2cSJim Jagielski         DirectoryItem aItem;
364*b1cdbd2cSJim Jagielski 
365*b1cdbd2cSJim Jagielski         // setup WatchFile list
366*b1cdbd2cSJim Jagielski         WatchFile aWatchFile;
367*b1cdbd2cSJim Jagielski         aWatchFile.m_aFilePath = aUniPath;
368*b1cdbd2cSJim Jagielski         if( ! DirectoryItem::get( aUniPath, aItem ) &&
369*b1cdbd2cSJim Jagielski             ! aItem.getFileStatus( aStatus ) )
370*b1cdbd2cSJim Jagielski         {
371*b1cdbd2cSJim Jagielski             aWatchFile.m_aModified = aStatus.getModifyTime();
372*b1cdbd2cSJim Jagielski         }
373*b1cdbd2cSJim Jagielski         else
374*b1cdbd2cSJim Jagielski         {
375*b1cdbd2cSJim Jagielski             aWatchFile.m_aModified.Seconds = 0;
376*b1cdbd2cSJim Jagielski             aWatchFile.m_aModified.Nanosec = 0;
377*b1cdbd2cSJim Jagielski         }
378*b1cdbd2cSJim Jagielski         m_aWatchFiles.push_back( aWatchFile );
379*b1cdbd2cSJim Jagielski 
380*b1cdbd2cSJim Jagielski         Config aConfig( aFile.PathToFileName() );
381*b1cdbd2cSJim Jagielski         for( int nGroup = 0; nGroup < aConfig.GetGroupCount(); nGroup++ )
382*b1cdbd2cSJim Jagielski         {
383*b1cdbd2cSJim Jagielski             aConfig.SetGroup( aConfig.GetGroupName( nGroup ) );
384*b1cdbd2cSJim Jagielski             ByteString aValue = aConfig.ReadKey( "Printer" );
385*b1cdbd2cSJim Jagielski             if( aValue.Len() )
386*b1cdbd2cSJim Jagielski             {
387*b1cdbd2cSJim Jagielski                 OUString aPrinterName;
388*b1cdbd2cSJim Jagielski 
389*b1cdbd2cSJim Jagielski                 int nNamePos = aValue.Search( '/' );
390*b1cdbd2cSJim Jagielski                 // check for valid value of "Printer"
391*b1cdbd2cSJim Jagielski                 if( nNamePos == STRING_NOTFOUND )
392*b1cdbd2cSJim Jagielski                     continue;
393*b1cdbd2cSJim Jagielski 
394*b1cdbd2cSJim Jagielski                 Printer aPrinter;
395*b1cdbd2cSJim Jagielski                 // initialize to global defaults
396*b1cdbd2cSJim Jagielski                 aPrinter.m_aInfo = m_aGlobalDefaults;
397*b1cdbd2cSJim Jagielski                 // global settings do not default the printer substitution
398*b1cdbd2cSJim Jagielski                 // list ! the substitution list in there is only used for
399*b1cdbd2cSJim Jagielski                 // newly created printers
400*b1cdbd2cSJim Jagielski                 aPrinter.m_aInfo.m_aFontSubstitutes.clear();
401*b1cdbd2cSJim Jagielski                 aPrinter.m_aInfo.m_aFontSubstitutions.clear();
402*b1cdbd2cSJim Jagielski 
403*b1cdbd2cSJim Jagielski                 aPrinterName = String( aValue.Copy( nNamePos+1 ), RTL_TEXTENCODING_UTF8 );
404*b1cdbd2cSJim Jagielski                 aPrinter.m_aInfo.m_aPrinterName     = aPrinterName;
405*b1cdbd2cSJim Jagielski                 aPrinter.m_aInfo.m_aDriverName      = String( aValue.Copy( 0, nNamePos ), RTL_TEXTENCODING_UTF8 );
406*b1cdbd2cSJim Jagielski 
407*b1cdbd2cSJim Jagielski                 // set parser, merge settings
408*b1cdbd2cSJim Jagielski                 // don't do this for CUPS printers as this is done
409*b1cdbd2cSJim Jagielski                 // by the CUPS system itself
410*b1cdbd2cSJim Jagielski                 if( aPrinter.m_aInfo.m_aDriverName.compareToAscii( "CUPS:", 5 ) != 0 )
411*b1cdbd2cSJim Jagielski                 {
412*b1cdbd2cSJim Jagielski                     aPrinter.m_aInfo.m_pParser          = PPDParser::getParser( aPrinter.m_aInfo.m_aDriverName );
413*b1cdbd2cSJim Jagielski                     aPrinter.m_aInfo.m_aContext.setParser( aPrinter.m_aInfo.m_pParser );
414*b1cdbd2cSJim Jagielski                     // note: setParser also purges the context
415*b1cdbd2cSJim Jagielski 
416*b1cdbd2cSJim Jagielski                     // ignore this printer if its driver is not found
417*b1cdbd2cSJim Jagielski                     if( ! aPrinter.m_aInfo.m_pParser )
418*b1cdbd2cSJim Jagielski                         continue;
419*b1cdbd2cSJim Jagielski 
420*b1cdbd2cSJim Jagielski                     // merge the ppd context keys if the printer has the same keys and values
421*b1cdbd2cSJim Jagielski                     // this is a bit tricky, since it involves mixing two PPDs
422*b1cdbd2cSJim Jagielski                     // without constraints which might end up badly
423*b1cdbd2cSJim Jagielski                     // this feature should be use with caution
424*b1cdbd2cSJim Jagielski                     // it is mainly to select default paper sizes for new printers
425*b1cdbd2cSJim Jagielski                     for( int nPPDValueModified = 0; nPPDValueModified < m_aGlobalDefaults.m_aContext.countValuesModified(); nPPDValueModified++ )
426*b1cdbd2cSJim Jagielski                     {
427*b1cdbd2cSJim Jagielski                         const PPDKey* pDefKey = m_aGlobalDefaults.m_aContext.getModifiedKey( nPPDValueModified );
428*b1cdbd2cSJim Jagielski                         const PPDValue* pDefValue = m_aGlobalDefaults.m_aContext.getValue( pDefKey );
429*b1cdbd2cSJim Jagielski                         const PPDKey* pPrinterKey = pDefKey ? aPrinter.m_aInfo.m_pParser->getKey( pDefKey->getKey() ) : NULL;
430*b1cdbd2cSJim Jagielski                         if( pDefKey && pPrinterKey )
431*b1cdbd2cSJim Jagielski                             // at least the options exist in both PPDs
432*b1cdbd2cSJim Jagielski                         {
433*b1cdbd2cSJim Jagielski                             if( pDefValue )
434*b1cdbd2cSJim Jagielski                             {
435*b1cdbd2cSJim Jagielski                                 const PPDValue* pPrinterValue = pPrinterKey->getValue( pDefValue->m_aOption );
436*b1cdbd2cSJim Jagielski                                 if( pPrinterValue )
437*b1cdbd2cSJim Jagielski                                     // the printer has a corresponding option for the key
438*b1cdbd2cSJim Jagielski                                 aPrinter.m_aInfo.m_aContext.setValue( pPrinterKey, pPrinterValue );
439*b1cdbd2cSJim Jagielski                             }
440*b1cdbd2cSJim Jagielski                             else
441*b1cdbd2cSJim Jagielski                                 aPrinter.m_aInfo.m_aContext.setValue( pPrinterKey, NULL );
442*b1cdbd2cSJim Jagielski                         }
443*b1cdbd2cSJim Jagielski                     }
444*b1cdbd2cSJim Jagielski 
445*b1cdbd2cSJim Jagielski                     aValue = aConfig.ReadKey( "Command" );
446*b1cdbd2cSJim Jagielski                     // no printer without a command
447*b1cdbd2cSJim Jagielski                     if( ! aValue.Len() )
448*b1cdbd2cSJim Jagielski                     {
449*b1cdbd2cSJim Jagielski                         /*  TODO:
450*b1cdbd2cSJim Jagielski                         *  porters: please append your platform to the Solaris
451*b1cdbd2cSJim Jagielski                         *  case if your platform has SystemV printing per default.
452*b1cdbd2cSJim Jagielski                         */
453*b1cdbd2cSJim Jagielski                         #if defined SOLARIS
454*b1cdbd2cSJim Jagielski                         aValue = "lp";
455*b1cdbd2cSJim Jagielski                         #else
456*b1cdbd2cSJim Jagielski                         aValue = "lpr";
457*b1cdbd2cSJim Jagielski                         #endif
458*b1cdbd2cSJim Jagielski                     }
459*b1cdbd2cSJim Jagielski                     aPrinter.m_aInfo.m_aCommand = String( aValue, RTL_TEXTENCODING_UTF8 );
460*b1cdbd2cSJim Jagielski                 }
461*b1cdbd2cSJim Jagielski 
462*b1cdbd2cSJim Jagielski                 aValue = aConfig.ReadKey( "QuickCommand" );
463*b1cdbd2cSJim Jagielski                 aPrinter.m_aInfo.m_aQuickCommand = String( aValue, RTL_TEXTENCODING_UTF8 );
464*b1cdbd2cSJim Jagielski 
465*b1cdbd2cSJim Jagielski                 aValue = aConfig.ReadKey( "Features" );
466*b1cdbd2cSJim Jagielski                 aPrinter.m_aInfo.m_aFeatures = String( aValue, RTL_TEXTENCODING_UTF8 );
467*b1cdbd2cSJim Jagielski 
468*b1cdbd2cSJim Jagielski                 // override the settings in m_aGlobalDefaults if keys exist
469*b1cdbd2cSJim Jagielski                 aValue = aConfig.ReadKey( "DefaultPrinter" );
470*b1cdbd2cSJim Jagielski                 if( ! aValue.Equals( "0" ) && ! aValue.EqualsIgnoreCaseAscii( "false" ) )
471*b1cdbd2cSJim Jagielski                     aDefaultPrinter = aPrinterName;
472*b1cdbd2cSJim Jagielski 
473*b1cdbd2cSJim Jagielski                 aValue = aConfig.ReadKey( "Location" );
474*b1cdbd2cSJim Jagielski                 aPrinter.m_aInfo.m_aLocation = String( aValue, RTL_TEXTENCODING_UTF8 );
475*b1cdbd2cSJim Jagielski 
476*b1cdbd2cSJim Jagielski                 aValue = aConfig.ReadKey( "Comment" );
477*b1cdbd2cSJim Jagielski                 aPrinter.m_aInfo.m_aComment = String( aValue, RTL_TEXTENCODING_UTF8 );
478*b1cdbd2cSJim Jagielski 
479*b1cdbd2cSJim Jagielski                 aValue = aConfig.ReadKey( "Copies" );
480*b1cdbd2cSJim Jagielski                 if( aValue.Len() )
481*b1cdbd2cSJim Jagielski                     aPrinter.m_aInfo.m_nCopies = aValue.ToInt32();
482*b1cdbd2cSJim Jagielski 
483*b1cdbd2cSJim Jagielski                 aValue = aConfig.ReadKey( "Orientation" );
484*b1cdbd2cSJim Jagielski                 if( aValue.Len() )
485*b1cdbd2cSJim Jagielski                     aPrinter.m_aInfo.m_eOrientation = aValue.EqualsIgnoreCaseAscii( "Landscape" ) ? orientation::Landscape : orientation::Portrait;
486*b1cdbd2cSJim Jagielski 
487*b1cdbd2cSJim Jagielski                 aValue = aConfig.ReadKey( "MarginAdjust" );
488*b1cdbd2cSJim Jagielski                 if( aValue.Len() )
489*b1cdbd2cSJim Jagielski                 {
490*b1cdbd2cSJim Jagielski                     aPrinter.m_aInfo.m_nLeftMarginAdjust    = aValue.GetToken( 0, ',' ).ToInt32();
491*b1cdbd2cSJim Jagielski                     aPrinter.m_aInfo.m_nRightMarginAdjust   = aValue.GetToken( 1, ',' ).ToInt32();
492*b1cdbd2cSJim Jagielski                     aPrinter.m_aInfo.m_nTopMarginAdjust     = aValue.GetToken( 2, ',' ).ToInt32();
493*b1cdbd2cSJim Jagielski                     aPrinter.m_aInfo.m_nBottomMarginAdjust  = aValue.GetToken( 3, ',' ).ToInt32();
494*b1cdbd2cSJim Jagielski                 }
495*b1cdbd2cSJim Jagielski 
496*b1cdbd2cSJim Jagielski                 aValue = aConfig.ReadKey( "ColorDepth" );
497*b1cdbd2cSJim Jagielski                 if( aValue.Len() )
498*b1cdbd2cSJim Jagielski                     aPrinter.m_aInfo.m_nColorDepth = aValue.ToInt32();
499*b1cdbd2cSJim Jagielski 
500*b1cdbd2cSJim Jagielski                 aValue = aConfig.ReadKey( "ColorDevice" );
501*b1cdbd2cSJim Jagielski                 if( aValue.Len() )
502*b1cdbd2cSJim Jagielski                     aPrinter.m_aInfo.m_nColorDevice = aValue.ToInt32();
503*b1cdbd2cSJim Jagielski 
504*b1cdbd2cSJim Jagielski                 aValue = aConfig.ReadKey( "PSLevel" );
505*b1cdbd2cSJim Jagielski                 if( aValue.Len() )
506*b1cdbd2cSJim Jagielski                     aPrinter.m_aInfo.m_nPSLevel = aValue.ToInt32();
507*b1cdbd2cSJim Jagielski 
508*b1cdbd2cSJim Jagielski                 aValue = aConfig.ReadKey( "PDFDevice" );
509*b1cdbd2cSJim Jagielski                 if( aValue.Len() )
510*b1cdbd2cSJim Jagielski                     aPrinter.m_aInfo.m_nPDFDevice = aValue.ToInt32();
511*b1cdbd2cSJim Jagielski 
512*b1cdbd2cSJim Jagielski                 aValue = aConfig.ReadKey( "PerformFontSubstitution" );
513*b1cdbd2cSJim Jagielski                 if( ! aValue.Equals( "0" ) && ! aValue.EqualsIgnoreCaseAscii( "false" ) )
514*b1cdbd2cSJim Jagielski                     aPrinter.m_aInfo.m_bPerformFontSubstitution = true;
515*b1cdbd2cSJim Jagielski                 else
516*b1cdbd2cSJim Jagielski                     aPrinter.m_aInfo.m_bPerformFontSubstitution = false;
517*b1cdbd2cSJim Jagielski 
518*b1cdbd2cSJim Jagielski                 // now iterate over all keys to extract multi key information:
519*b1cdbd2cSJim Jagielski                 // 1. PPDContext information
520*b1cdbd2cSJim Jagielski                 // 2. Font substitution table
521*b1cdbd2cSJim Jagielski                 for( int nKey = 0; nKey < aConfig.GetKeyCount(); nKey++ )
522*b1cdbd2cSJim Jagielski                 {
523*b1cdbd2cSJim Jagielski                     ByteString aKey( aConfig.GetKeyName( nKey ) );
524*b1cdbd2cSJim Jagielski                     if( aKey.CompareTo( "PPD_", 4 ) == COMPARE_EQUAL && aPrinter.m_aInfo.m_pParser )
525*b1cdbd2cSJim Jagielski                     {
526*b1cdbd2cSJim Jagielski                         aValue = aConfig.ReadKey( aKey );
527*b1cdbd2cSJim Jagielski                         const PPDKey* pKey = aPrinter.m_aInfo.m_pParser->getKey( String( aKey.Copy( 4 ), RTL_TEXTENCODING_ISO_8859_1 ) );
528*b1cdbd2cSJim Jagielski                         if( pKey )
529*b1cdbd2cSJim Jagielski                         {
530*b1cdbd2cSJim Jagielski                             aPrinter.m_aInfo.m_aContext.
531*b1cdbd2cSJim Jagielski                             setValue( pKey,
532*b1cdbd2cSJim Jagielski                             aValue.Equals( "*nil" ) ? NULL : pKey->getValue( String( aValue, RTL_TEXTENCODING_ISO_8859_1 ) ),
533*b1cdbd2cSJim Jagielski                             sal_True );
534*b1cdbd2cSJim Jagielski                         }
535*b1cdbd2cSJim Jagielski                     }
536*b1cdbd2cSJim Jagielski                     else if( aKey.Len() > 10 && aKey.CompareTo("SubstFont_", 10 ) == COMPARE_EQUAL )
537*b1cdbd2cSJim Jagielski                     {
538*b1cdbd2cSJim Jagielski                         aValue = aConfig.ReadKey( aKey );
539*b1cdbd2cSJim Jagielski                         aPrinter.m_aInfo.m_aFontSubstitutes[ OStringToOUString( aKey.Copy( 10 ), RTL_TEXTENCODING_ISO_8859_1 ) ] = OStringToOUString( aValue, RTL_TEXTENCODING_ISO_8859_1 );
540*b1cdbd2cSJim Jagielski                     }
541*b1cdbd2cSJim Jagielski                 }
542*b1cdbd2cSJim Jagielski 
543*b1cdbd2cSJim Jagielski                 setDefaultPaper( aPrinter.m_aInfo.m_aContext );
544*b1cdbd2cSJim Jagielski                 fillFontSubstitutions( aPrinter.m_aInfo );
545*b1cdbd2cSJim Jagielski 
546*b1cdbd2cSJim Jagielski                 // finally insert printer
547*b1cdbd2cSJim Jagielski                 FileBase::getFileURLFromSystemPath( aFile.PathToFileName(), aPrinter.m_aFile );
548*b1cdbd2cSJim Jagielski                 aPrinter.m_bModified    = false;
549*b1cdbd2cSJim Jagielski                 aPrinter.m_aGroup       = aConfig.GetGroupName( nGroup );
550*b1cdbd2cSJim Jagielski                 std::hash_map< OUString, Printer, OUStringHash >::const_iterator find_it =
551*b1cdbd2cSJim Jagielski                 m_aPrinters.find( aPrinterName );
552*b1cdbd2cSJim Jagielski                 if( find_it != m_aPrinters.end() )
553*b1cdbd2cSJim Jagielski                 {
554*b1cdbd2cSJim Jagielski                     aPrinter.m_aAlternateFiles = find_it->second.m_aAlternateFiles;
555*b1cdbd2cSJim Jagielski                     aPrinter.m_aAlternateFiles.push_front( find_it->second.m_aFile );
556*b1cdbd2cSJim Jagielski                 }
557*b1cdbd2cSJim Jagielski                 m_aPrinters[ aPrinterName ] = aPrinter;
558*b1cdbd2cSJim Jagielski             }
559*b1cdbd2cSJim Jagielski         }
560*b1cdbd2cSJim Jagielski     }
561*b1cdbd2cSJim Jagielski 
562*b1cdbd2cSJim Jagielski     // set default printer
563*b1cdbd2cSJim Jagielski     if( m_aPrinters.size() )
564*b1cdbd2cSJim Jagielski     {
565*b1cdbd2cSJim Jagielski         if( m_aPrinters.find( aDefaultPrinter ) == m_aPrinters.end() )
566*b1cdbd2cSJim Jagielski             aDefaultPrinter = m_aPrinters.begin()->first;
567*b1cdbd2cSJim Jagielski     }
568*b1cdbd2cSJim Jagielski     else
569*b1cdbd2cSJim Jagielski         aDefaultPrinter = OUString();
570*b1cdbd2cSJim Jagielski     m_aDefaultPrinter = aDefaultPrinter;
571*b1cdbd2cSJim Jagielski 
572*b1cdbd2cSJim Jagielski     if( m_eType != Default )
573*b1cdbd2cSJim Jagielski         return;
574*b1cdbd2cSJim Jagielski 
575*b1cdbd2cSJim Jagielski     // add a default printer for every available print queue
576*b1cdbd2cSJim Jagielski     // merge paper and font substitution from default printer,
577*b1cdbd2cSJim Jagielski     // all else from global defaults
578*b1cdbd2cSJim Jagielski     PrinterInfo aMergeInfo( m_aGlobalDefaults );
579*b1cdbd2cSJim Jagielski     aMergeInfo.m_aDriverName    = String( RTL_CONSTASCII_USTRINGPARAM( "SGENPRT" ) );
580*b1cdbd2cSJim Jagielski     aMergeInfo.m_aFeatures      = String( RTL_CONSTASCII_USTRINGPARAM( "autoqueue" ) );
581*b1cdbd2cSJim Jagielski 
582*b1cdbd2cSJim Jagielski     if( m_aDefaultPrinter.getLength() )
583*b1cdbd2cSJim Jagielski     {
584*b1cdbd2cSJim Jagielski         PrinterInfo aDefaultInfo( getPrinterInfo( m_aDefaultPrinter ) );
585*b1cdbd2cSJim Jagielski         aMergeInfo.m_bPerformFontSubstitution = aDefaultInfo.m_bPerformFontSubstitution;
586*b1cdbd2cSJim Jagielski         fillFontSubstitutions( aMergeInfo );
587*b1cdbd2cSJim Jagielski 
588*b1cdbd2cSJim Jagielski         const PPDKey* pDefKey           = aDefaultInfo.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "PageSize" ) ) );
589*b1cdbd2cSJim Jagielski         const PPDKey* pMergeKey         = aMergeInfo.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "PageSize" ) ) );
590*b1cdbd2cSJim Jagielski         const PPDValue* pDefValue       = aDefaultInfo.m_aContext.getValue( pDefKey );
591*b1cdbd2cSJim Jagielski         const PPDValue* pMergeValue     = pMergeKey ? pMergeKey->getValue( pDefValue->m_aOption ) : NULL;
592*b1cdbd2cSJim Jagielski         if( pMergeKey && pMergeValue )
593*b1cdbd2cSJim Jagielski             aMergeInfo.m_aContext.setValue( pMergeKey, pMergeValue );
594*b1cdbd2cSJim Jagielski     }
595*b1cdbd2cSJim Jagielski 
596*b1cdbd2cSJim Jagielski     getSystemPrintQueues();
597*b1cdbd2cSJim Jagielski     for( ::std::list< SystemPrintQueue >::iterator it = m_aSystemPrintQueues.begin(); it != m_aSystemPrintQueues.end(); ++it )
598*b1cdbd2cSJim Jagielski     {
599*b1cdbd2cSJim Jagielski         String aPrinterName( RTL_CONSTASCII_USTRINGPARAM( "<" ) );
600*b1cdbd2cSJim Jagielski         aPrinterName += String( it->m_aQueue );
601*b1cdbd2cSJim Jagielski         aPrinterName.Append( '>' );
602*b1cdbd2cSJim Jagielski 
603*b1cdbd2cSJim Jagielski         if( m_aPrinters.find( aPrinterName ) != m_aPrinters.end() )
604*b1cdbd2cSJim Jagielski             // probably user made this one permanent in padmin
605*b1cdbd2cSJim Jagielski         continue;
606*b1cdbd2cSJim Jagielski 
607*b1cdbd2cSJim Jagielski         String aCmd( m_aSystemPrintCommand );
608*b1cdbd2cSJim Jagielski         aCmd.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "(PRINTER)" ) ), it->m_aQueue );
609*b1cdbd2cSJim Jagielski 
610*b1cdbd2cSJim Jagielski         Printer aPrinter;
611*b1cdbd2cSJim Jagielski 
612*b1cdbd2cSJim Jagielski         // initialize to merged defaults
613*b1cdbd2cSJim Jagielski         aPrinter.m_aInfo = aMergeInfo;
614*b1cdbd2cSJim Jagielski         aPrinter.m_aInfo.m_aPrinterName     = aPrinterName;
615*b1cdbd2cSJim Jagielski         aPrinter.m_aInfo.m_aCommand         = aCmd;
616*b1cdbd2cSJim Jagielski         aPrinter.m_aInfo.m_aComment         = it->m_aComment;
617*b1cdbd2cSJim Jagielski         aPrinter.m_aInfo.m_aLocation        = it->m_aLocation;
618*b1cdbd2cSJim Jagielski         aPrinter.m_bModified                = false;
619*b1cdbd2cSJim Jagielski         aPrinter.m_aGroup                   = ByteString( aPrinterName, aEncoding ); //provide group name in case user makes this one permanent in padmin
620*b1cdbd2cSJim Jagielski 
621*b1cdbd2cSJim Jagielski         m_aPrinters[ aPrinterName ] = aPrinter;
622*b1cdbd2cSJim Jagielski     }
623*b1cdbd2cSJim Jagielski }
624*b1cdbd2cSJim Jagielski 
625*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------
626*b1cdbd2cSJim Jagielski 
listPrinters(::std::list<OUString> & rList) const627*b1cdbd2cSJim Jagielski void PrinterInfoManager::listPrinters( ::std::list< OUString >& rList ) const
628*b1cdbd2cSJim Jagielski {
629*b1cdbd2cSJim Jagielski     ::std::hash_map< OUString, Printer, OUStringHash >::const_iterator it;
630*b1cdbd2cSJim Jagielski     rList.clear();
631*b1cdbd2cSJim Jagielski     for( it = m_aPrinters.begin(); it != m_aPrinters.end(); ++it )
632*b1cdbd2cSJim Jagielski         rList.push_back( it->first );
633*b1cdbd2cSJim Jagielski }
634*b1cdbd2cSJim Jagielski 
635*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------
636*b1cdbd2cSJim Jagielski 
getPrinterInfo(const OUString & rPrinter) const637*b1cdbd2cSJim Jagielski const PrinterInfo& PrinterInfoManager::getPrinterInfo( const OUString& rPrinter ) const
638*b1cdbd2cSJim Jagielski {
639*b1cdbd2cSJim Jagielski     static PrinterInfo aEmptyInfo;
640*b1cdbd2cSJim Jagielski     ::std::hash_map< OUString, Printer, OUStringHash >::const_iterator it = m_aPrinters.find( rPrinter );
641*b1cdbd2cSJim Jagielski 
642*b1cdbd2cSJim Jagielski     DBG_ASSERT( it != m_aPrinters.end(), "Do not ask for info about nonexistent printers" );
643*b1cdbd2cSJim Jagielski 
644*b1cdbd2cSJim Jagielski     return it != m_aPrinters.end() ? it->second.m_aInfo : aEmptyInfo;
645*b1cdbd2cSJim Jagielski }
646*b1cdbd2cSJim Jagielski 
647*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------
648*b1cdbd2cSJim Jagielski 
changePrinterInfo(const OUString & rPrinter,const PrinterInfo & rNewInfo)649*b1cdbd2cSJim Jagielski void PrinterInfoManager::changePrinterInfo( const OUString& rPrinter, const PrinterInfo& rNewInfo )
650*b1cdbd2cSJim Jagielski {
651*b1cdbd2cSJim Jagielski     ::std::hash_map< OUString, Printer, OUStringHash >::iterator it = m_aPrinters.find( rPrinter );
652*b1cdbd2cSJim Jagielski 
653*b1cdbd2cSJim Jagielski     DBG_ASSERT( it != m_aPrinters.end(), "Do not change nonexistant printers" );
654*b1cdbd2cSJim Jagielski 
655*b1cdbd2cSJim Jagielski     if( it != m_aPrinters.end() )
656*b1cdbd2cSJim Jagielski     {
657*b1cdbd2cSJim Jagielski         it->second.m_aInfo      = rNewInfo;
658*b1cdbd2cSJim Jagielski         // recalculate font substitutions
659*b1cdbd2cSJim Jagielski         fillFontSubstitutions( it->second.m_aInfo );
660*b1cdbd2cSJim Jagielski         it->second.m_bModified  = true;
661*b1cdbd2cSJim Jagielski         writePrinterConfig();
662*b1cdbd2cSJim Jagielski     }
663*b1cdbd2cSJim Jagielski }
664*b1cdbd2cSJim Jagielski 
665*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------
666*b1cdbd2cSJim Jagielski 
667*b1cdbd2cSJim Jagielski // need to check writeability / creatability of config files
checkWriteability(const OUString & rUniPath)668*b1cdbd2cSJim Jagielski static bool checkWriteability( const OUString& rUniPath )
669*b1cdbd2cSJim Jagielski {
670*b1cdbd2cSJim Jagielski     bool bRet = false;
671*b1cdbd2cSJim Jagielski     OUString aSysPath;
672*b1cdbd2cSJim Jagielski     FileBase::getSystemPathFromFileURL( rUniPath, aSysPath );
673*b1cdbd2cSJim Jagielski     SvFileStream aStream( aSysPath, STREAM_READ | STREAM_WRITE );
674*b1cdbd2cSJim Jagielski     if( aStream.IsOpen() && aStream.IsWritable() )
675*b1cdbd2cSJim Jagielski         bRet = true;
676*b1cdbd2cSJim Jagielski     return bRet;
677*b1cdbd2cSJim Jagielski }
678*b1cdbd2cSJim Jagielski 
writePrinterConfig()679*b1cdbd2cSJim Jagielski bool PrinterInfoManager::writePrinterConfig()
680*b1cdbd2cSJim Jagielski {
681*b1cdbd2cSJim Jagielski     // find at least one writeable config
682*b1cdbd2cSJim Jagielski     ::std::hash_map< OUString, Config*, OUStringHash > files;
683*b1cdbd2cSJim Jagielski     ::std::hash_map< OUString, int, OUStringHash > rofiles;
684*b1cdbd2cSJim Jagielski     ::std::hash_map< OUString, Config*, OUStringHash >::iterator file_it;
685*b1cdbd2cSJim Jagielski 
686*b1cdbd2cSJim Jagielski     for( ::std::list< WatchFile >::const_iterator wit = m_aWatchFiles.begin(); wit != m_aWatchFiles.end(); ++wit )
687*b1cdbd2cSJim Jagielski     {
688*b1cdbd2cSJim Jagielski         if( checkWriteability( wit->m_aFilePath ) )
689*b1cdbd2cSJim Jagielski         {
690*b1cdbd2cSJim Jagielski             files[ wit->m_aFilePath ] = new Config( wit->m_aFilePath );
691*b1cdbd2cSJim Jagielski             break;
692*b1cdbd2cSJim Jagielski         }
693*b1cdbd2cSJim Jagielski     }
694*b1cdbd2cSJim Jagielski 
695*b1cdbd2cSJim Jagielski     if( files.empty() )
696*b1cdbd2cSJim Jagielski         return false;
697*b1cdbd2cSJim Jagielski 
698*b1cdbd2cSJim Jagielski     Config* pGlobal = files.begin()->second;
699*b1cdbd2cSJim Jagielski     pGlobal->SetGroup( GLOBAL_DEFAULTS_GROUP );
700*b1cdbd2cSJim Jagielski     pGlobal->WriteKey( "DisableCUPS", m_bDisableCUPS ? "true" : "false" );
701*b1cdbd2cSJim Jagielski 
702*b1cdbd2cSJim Jagielski     ::std::hash_map< OUString, Printer, OUStringHash >::iterator it;
703*b1cdbd2cSJim Jagielski     for( it = m_aPrinters.begin(); it != m_aPrinters.end(); ++it )
704*b1cdbd2cSJim Jagielski     {
705*b1cdbd2cSJim Jagielski         if( ! it->second.m_bModified )
706*b1cdbd2cSJim Jagielski             // printer was not changed, do nothing
707*b1cdbd2cSJim Jagielski         continue;
708*b1cdbd2cSJim Jagielski 
709*b1cdbd2cSJim Jagielski         // don't save autoqueue printers
710*b1cdbd2cSJim Jagielski         sal_Int32 nIndex = 0;
711*b1cdbd2cSJim Jagielski         bool bAutoQueue = false;
712*b1cdbd2cSJim Jagielski         while( nIndex != -1 && ! bAutoQueue )
713*b1cdbd2cSJim Jagielski         {
714*b1cdbd2cSJim Jagielski             OUString aToken( it->second.m_aInfo.m_aFeatures.getToken( 0, ',', nIndex ) );
715*b1cdbd2cSJim Jagielski             if( aToken.getLength() && aToken.compareToAscii( "autoqueue" ) == 0 )
716*b1cdbd2cSJim Jagielski                 bAutoQueue = true;
717*b1cdbd2cSJim Jagielski         }
718*b1cdbd2cSJim Jagielski         if( bAutoQueue )
719*b1cdbd2cSJim Jagielski             continue;
720*b1cdbd2cSJim Jagielski 
721*b1cdbd2cSJim Jagielski         if( it->second.m_aFile.getLength() )
722*b1cdbd2cSJim Jagielski         {
723*b1cdbd2cSJim Jagielski             // check if file is writable
724*b1cdbd2cSJim Jagielski             if( files.find( it->second.m_aFile ) == files.end() )
725*b1cdbd2cSJim Jagielski             {
726*b1cdbd2cSJim Jagielski                 bool bInsertToNewFile = false;
727*b1cdbd2cSJim Jagielski                 // maybe it is simply not inserted yet
728*b1cdbd2cSJim Jagielski                 if( rofiles.find( it->second.m_aFile ) == rofiles.end() )
729*b1cdbd2cSJim Jagielski                 {
730*b1cdbd2cSJim Jagielski                     if( checkWriteability( it->second.m_aFile ) )
731*b1cdbd2cSJim Jagielski                         files[ it->second.m_aFile ] = new Config( it->second.m_aFile );
732*b1cdbd2cSJim Jagielski                     else
733*b1cdbd2cSJim Jagielski                         bInsertToNewFile = true;
734*b1cdbd2cSJim Jagielski                 }
735*b1cdbd2cSJim Jagielski                 else
736*b1cdbd2cSJim Jagielski                     bInsertToNewFile = true;
737*b1cdbd2cSJim Jagielski                 // original file is read only, insert printer in a new writeable file
738*b1cdbd2cSJim Jagielski                 if( bInsertToNewFile )
739*b1cdbd2cSJim Jagielski                 {
740*b1cdbd2cSJim Jagielski                     rofiles[ it->second.m_aFile ] = 1;
741*b1cdbd2cSJim Jagielski                     // update alternate file list
742*b1cdbd2cSJim Jagielski                     // the remove operation ensures uniqueness of each alternate
743*b1cdbd2cSJim Jagielski                     it->second.m_aAlternateFiles.remove( it->second.m_aFile );
744*b1cdbd2cSJim Jagielski                     it->second.m_aAlternateFiles.remove( files.begin()->first );
745*b1cdbd2cSJim Jagielski                     it->second.m_aAlternateFiles.push_front( it->second.m_aFile );
746*b1cdbd2cSJim Jagielski                     // update file
747*b1cdbd2cSJim Jagielski                     it->second.m_aFile = files.begin()->first;
748*b1cdbd2cSJim Jagielski                 }
749*b1cdbd2cSJim Jagielski             }
750*b1cdbd2cSJim Jagielski         }
751*b1cdbd2cSJim Jagielski         else // a new printer, write it to the first file available
752*b1cdbd2cSJim Jagielski             it->second.m_aFile = files.begin()->first;
753*b1cdbd2cSJim Jagielski 
754*b1cdbd2cSJim Jagielski         if( ! it->second.m_aGroup.getLength() ) // probably a new printer
755*b1cdbd2cSJim Jagielski             it->second.m_aGroup = OString( it->first.getStr(), it->first.getLength(), RTL_TEXTENCODING_UTF8 );
756*b1cdbd2cSJim Jagielski 
757*b1cdbd2cSJim Jagielski         if( files.find( it->second.m_aFile ) != files.end() )
758*b1cdbd2cSJim Jagielski         {
759*b1cdbd2cSJim Jagielski             Config* pConfig = files[ it->second.m_aFile ];
760*b1cdbd2cSJim Jagielski             pConfig->DeleteGroup( it->second.m_aGroup ); // else some old keys may remain
761*b1cdbd2cSJim Jagielski             pConfig->SetGroup( it->second.m_aGroup );
762*b1cdbd2cSJim Jagielski 
763*b1cdbd2cSJim Jagielski             ByteString aValue( String( it->second.m_aInfo.m_aDriverName ), RTL_TEXTENCODING_UTF8 );
764*b1cdbd2cSJim Jagielski             aValue += '/';
765*b1cdbd2cSJim Jagielski             aValue += ByteString( String( it->first ), RTL_TEXTENCODING_UTF8 );
766*b1cdbd2cSJim Jagielski             pConfig->WriteKey( "Printer", aValue );
767*b1cdbd2cSJim Jagielski             pConfig->WriteKey( "DefaultPrinter", it->first == m_aDefaultPrinter ? "1" : "0" );
768*b1cdbd2cSJim Jagielski             pConfig->WriteKey( "Location", ByteString( String( it->second.m_aInfo.m_aLocation ), RTL_TEXTENCODING_UTF8 ) );
769*b1cdbd2cSJim Jagielski             pConfig->WriteKey( "Comment", ByteString( String( it->second.m_aInfo.m_aComment ), RTL_TEXTENCODING_UTF8 ) );
770*b1cdbd2cSJim Jagielski             pConfig->WriteKey( "Command", ByteString( String( it->second.m_aInfo.m_aCommand ), RTL_TEXTENCODING_UTF8 ) );
771*b1cdbd2cSJim Jagielski             pConfig->WriteKey( "QuickCommand", ByteString( String( it->second.m_aInfo.m_aQuickCommand ), RTL_TEXTENCODING_UTF8 ) );
772*b1cdbd2cSJim Jagielski             pConfig->WriteKey( "Features", ByteString( String( it->second.m_aInfo.m_aFeatures ), RTL_TEXTENCODING_UTF8 ) );
773*b1cdbd2cSJim Jagielski             pConfig->WriteKey( "Copies", ByteString::CreateFromInt32( it->second.m_aInfo.m_nCopies ) );
774*b1cdbd2cSJim Jagielski             pConfig->WriteKey( "Orientation", it->second.m_aInfo.m_eOrientation == orientation::Landscape ? "Landscape" : "Portrait" );
775*b1cdbd2cSJim Jagielski             pConfig->WriteKey( "PSLevel", ByteString::CreateFromInt32( it->second.m_aInfo.m_nPSLevel ) );
776*b1cdbd2cSJim Jagielski             pConfig->WriteKey( "PDFDevice", ByteString::CreateFromInt32( it->second.m_aInfo.m_nPDFDevice ) );
777*b1cdbd2cSJim Jagielski             pConfig->WriteKey( "ColorDevice", ByteString::CreateFromInt32( it->second.m_aInfo.m_nColorDevice ) );
778*b1cdbd2cSJim Jagielski             pConfig->WriteKey( "ColorDepth", ByteString::CreateFromInt32( it->second.m_aInfo.m_nColorDepth ) );
779*b1cdbd2cSJim Jagielski             aValue = ByteString::CreateFromInt32( it->second.m_aInfo.m_nLeftMarginAdjust );
780*b1cdbd2cSJim Jagielski             aValue += ',';
781*b1cdbd2cSJim Jagielski             aValue += ByteString::CreateFromInt32( it->second.m_aInfo.m_nRightMarginAdjust );
782*b1cdbd2cSJim Jagielski             aValue += ',';
783*b1cdbd2cSJim Jagielski             aValue += ByteString::CreateFromInt32( it->second.m_aInfo.m_nTopMarginAdjust );
784*b1cdbd2cSJim Jagielski             aValue += ',';
785*b1cdbd2cSJim Jagielski             aValue += ByteString::CreateFromInt32( it->second.m_aInfo.m_nBottomMarginAdjust );
786*b1cdbd2cSJim Jagielski             pConfig->WriteKey( "MarginAdjust", aValue );
787*b1cdbd2cSJim Jagielski 
788*b1cdbd2cSJim Jagielski             if( it->second.m_aInfo.m_aDriverName.compareToAscii( "CUPS:", 5 ) != 0 )
789*b1cdbd2cSJim Jagielski             {
790*b1cdbd2cSJim Jagielski                 // write PPDContext (not for CUPS)
791*b1cdbd2cSJim Jagielski                 for( int i = 0; i < it->second.m_aInfo.m_aContext.countValuesModified(); i++ )
792*b1cdbd2cSJim Jagielski                 {
793*b1cdbd2cSJim Jagielski                     const PPDKey* pKey = it->second.m_aInfo.m_aContext.getModifiedKey( i );
794*b1cdbd2cSJim Jagielski                     ByteString aKey( "PPD_" );
795*b1cdbd2cSJim Jagielski                     aKey += ByteString( pKey->getKey(), RTL_TEXTENCODING_ISO_8859_1 );
796*b1cdbd2cSJim Jagielski 
797*b1cdbd2cSJim Jagielski                     const PPDValue* pValue = it->second.m_aInfo.m_aContext.getValue( pKey );
798*b1cdbd2cSJim Jagielski                     aValue = pValue ? ByteString( pValue->m_aOption, RTL_TEXTENCODING_ISO_8859_1 ) : ByteString( "*nil" );
799*b1cdbd2cSJim Jagielski                     pConfig->WriteKey( aKey, aValue );
800*b1cdbd2cSJim Jagielski                 }
801*b1cdbd2cSJim Jagielski             }
802*b1cdbd2cSJim Jagielski 
803*b1cdbd2cSJim Jagielski             // write font substitution table
804*b1cdbd2cSJim Jagielski             pConfig->WriteKey( "PerformFontSubstitution", it->second.m_aInfo.m_bPerformFontSubstitution ? "true" : "false" );
805*b1cdbd2cSJim Jagielski             for( ::std::hash_map< OUString, OUString, OUStringHash >::const_iterator subst = it->second.m_aInfo.m_aFontSubstitutes.begin();
806*b1cdbd2cSJim Jagielski             subst != it->second.m_aInfo.m_aFontSubstitutes.end(); ++subst )
807*b1cdbd2cSJim Jagielski             {
808*b1cdbd2cSJim Jagielski                 ByteString aKey( "SubstFont_" );
809*b1cdbd2cSJim Jagielski                 aKey.Append( OUStringToOString( subst->first, RTL_TEXTENCODING_ISO_8859_1 ).getStr() );
810*b1cdbd2cSJim Jagielski                 pConfig->WriteKey( aKey, OUStringToOString( subst->second, RTL_TEXTENCODING_ISO_8859_1 ) );
811*b1cdbd2cSJim Jagielski             }
812*b1cdbd2cSJim Jagielski         }
813*b1cdbd2cSJim Jagielski     }
814*b1cdbd2cSJim Jagielski 
815*b1cdbd2cSJim Jagielski     // get rid of Config objects. this also writes any changes
816*b1cdbd2cSJim Jagielski     for( file_it = files.begin(); file_it != files.end(); ++file_it )
817*b1cdbd2cSJim Jagielski         delete file_it->second;
818*b1cdbd2cSJim Jagielski 
819*b1cdbd2cSJim Jagielski     return true;
820*b1cdbd2cSJim Jagielski }
821*b1cdbd2cSJim Jagielski 
822*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------
823*b1cdbd2cSJim Jagielski 
addPrinter(const OUString & rPrinterName,const OUString & rDriverName)824*b1cdbd2cSJim Jagielski bool PrinterInfoManager::addPrinter( const OUString& rPrinterName, const OUString& rDriverName )
825*b1cdbd2cSJim Jagielski {
826*b1cdbd2cSJim Jagielski     bool bSuccess = false;
827*b1cdbd2cSJim Jagielski 
828*b1cdbd2cSJim Jagielski     const PPDParser* pParser = NULL;
829*b1cdbd2cSJim Jagielski     if( m_aPrinters.find( rPrinterName ) == m_aPrinters.end() && ( pParser = PPDParser::getParser( rDriverName ) ) )
830*b1cdbd2cSJim Jagielski     {
831*b1cdbd2cSJim Jagielski         Printer aPrinter;
832*b1cdbd2cSJim Jagielski         aPrinter.m_bModified                        = true;
833*b1cdbd2cSJim Jagielski         aPrinter.m_aInfo                            = m_aGlobalDefaults;
834*b1cdbd2cSJim Jagielski         aPrinter.m_aInfo.m_aDriverName              = rDriverName;
835*b1cdbd2cSJim Jagielski         aPrinter.m_aInfo.m_pParser                  = pParser;
836*b1cdbd2cSJim Jagielski         aPrinter.m_aInfo.m_aContext.setParser( pParser );
837*b1cdbd2cSJim Jagielski         aPrinter.m_aInfo.m_aPrinterName             = rPrinterName;
838*b1cdbd2cSJim Jagielski 
839*b1cdbd2cSJim Jagielski         fillFontSubstitutions( aPrinter.m_aInfo );
840*b1cdbd2cSJim Jagielski         // merge PPD values with global defaults
841*b1cdbd2cSJim Jagielski         for( int nPPDValueModified = 0; nPPDValueModified < m_aGlobalDefaults.m_aContext.countValuesModified(); nPPDValueModified++ )
842*b1cdbd2cSJim Jagielski         {
843*b1cdbd2cSJim Jagielski             const PPDKey* pDefKey = m_aGlobalDefaults.m_aContext.getModifiedKey( nPPDValueModified );
844*b1cdbd2cSJim Jagielski             const PPDValue* pDefValue = m_aGlobalDefaults.m_aContext.getValue( pDefKey );
845*b1cdbd2cSJim Jagielski             const PPDKey* pPrinterKey = pDefKey ? aPrinter.m_aInfo.m_pParser->getKey( pDefKey->getKey() ) : NULL;
846*b1cdbd2cSJim Jagielski             if( pDefKey && pPrinterKey )
847*b1cdbd2cSJim Jagielski                 // at least the options exist in both PPDs
848*b1cdbd2cSJim Jagielski             {
849*b1cdbd2cSJim Jagielski                 if( pDefValue )
850*b1cdbd2cSJim Jagielski                 {
851*b1cdbd2cSJim Jagielski                     const PPDValue* pPrinterValue = pPrinterKey->getValue( pDefValue->m_aOption );
852*b1cdbd2cSJim Jagielski                     if( pPrinterValue )
853*b1cdbd2cSJim Jagielski                         // the printer has a corresponding option for the key
854*b1cdbd2cSJim Jagielski                     aPrinter.m_aInfo.m_aContext.setValue( pPrinterKey, pPrinterValue );
855*b1cdbd2cSJim Jagielski                 }
856*b1cdbd2cSJim Jagielski                 else
857*b1cdbd2cSJim Jagielski                     aPrinter.m_aInfo.m_aContext.setValue( pPrinterKey, NULL );
858*b1cdbd2cSJim Jagielski             }
859*b1cdbd2cSJim Jagielski         }
860*b1cdbd2cSJim Jagielski 
861*b1cdbd2cSJim Jagielski         m_aPrinters[ rPrinterName ] = aPrinter;
862*b1cdbd2cSJim Jagielski         bSuccess = true;
863*b1cdbd2cSJim Jagielski         #if OSL_DEBUG_LEVEL > 1
864*b1cdbd2cSJim Jagielski         fprintf( stderr, "new printer %s, level = %d, pdfdevice = %d, colordevice = %d, depth = %d\n",
865*b1cdbd2cSJim Jagielski         OUStringToOString( rPrinterName, osl_getThreadTextEncoding() ).getStr(),
866*b1cdbd2cSJim Jagielski         m_aPrinters[rPrinterName].m_aInfo.m_nPSLevel,
867*b1cdbd2cSJim Jagielski         m_aPrinters[rPrinterName].m_aInfo.m_nPDFDevice,
868*b1cdbd2cSJim Jagielski         m_aPrinters[rPrinterName].m_aInfo.m_nColorDevice,
869*b1cdbd2cSJim Jagielski         m_aPrinters[rPrinterName].m_aInfo.m_nColorDepth );
870*b1cdbd2cSJim Jagielski         #endif
871*b1cdbd2cSJim Jagielski         // comment: logically one should writePrinterConfig() here
872*b1cdbd2cSJim Jagielski         // but immediately after addPrinter() a changePrinterInfo()
873*b1cdbd2cSJim Jagielski         // will follow (see padmin code), which writes it again,
874*b1cdbd2cSJim Jagielski         // so we can currently save some performance here
875*b1cdbd2cSJim Jagielski     }
876*b1cdbd2cSJim Jagielski     return bSuccess;
877*b1cdbd2cSJim Jagielski }
878*b1cdbd2cSJim Jagielski 
879*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------
880*b1cdbd2cSJim Jagielski 
removePrinter(const OUString & rPrinterName,bool bCheckOnly)881*b1cdbd2cSJim Jagielski bool PrinterInfoManager::removePrinter( const OUString& rPrinterName, bool bCheckOnly )
882*b1cdbd2cSJim Jagielski {
883*b1cdbd2cSJim Jagielski     bool bSuccess = true;
884*b1cdbd2cSJim Jagielski 
885*b1cdbd2cSJim Jagielski     ::std::hash_map< OUString, Printer, OUStringHash >::iterator it = m_aPrinters.find( rPrinterName );
886*b1cdbd2cSJim Jagielski     if( it != m_aPrinters.end() )
887*b1cdbd2cSJim Jagielski     {
888*b1cdbd2cSJim Jagielski         if( it->second.m_aFile.getLength() )
889*b1cdbd2cSJim Jagielski         {
890*b1cdbd2cSJim Jagielski             // this printer already exists in a config file
891*b1cdbd2cSJim Jagielski 
892*b1cdbd2cSJim Jagielski 
893*b1cdbd2cSJim Jagielski             // check writeability of config file(s)
894*b1cdbd2cSJim Jagielski             if( ! checkWriteability( it->second.m_aFile ) )
895*b1cdbd2cSJim Jagielski                 bSuccess = false;
896*b1cdbd2cSJim Jagielski             else
897*b1cdbd2cSJim Jagielski             {
898*b1cdbd2cSJim Jagielski                 for( std::list< OUString >::const_iterator file_it = it->second.m_aAlternateFiles.begin();
899*b1cdbd2cSJim Jagielski                 file_it != it->second.m_aAlternateFiles.end() && bSuccess; ++file_it )
900*b1cdbd2cSJim Jagielski                 {
901*b1cdbd2cSJim Jagielski                     if( ! checkWriteability( *file_it ) )
902*b1cdbd2cSJim Jagielski                         bSuccess = false;
903*b1cdbd2cSJim Jagielski                 }
904*b1cdbd2cSJim Jagielski             }
905*b1cdbd2cSJim Jagielski             if( bSuccess && ! bCheckOnly )
906*b1cdbd2cSJim Jagielski             {
907*b1cdbd2cSJim Jagielski 
908*b1cdbd2cSJim Jagielski                 Config aConfig( it->second.m_aFile );
909*b1cdbd2cSJim Jagielski                 aConfig.DeleteGroup( it->second.m_aGroup );
910*b1cdbd2cSJim Jagielski                 aConfig.Flush();
911*b1cdbd2cSJim Jagielski                 for( std::list< OUString >::const_iterator file_it = it->second.m_aAlternateFiles.begin();
912*b1cdbd2cSJim Jagielski                 file_it != it->second.m_aAlternateFiles.end() && bSuccess; ++file_it )
913*b1cdbd2cSJim Jagielski                 {
914*b1cdbd2cSJim Jagielski                     Config aAltConfig( *file_it );
915*b1cdbd2cSJim Jagielski                     aAltConfig.DeleteGroup( it->second.m_aGroup );
916*b1cdbd2cSJim Jagielski                     aAltConfig.Flush();
917*b1cdbd2cSJim Jagielski                 }
918*b1cdbd2cSJim Jagielski             }
919*b1cdbd2cSJim Jagielski         }
920*b1cdbd2cSJim Jagielski         if( bSuccess && ! bCheckOnly )
921*b1cdbd2cSJim Jagielski         {
922*b1cdbd2cSJim Jagielski             m_aPrinters.erase( it );
923*b1cdbd2cSJim Jagielski             // need this here because someone may call
924*b1cdbd2cSJim Jagielski             // checkPrintersChanged after the removal
925*b1cdbd2cSJim Jagielski             // but then other added printers were not flushed
926*b1cdbd2cSJim Jagielski             // to disk, so they are discarded
927*b1cdbd2cSJim Jagielski             writePrinterConfig();
928*b1cdbd2cSJim Jagielski         }
929*b1cdbd2cSJim Jagielski     }
930*b1cdbd2cSJim Jagielski     return bSuccess;
931*b1cdbd2cSJim Jagielski }
932*b1cdbd2cSJim Jagielski 
933*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------
934*b1cdbd2cSJim Jagielski 
setDefaultPrinter(const OUString & rPrinterName)935*b1cdbd2cSJim Jagielski bool PrinterInfoManager::setDefaultPrinter( const OUString& rPrinterName )
936*b1cdbd2cSJim Jagielski {
937*b1cdbd2cSJim Jagielski     bool bSuccess = false;
938*b1cdbd2cSJim Jagielski 
939*b1cdbd2cSJim Jagielski     ::std::hash_map< OUString, Printer, OUStringHash >::iterator it = m_aPrinters.find( rPrinterName );
940*b1cdbd2cSJim Jagielski     if( it != m_aPrinters.end() )
941*b1cdbd2cSJim Jagielski     {
942*b1cdbd2cSJim Jagielski         bSuccess = true;
943*b1cdbd2cSJim Jagielski         it->second.m_bModified = true;
944*b1cdbd2cSJim Jagielski         if( ( it = m_aPrinters.find( m_aDefaultPrinter ) ) != m_aPrinters.end() )
945*b1cdbd2cSJim Jagielski             it->second.m_bModified = true;
946*b1cdbd2cSJim Jagielski         m_aDefaultPrinter = rPrinterName;
947*b1cdbd2cSJim Jagielski         writePrinterConfig();
948*b1cdbd2cSJim Jagielski     }
949*b1cdbd2cSJim Jagielski     return bSuccess;
950*b1cdbd2cSJim Jagielski }
951*b1cdbd2cSJim Jagielski 
952*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------
addOrRemovePossible() const953*b1cdbd2cSJim Jagielski bool PrinterInfoManager::addOrRemovePossible() const
954*b1cdbd2cSJim Jagielski {
955*b1cdbd2cSJim Jagielski     return true;
956*b1cdbd2cSJim Jagielski }
957*b1cdbd2cSJim Jagielski 
958*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------
959*b1cdbd2cSJim Jagielski 
fillFontSubstitutions(PrinterInfo & rInfo) const960*b1cdbd2cSJim Jagielski void PrinterInfoManager::fillFontSubstitutions( PrinterInfo& rInfo ) const
961*b1cdbd2cSJim Jagielski {
962*b1cdbd2cSJim Jagielski     PrintFontManager& rFontManager( PrintFontManager::get() );
963*b1cdbd2cSJim Jagielski     rInfo.m_aFontSubstitutions.clear();
964*b1cdbd2cSJim Jagielski 
965*b1cdbd2cSJim Jagielski     if( ! rInfo.m_bPerformFontSubstitution ||
966*b1cdbd2cSJim Jagielski         ! rInfo.m_aFontSubstitutes.size() )
967*b1cdbd2cSJim Jagielski     return;
968*b1cdbd2cSJim Jagielski 
969*b1cdbd2cSJim Jagielski     ::std::list< FastPrintFontInfo > aFonts;
970*b1cdbd2cSJim Jagielski     ::std::hash_map< OUString, ::std::list< FastPrintFontInfo >, OUStringHash > aPrinterFonts;
971*b1cdbd2cSJim Jagielski     rFontManager.getFontListWithFastInfo( aFonts, rInfo.m_pParser );
972*b1cdbd2cSJim Jagielski 
973*b1cdbd2cSJim Jagielski     // get builtin fonts
974*b1cdbd2cSJim Jagielski     ::std::list< FastPrintFontInfo >::const_iterator it;
975*b1cdbd2cSJim Jagielski     for( it = aFonts.begin(); it != aFonts.end(); ++it )
976*b1cdbd2cSJim Jagielski         if( it->m_eType == fonttype::Builtin )
977*b1cdbd2cSJim Jagielski             aPrinterFonts[ it->m_aFamilyName.toAsciiLowerCase() ].push_back( *it );
978*b1cdbd2cSJim Jagielski 
979*b1cdbd2cSJim Jagielski     // map lower case, so build a local copy of the font substitutions
980*b1cdbd2cSJim Jagielski     ::std::hash_map< OUString, OUString, OUStringHash > aSubstitutions;
981*b1cdbd2cSJim Jagielski     ::std::hash_map< OUString, OUString, OUStringHash >::const_iterator subst;
982*b1cdbd2cSJim Jagielski     for( subst = rInfo.m_aFontSubstitutes.begin(); subst != rInfo.m_aFontSubstitutes.end(); ++subst )
983*b1cdbd2cSJim Jagielski     {
984*b1cdbd2cSJim Jagielski         OUString aFamily( subst->first.toAsciiLowerCase() );
985*b1cdbd2cSJim Jagielski         // first look if there is a builtin of this family
986*b1cdbd2cSJim Jagielski         // in this case override the substitution table
987*b1cdbd2cSJim Jagielski         if( aPrinterFonts.find( aFamily ) != aPrinterFonts.end() )
988*b1cdbd2cSJim Jagielski             aSubstitutions[ aFamily ] = aFamily;
989*b1cdbd2cSJim Jagielski         else
990*b1cdbd2cSJim Jagielski             aSubstitutions[ aFamily ] = subst->second.toAsciiLowerCase();
991*b1cdbd2cSJim Jagielski     }
992*b1cdbd2cSJim Jagielski 
993*b1cdbd2cSJim Jagielski 
994*b1cdbd2cSJim Jagielski     // now find substitutions
995*b1cdbd2cSJim Jagielski     for( it = aFonts.begin(); it != aFonts.end(); ++it )
996*b1cdbd2cSJim Jagielski     {
997*b1cdbd2cSJim Jagielski         if( it->m_eType != fonttype::Builtin )
998*b1cdbd2cSJim Jagielski         {
999*b1cdbd2cSJim Jagielski             OUString aFamily( it->m_aFamilyName.toAsciiLowerCase() );
1000*b1cdbd2cSJim Jagielski             subst = aSubstitutions.find( aFamily );
1001*b1cdbd2cSJim Jagielski             if( subst != aSubstitutions.end() )
1002*b1cdbd2cSJim Jagielski             {
1003*b1cdbd2cSJim Jagielski                 // search a substitution
1004*b1cdbd2cSJim Jagielski                 const ::std::list< FastPrintFontInfo >& rBuiltins( aPrinterFonts[ aSubstitutions[ aFamily ] ] );
1005*b1cdbd2cSJim Jagielski                 ::std::list< FastPrintFontInfo >::const_iterator builtin;
1006*b1cdbd2cSJim Jagielski                 int nLastMatch = -10000;
1007*b1cdbd2cSJim Jagielski                 fontID nSubstitute = -1;
1008*b1cdbd2cSJim Jagielski                 for( builtin = rBuiltins.begin(); builtin != rBuiltins.end(); ++builtin )
1009*b1cdbd2cSJim Jagielski                 {
1010*b1cdbd2cSJim Jagielski                     int nMatch = 0;
1011*b1cdbd2cSJim Jagielski                     int nDiff;
1012*b1cdbd2cSJim Jagielski                     if( builtin->m_eItalic == it->m_eItalic )
1013*b1cdbd2cSJim Jagielski                         nMatch += 8000;
1014*b1cdbd2cSJim Jagielski 
1015*b1cdbd2cSJim Jagielski                     nDiff = builtin->m_eWeight - it->m_eWeight;
1016*b1cdbd2cSJim Jagielski                     nDiff = nDiff < 0 ? -nDiff : nDiff;
1017*b1cdbd2cSJim Jagielski                     nMatch += 4000 - 1000*nDiff;
1018*b1cdbd2cSJim Jagielski 
1019*b1cdbd2cSJim Jagielski                     nDiff = builtin->m_eWidth - it->m_eWidth;
1020*b1cdbd2cSJim Jagielski                     nDiff = nDiff < 0 ? -nDiff : nDiff;
1021*b1cdbd2cSJim Jagielski                     nMatch += 2000 - 500*nDiff;
1022*b1cdbd2cSJim Jagielski 
1023*b1cdbd2cSJim Jagielski                     if( nMatch > nLastMatch )
1024*b1cdbd2cSJim Jagielski                     {
1025*b1cdbd2cSJim Jagielski                         nLastMatch = nMatch;
1026*b1cdbd2cSJim Jagielski                         nSubstitute = builtin->m_nID;
1027*b1cdbd2cSJim Jagielski                     }
1028*b1cdbd2cSJim Jagielski                 }
1029*b1cdbd2cSJim Jagielski                 if( nSubstitute != -1 )
1030*b1cdbd2cSJim Jagielski                 {
1031*b1cdbd2cSJim Jagielski                     rInfo.m_aFontSubstitutions[ it->m_nID ] = nSubstitute;
1032*b1cdbd2cSJim Jagielski                     #if OSL_DEBUG_LEVEL > 2
1033*b1cdbd2cSJim Jagielski                     FastPrintFontInfo aInfo;
1034*b1cdbd2cSJim Jagielski                     rFontManager.getFontFastInfo( nSubstitute, aInfo );
1035*b1cdbd2cSJim Jagielski                     fprintf( stderr,
1036*b1cdbd2cSJim Jagielski                     "substitute %s %s %d %d\n"
1037*b1cdbd2cSJim Jagielski                     " ->        %s %s %d %d\n",
1038*b1cdbd2cSJim Jagielski                     OUStringToOString( it->m_aFamilyName, RTL_TEXTENCODING_ISO_8859_1 ).getStr(),
1039*b1cdbd2cSJim Jagielski                     it->m_eItalic == italic::Upright ? "r" : it->m_eItalic == italic::Oblique ? "o" : it->m_eItalic == italic::Italic ? "i" : "u",
1040*b1cdbd2cSJim Jagielski                     it->m_eWeight,
1041*b1cdbd2cSJim Jagielski                     it->m_eWidth,
1042*b1cdbd2cSJim Jagielski 
1043*b1cdbd2cSJim Jagielski                     OUStringToOString( aInfo.m_aFamilyName, RTL_TEXTENCODING_ISO_8859_1 ).getStr(),
1044*b1cdbd2cSJim Jagielski                     aInfo.m_eItalic == italic::Upright ? "r" : aInfo.m_eItalic == italic::Oblique ? "o" : aInfo.m_eItalic == italic::Italic ? "i" : "u",
1045*b1cdbd2cSJim Jagielski                     aInfo.m_eWeight,
1046*b1cdbd2cSJim Jagielski                     aInfo.m_eWidth
1047*b1cdbd2cSJim Jagielski                     );
1048*b1cdbd2cSJim Jagielski                     #endif
1049*b1cdbd2cSJim Jagielski                 }
1050*b1cdbd2cSJim Jagielski             }
1051*b1cdbd2cSJim Jagielski         }
1052*b1cdbd2cSJim Jagielski     }
1053*b1cdbd2cSJim Jagielski }
1054*b1cdbd2cSJim Jagielski 
1055*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------
1056*b1cdbd2cSJim Jagielski 
getSystemPrintCommands(std::list<OUString> & rCommands)1057*b1cdbd2cSJim Jagielski void PrinterInfoManager::getSystemPrintCommands( std::list< OUString >& rCommands )
1058*b1cdbd2cSJim Jagielski {
1059*b1cdbd2cSJim Jagielski     if( m_pQueueInfo && m_pQueueInfo->hasChanged() )
1060*b1cdbd2cSJim Jagielski     {
1061*b1cdbd2cSJim Jagielski         m_aSystemPrintCommand = m_pQueueInfo->getCommand();
1062*b1cdbd2cSJim Jagielski         m_pQueueInfo->getSystemQueues( m_aSystemPrintQueues );
1063*b1cdbd2cSJim Jagielski         delete m_pQueueInfo, m_pQueueInfo = NULL;
1064*b1cdbd2cSJim Jagielski     }
1065*b1cdbd2cSJim Jagielski 
1066*b1cdbd2cSJim Jagielski     std::list< SystemPrintQueue >::const_iterator it;
1067*b1cdbd2cSJim Jagielski     rCommands.clear();
1068*b1cdbd2cSJim Jagielski     String aPrinterConst( RTL_CONSTASCII_USTRINGPARAM( "(PRINTER)" ) );
1069*b1cdbd2cSJim Jagielski     for( it = m_aSystemPrintQueues.begin(); it != m_aSystemPrintQueues.end(); ++it )
1070*b1cdbd2cSJim Jagielski     {
1071*b1cdbd2cSJim Jagielski         String aCmd( m_aSystemPrintCommand );
1072*b1cdbd2cSJim Jagielski         aCmd.SearchAndReplace( aPrinterConst, it->m_aQueue );
1073*b1cdbd2cSJim Jagielski         rCommands.push_back( aCmd );
1074*b1cdbd2cSJim Jagielski     }
1075*b1cdbd2cSJim Jagielski }
1076*b1cdbd2cSJim Jagielski 
getSystemPrintQueues()1077*b1cdbd2cSJim Jagielski const std::list< PrinterInfoManager::SystemPrintQueue >& PrinterInfoManager::getSystemPrintQueues()
1078*b1cdbd2cSJim Jagielski {
1079*b1cdbd2cSJim Jagielski     if( m_pQueueInfo && m_pQueueInfo->hasChanged() )
1080*b1cdbd2cSJim Jagielski     {
1081*b1cdbd2cSJim Jagielski         m_aSystemPrintCommand = m_pQueueInfo->getCommand();
1082*b1cdbd2cSJim Jagielski         m_pQueueInfo->getSystemQueues( m_aSystemPrintQueues );
1083*b1cdbd2cSJim Jagielski         delete m_pQueueInfo, m_pQueueInfo = NULL;
1084*b1cdbd2cSJim Jagielski     }
1085*b1cdbd2cSJim Jagielski 
1086*b1cdbd2cSJim Jagielski     return m_aSystemPrintQueues;
1087*b1cdbd2cSJim Jagielski }
1088*b1cdbd2cSJim Jagielski 
checkFeatureToken(const rtl::OUString & rPrinterName,const char * pToken) const1089*b1cdbd2cSJim Jagielski bool PrinterInfoManager::checkFeatureToken( const rtl::OUString& rPrinterName, const char* pToken ) const
1090*b1cdbd2cSJim Jagielski {
1091*b1cdbd2cSJim Jagielski     const PrinterInfo& rPrinterInfo( getPrinterInfo( rPrinterName ) );
1092*b1cdbd2cSJim Jagielski     sal_Int32 nIndex = 0;
1093*b1cdbd2cSJim Jagielski     while( nIndex != -1 )
1094*b1cdbd2cSJim Jagielski     {
1095*b1cdbd2cSJim Jagielski         OUString aOuterToken = rPrinterInfo.m_aFeatures.getToken( 0, ',', nIndex );
1096*b1cdbd2cSJim Jagielski         sal_Int32 nInnerIndex = 0;
1097*b1cdbd2cSJim Jagielski         OUString aInnerToken = aOuterToken.getToken( 0, '=', nInnerIndex );
1098*b1cdbd2cSJim Jagielski         if( aInnerToken.equalsIgnoreAsciiCaseAscii( pToken ) )
1099*b1cdbd2cSJim Jagielski             return true;
1100*b1cdbd2cSJim Jagielski     }
1101*b1cdbd2cSJim Jagielski     return false;
1102*b1cdbd2cSJim Jagielski }
1103*b1cdbd2cSJim Jagielski 
startSpool(const OUString & rPrintername,bool bQuickCommand)1104*b1cdbd2cSJim Jagielski FILE* PrinterInfoManager::startSpool( const OUString& rPrintername, bool bQuickCommand )
1105*b1cdbd2cSJim Jagielski {
1106*b1cdbd2cSJim Jagielski     const PrinterInfo&   rPrinterInfo   = getPrinterInfo (rPrintername);
1107*b1cdbd2cSJim Jagielski     const rtl::OUString& rCommand       = (bQuickCommand && rPrinterInfo.m_aQuickCommand.getLength() ) ?
1108*b1cdbd2cSJim Jagielski                                           rPrinterInfo.m_aQuickCommand : rPrinterInfo.m_aCommand;
1109*b1cdbd2cSJim Jagielski     rtl::OString aShellCommand  = OUStringToOString (rCommand, RTL_TEXTENCODING_ISO_8859_1);
1110*b1cdbd2cSJim Jagielski     aShellCommand += rtl::OString( " 2>/dev/null" );
1111*b1cdbd2cSJim Jagielski 
1112*b1cdbd2cSJim Jagielski     return popen (aShellCommand.getStr(), "w");
1113*b1cdbd2cSJim Jagielski }
1114*b1cdbd2cSJim Jagielski 
endSpool(const OUString &,const OUString &,FILE * pFile,const JobData &,bool)1115*b1cdbd2cSJim Jagielski int PrinterInfoManager::endSpool( const OUString& /*rPrintername*/, const OUString& /*rJobTitle*/, FILE* pFile, const JobData& /*rDocumentJobData*/, bool /*bBanner*/ )
1116*b1cdbd2cSJim Jagielski {
1117*b1cdbd2cSJim Jagielski     return (0 == pclose( pFile ));
1118*b1cdbd2cSJim Jagielski }
1119*b1cdbd2cSJim Jagielski 
setupJobContextData(JobData & rData)1120*b1cdbd2cSJim Jagielski void PrinterInfoManager::setupJobContextData( JobData& rData )
1121*b1cdbd2cSJim Jagielski {
1122*b1cdbd2cSJim Jagielski     std::hash_map< OUString, Printer, OUStringHash >::iterator it =
1123*b1cdbd2cSJim Jagielski     m_aPrinters.find( rData.m_aPrinterName );
1124*b1cdbd2cSJim Jagielski     if( it != m_aPrinters.end() )
1125*b1cdbd2cSJim Jagielski     {
1126*b1cdbd2cSJim Jagielski         rData.m_pParser     = it->second.m_aInfo.m_pParser;
1127*b1cdbd2cSJim Jagielski         rData.m_aContext    = it->second.m_aInfo.m_aContext;
1128*b1cdbd2cSJim Jagielski     }
1129*b1cdbd2cSJim Jagielski }
1130*b1cdbd2cSJim Jagielski 
setDefaultPaper(PPDContext & rContext) const1131*b1cdbd2cSJim Jagielski void PrinterInfoManager::setDefaultPaper( PPDContext& rContext ) const
1132*b1cdbd2cSJim Jagielski {
1133*b1cdbd2cSJim Jagielski     if(  ! rContext.getParser() )
1134*b1cdbd2cSJim Jagielski         return;
1135*b1cdbd2cSJim Jagielski 
1136*b1cdbd2cSJim Jagielski     const PPDKey* pPageSizeKey = rContext.getParser()->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "PageSize" ) ) );
1137*b1cdbd2cSJim Jagielski     if( ! pPageSizeKey )
1138*b1cdbd2cSJim Jagielski         return;
1139*b1cdbd2cSJim Jagielski 
1140*b1cdbd2cSJim Jagielski     int nModified = rContext.countValuesModified();
1141*b1cdbd2cSJim Jagielski     while( nModified-- &&
1142*b1cdbd2cSJim Jagielski         rContext.getModifiedKey( nModified ) != pPageSizeKey )
1143*b1cdbd2cSJim Jagielski     ;
1144*b1cdbd2cSJim Jagielski 
1145*b1cdbd2cSJim Jagielski     if( nModified >= 0 ) // paper was set already, do not modify
1146*b1cdbd2cSJim Jagielski     {
1147*b1cdbd2cSJim Jagielski         #if OSL_DEBUG_LEVEL > 1
1148*b1cdbd2cSJim Jagielski         fprintf( stderr, "not setting default paper, already set %s\n",
1149*b1cdbd2cSJim Jagielski         OUStringToOString( rContext.getValue( pPageSizeKey )->m_aOption, RTL_TEXTENCODING_ISO_8859_1 ).getStr() );
1150*b1cdbd2cSJim Jagielski         #endif
1151*b1cdbd2cSJim Jagielski         return;
1152*b1cdbd2cSJim Jagielski     }
1153*b1cdbd2cSJim Jagielski 
1154*b1cdbd2cSJim Jagielski     // paper not set, fill in default value
1155*b1cdbd2cSJim Jagielski     const PPDValue* pPaperVal = NULL;
1156*b1cdbd2cSJim Jagielski     int nValues = pPageSizeKey->countValues();
1157*b1cdbd2cSJim Jagielski     for( int i = 0; i < nValues && ! pPaperVal; i++ )
1158*b1cdbd2cSJim Jagielski     {
1159*b1cdbd2cSJim Jagielski         const PPDValue* pVal = pPageSizeKey->getValue( i );
1160*b1cdbd2cSJim Jagielski         if( pVal->m_aOption.EqualsIgnoreCaseAscii( m_aSystemDefaultPaper.getStr() ) )
1161*b1cdbd2cSJim Jagielski             pPaperVal = pVal;
1162*b1cdbd2cSJim Jagielski     }
1163*b1cdbd2cSJim Jagielski     if( pPaperVal )
1164*b1cdbd2cSJim Jagielski     {
1165*b1cdbd2cSJim Jagielski         #if OSL_DEBUG_LEVEL > 1
1166*b1cdbd2cSJim Jagielski         fprintf( stderr, "setting default paper %s\n", OUStringToOString( pPaperVal->m_aOption, RTL_TEXTENCODING_ISO_8859_1 ).getStr() );
1167*b1cdbd2cSJim Jagielski         #endif
1168*b1cdbd2cSJim Jagielski         rContext.setValue( pPageSizeKey, pPaperVal );
1169*b1cdbd2cSJim Jagielski         #if OSL_DEBUG_LEVEL > 1
1170*b1cdbd2cSJim Jagielski         pPaperVal = rContext.getValue( pPageSizeKey );
1171*b1cdbd2cSJim Jagielski         fprintf( stderr, "-> got paper %s\n", OUStringToOString( pPaperVal->m_aOption, RTL_TEXTENCODING_ISO_8859_1 ).getStr() );
1172*b1cdbd2cSJim Jagielski         #endif
1173*b1cdbd2cSJim Jagielski     }
1174*b1cdbd2cSJim Jagielski }
1175*b1cdbd2cSJim Jagielski 
1176*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------
1177*b1cdbd2cSJim Jagielski 
SystemQueueInfo()1178*b1cdbd2cSJim Jagielski SystemQueueInfo::SystemQueueInfo() :
1179*b1cdbd2cSJim Jagielski     m_bChanged( false )
1180*b1cdbd2cSJim Jagielski {
1181*b1cdbd2cSJim Jagielski     create();
1182*b1cdbd2cSJim Jagielski }
1183*b1cdbd2cSJim Jagielski 
~SystemQueueInfo()1184*b1cdbd2cSJim Jagielski SystemQueueInfo::~SystemQueueInfo()
1185*b1cdbd2cSJim Jagielski {
1186*b1cdbd2cSJim Jagielski     static const char* pNoSyncDetection = getenv( "SAL_DISABLE_SYNCHRONOUS_PRINTER_DETECTION" );
1187*b1cdbd2cSJim Jagielski     if( ! pNoSyncDetection || !*pNoSyncDetection )
1188*b1cdbd2cSJim Jagielski         join();
1189*b1cdbd2cSJim Jagielski     else
1190*b1cdbd2cSJim Jagielski         terminate();
1191*b1cdbd2cSJim Jagielski }
1192*b1cdbd2cSJim Jagielski 
hasChanged() const1193*b1cdbd2cSJim Jagielski bool SystemQueueInfo::hasChanged() const
1194*b1cdbd2cSJim Jagielski {
1195*b1cdbd2cSJim Jagielski     MutexGuard aGuard( m_aMutex );
1196*b1cdbd2cSJim Jagielski     bool bChanged = m_bChanged;
1197*b1cdbd2cSJim Jagielski     return bChanged;
1198*b1cdbd2cSJim Jagielski }
1199*b1cdbd2cSJim Jagielski 
getSystemQueues(std::list<PrinterInfoManager::SystemPrintQueue> & rQueues)1200*b1cdbd2cSJim Jagielski void SystemQueueInfo::getSystemQueues( std::list< PrinterInfoManager::SystemPrintQueue >& rQueues )
1201*b1cdbd2cSJim Jagielski {
1202*b1cdbd2cSJim Jagielski     MutexGuard aGuard( m_aMutex );
1203*b1cdbd2cSJim Jagielski     rQueues = m_aQueues;
1204*b1cdbd2cSJim Jagielski     m_bChanged = false;
1205*b1cdbd2cSJim Jagielski }
1206*b1cdbd2cSJim Jagielski 
getCommand() const1207*b1cdbd2cSJim Jagielski OUString SystemQueueInfo::getCommand() const
1208*b1cdbd2cSJim Jagielski {
1209*b1cdbd2cSJim Jagielski     MutexGuard aGuard( m_aMutex );
1210*b1cdbd2cSJim Jagielski     OUString aRet = m_aCommand;
1211*b1cdbd2cSJim Jagielski     return aRet;
1212*b1cdbd2cSJim Jagielski }
1213*b1cdbd2cSJim Jagielski 
1214*b1cdbd2cSJim Jagielski struct SystemCommandParameters;
1215*b1cdbd2cSJim Jagielski typedef void(* tokenHandler)(const std::list< rtl::OString >&,
1216*b1cdbd2cSJim Jagielski                 std::list< PrinterInfoManager::SystemPrintQueue >&,
1217*b1cdbd2cSJim Jagielski                 const SystemCommandParameters*);
1218*b1cdbd2cSJim Jagielski 
1219*b1cdbd2cSJim Jagielski struct SystemCommandParameters
1220*b1cdbd2cSJim Jagielski {
1221*b1cdbd2cSJim Jagielski     const char*     pQueueCommand;
1222*b1cdbd2cSJim Jagielski     const char*     pPrintCommand;
1223*b1cdbd2cSJim Jagielski     const char*     pForeToken;
1224*b1cdbd2cSJim Jagielski     const char*     pAftToken;
1225*b1cdbd2cSJim Jagielski     unsigned int    nForeTokenCount;
1226*b1cdbd2cSJim Jagielski     tokenHandler    pHandler;
1227*b1cdbd2cSJim Jagielski };
1228*b1cdbd2cSJim Jagielski 
1229*b1cdbd2cSJim Jagielski #if ! (defined(LINUX) || defined(NETBSD) || defined(FREEBSD))
lpgetSysQueueTokenHandler(const std::list<rtl::OString> & i_rLines,std::list<PrinterInfoManager::SystemPrintQueue> & o_rQueues,const SystemCommandParameters *)1230*b1cdbd2cSJim Jagielski static void lpgetSysQueueTokenHandler(
1231*b1cdbd2cSJim Jagielski     const std::list< rtl::OString >& i_rLines,
1232*b1cdbd2cSJim Jagielski     std::list< PrinterInfoManager::SystemPrintQueue >& o_rQueues,
1233*b1cdbd2cSJim Jagielski     const SystemCommandParameters* )
1234*b1cdbd2cSJim Jagielski {
1235*b1cdbd2cSJim Jagielski     rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
1236*b1cdbd2cSJim Jagielski     std::hash_set< OUString, OUStringHash > aUniqueSet;
1237*b1cdbd2cSJim Jagielski     std::hash_set< OUString, OUStringHash > aOnlySet;
1238*b1cdbd2cSJim Jagielski     aUniqueSet.insert( OUString( RTL_CONSTASCII_USTRINGPARAM( "_all" ) ) );
1239*b1cdbd2cSJim Jagielski     aUniqueSet.insert( OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ) );
1240*b1cdbd2cSJim Jagielski 
1241*b1cdbd2cSJim Jagielski     // the eventual "all" attribute of the "_all" queue tells us, which
1242*b1cdbd2cSJim Jagielski     // printers are to be used for this user at all
1243*b1cdbd2cSJim Jagielski 
1244*b1cdbd2cSJim Jagielski     // find _all: line
1245*b1cdbd2cSJim Jagielski     rtl::OString aAllLine( "_all:" );
1246*b1cdbd2cSJim Jagielski     rtl::OString aAllAttr( "all=" );
1247*b1cdbd2cSJim Jagielski     for( std::list< rtl::OString >::const_iterator it = i_rLines.begin();
1248*b1cdbd2cSJim Jagielski          it != i_rLines.end(); ++it )
1249*b1cdbd2cSJim Jagielski     {
1250*b1cdbd2cSJim Jagielski         if( it->indexOf( aAllLine, 0 ) == 0 )
1251*b1cdbd2cSJim Jagielski         {
1252*b1cdbd2cSJim Jagielski             // now find the "all" attribute
1253*b1cdbd2cSJim Jagielski             ++it;
1254*b1cdbd2cSJim Jagielski             while( it != i_rLines.end() )
1255*b1cdbd2cSJim Jagielski             {
1256*b1cdbd2cSJim Jagielski                 rtl::OString aClean( WhitespaceToSpace( *it ) );
1257*b1cdbd2cSJim Jagielski                 if( aClean.indexOf( aAllAttr, 0 ) == 0 )
1258*b1cdbd2cSJim Jagielski                 {
1259*b1cdbd2cSJim Jagielski                     // insert the comma separated entries into the set of printers to use
1260*b1cdbd2cSJim Jagielski                     sal_Int32 nPos = aAllAttr.getLength();
1261*b1cdbd2cSJim Jagielski                     while( nPos != -1 )
1262*b1cdbd2cSJim Jagielski                     {
1263*b1cdbd2cSJim Jagielski                         OString aTok( aClean.getToken( 0, ',', nPos ) );
1264*b1cdbd2cSJim Jagielski                         if( aTok.getLength() > 0 )
1265*b1cdbd2cSJim Jagielski                             aOnlySet.insert( rtl::OStringToOUString( aTok, aEncoding ) );
1266*b1cdbd2cSJim Jagielski                     }
1267*b1cdbd2cSJim Jagielski                     break;
1268*b1cdbd2cSJim Jagielski                 }
1269*b1cdbd2cSJim Jagielski             }
1270*b1cdbd2cSJim Jagielski             break;
1271*b1cdbd2cSJim Jagielski         }
1272*b1cdbd2cSJim Jagielski     }
1273*b1cdbd2cSJim Jagielski 
1274*b1cdbd2cSJim Jagielski     bool bInsertAttribute = false;
1275*b1cdbd2cSJim Jagielski     rtl::OString aDescrStr( "description=" );
1276*b1cdbd2cSJim Jagielski     rtl::OString aLocStr( "location=" );
1277*b1cdbd2cSJim Jagielski     for( std::list< rtl::OString >::const_iterator it = i_rLines.begin();
1278*b1cdbd2cSJim Jagielski          it != i_rLines.end(); ++it )
1279*b1cdbd2cSJim Jagielski     {
1280*b1cdbd2cSJim Jagielski         sal_Int32 nPos = 0;
1281*b1cdbd2cSJim Jagielski         // find the begin of a new printer section
1282*b1cdbd2cSJim Jagielski         nPos = it->indexOf( ':', 0 );
1283*b1cdbd2cSJim Jagielski         if( nPos != -1 )
1284*b1cdbd2cSJim Jagielski         {
1285*b1cdbd2cSJim Jagielski             OUString aSysQueue( rtl::OStringToOUString( it->copy( 0, nPos ), aEncoding ) );
1286*b1cdbd2cSJim Jagielski             // do not insert duplicates (e.g. lpstat tends to produce such lines)
1287*b1cdbd2cSJim Jagielski             // in case there was a "_all" section, insert only those printer explicitly
1288*b1cdbd2cSJim Jagielski             // set in the "all" attribute
1289*b1cdbd2cSJim Jagielski             if( aUniqueSet.find( aSysQueue ) == aUniqueSet.end() &&
1290*b1cdbd2cSJim Jagielski                 ( aOnlySet.empty() || aOnlySet.find( aSysQueue ) != aOnlySet.end() )
1291*b1cdbd2cSJim Jagielski                 )
1292*b1cdbd2cSJim Jagielski             {
1293*b1cdbd2cSJim Jagielski                 o_rQueues.push_back( PrinterInfoManager::SystemPrintQueue() );
1294*b1cdbd2cSJim Jagielski                 o_rQueues.back().m_aQueue = aSysQueue;
1295*b1cdbd2cSJim Jagielski                 o_rQueues.back().m_aLocation = aSysQueue;
1296*b1cdbd2cSJim Jagielski                 aUniqueSet.insert( aSysQueue );
1297*b1cdbd2cSJim Jagielski                 bInsertAttribute = true;
1298*b1cdbd2cSJim Jagielski             }
1299*b1cdbd2cSJim Jagielski             else
1300*b1cdbd2cSJim Jagielski                 bInsertAttribute = false;
1301*b1cdbd2cSJim Jagielski             continue;
1302*b1cdbd2cSJim Jagielski         }
1303*b1cdbd2cSJim Jagielski         if( bInsertAttribute && ! o_rQueues.empty() )
1304*b1cdbd2cSJim Jagielski         {
1305*b1cdbd2cSJim Jagielski             // look for "description" attribute, insert as comment
1306*b1cdbd2cSJim Jagielski             nPos = it->indexOf( aDescrStr, 0 );
1307*b1cdbd2cSJim Jagielski             if( nPos != -1 )
1308*b1cdbd2cSJim Jagielski             {
1309*b1cdbd2cSJim Jagielski                 ByteString aComment( WhitespaceToSpace( it->copy(nPos+12) ) );
1310*b1cdbd2cSJim Jagielski                 if( aComment.Len() > 0 )
1311*b1cdbd2cSJim Jagielski                     o_rQueues.back().m_aComment = String( aComment, aEncoding );
1312*b1cdbd2cSJim Jagielski                 continue;
1313*b1cdbd2cSJim Jagielski             }
1314*b1cdbd2cSJim Jagielski             // look for "location" attribute, inser as location
1315*b1cdbd2cSJim Jagielski             nPos = it->indexOf( aLocStr, 0 );
1316*b1cdbd2cSJim Jagielski             if( nPos != -1 )
1317*b1cdbd2cSJim Jagielski             {
1318*b1cdbd2cSJim Jagielski                 ByteString aLoc( WhitespaceToSpace( it->copy(nPos+9) ) );
1319*b1cdbd2cSJim Jagielski                 if( aLoc.Len() > 0 )
1320*b1cdbd2cSJim Jagielski                     o_rQueues.back().m_aLocation = String( aLoc, aEncoding );
1321*b1cdbd2cSJim Jagielski                 continue;
1322*b1cdbd2cSJim Jagielski             }
1323*b1cdbd2cSJim Jagielski         }
1324*b1cdbd2cSJim Jagielski     }
1325*b1cdbd2cSJim Jagielski }
1326*b1cdbd2cSJim Jagielski #endif
standardSysQueueTokenHandler(const std::list<rtl::OString> & i_rLines,std::list<PrinterInfoManager::SystemPrintQueue> & o_rQueues,const SystemCommandParameters * i_pParms)1327*b1cdbd2cSJim Jagielski static void standardSysQueueTokenHandler(
1328*b1cdbd2cSJim Jagielski     const std::list< rtl::OString >& i_rLines,
1329*b1cdbd2cSJim Jagielski     std::list< PrinterInfoManager::SystemPrintQueue >& o_rQueues,
1330*b1cdbd2cSJim Jagielski     const SystemCommandParameters* i_pParms)
1331*b1cdbd2cSJim Jagielski {
1332*b1cdbd2cSJim Jagielski     rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
1333*b1cdbd2cSJim Jagielski     std::hash_set< OUString, OUStringHash > aUniqueSet;
1334*b1cdbd2cSJim Jagielski     rtl::OString aForeToken( i_pParms->pForeToken );
1335*b1cdbd2cSJim Jagielski     rtl::OString aAftToken( i_pParms->pAftToken );
1336*b1cdbd2cSJim Jagielski     /* Normal Unix print queue discovery, also used for Darwin 5 LPR printing
1337*b1cdbd2cSJim Jagielski     */
1338*b1cdbd2cSJim Jagielski     for( std::list< rtl::OString >::const_iterator it = i_rLines.begin();
1339*b1cdbd2cSJim Jagielski          it != i_rLines.end(); ++it )
1340*b1cdbd2cSJim Jagielski     {
1341*b1cdbd2cSJim Jagielski         sal_Int32 nPos = 0;
1342*b1cdbd2cSJim Jagielski 
1343*b1cdbd2cSJim Jagielski         // search for a line describing a printer:
1344*b1cdbd2cSJim Jagielski         // find if there are enough tokens before the name
1345*b1cdbd2cSJim Jagielski         for( unsigned int i = 0; i < i_pParms->nForeTokenCount && nPos != -1; i++ )
1346*b1cdbd2cSJim Jagielski         {
1347*b1cdbd2cSJim Jagielski             nPos = it->indexOf( aForeToken, nPos );
1348*b1cdbd2cSJim Jagielski             if( nPos != -1 && it->getLength() >= nPos+aForeToken.getLength() )
1349*b1cdbd2cSJim Jagielski                 nPos += aForeToken.getLength();
1350*b1cdbd2cSJim Jagielski         }
1351*b1cdbd2cSJim Jagielski         if( nPos != -1 )
1352*b1cdbd2cSJim Jagielski         {
1353*b1cdbd2cSJim Jagielski             // find if there is the token after the queue
1354*b1cdbd2cSJim Jagielski             sal_Int32 nAftPos = it->indexOf( aAftToken, nPos );
1355*b1cdbd2cSJim Jagielski             if( nAftPos != -1 )
1356*b1cdbd2cSJim Jagielski             {
1357*b1cdbd2cSJim Jagielski                 // get the queue name between fore and aft tokens
1358*b1cdbd2cSJim Jagielski                 OUString aSysQueue( rtl::OStringToOUString( it->copy( nPos, nAftPos - nPos ), aEncoding ) );
1359*b1cdbd2cSJim Jagielski                 // do not insert duplicates (e.g. lpstat tends to produce such lines)
1360*b1cdbd2cSJim Jagielski                 if( aUniqueSet.find( aSysQueue ) == aUniqueSet.end() )
1361*b1cdbd2cSJim Jagielski                 {
1362*b1cdbd2cSJim Jagielski                     o_rQueues.push_back( PrinterInfoManager::SystemPrintQueue() );
1363*b1cdbd2cSJim Jagielski                     o_rQueues.back().m_aQueue = aSysQueue;
1364*b1cdbd2cSJim Jagielski                     o_rQueues.back().m_aLocation = aSysQueue;
1365*b1cdbd2cSJim Jagielski                     aUniqueSet.insert( aSysQueue );
1366*b1cdbd2cSJim Jagielski                 }
1367*b1cdbd2cSJim Jagielski             }
1368*b1cdbd2cSJim Jagielski         }
1369*b1cdbd2cSJim Jagielski     }
1370*b1cdbd2cSJim Jagielski }
1371*b1cdbd2cSJim Jagielski 
1372*b1cdbd2cSJim Jagielski static const struct SystemCommandParameters aParms[] =
1373*b1cdbd2cSJim Jagielski {
1374*b1cdbd2cSJim Jagielski     #if defined(LINUX) || defined(NETBSD) || defined(FREEBSD)
1375*b1cdbd2cSJim Jagielski     { "/usr/sbin/lpc status", "lpr -P \"(PRINTER)\"", "", ":", 0, standardSysQueueTokenHandler },
1376*b1cdbd2cSJim Jagielski     { "lpc status", "lpr -P \"(PRINTER)\"", "", ":", 0, standardSysQueueTokenHandler },
1377*b1cdbd2cSJim Jagielski     { "LANG=C;LC_ALL=C;export LANG LC_ALL;lpstat -s", "lp -d \"(PRINTER)\"", "system for ", ": ", 1, standardSysQueueTokenHandler }
1378*b1cdbd2cSJim Jagielski     #else
1379*b1cdbd2cSJim Jagielski     { "LANG=C;LC_ALL=C;export LANG LC_ALL;lpget list", "lp -d \"(PRINTER)\"", "", ":", 0, lpgetSysQueueTokenHandler },
1380*b1cdbd2cSJim Jagielski     { "LANG=C;LC_ALL=C;export LANG LC_ALL;lpstat -s", "lp -d \"(PRINTER)\"", "system for ", ": ", 1, standardSysQueueTokenHandler },
1381*b1cdbd2cSJim Jagielski     { "/usr/sbin/lpc status", "lpr -P \"(PRINTER)\"", "", ":", 0, standardSysQueueTokenHandler },
1382*b1cdbd2cSJim Jagielski     { "lpc status", "lpr -P \"(PRINTER)\"", "", ":", 0, standardSysQueueTokenHandler }
1383*b1cdbd2cSJim Jagielski     #endif
1384*b1cdbd2cSJim Jagielski };
1385*b1cdbd2cSJim Jagielski 
run()1386*b1cdbd2cSJim Jagielski void SystemQueueInfo::run()
1387*b1cdbd2cSJim Jagielski {
1388*b1cdbd2cSJim Jagielski     char pBuffer[1024];
1389*b1cdbd2cSJim Jagielski     FILE *pPipe;
1390*b1cdbd2cSJim Jagielski     std::list< rtl::OString > aLines;
1391*b1cdbd2cSJim Jagielski 
1392*b1cdbd2cSJim Jagielski     /* Discover which command we can use to get a list of all printer queues */
1393*b1cdbd2cSJim Jagielski     for( unsigned int i = 0; i < sizeof(aParms)/sizeof(aParms[0]); i++ )
1394*b1cdbd2cSJim Jagielski     {
1395*b1cdbd2cSJim Jagielski         aLines.clear();
1396*b1cdbd2cSJim Jagielski         rtl::OStringBuffer aCmdLine( 128 );
1397*b1cdbd2cSJim Jagielski         aCmdLine.append( aParms[i].pQueueCommand );
1398*b1cdbd2cSJim Jagielski         #if OSL_DEBUG_LEVEL > 1
1399*b1cdbd2cSJim Jagielski         fprintf( stderr, "trying print queue command \"%s\" ... ", aParms[i].pQueueCommand );
1400*b1cdbd2cSJim Jagielski         #endif
1401*b1cdbd2cSJim Jagielski         aCmdLine.append( " 2>/dev/null" );
1402*b1cdbd2cSJim Jagielski         if( (pPipe = popen( aCmdLine.getStr(), "r" )) )
1403*b1cdbd2cSJim Jagielski         {
1404*b1cdbd2cSJim Jagielski             while( fgets( pBuffer, 1024, pPipe ) )
1405*b1cdbd2cSJim Jagielski                 aLines.push_back( rtl::OString( pBuffer ) );
1406*b1cdbd2cSJim Jagielski             if( ! pclose( pPipe ) )
1407*b1cdbd2cSJim Jagielski             {
1408*b1cdbd2cSJim Jagielski                 std::list< PrinterInfoManager::SystemPrintQueue > aSysPrintQueues;
1409*b1cdbd2cSJim Jagielski                 aParms[i].pHandler( aLines, aSysPrintQueues, &(aParms[i]) );
1410*b1cdbd2cSJim Jagielski                 MutexGuard aGuard( m_aMutex );
1411*b1cdbd2cSJim Jagielski                 m_bChanged  = true;
1412*b1cdbd2cSJim Jagielski                 m_aQueues   = aSysPrintQueues;
1413*b1cdbd2cSJim Jagielski                 m_aCommand  = rtl::OUString::createFromAscii( aParms[i].pPrintCommand );
1414*b1cdbd2cSJim Jagielski                 #if OSL_DEBUG_LEVEL > 1
1415*b1cdbd2cSJim Jagielski                 fprintf( stderr, "success\n" );
1416*b1cdbd2cSJim Jagielski                 #endif
1417*b1cdbd2cSJim Jagielski                 break;
1418*b1cdbd2cSJim Jagielski             }
1419*b1cdbd2cSJim Jagielski         }
1420*b1cdbd2cSJim Jagielski         #if OSL_DEBUG_LEVEL > 1
1421*b1cdbd2cSJim Jagielski         fprintf( stderr, "failed\n" );
1422*b1cdbd2cSJim Jagielski         #endif
1423*b1cdbd2cSJim Jagielski     }
1424*b1cdbd2cSJim Jagielski }
1425*b1cdbd2cSJim Jagielski 
1426