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