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