20 #include "ppdloader.h"
21 #include "foomatic2loader.h"
24 #include <kfilterdev.h>
30 void kdeprint_ppdscanner_init( TQIODevice* );
31 void kdeprint_ppdscanner_terminate(
bool deleteIt =
true );
32 int kdeprint_ppdscanner_numberoflines();
34 static TQString processLocaleString(
const TQString& s )
38 while ( pos < s.length() )
40 TQChar c = s[ pos++ ];
45 while ( pos < s.length() )
47 TQChar cc = s[ pos++ ];
51 else if ( cc.isDigit() )
52 _hc = cc.digitValue();
54 _hc = cc.lower().latin1() -
'a' + 10;
58 res.append( TQChar( hc ) );
74 static TQValueList<float> splitNumberString(
const TQString& _s )
76 TQString s = _s.simplifyWhiteSpace();
81 p2 = s.find(
' ', p1 );
84 l.append( s.mid( p1, p2-p1 ).toFloat() );
90 l.append( s.mid( p1, s.length() - p1 - 1 ).toFloat() );
106 float left, bottom, right, top;
110 PPDLoader::PPDLoader()
113 m_ps.setAutoDelete(
true );
116 PPDLoader::~PPDLoader()
120 DrMain* PPDLoader::readFromFile(
const TQString& filename )
127 TQIODevice *d = KFilterDev::deviceForFile( filename );
128 if ( d && d->open( IO_ReadOnly ) )
130 DrMain *driver =
new DrMain;
133 m_groups.push( driver );
134 kdeprint_ppdscanner_init( d );
135 if ( kdeprint_ppdparse(
this ) != 0 )
137 kdeprint_ppdscanner_terminate(
true );
141 if ( m_groups.size() > 1 )
142 kdWarning( 500 ) <<
"PPD syntax error, GROUP specification not correctly closed" << endl;
143 if ( driver->has(
"foodata" ) )
145 Foomatic2Loader loader;
146 if ( loader.readFromBuffer( driver->get(
"foodata" ) ) )
148 driver = loader.modifyDriver( driver );
151 kdWarning( 500 ) <<
"PPD syntax error, Foomatic data read failed" << endl;
153 processPageSizes( driver );
154 if ( !m_fonts.isEmpty() )
155 driver->set(
"fonts", m_fonts.join(
"," ) );
159 kdWarning( 500 ) <<
"PPD syntax error, PPD parse failed" << endl;
164 kdWarning( 500 ) <<
"PPD read error, unable to open device for file " << filename << endl;
168 DrMain* PPDLoader::loadDriver(
const TQString& filename, TQString* msg )
171 DrMain *driver = loader.readFromFile( filename );
172 if ( !driver && msg )
173 *msg = filename + i18n(
"(line %1): " ).arg( kdeprint_ppdscanner_numberoflines() ) + loader.errorMsg();
177 bool PPDLoader::openUi(
const TQString& name,
const TQString& desc,
const TQString& type )
181 qWarning(
"PPD syntax error, UI specification not correctly closed" );
182 endUi( m_option->name() );
185 if ( type ==
"PickOne" || type ==
"PickMany" )
186 m_option =
new DrListOption;
187 else if ( type ==
"Boolean" )
188 m_option =
new DrBooleanOption;
191 if ( name[ 0 ] ==
'*' )
192 m_option->setName( name.mid( 1 ) );
194 m_option->setName( name );
195 if ( desc.isEmpty() )
196 m_option->set(
"text", m_option->name() );
198 m_option->set(
"text", processLocaleString( desc ) );
202 bool PPDLoader::endUi(
const TQString& name )
204 if ( m_option && ( m_option->name() == name || m_option->name() == name.mid( 1 ) ) )
206 if ( m_option->name() ==
"PageRegion" )
210 TQString defval = m_option->get(
"default" );
212 if ( !defval.isEmpty() )
213 m_option->setValueText( defval );
214 if ( m_groups.size() == 1 )
218 grp = findOrCreateGroupForOption( m_option->name() );
221 grp = m_groups.top();
222 grp->addOption( m_option );
223 if ( grp->get(
"text" ).contains(
"install",
false ) )
224 m_option->set(
"fixed",
"1" );
232 bool PPDLoader::openGroup(
const TQString& name,
const TQString& desc )
234 DrGroup *grp =
new DrGroup;
235 grp->setName( name );
236 if ( desc.isEmpty() )
237 grp->set(
"text", name );
239 grp->set(
"text", processLocaleString( desc ) );
240 m_groups.top()->addGroup( grp );
241 m_groups.push( grp );
245 bool PPDLoader::endGroup(
const TQString& name )
247 if ( m_groups.size() > 1 && m_groups.top()->name() == name )
255 bool PPDLoader::putStatement(
const TQString& keyword,
const TQString& name,
const TQString& desc,
const TQStringList& values )
259 if ( !name.isEmpty() && m_option->name() == keyword )
261 if ( m_option->type() >= DrBase::List )
263 DrBase *ch =
new DrBase;
265 if ( desc.isEmpty() )
266 ch->set(
"text", name );
268 ch->set(
"text", processLocaleString( desc ) );
269 static_cast<DrListOption*
>( m_option )->addChoice( ch );
273 TQString fv = m_option->get(
"fixedvals" );
277 fv.append(
"|" + name );
278 m_option->set(
"fixedvals", fv );
281 else if ( keyword ==
"FoomaticRIPOption" && name == m_option->name()
282 && values.size() > 1 )
284 TQString type = values[ 0 ];
285 if ( type ==
"float" || type ==
"int" )
288 if ( type ==
"float" )
289 opt =
new DrFloatOption;
291 opt =
new DrIntegerOption;
292 opt->setName( m_option->name() );
293 opt->set(
"text", m_option->get(
"text" ) );
294 opt->set(
"default", m_option->get(
"default" ) );
295 if ( m_option->type() == DrBase::List )
298 TQPtrListIterator<DrBase> it( *( static_cast<DrListOption*>( m_option )->choices() ) );
299 for ( ; it.current(); ++it )
300 vals.append( it.current()->name() );
301 opt->set(
"fixedvals", vals.join(
"|" ) );
308 else if ( keyword ==
"FoomaticRIPOptionRange" && name == m_option->name()
309 && values.size() >= 2 && ( m_option->type() == DrBase::Float || m_option->type() == DrBase::Integer ) )
311 m_option->set(
"minval", values[ 0 ] );
312 m_option->set(
"maxval", values[ 1 ] );
315 else if ( keyword ==
"Font" && m_groups.size() > 0 )
322 bool PPDLoader::putStatement2(
const TQString& keyword,
const TQString& value )
324 if ( !m_option && m_groups.size() == 1 )
326 DrGroup *driver = m_groups.top();
327 if ( keyword ==
"NickName" )
329 driver->set(
"text", value );
330 driver->set(
"description", value );
332 else if ( keyword ==
"Manufacturer" )
333 driver->set(
"manufacturer", value );
334 else if ( keyword ==
"ShortNickName" )
335 driver->set(
"model", value );
336 else if ( keyword ==
"ColorDevice" )
337 driver->set(
"colordevice", value ==
"True" ?
"1" :
"0" );
342 bool PPDLoader::putDefault(
const TQString& keyword,
const TQString& value )
344 if ( keyword ==
"Resolution" && m_groups.size() > 0 )
349 m_groups[ 0 ]->set(
"resolution", value );
352 if ( m_option && m_option->name() == keyword )
354 m_option->set(
"default", value );
361 bool PPDLoader::putConstraint(
const TQString& opt1,
const TQString& opt2,
const TQString& ch1,
const TQString& ch2 )
363 if ( !m_option && m_groups.size() == 1 )
365 DrMain *driver =
static_cast<DrMain*
>( m_groups.top() );
366 driver->addConstraint(
new DrConstraint( opt1, opt2, ch1, ch2 ) );
371 bool PPDLoader::putFooData(
const TQString& data )
373 if ( !m_option && m_groups.size() == 1 )
375 m_groups.top()->set(
"foodata", m_groups.top()->get(
"foodata" ) + data +
"\n" );
380 bool PPDLoader::putFooProcessedData(
const TQVariant& var )
382 TQMap<TQString,TQVariant>::ConstIterator it = var.mapFind(
"args_byname" );
383 if ( it != var.mapEnd() )
385 TQVariant opts = it.data();
386 for ( it = opts.mapBegin(); it != opts.mapEnd(); ++it )
388 TQMap<TQString,TQVariant> opt = it.data().toMap();
389 TQString type = opt[
"type" ].toString();
390 if ( type ==
"float" || type ==
"int" )
393 if ( type ==
"float" )
394 o =
new DrFloatOption;
396 o =
new DrIntegerOption;
397 o->setName( opt[
"name" ].toString() );
398 o->set(
"text", opt[
"comment" ].toString() );
399 o->set(
"minval", opt[
"min" ].toString() );
400 o->set(
"maxval", opt[
"max" ].toString() );
401 o->set(
"default", opt[
"default" ].toString() );
402 o->setValueText( o->get(
"default" ) );
405 DrBase *old = m_groups.top()->findOption( o->name(), &grp );
408 if ( old->type() == DrBase::List )
411 TQPtrListIterator<DrBase> it( *( static_cast<DrListOption*>( old )->choices() ) );
412 for ( ; it.current(); ++it )
413 vals.append( it.current()->name() );
414 o->set(
"fixedvals", vals.join(
"|" ) );
416 grp->removeOption( o->name() );
421 qWarning(
"Option %s not found in original PPD file", o->name().latin1() );
430 bool PPDLoader::putPaperDimension(
const TQString& name,
const TQString& s )
432 TQValueList<float> l = splitNumberString( s );
434 PS_private *ps = m_ps.find( name );
439 m_ps.insert( name, ps );
441 ps->size.width = l[ 0 ];
442 ps->size.height = l[ 1 ];
447 bool PPDLoader::putImageableArea(
const TQString& name,
const TQString& s )
449 TQValueList<float> l = splitNumberString( s );
451 PS_private *ps = m_ps.find( name );
456 m_ps.insert( name, ps );
458 ps->area.left = l[ 0 ];
459 ps->area.bottom = l[ 1 ];
460 ps->area.right = l[ 2 ];
461 ps->area.top = l[ 3 ];
466 DrGroup* PPDLoader::findOrCreateGroupForOption(
const TQString& optname )
469 if ( optname ==
"PageSize" ||
470 optname ==
"InputSlot" ||
471 optname ==
"ManualFeed" ||
472 optname ==
"MediaType" ||
473 optname ==
"MediaColor" ||
474 optname ==
"MediaWeight" )
476 else if ( optname.startsWith(
"stp" ) ||
478 optname ==
"Yellow" ||
479 optname ==
"Magenta" ||
480 optname ==
"Density" ||
481 optname ==
"Contrast" )
482 grpname =
"Adjustments";
483 else if ( optname.startsWith(
"JCL" ) )
489 for ( TQPtrListIterator<DrGroup> it( m_groups[ 0 ]->groups() ); it.current(); ++it )
490 if ( it.current()->name() == grpname )
498 grp->setName( grpname );
499 grp->set(
"text", grpname );
500 m_groups[ 0 ]->addGroup( grp );
505 void PPDLoader::processPageSizes( DrMain *driver )
507 TQDictIterator<PS_private> it( m_ps );
508 for ( ; it.current(); ++it )
514 driver->addPageSize(
new DrPageSize( it.current()->name,
515 ( int )it.current()->size.width, ( int )it.current()->size.height,
516 ( int )it.current()->area.left, ( int )it.current()->area.bottom,
517 ( int )ceil( it.current()->size.width - it.current()->area.right ),
518 (
int )ceil( it.current()->size.height - it.current()->area.top ) ) );
523 void PPDLoader::setErrorMsg(
const TQString& msg )
528 TQString PPDLoader::errorMsg()
const