26 #include <tqtextstream.h> 30 #include <kaboutdata.h> 31 #include <kapplication.h> 34 #include <kcmdlineargs.h> 37 #include <ksimpleconfig.h> 38 #include <kstandarddirs.h> 45 {
"directory <dir>",
I18N_NOOP(
"Directory to generate files in"),
"." },
46 {
"+file.kcfg",
I18N_NOOP(
"Input kcfg XML file"), 0 },
47 {
"+file.kcfgc",
I18N_NOOP(
"Code generation options file"), 0 },
55 TQStringList allNames;
56 TQRegExp *validNameRegexp;
70 CfgEntry(
const TQString &group,
const TQString &type,
const TQString &key,
71 const TQString &name,
const TQString &label,
72 const TQString &whatsThis,
const TQString &code,
73 const TQString &defaultValue,
const TQValueList<Choice> &choices,
75 : mGroup( group ), mType( type ), mKey( key ), mName( name ),
76 mLabel( label ), mWhatsThis( whatsThis ), mCode( code ),
77 mDefaultValue( defaultValue ),
78 mChoices( choices ), mHidden( hidden )
82 void setGroup(
const TQString &group ) { mGroup = group; }
83 TQString group()
const {
return mGroup; }
85 void setType(
const TQString &type ) { mType = type; }
86 TQString type()
const {
return mType; }
88 void setKey(
const TQString &key ) { mKey = key; }
89 TQString
key()
const {
return mKey; }
91 void setName(
const TQString &name ) { mName = name; }
92 TQString
name()
const {
return mName; }
94 void setLabel(
const TQString &label ) { mLabel = label; }
95 TQString
label()
const {
return mLabel; }
97 void setWhatsThis(
const TQString &whatsThis ) { mWhatsThis = whatsThis; }
98 TQString
whatsThis()
const {
return mWhatsThis; }
100 void setDefaultValue(
const TQString &d ) { mDefaultValue = d; }
101 TQString defaultValue()
const {
return mDefaultValue; }
103 void setCode(
const TQString &d ) { mCode = d; }
104 TQString code()
const {
return mCode; }
106 void setMinValue(
const TQString &d ) { mMin = d; }
107 TQString minValue()
const {
return mMin; }
109 void setMaxValue(
const TQString &d ) { mMax = d; }
110 TQString maxValue()
const {
return mMax; }
112 void setParam(
const TQString &d ) { mParam = d; }
113 TQString param()
const {
return mParam; }
115 void setParamName(
const TQString &d ) { mParamName = d; }
116 TQString paramName()
const {
return mParamName; }
118 void setParamType(
const TQString &d ) { mParamType = d; }
119 TQString paramType()
const {
return mParamType; }
121 void setChoices(
const TQValueList<Choice> &d ) { mChoices = d; }
122 TQValueList<Choice> choices()
const {
return mChoices; }
124 void setParamValues(
const TQStringList &d ) { mParamValues = d; }
125 TQStringList paramValues()
const {
return mParamValues; }
127 void setParamDefaultValues(
const TQStringList &d ) { mParamDefaultValues = d; }
128 TQString paramDefaultValue(
int i)
const {
return mParamDefaultValues[i]; }
130 void setParamMax(
int d ) { mParamMax = d; }
131 int paramMax()
const {
return mParamMax; }
133 bool hidden()
const {
return mHidden; }
137 kdDebug() <<
"<entry>" <<
endl;
138 kdDebug() <<
" group: " << mGroup <<
endl;
139 kdDebug() <<
" type: " << mType <<
endl;
140 kdDebug() <<
" key: " << mKey <<
endl;
141 kdDebug() <<
" name: " << mName <<
endl;
142 kdDebug() <<
" label: " << mLabel <<
endl;
144 kdDebug() <<
" code: " << mCode <<
endl;
147 if (!param().isEmpty())
149 kdDebug() <<
" param name: "<< mParamName <<
endl;
150 kdDebug() <<
" param type: "<< mParamType <<
endl;
151 kdDebug() <<
" paramvalues: " << mParamValues.join(
":") <<
endl;
153 kdDebug() <<
" default: " << mDefaultValue <<
endl;
154 kdDebug() <<
" hidden: " << mHidden <<
endl;
155 kdDebug() <<
" min: " << mMin <<
endl;
156 kdDebug() <<
" max: " << mMax <<
endl;
157 kdDebug() <<
"</entry>" <<
endl;
168 TQString mDefaultValue;
172 TQValueList<Choice> mChoices;
173 TQStringList mParamValues;
174 TQStringList mParamDefaultValues;
190 static TQString varName(
const TQString &n)
195 result[1] = result[1].upper();
199 result[0] = result[0].lower();
204 static TQString varPath(
const TQString &n)
208 result =
"d->"+varName(n);
216 static TQString enumName(
const TQString &n)
218 TQString result =
"Enum"+n;
219 result[4] = result[4].upper();
223 static TQString setFunction(
const TQString &n,
const TQString &className = TQString())
225 TQString result =
"set"+n;
226 result[3] = result[3].upper();
228 if ( !className.isEmpty() )
229 result = className +
"::" + result;
234 static TQString getFunction(
const TQString &n,
const TQString &className = TQString())
237 result[0] = result[0].lower();
239 if ( !className.isEmpty() )
240 result = className +
"::" + result;
245 static void addQuotes( TQString &s )
247 if ( s.left( 1 ) !=
"\"" ) s.prepend(
"\"" );
248 if ( s.right( 1 ) !=
"\"" ) s.append(
"\"" );
251 static TQString quoteString(
const TQString &s )
254 r.replace(
"\\",
"\\\\" );
255 r.replace(
"\"",
"\\\"" );
256 r.replace(
"\r",
"" );
257 r.replace(
"\n",
"\\n\"\n\"" );
258 return "\"" + r +
"\"";
261 static TQString literalString(
const TQString &s )
264 for(
int i = s.length(); i--;)
265 if (s[i].unicode() > 127) isAscii =
false;
268 return "TQString::fromLatin1( " + quoteString(s) +
" )";
270 return "TQString::fromUtf8( " + quoteString(s) +
" )";
273 static TQString dumpNode(
const TQDomNode &node)
276 TQTextStream s(&msg, IO_WriteOnly );
279 msg = msg.simplifyWhiteSpace();
280 if (msg.length() > 40)
281 return msg.left(37)+
"...";
285 static TQString filenameOnly(TQString path)
287 int i = path.findRev(
'/');
289 return path.mid(i+1);
293 static void preProcessDefault( TQString &defaultValue,
const TQString &name,
294 const TQString &type,
295 const TQValueList<CfgEntry::Choice> &choices,
298 if ( type ==
"String" && !defaultValue.isEmpty() ) {
299 defaultValue = literalString(defaultValue);
301 }
else if ( type ==
"Path" && !defaultValue.isEmpty() ) {
302 defaultValue = literalString( defaultValue );
304 }
else if ( (type ==
"StringList" || type ==
"PathList") && !defaultValue.isEmpty() ) {
305 TQTextStream cpp( &code, IO_WriteOnly | IO_Append );
309 cpp <<
" TQStringList default" << name <<
";" <<
endl;
310 TQStringList defaults = TQStringList::split(
",", defaultValue );
311 TQStringList::ConstIterator it;
312 for( it = defaults.begin(); it != defaults.end(); ++it ) {
313 cpp <<
" default" << name <<
".append( TQString::fromUtf8( \"" << *it <<
"\" ) );" 316 defaultValue =
"default" + name;
318 }
else if ( type ==
"Color" && !defaultValue.isEmpty() ) {
319 TQRegExp colorRe(
"\\d+,\\s*\\d+,\\s*\\d+");
320 if (colorRe.exactMatch(defaultValue))
322 defaultValue =
"TQColor( " + defaultValue +
" )";
326 defaultValue =
"TQColor( \"" + defaultValue +
"\" )";
329 }
else if ( type ==
"Enum" ) {
330 if ( !globalEnums ) {
331 TQValueList<CfgEntry::Choice>::ConstIterator it;
332 for( it = choices.begin(); it != choices.end(); ++it ) {
333 if ( (*it).name == defaultValue ) {
334 defaultValue.prepend( enumName(name) +
"::");
340 }
else if ( type ==
"IntList" ) {
341 TQTextStream cpp( &code, IO_WriteOnly | IO_Append );
345 cpp <<
" TQValueList<int> default" << name <<
";" <<
endl;
346 TQStringList defaults = TQStringList::split(
",", defaultValue );
347 TQStringList::ConstIterator it;
348 for( it = defaults.begin(); it != defaults.end(); ++it ) {
349 cpp <<
" default" << name <<
".append( " << *it <<
" );" 352 defaultValue =
"default" + name;
357 CfgEntry *parseEntry(
const TQString &group,
const TQDomElement &element )
359 bool defaultCode =
false;
360 TQString type = element.attribute(
"type" );
361 TQString name = element.attribute(
"name" );
362 TQString
key = element.attribute(
"key" );
363 TQString hidden = element.attribute(
"hidden" );
366 TQString defaultValue;
371 TQValueList<CfgEntry::Choice> choices;
372 TQStringList paramValues;
373 TQStringList paramDefaultValues;
379 for ( n = element.firstChild(); !n.isNull(); n = n.nextSibling() ) {
380 TQDomElement e = n.toElement();
381 TQString tag = e.tagName();
382 if ( tag ==
"label" ) label = e.text();
383 else if ( tag ==
"whatsthis" ) whatsThis = e.text();
384 else if ( tag ==
"min" ) minValue = e.text();
385 else if ( tag ==
"max" ) maxValue = e.text();
386 else if ( tag ==
"code" ) code = e.text();
387 else if ( tag ==
"parameter" )
389 param = e.attribute(
"name" );
390 paramType = e.attribute(
"type" );
391 if ( param.isEmpty() ) {
392 kdError() <<
"Parameter must have a name: " << dumpNode(e) <<
endl;
395 if ( paramType.isEmpty() ) {
396 kdError() <<
"Parameter must have a type: " << dumpNode(e) <<
endl;
399 if ((paramType ==
"Int") || (paramType ==
"UInt"))
402 paramMax = e.attribute(
"max").toInt(&ok);
405 kdError() <<
"Integer parameter must have a maximum (e.g. max=\"0\"): " << dumpNode(e) <<
endl;
409 else if (paramType ==
"Enum")
412 for ( n2 = e.firstChild(); !n2.isNull(); n2 = n2.nextSibling() ) {
413 TQDomElement e2 = n2.toElement();
414 if (e2.tagName() ==
"values")
417 for ( n3 = e2.firstChild(); !n3.isNull(); n3 = n3.nextSibling() ) {
418 TQDomElement e3 = n3.toElement();
419 if (e3.tagName() ==
"value")
421 paramValues.append( e3.text() );
427 if (paramValues.isEmpty())
429 kdError() <<
"No values specified for parameter '" << param <<
"'." <<
endl;
432 paramMax = paramValues.count()-1;
436 kdError() <<
"Parameter '" << param <<
"' has type " << paramType <<
" but must be of type int, uint or Enum." <<
endl;
440 else if ( tag ==
"default" )
442 if (e.attribute(
"param").isEmpty())
444 defaultValue = e.text();
445 if (e.attribute(
"code" ) ==
"true")
449 else if ( tag ==
"choices" ) {
451 for( n2 = e.firstChild(); !n2.isNull(); n2 = n2.nextSibling() ) {
452 TQDomElement e2 = n2.toElement();
453 if ( e2.tagName() ==
"choice" ) {
455 CfgEntry::Choice choice;
456 choice.name = e2.attribute(
"name" );
457 if ( choice.name.isEmpty() ) {
458 kdError() <<
"Tag <choice> requires attribute 'name'." <<
endl;
460 for( n3 = e2.firstChild(); !n3.isNull(); n3 = n3.nextSibling() ) {
461 TQDomElement e3 = n3.toElement();
462 if ( e3.tagName() ==
"label" ) choice.label = e3.text();
463 if ( e3.tagName() ==
"whatsthis" ) choice.whatsThis = e3.text();
465 choices.append( choice );
471 bool nameIsEmpty = name.isEmpty();
472 if ( nameIsEmpty && key.isEmpty() ) {
473 kdError() <<
"Entry must have a name or a key: " << dumpNode(element) <<
endl;
477 if ( key.isEmpty() ) {
483 name.replace(
" ", TQString() );
484 }
else if ( name.contains(
' ' ) ) {
485 kdWarning()<<
"Entry '"<<name<<
"' contains spaces! <name> elements can't contain speces!"<<
endl;
489 if (name.contains(
"$("))
493 kdError() <<
"Name may not be parameterized: " << name <<
endl;
499 if (!param.isEmpty())
501 kdError() <<
"Name must contain '$(" << param <<
")': " << name <<
endl;
506 if ( label.isEmpty() ) {
510 if ( type.isEmpty() ) type =
"String";
512 if (!param.isEmpty())
516 name.replace(
"$("+param+
")", TQString());
518 for(
int i = 0; i <= paramMax; i++)
520 paramDefaultValues.append(TQString());
524 for ( n = element.firstChild(); !n.isNull(); n = n.nextSibling() ) {
525 TQDomElement e = n.toElement();
526 TQString tag = e.tagName();
527 if ( tag ==
"default" )
529 TQString index = e.attribute(
"param");
534 int i = index.toInt(&ok);
537 i = paramValues.findIndex(index);
540 kdError() <<
"Index '" << index <<
"' for default value is unknown." <<
endl;
545 if ((i < 0) || (i > paramMax))
547 kdError() <<
"Index '" << i <<
"' for default value is out of range [0, "<< paramMax<<
"]." <<
endl;
551 TQString tmpDefaultValue = e.text();
553 if (e.attribute(
"code" ) !=
"true")
554 preProcessDefault(tmpDefaultValue, name, type, choices, code);
556 paramDefaultValues[i] = tmpDefaultValue;
561 if (!validNameRegexp->exactMatch(name))
564 kdError() <<
"The key '" << key <<
"' can not be used as name for the entry because " 565 "it is not a valid name. You need to specify a valid name for this entry." <<
endl;
567 kdError() <<
"The name '" << name <<
"' is not a valid name for an entry." <<
endl;
571 if (allNames.contains(name))
574 kdError() <<
"The key '" << key <<
"' can not be used as name for the entry because " 575 "it does not result in a unique name. You need to specify a unique name for this entry." <<
endl;
577 kdError() <<
"The name '" << name <<
"' is not unique." <<
endl;
580 allNames.append(name);
584 preProcessDefault(defaultValue, name, type, choices, code);
587 CfgEntry *result =
new CfgEntry( group, type, key, name, label, whatsThis,
588 code, defaultValue, choices,
590 if (!param.isEmpty())
592 result->setParam(param);
593 result->setParamName(paramName);
594 result->setParamType(paramType);
595 result->setParamValues(paramValues);
596 result->setParamDefaultValues(paramDefaultValues);
597 result->setParamMax(paramMax);
599 result->setMinValue(minValue);
600 result->setMaxValue(maxValue);
608 TQString param(
const TQString &type )
610 if ( type ==
"String" )
return "const TQString &";
611 else if ( type ==
"StringList" )
return "const TQStringList &";
612 else if ( type ==
"Font" )
return "const TQFont &";
613 else if ( type ==
"Rect" )
return "const TQRect &";
614 else if ( type ==
"Size" )
return "const TQSize &";
615 else if ( type ==
"Color" )
return "const TQColor &";
616 else if ( type ==
"Point" )
return "const TQPoint &";
617 else if ( type ==
"Int" )
return "int";
618 else if ( type ==
"UInt" )
return "uint";
619 else if ( type ==
"Bool" )
return "bool";
620 else if ( type ==
"Double" )
return "double";
621 else if ( type ==
"DateTime" )
return "const TQDateTime &";
622 else if ( type ==
"Int64" )
return "TQ_INT64";
623 else if ( type ==
"UInt64" )
return "TQ_UINT64";
624 else if ( type ==
"IntList" )
return "const TQValueList<int> &";
625 else if ( type ==
"Enum" )
return "int";
626 else if ( type ==
"Path" )
return "const TQString &";
627 else if ( type ==
"PathList" )
return "const TQStringList &";
628 else if ( type ==
"Password" )
return "const TQString &";
630 kdError() <<
"kconfig_compiler does not support type \""<< type <<
"\""<<
endl;
638 TQString cppType(
const TQString &type )
640 if ( type ==
"String" )
return "TQString";
641 else if ( type ==
"StringList" )
return "TQStringList";
642 else if ( type ==
"Font" )
return "TQFont";
643 else if ( type ==
"Rect" )
return "TQRect";
644 else if ( type ==
"Size" )
return "TQSize";
645 else if ( type ==
"Color" )
return "TQColor";
646 else if ( type ==
"Point" )
return "TQPoint";
647 else if ( type ==
"Int" )
return "int";
648 else if ( type ==
"UInt" )
return "uint";
649 else if ( type ==
"Bool" )
return "bool";
650 else if ( type ==
"Double" )
return "double";
651 else if ( type ==
"DateTime" )
return "TQDateTime";
652 else if ( type ==
"Int64" )
return "TQ_INT64";
653 else if ( type ==
"UInt64" )
return "TQ_UINT64";
654 else if ( type ==
"IntList" )
return "TQValueList<int>";
655 else if ( type ==
"Enum" )
return "int";
656 else if ( type ==
"Path" )
return "TQString";
657 else if ( type ==
"PathList" )
return "TQStringList";
658 else if ( type ==
"Password" )
return "TQString";
660 kdError()<<
"kconfig_compiler does not support type \""<< type <<
"\""<<
endl;
665 TQString defaultValue(
const TQString &type )
667 if ( type ==
"String" )
return "\"\"";
668 else if ( type ==
"StringList" )
return "TQStringList()";
669 else if ( type ==
"Font" )
return "KGlobalSettings::generalFont()";
670 else if ( type ==
"Rect" )
return "TQRect()";
671 else if ( type ==
"Size" )
return "TQSize()";
672 else if ( type ==
"Color" )
return "TQColor(128, 128, 128)";
673 else if ( type ==
"Point" )
return "TQPoint()";
674 else if ( type ==
"Int" )
return "0";
675 else if ( type ==
"UInt" )
return "0";
676 else if ( type ==
"Bool" )
return "false";
677 else if ( type ==
"Double" )
return "0.0";
678 else if ( type ==
"DateTime" )
return "TQDateTime()";
679 else if ( type ==
"Int64" )
return "0";
680 else if ( type ==
"UInt64" )
return "0";
681 else if ( type ==
"IntList" )
return "TQValueList<int>()";
682 else if ( type ==
"Enum" )
return "0";
683 else if ( type ==
"Path" )
return "\"\"";
684 else if ( type ==
"PathList" )
return "TQStringList()";
685 else if ( type ==
"Password" )
return "\"\"";
687 kdWarning()<<
"Error, kconfig_compiler doesn't support the \""<< type <<
"\" type!"<<
endl;
692 TQString itemType(
const TQString &type )
697 t.replace( 0, 1, t.left( 1 ).upper() );
702 static TQString itemDeclaration(
const CfgEntry *e)
707 TQString fCap = e->name();
708 fCap[0] = fCap[0].upper();
709 return " KConfigSkeleton::Item"+itemType( e->type() ) +
711 ( (!e->param().isEmpty())?(TQString(
"[%1]").arg(e->paramMax()+1)) : TQString()) +
718 static TQString itemVar(
const CfgEntry *e)
725 result =
"m" + e->name() +
"Item";
726 result[1] = result[1].upper();
730 result = e->name() +
"Item";
731 result[0] = result[0].lower();
736 result =
"item" + e->name();
737 result[4] = result[4].upper();
742 static TQString itemPath(
const CfgEntry *e)
746 result =
"d->"+itemVar(e);
754 TQString newItem(
const TQString &type,
const TQString &name,
const TQString &key,
755 const TQString &defaultValue,
const TQString ¶m = TQString())
757 TQString t =
"new KConfigSkeleton::Item" + itemType( type ) +
758 "( currentGroup(), " + key +
", " + varPath( name ) + param;
759 if ( type ==
"Enum" ) t +=
", values" + name;
760 if ( !defaultValue.isEmpty() ) {
762 if ( type ==
"String" ) t += defaultValue;
763 else t+= defaultValue;
770 TQString paramString(
const TQString &s,
const CfgEntry *e,
int i)
773 TQString needle =
"$("+e->param()+
")";
774 if (result.contains(needle))
777 if (e->paramType() ==
"Enum")
779 tmp = e->paramValues()[i];
783 tmp = TQString::number(i);
786 result.replace(needle, tmp);
791 TQString paramString(
const TQString &group,
const TQValueList<Param> ¶meters)
793 TQString paramString = group;
796 for (TQValueList<Param>::ConstIterator it = parameters.begin();
797 it != parameters.end(); ++it)
799 if (paramString.contains(
"$("+(*it).name+
")"))
802 tmp.sprintf(
"%%%d", i++);
803 paramString.replace(
"$("+(*it).name+
")", tmp);
804 arguments +=
".arg( mParam"+(*it).name+
" )";
807 if (arguments.isEmpty())
808 return "TQString::fromLatin1( \""+group+
"\" )";
810 return "TQString::fromLatin1( \""+paramString+
"\" )"+arguments;
814 TQString userTextsFunctions( CfgEntry *e, TQString itemVarStr=TQString(), TQString i=TQString() )
817 if (itemVarStr.isNull()) itemVarStr=itemPath(e);
818 if ( !e->label().isEmpty() ) {
819 txt +=
" " + itemVarStr +
"->setLabel( i18n(";
820 if ( !e->param().isEmpty() )
821 txt += quoteString(e->label().replace(
"$("+e->param()+
")", i));
823 txt+= quoteString(e->label());
826 if ( !e->whatsThis().isEmpty() ) {
827 txt +=
" " + itemVarStr +
"->setWhatsThis( i18n(";
828 if ( !e->param().isEmpty() )
829 txt += quoteString(e->whatsThis().replace(
"$("+e->param()+
")", i));
831 txt+= quoteString(e->whatsThis());
840 TQString memberAccessorBody( CfgEntry *e )
843 TQTextStream out(&result, IO_WriteOnly);
844 TQString n = e->name();
845 TQString t = e->type();
847 out <<
"return " << This << varPath(n);
848 if (!e->param().isEmpty()) out <<
"[i]";
857 TQString memberMutatorBody( CfgEntry *e )
860 TQTextStream out(&result, IO_WriteOnly);
861 TQString n = e->name();
862 TQString t = e->type();
864 if (!e->minValue().isEmpty())
866 out <<
"if (v < " << e->minValue() <<
")" <<
endl;
868 out <<
" kdDebug() << \"" << setFunction(n);
869 out <<
": value \" << v << \" is less than the minimum value of ";
870 out << e->minValue()<<
"\" << endl;" <<
endl;
871 out <<
" v = " << e->minValue() <<
";" <<
endl;
875 if (!e->maxValue().isEmpty())
877 out << endl <<
"if (v > " << e->maxValue() <<
")" <<
endl;
879 out <<
" kdDebug() << \"" << setFunction(n);
880 out <<
": value \" << v << \" is greater than the maximum value of ";
881 out << e->maxValue()<<
"\" << endl;" <<
endl;
882 out <<
" v = " << e->maxValue() <<
";" <<
endl;
883 out <<
"}" << endl <<
endl;
886 out <<
"if (!" << This <<
"isImmutable( TQString::fromLatin1( \"";
887 if (!e->param().isEmpty())
889 out << e->paramName().replace(
"$("+e->param()+
")",
"%1") <<
"\" ).arg( ";
890 if ( e->paramType() ==
"Enum" ) {
891 out <<
"TQString::fromLatin1( ";
894 out << enumName(e->param()) <<
"ToString[i]";
896 out << enumName(e->param()) <<
"::enumToString[i]";
910 out <<
" ))" <<
endl;
911 out <<
" " << This << varPath(n);
912 if (!e->param().isEmpty())
914 out <<
" = v;" <<
endl;
922 TQString itemAccessorBody( CfgEntry *e )
925 TQTextStream out(&result, IO_WriteOnly);
927 out <<
"return " << itemPath(e);
928 if (!e->param().isEmpty()) out <<
"[i]";
935 TQString indent(TQString text,
int spaces)
938 TQTextStream out(&result, IO_WriteOnly);
939 TQTextStream in(&text, IO_ReadOnly);
941 while ( !in.atEnd() )
943 currLine = in.readLine();
944 if (!currLine.isEmpty())
945 for (
int i=0; i < spaces; i++)
947 out << currLine <<
endl;
953 int main(
int argc,
char **argv )
955 KAboutData aboutData(
"kconfig_compiler", I18N_NOOP(
"KDE .kcfg compiler"),
"0.3",
956 I18N_NOOP(
"KConfig Compiler") , KAboutData::License_LGPL );
957 aboutData.addAuthor(
"Cornelius Schumacher", 0,
"schumacher@kde.org" );
958 aboutData.addAuthor(
"Waldo Bastian", 0,
"bastian@kde.org" );
959 aboutData.addAuthor(
"Zack Rusin", 0,
"zack@kde.org" );
960 aboutData.addCredit(
"Reinhold Kainhofer",
"Fix for parametrized entries",
961 "reinhold@kainhofer.com",
"http://reinhold.kainhofer.com" );
962 aboutData.addCredit(
"Duncan Mac-Vicar P.",
"dpointer support",
963 "duncan@kde.org",
"http://www.mac-vicar.com/~duncan" );
972 if ( args->
count() < 2 ) {
973 kdError() <<
"Too few arguments." <<
endl;
976 if ( args->
count() > 2 ) {
977 kdError() <<
"Too many arguments." <<
endl;
981 validNameRegexp =
new TQRegExp(
"[a-zA-Z_][a-zA-Z0-9_]*");
983 TQString baseDir = TQFile::decodeName(args->
getOption(
"directory"));
984 if (!baseDir.endsWith(
"/"))
987 TQString inputFilename = args->
url( 0 ).
path();
988 TQString codegenFilename = args->
url( 1 ).
path();
990 if (!codegenFilename.endsWith(
".kcfgc"))
992 kdError() <<
"Codegen options file must have extension .kcfgc" <<
endl;
996 baseName = baseName.left(baseName.length() - 6);
1000 TQString nameSpace = codegenConfig.readEntry(
"NameSpace");
1001 TQString className = codegenConfig.readEntry(
"ClassName");
1002 TQString inherits = codegenConfig.readEntry(
"Inherits");
1003 TQString visibility = codegenConfig.readEntry(
"Visibility");
1004 if (!visibility.isEmpty()) visibility+=
" ";
1005 bool singleton = codegenConfig.readBoolEntry(
"Singleton",
false);
1006 bool staticAccessors = singleton;
1008 bool customAddons = codegenConfig.readBoolEntry(
"CustomAdditions");
1009 TQString memberVariables = codegenConfig.readEntry(
"MemberVariables");
1010 TQStringList headerIncludes = codegenConfig.readListEntry(
"IncludeFiles");
1011 TQStringList mutators = codegenConfig.readListEntry(
"Mutators");
1012 bool allMutators =
false;
1013 if ((mutators.count() == 1) && (mutators[0].lower() ==
"true"))
1015 itemAccessors = codegenConfig.readBoolEntry(
"ItemAccessors",
false );
1016 bool setUserTexts = codegenConfig.readBoolEntry(
"SetUserTexts",
false );
1018 globalEnums = codegenConfig.readBoolEntry(
"GlobalEnums",
false );
1020 dpointer = (memberVariables ==
"dpointer");
1022 TQFile input( inputFilename );
1028 if ( !doc.setContent( &input, &errorMsg, &errorRow, &errorCol ) ) {
1029 kdError() <<
"Unable to load document." <<
endl;
1030 kdError() <<
"Parse error in " << args->
url( 0 ).
fileName() <<
", line " << errorRow <<
", col " << errorCol <<
": " << errorMsg <<
endl;
1034 TQDomElement cfgElement = doc.documentElement();
1036 if ( cfgElement.isNull() ) {
1037 kdError() <<
"No document in kcfg file" <<
endl;
1041 TQString cfgFileName;
1042 bool cfgFileNameArg =
false;
1043 TQValueList<Param> parameters;
1044 TQStringList includes;
1046 TQPtrList<CfgEntry> entries;
1047 entries.setAutoDelete(
true );
1050 for ( n = cfgElement.firstChild(); !n.isNull(); n = n.nextSibling() ) {
1051 TQDomElement e = n.toElement();
1053 TQString tag = e.tagName();
1055 if ( tag ==
"include" ) {
1056 TQString includeFile = e.text();
1057 if (!includeFile.isEmpty())
1058 includes.append(includeFile);
1060 }
else if ( tag ==
"kcfgfile" ) {
1061 cfgFileName = e.attribute(
"name" );
1062 cfgFileNameArg = e.attribute(
"arg" ).lower() ==
"true";
1064 for( n2 = e.firstChild(); !n2.isNull(); n2 = n2.nextSibling() ) {
1065 TQDomElement e2 = n2.toElement();
1066 if ( e2.tagName() ==
"parameter" ) {
1068 p.name = e2.attribute(
"name" );
1069 p.type = e2.attribute(
"type" );
1070 if (p.type.isEmpty())
1072 parameters.append( p );
1076 }
else if ( tag ==
"group" ) {
1077 TQString group = e.attribute(
"name" );
1078 if ( group.isEmpty() ) {
1079 kdError() <<
"Group without name" <<
endl;
1083 for( n2 = e.firstChild(); !n2.isNull(); n2 = n2.nextSibling() ) {
1084 TQDomElement e2 = n2.toElement();
1085 if ( e2.tagName() !=
"entry" )
continue;
1086 CfgEntry *entry = parseEntry( group, e2 );
1087 if ( entry ) entries.append( entry );
1089 kdError() <<
"Can't parse entry." <<
endl;
1096 if ( inherits.isEmpty() ) inherits =
"KConfigSkeleton";
1098 if ( className.isEmpty() ) {
1099 kdError() <<
"Class name missing" <<
endl;
1103 if ( singleton && !parameters.isEmpty() ) {
1104 kdError() <<
"Singleton class can not have parameters" <<
endl;
1108 if ( !cfgFileName.isEmpty() && cfgFileNameArg)
1110 kdError() <<
"Having both a fixed filename and a filename as argument is not possible." <<
endl;
1114 if ( entries.isEmpty() ) {
1115 kdWarning() <<
"No entries." <<
endl;
1120 for( cfg = entries.first(); cfg; cfg = entries.next() ) {
1125 TQString headerFileName = baseName +
".h";
1126 TQString implementationFileName = baseName +
".cpp";
1127 TQString cppPreamble;
1129 TQFile header( baseDir + headerFileName );
1130 if ( !header.open( IO_WriteOnly ) ) {
1131 kdError() <<
"Can't open '" << headerFileName <<
"' for writing." <<
endl;
1135 TQTextStream h( &header );
1137 h <<
"// This file is generated by kconfig_compiler from " << args->
url(0).
fileName() <<
"." <<
endl;
1138 h <<
"// All changes you do to this file will be lost." <<
endl;
1140 h <<
"#ifndef " << ( !nameSpace.isEmpty() ? nameSpace.upper() +
"_" :
"" )
1141 << className.upper() <<
"_H" <<
endl;
1142 h <<
"#define " << ( !nameSpace.isEmpty() ? nameSpace.upper() +
"_" :
"" )
1143 << className.upper() <<
"_H" << endl <<
endl;
1146 TQStringList::ConstIterator it;
1147 for( it = headerIncludes.begin(); it != headerIncludes.end(); ++it ) {
1148 h <<
"#include <" << *it <<
">" <<
endl;
1151 if ( headerIncludes.count() > 0 ) h << endl;
1153 if ( !singleton && cfgFileNameArg && parameters.isEmpty() )
1154 h <<
"#include <kglobal.h>" << endl;
1156 h <<
"#include <kconfigskeleton.h>" <<
endl;
1157 h <<
"#include <kdebug.h>" << endl <<
endl;
1160 for( it = includes.begin(); it != includes.end(); ++it ) {
1161 h <<
"#include <" << *it <<
">" <<
endl;
1165 if ( !nameSpace.isEmpty() )
1166 h <<
"namespace " << nameSpace <<
" {" << endl << endl;
1170 h <<
"class " << className <<
"Private;" << endl <<
endl;
1173 h <<
"class " << visibility << className <<
" : public " << inherits <<
endl;
1175 h <<
" public:" <<
endl;
1179 for( e = entries.first(); e; e = entries.next() ) {
1180 TQValueList<CfgEntry::Choice> choices = e->choices();
1181 if ( !choices.isEmpty() ) {
1182 TQStringList values;
1183 TQValueList<CfgEntry::Choice>::ConstIterator itChoice;
1184 for( itChoice = choices.begin(); itChoice != choices.end(); ++itChoice ) {
1185 values.append( (*itChoice).name );
1187 if ( globalEnums ) {
1188 h <<
" enum { " << values.join(
", " ) <<
" };" <<
endl;
1190 h <<
" class " << enumName(e->name()) << endl;
1192 h <<
" public:" <<
endl;
1193 h <<
" enum type { " << values.join(
", " ) <<
", COUNT };" <<
endl;
1197 TQStringList values = e->paramValues();
1198 if ( !values.isEmpty() ) {
1199 if ( globalEnums ) {
1200 h <<
" enum { " << values.join(
", " ) <<
" };" <<
endl;
1201 h <<
" static const char* const " << enumName(e->param()) <<
"ToString[];" << endl;
1202 cppPreamble +=
"const char* const " + className +
"::" + enumName(e->param()) +
"ToString[] = " +
1203 "{ \"" + values.join(
"\", \"" ) +
"\" };\n";
1205 h <<
" class " << enumName(e->param()) << endl;
1207 h <<
" public:" <<
endl;
1208 h <<
" enum type { " << values.join(
", " ) <<
", COUNT };" <<
endl;
1209 h <<
" static const char* const enumToString[];" <<
endl;
1211 cppPreamble +=
"const char* const " + className +
"::" + enumName(e->param()) +
"::enumToString[] = " +
1212 "{ \"" + values.join(
"\", \"" ) +
"\" };\n";
1221 h <<
" " << className <<
"(";
1223 h <<
" KSharedConfig::Ptr config" << (parameters.isEmpty() ?
" = KGlobal::sharedConfig()" :
", ");
1224 for (TQValueList<Param>::ConstIterator it = parameters.begin();
1225 it != parameters.end(); ++it)
1227 if (it != parameters.begin())
1229 h <<
" " << param((*it).type) <<
" " << (*it).name;
1233 h <<
" static " << className <<
" *self();" <<
endl;
1235 h <<
" static void instance(const char * cfgfilename);" <<
endl;
1239 h <<
" ~" << className <<
"();" << endl <<
endl;
1242 if (staticAccessors)
1247 for( e = entries.first(); e; e = entries.next() ) {
1248 TQString n = e->name();
1249 TQString t = e->type();
1252 if (allMutators || mutators.contains(n))
1254 h <<
" /**" <<
endl;
1255 h <<
" Set " << e->label() <<
endl;
1257 if (staticAccessors)
1258 h <<
" static" <<
endl;
1259 h <<
" void " << setFunction(n) <<
"( ";
1260 if (!e->param().isEmpty())
1261 h << cppType(e->paramType()) <<
" i, ";
1262 h << param( t ) <<
" v )";
1267 h << endl <<
" {" <<
endl;
1268 h << indent(memberMutatorBody(e), 6 );
1278 h <<
" /**" <<
endl;
1279 h <<
" Get " << e->label() <<
endl;
1281 if (staticAccessors)
1282 h <<
" static" <<
endl;
1283 h <<
" " << cppType(t) <<
" " << getFunction(n) <<
"(";
1284 if (!e->param().isEmpty())
1285 h <<
" " << cppType(e->paramType()) <<
" i ";
1291 h << endl <<
" {" <<
endl;
1292 h << indent(memberAccessorBody(e), 6 );
1301 if ( itemAccessors ) {
1303 h <<
" /**" <<
endl;
1304 h <<
" Get Item object corresponding to " << n <<
"()" 1307 h <<
" Item" << itemType( e->type() ) <<
" *" 1308 << getFunction( n ) <<
"Item(";
1309 if (!e->param().isEmpty()) {
1310 h <<
" " << cppType(e->paramType()) <<
" i ";
1315 h << endl <<
" {" <<
endl;
1316 h << indent( itemAccessorBody(e), 6);
1330 h <<
" static" <<
endl;
1331 h <<
" void writeConfig()" <<
endl;
1333 h <<
" static_cast<KConfigSkeleton*>(self())->writeConfig();" <<
endl;
1337 h <<
" protected:" <<
endl;
1341 h <<
" " << className <<
"(";
1342 if ( cfgFileNameArg )
1343 h <<
"const char *arg";
1345 h <<
" static " << className <<
" *mSelf;" << endl <<
endl;
1349 if ( !memberVariables.isEmpty() && memberVariables !=
"private" && memberVariables !=
"dpointer") {
1350 h <<
" " << memberVariables <<
":" <<
endl;
1354 for (TQValueList<Param>::ConstIterator it = parameters.begin();
1355 it != parameters.end(); ++it)
1357 h <<
" " << cppType((*it).type) <<
" mParam" << (*it).name <<
";" <<
endl;
1360 if ( memberVariables !=
"dpointer" )
1363 for( e = entries.first(); e; e = entries.next() ) {
1364 if ( e->group() != group ) {
1367 h <<
" // " << group <<
endl;
1369 h <<
" " << cppType(e->type()) <<
" " << varName(e->name());
1370 if (!e->param().isEmpty())
1372 h << TQString(
"[%1]").arg(e->paramMax()+1);
1377 h << endl <<
" private:" <<
endl;
1378 if ( itemAccessors ) {
1379 for( e = entries.first(); e; e = entries.next() ) {
1380 h <<
" Item" << itemType( e->type() ) <<
" *" << itemVar( e );
1381 if (!e->param().isEmpty() ) h << TQString(
"[%1]").arg( e->paramMax()+1 );
1390 h <<
" private:" <<
endl;
1391 h <<
" " + className +
"Private *d;" <<
endl;
1396 h <<
" // Include custom additions" <<
endl;
1397 h <<
" #include \"" << filenameOnly(baseName) <<
"_addons.h\"" <<
endl;
1400 h <<
"};" << endl <<
endl;
1402 if ( !nameSpace.isEmpty() ) h <<
"}" << endl << endl;
1404 h <<
"#endif" << endl <<
endl;
1409 TQFile implementation( baseDir + implementationFileName );
1410 if ( !implementation.open( IO_WriteOnly ) ) {
1411 kdError() <<
"Can't open '" << implementationFileName <<
"' for writing." 1416 TQTextStream cpp( &implementation );
1419 cpp <<
"// This file is generated by kconfig_compiler from " << args->
url(0).
fileName() <<
"." <<
endl;
1420 cpp <<
"// All changes you do to this file will be lost." << endl <<
endl;
1422 cpp <<
"#include \"" << headerFileName <<
"\"" << endl <<
endl;
1424 if ( setUserTexts ) cpp <<
"#include <klocale.h>" << endl <<
endl;
1428 cpp <<
"#include <kstaticdeleter.h>" << endl <<
endl;
1429 if ( singleton && cfgFileNameArg )
1430 cpp <<
"#include <kdebug.h>" << endl <<
endl;
1432 if ( !nameSpace.isEmpty() )
1433 cpp <<
"using namespace " << nameSpace <<
";" << endl << endl;
1440 cpp <<
"class " << className <<
"Private" <<
endl;
1442 cpp <<
" public:" <<
endl;
1443 for( e = entries.first(); e; e = entries.next() ) {
1444 if ( e->group() != group ) {
1447 cpp <<
" // " << group <<
endl;
1449 cpp <<
" " << cppType(e->type()) <<
" " << varName(e->name());
1450 if (!e->param().isEmpty())
1452 cpp << TQString(
"[%1]").arg(e->paramMax()+1);
1456 cpp << endl <<
" // items" <<
endl;
1457 for( e = entries.first(); e; e = entries.next() ) {
1458 cpp <<
" KConfigSkeleton::Item" << itemType( e->type() ) <<
" *" << itemVar( e );
1459 if (!e->param().isEmpty() ) cpp << TQString(
"[%1]").arg( e->paramMax()+1 );
1463 cpp <<
"};" << endl <<
endl;
1468 cpp << className <<
" *" << className <<
"::mSelf = 0;" <<
endl;
1469 cpp <<
"static KStaticDeleter<" << className <<
"> static" << className <<
"Deleter;" << endl <<
endl;
1471 cpp << className <<
" *" << className <<
"::self()" <<
endl;
1473 if ( cfgFileNameArg ) {
1474 cpp <<
" if (!mSelf)" <<
endl;
1475 cpp <<
" kdFatal() << \"you need to call " << className <<
"::instance before using\" << endl;" <<
endl;
1477 cpp <<
" if ( !mSelf ) {" <<
endl;
1478 cpp <<
" static" << className <<
"Deleter.setObject( mSelf, new " << className <<
"() );" <<
endl;
1479 cpp <<
" mSelf->readConfig();" <<
endl;
1480 cpp <<
" }" << endl <<
endl;
1482 cpp <<
" return mSelf;" <<
endl;
1483 cpp <<
"}" << endl <<
endl;
1485 if ( cfgFileNameArg ) {
1486 cpp <<
"void " << className <<
"::instance(const char *cfgfilename)" <<
endl;
1488 cpp <<
" if (mSelf) {" <<
endl;
1489 cpp <<
" kdError() << \"" << className <<
"::instance called after the first use - ignoring\" << endl;" <<
endl;
1490 cpp <<
" return;" <<
endl;
1491 cpp <<
" }" <<
endl;
1492 cpp <<
" static" << className <<
"Deleter.setObject( mSelf, new " << className <<
"(cfgfilename) );" <<
endl;
1493 cpp <<
" mSelf->readConfig();" <<
endl;
1494 cpp <<
"}" << endl <<
endl;
1498 if ( !cppPreamble.isEmpty() )
1499 cpp << cppPreamble << endl;
1502 cpp << className <<
"::" << className <<
"( ";
1503 if ( cfgFileNameArg ) {
1505 cpp <<
" KSharedConfig::Ptr config";
1507 cpp <<
" const char *config";
1508 cpp << (parameters.isEmpty() ?
" " :
", ");
1511 for (TQValueList<Param>::ConstIterator it = parameters.begin();
1512 it != parameters.end(); ++it)
1514 if (it != parameters.begin())
1516 cpp <<
" " << param((*it).type) <<
" " << (*it).name;
1518 cpp <<
" )" <<
endl;
1520 cpp <<
" : " << inherits <<
"(";
1521 if ( !cfgFileName.isEmpty() ) cpp <<
" TQString::fromLatin1( \"" << cfgFileName <<
"\" ";
1522 if ( cfgFileNameArg ) cpp <<
" config ";
1523 if ( !cfgFileName.isEmpty() ) cpp <<
") ";
1527 for (TQValueList<Param>::ConstIterator it = parameters.begin();
1528 it != parameters.end(); ++it)
1530 cpp <<
" , mParam" << (*it).name <<
"(" << (*it).name <<
")" <<
endl;
1536 cpp <<
" d = new " + className +
"Private;" <<
endl;
1540 cpp <<
" mSelf = this;" <<
endl;
1543 for( e = entries.first(); e; e = entries.next() ) {
1544 if ( e->group() != group ) {
1545 if ( !group.isEmpty() ) cpp << endl;
1547 cpp <<
" setCurrentGroup( " << paramString(group, parameters) <<
" );" << endl <<
endl;
1550 TQString key = paramString(e->key(), parameters);
1551 if ( !e->code().isEmpty())
1553 cpp << e->code() <<
endl;
1555 if ( e->type() ==
"Enum" ) {
1556 cpp <<
" TQValueList<KConfigSkeleton::ItemEnum::Choice> values" 1557 << e->name() <<
";" <<
endl;
1558 TQValueList<CfgEntry::Choice> choices = e->choices();
1559 TQValueList<CfgEntry::Choice>::ConstIterator it;
1560 for( it = choices.begin(); it != choices.end(); ++it ) {
1561 cpp <<
" {" <<
endl;
1562 cpp <<
" KConfigSkeleton::ItemEnum::Choice choice;" <<
endl;
1563 cpp <<
" choice.name = TQString::fromLatin1( \"" << (*it).name <<
"\" );" <<
endl;
1564 if ( setUserTexts ) {
1565 if ( !(*it).label.isEmpty() )
1566 cpp <<
" choice.label = i18n(" << quoteString((*it).label) <<
");" <<
endl;
1567 if ( !(*it).whatsThis.isEmpty() )
1568 cpp <<
" choice.whatsThis = i18n(" << quoteString((*it).whatsThis) <<
");" <<
endl;
1570 cpp <<
" values" << e->name() <<
".append( choice );" <<
endl;
1571 cpp <<
" }" <<
endl;
1576 cpp << itemDeclaration(e);
1578 if (e->param().isEmpty())
1581 cpp <<
" " << itemPath(e) <<
" = " 1582 << newItem( e->type(), e->name(), key, e->defaultValue() ) << endl;
1584 if ( !e->minValue().isEmpty() )
1585 cpp <<
" " << itemPath(e) <<
"->setMinValue(" << e->minValue() <<
");" <<
endl;
1586 if ( !e->maxValue().isEmpty() )
1587 cpp <<
" " << itemPath(e) <<
"->setMaxValue(" << e->maxValue() <<
");" <<
endl;
1590 cpp << userTextsFunctions( e );
1592 cpp <<
" addItem( " << itemPath(e);
1593 TQString quotedName = e->name();
1594 addQuotes( quotedName );
1595 if ( quotedName != key ) cpp <<
", TQString::fromLatin1( \"" << e->name() <<
"\" )";
1596 cpp <<
" );" <<
endl;
1601 for(
int i = 0; i <= e->paramMax(); i++)
1603 TQString defaultStr;
1604 TQString itemVarStr(itemPath(e)+TQString(
"[%1]").arg(i));
1606 if ( !e->paramDefaultValue(i).isEmpty() )
1607 defaultStr = e->paramDefaultValue(i);
1608 else if ( !e->defaultValue().isEmpty() )
1609 defaultStr = paramString(e->defaultValue(), e, i);
1611 defaultStr = defaultValue( e->type() );
1613 cpp <<
" " << itemVarStr <<
" = " 1614 << newItem( e->type(), e->name(), paramString(key, e, i), defaultStr, TQString(
"[%1]").arg(i) )
1618 cpp << userTextsFunctions( e, itemVarStr, e->paramName() );
1624 cpp <<
" addItem( " << itemVarStr <<
", TQString::fromLatin1( \"";
1625 if ( e->paramType()==
"Enum" )
1626 cpp << e->paramName().replace(
"$("+e->param()+
")",
"%1").arg(e->paramValues()[i] );
1628 cpp << e->paramName().replace(
"$("+e->param()+
")",
"%1").arg(i);
1629 cpp <<
"\" ) );" <<
endl;
1634 cpp <<
"}" << endl <<
endl;
1639 for( e = entries.first(); e; e = entries.next() )
1641 TQString n = e->name();
1642 TQString t = e->type();
1645 if (allMutators || mutators.contains(n))
1647 cpp <<
"void " << setFunction(n, className) <<
"( ";
1648 if (!e->param().isEmpty())
1649 cpp << cppType(e->paramType()) <<
" i, ";
1650 cpp << param( t ) <<
" v )" <<
endl;
1654 cpp << indent(memberMutatorBody(e), 6);
1655 cpp <<
"}" << endl <<
endl;
1659 cpp << cppType(t) <<
" " << getFunction(n, className) <<
"(";
1660 if (!e->param().isEmpty())
1661 cpp <<
" " << cppType(e->paramType()) <<
" i ";
1662 cpp <<
")" << Const <<
endl;
1666 cpp << indent(memberAccessorBody(e), 2);
1667 cpp <<
"}" << endl <<
endl;
1670 if ( itemAccessors )
1673 cpp <<
"KConfigSkeleton::Item" << itemType( e->type() ) <<
" *" 1674 << getFunction( n, className ) <<
"Item(";
1675 if (!e->param().isEmpty()) {
1676 cpp <<
" " << cppType(e->paramType()) <<
" i ";
1680 cpp << indent(itemAccessorBody(e), 2);
1689 cpp << className <<
"::~" << className <<
"()" <<
endl;
1693 cpp <<
" delete d;" <<
endl;
1694 cpp <<
" if ( mSelf == this )" <<
endl;
1695 cpp <<
" static" << className <<
"Deleter.setObject( mSelf, 0, false );" <<
endl;
1697 cpp <<
"}" << endl <<
endl;
1699 implementation.close();
TQString label(StdAccel id)
Returns a localized label for user-visible display.
A class for command-line argument handling.
TQString fileName(bool _ignore_trailing_slash_in_path=true) const
Returns the filename of the path.
static KCmdLineArgs * parsedArgs(const char *id=0)
Access parsed arguments.
int count() const
Read the number of arguments that aren't options (but, for example, filenames).
Structure that holds command line options.
Access to KDE global objects for use in shared libraries.
This class is used to store information about a program.
const char * name(StdAction id)
static void init(int _argc, char **_argv, const char *_appname, const char *programName, const char *_description, const char *_version, bool noKApp=false)
Initialize class.
static void addCmdLineOptions(const KCmdLineOptions *options, const char *name=0, const char *id=0, const char *afterId=0)
Add options to your application.
KAction * whatsThis(const TQObject *recvr, const char *slot, KActionCollection *parent, const char *name=0)
KURL url(int n) const
Read out an argument representing a URL.
TQString path() const
Returns the current decoded path.
kndbgstream & endl(kndbgstream &s)
Does nothing.
KDE Configuration entries.
TQCString getOption(const char *option) const
Read out a string option.