00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
#include <qfile.h>
00026
#include <qtextstream.h>
00027
#include <qdom.h>
00028
#include <qregexp.h>
00029
00030
#include <kaboutdata.h>
00031
#include <kapplication.h>
00032
#include <kdebug.h>
00033
#include <klocale.h>
00034
#include <kcmdlineargs.h>
00035
#include <kglobal.h>
00036
#include <kconfig.h>
00037
#include <ksimpleconfig.h>
00038
#include <kstandarddirs.h>
00039
00040
#include <iostream>
00041
00042
static const KCmdLineOptions options[] =
00043 {
00044 {
"d", 0, 0 },
00045 {
"directory <dir>", I18N_NOOP(
"Directory to generate files in"),
"." },
00046 {
"+file.kcfg", I18N_NOOP(
"Input kcfg XML file"), 0 },
00047 {
"+file.kcfgc", I18N_NOOP(
"Code generation options file"), 0 },
00048 KCmdLineLastOption
00049 };
00050
00051
00052
bool globalEnums;
00053
bool itemAccessors;
00054
QStringList allNames;
00055
QRegExp *validNameRegexp;
00056
00057
class CfgEntry
00058 {
00059
public:
00060
struct Choice
00061 {
00062
QString name;
00063
QString label;
00064
QString whatsThis;
00065 };
00066
00067 CfgEntry(
const QString &group,
const QString &type,
const QString &key,
00068
const QString &name,
const QString &label,
00069
const QString &whatsThis,
const QString &code,
00070
const QString &defaultValue,
const QValueList<Choice> &choices,
00071
bool hidden )
00072 : mGroup( group ), mType( type ), mKey(
key ), mName(
name ),
00073 mLabel(
label ), mWhatsThis(
whatsThis ), mCode( code ),
00074 mDefaultValue( defaultValue ),
00075 mChoices( choices ), mHidden( hidden )
00076 {
00077 }
00078
00079
void setGroup(
const QString &group ) { mGroup = group; }
00080
QString group()
const {
return mGroup; }
00081
00082
void setType(
const QString &type ) { mType = type; }
00083
QString type()
const {
return mType; }
00084
00085
void setKey(
const QString &key ) { mKey =
key; }
00086
QString key()
const {
return mKey; }
00087
00088
void setName(
const QString &name ) { mName =
name; }
00089
QString name()
const {
return mName; }
00090
00091
void setLabel(
const QString &label ) { mLabel =
label; }
00092
QString label()
const {
return mLabel; }
00093
00094
void setWhatsThis(
const QString &whatsThis ) { mWhatsThis =
whatsThis; }
00095
QString whatsThis()
const {
return mWhatsThis; }
00096
00097
void setDefaultValue(
const QString &d ) { mDefaultValue = d; }
00098
QString defaultValue()
const {
return mDefaultValue; }
00099
00100
void setCode(
const QString &d ) { mCode = d; }
00101
QString code()
const {
return mCode; }
00102
00103
void setMinValue(
const QString &d ) { mMin = d; }
00104
QString minValue()
const {
return mMin; }
00105
00106
void setMaxValue(
const QString &d ) { mMax = d; }
00107
QString maxValue()
const {
return mMax; }
00108
00109
void setParam(
const QString &d ) { mParam = d; }
00110
QString param()
const {
return mParam; }
00111
00112
void setParamName(
const QString &d ) { mParamName = d; }
00113
QString paramName()
const {
return mParamName; }
00114
00115
void setParamType(
const QString &d ) { mParamType = d; }
00116
QString paramType()
const {
return mParamType; }
00117
00118
void setChoices(
const QValueList<Choice> &d ) { mChoices = d; }
00119
QValueList<Choice> choices()
const {
return mChoices; }
00120
00121
void setParamValues(
const QStringList &d ) { mParamValues = d; }
00122
QStringList paramValues()
const {
return mParamValues; }
00123
00124
void setParamDefaultValues(
const QStringList &d ) { mParamDefaultValues = d; }
00125
QString paramDefaultValue(
int i)
const {
return mParamDefaultValues[i]; }
00126
00127
void setParamMax(
int d ) { mParamMax = d; }
00128
int paramMax()
const {
return mParamMax; }
00129
00130
bool hidden()
const {
return mHidden; }
00131
00132
void dump()
const
00133
{
00134 kdDebug() <<
"<entry>" <<
endl;
00135 kdDebug() <<
" group: " << mGroup <<
endl;
00136 kdDebug() <<
" type: " << mType <<
endl;
00137 kdDebug() <<
" key: " << mKey <<
endl;
00138 kdDebug() <<
" name: " << mName <<
endl;
00139 kdDebug() <<
" label: " << mLabel <<
endl;
00140
00141 kdDebug() <<
" code: " << mCode <<
endl;
00142
00143
00144
if (!param().isEmpty())
00145 {
00146 kdDebug() <<
" param name: "<< mParamName <<
endl;
00147 kdDebug() <<
" param type: "<< mParamType <<
endl;
00148 kdDebug() <<
" paramvalues: " << mParamValues.join(
":") <<
endl;
00149 }
00150 kdDebug() <<
" default: " << mDefaultValue <<
endl;
00151 kdDebug() <<
" hidden: " << mHidden <<
endl;
00152 kdDebug() <<
" min: " << mMin <<
endl;
00153 kdDebug() <<
" max: " << mMax <<
endl;
00154 kdDebug() <<
"</entry>" <<
endl;
00155 }
00156
00157
private:
00158
QString mGroup;
00159
QString mType;
00160
QString mKey;
00161
QString mName;
00162
QString mLabel;
00163
QString mWhatsThis;
00164
QString mCode;
00165
QString mDefaultValue;
00166
QString mParam;
00167
QString mParamName;
00168
QString mParamType;
00169
QValueList<Choice> mChoices;
00170
QStringList mParamValues;
00171
QStringList mParamDefaultValues;
00172
int mParamMax;
00173
bool mHidden;
00174
QString mMin;
00175
QString mMax;
00176 };
00177
00178
class Param {
00179
public:
00180
QString name;
00181
QString type;
00182 };
00183
00184
static QString varName(
const QString &n)
00185 {
00186
QString result =
"m"+n;
00187 result[1] = result[1].upper();
00188
return result;
00189 }
00190
00191
static QString enumName(
const QString &n)
00192 {
00193
QString result =
"Enum"+n;
00194 result[4] = result[4].upper();
00195
return result;
00196 }
00197
00198
static QString setFunction(
const QString &n)
00199 {
00200
QString result =
"set"+n;
00201 result[3] = result[3].upper();
00202
return result;
00203 }
00204
00205
00206
static QString getFunction(
const QString &n)
00207 {
00208
QString result = n;
00209 result[0] = result[0].lower();
00210
return result;
00211 }
00212
00213
00214
static void addQuotes(
QString &s )
00215 {
00216
if ( s.left( 1 ) !=
"\"" ) s.prepend(
"\"" );
00217
if ( s.right( 1 ) !=
"\"" ) s.append(
"\"" );
00218 }
00219
00220
static QString quoteString(
const QString &s )
00221 {
00222
QString r = s;
00223 r.replace(
"\\",
"\\\\" );
00224 r.replace(
"\"",
"\\\"" );
00225 r.replace(
"\r",
"" );
00226 r.replace(
"\n",
"\\n\"\n\"" );
00227
return "\"" + r +
"\"";
00228 }
00229
00230
static QString literalString(
const QString &s )
00231 {
00232
bool isAscii =
true;
00233
for(
int i = s.length(); i--;)
00234
if (s[i].unicode() > 127) isAscii =
false;
00235
00236
if (isAscii)
00237
return "QString::fromLatin1( " + quoteString(s) +
" )";
00238
else
00239
return "QString::fromUtf8( " + quoteString(s) +
" )";
00240 }
00241
00242
static QString dumpNode(
const QDomNode &node)
00243 {
00244
QString msg;
00245
QTextStream s(&msg, IO_WriteOnly );
00246 node.save(s, 0);
00247
00248 msg = msg.simplifyWhiteSpace();
00249
if (msg.length() > 40)
00250
return msg.left(37)+
"...";
00251
return msg;
00252 }
00253
00254
static QString filenameOnly(
QString path)
00255 {
00256
int i = path.findRev(
'/');
00257
if (i >= 0)
00258
return path.mid(i+1);
00259
return path;
00260 }
00261
00262
static void preProcessDefault(
QString &defaultValue,
const QString &name,
00263
const QString &type,
00264
const QValueList<CfgEntry::Choice> &choices,
00265
QString &code )
00266 {
00267
if ( type ==
"String" && !defaultValue.isEmpty() ) {
00268 defaultValue = literalString(defaultValue);
00269
00270 }
else if ( type ==
"Path" && !defaultValue.isEmpty() ) {
00271 defaultValue = literalString( defaultValue );
00272
00273 }
else if ( (type ==
"StringList" || type ==
"PathList") && !defaultValue.isEmpty() ) {
00274
QTextStream cpp( &code, IO_WriteOnly | IO_Append );
00275
if (!code.isEmpty())
00276 cpp <<
endl;
00277
00278 cpp <<
" QStringList default" <<
name <<
";" <<
endl;
00279
QStringList defaults = QStringList::split(
",", defaultValue );
00280 QStringList::ConstIterator it;
00281
for( it = defaults.begin(); it != defaults.end(); ++it ) {
00282 cpp <<
" default" <<
name <<
".append( QString::fromUtf8( \"" << *it <<
"\" ) );"
00283 <<
endl;
00284 }
00285 defaultValue =
"default" +
name;
00286
00287 }
else if ( type ==
"Color" && !defaultValue.isEmpty() ) {
00288
QRegExp colorRe(
"\\d+,\\s*\\d+,\\s*\\d+");
00289
if (colorRe.exactMatch(defaultValue))
00290 {
00291 defaultValue =
"QColor( " + defaultValue +
" )";
00292 }
00293
else
00294 {
00295 defaultValue =
"QColor( \"" + defaultValue +
"\" )";
00296 }
00297
00298 }
else if ( type ==
"Enum" ) {
00299
if ( !globalEnums ) {
00300
QValueList<CfgEntry::Choice>::ConstIterator it;
00301
for( it = choices.begin(); it != choices.end(); ++it ) {
00302
if ( (*it).name == defaultValue ) {
00303 defaultValue.prepend( enumName(name) +
"::");
00304
break;
00305 }
00306 }
00307 }
00308
00309 }
else if ( type ==
"IntList" ) {
00310
QTextStream cpp( &code, IO_WriteOnly | IO_Append );
00311
if (!code.isEmpty())
00312 cpp <<
endl;
00313
00314 cpp <<
" QValueList<int> default" <<
name <<
";" <<
endl;
00315
QStringList defaults = QStringList::split(
",", defaultValue );
00316 QStringList::ConstIterator it;
00317
for( it = defaults.begin(); it != defaults.end(); ++it ) {
00318 cpp <<
" default" <<
name <<
".append( " << *it <<
" );"
00319 <<
endl;
00320 }
00321 defaultValue =
"default" +
name;
00322 }
00323 }
00324
00325
00326 CfgEntry *parseEntry(
const QString &group,
const QDomElement &element )
00327 {
00328
bool defaultCode =
false;
00329
QString type = element.attribute(
"type" );
00330
QString name = element.attribute(
"name" );
00331
QString key = element.attribute(
"key" );
00332
QString hidden = element.attribute(
"hidden" );
00333
QString label;
00334
QString whatsThis;
00335
QString defaultValue;
00336
QString code;
00337
QString param;
00338
QString paramName;
00339
QString paramType;
00340
QValueList<CfgEntry::Choice> choices;
00341
QStringList paramValues;
00342
QStringList paramDefaultValues;
00343
QString minValue;
00344
QString maxValue;
00345
int paramMax = 0;
00346
00347
QDomNode n;
00348
for ( n = element.firstChild(); !n.isNull(); n = n.nextSibling() ) {
00349
QDomElement e = n.toElement();
00350
QString tag = e.tagName();
00351
if ( tag ==
"label" )
label = e.text();
00352
else if ( tag ==
"whatsthis" )
whatsThis = e.text();
00353
else if ( tag ==
"min" ) minValue = e.text();
00354
else if ( tag ==
"max" ) maxValue = e.text();
00355
else if ( tag ==
"code" ) code = e.text();
00356
else if ( tag ==
"parameter" )
00357 {
00358 param = e.attribute(
"name" );
00359 paramType = e.attribute(
"type" );
00360
if ( param.isEmpty() ) {
00361 kdError() <<
"Parameter must have a name: " << dumpNode(e) <<
endl;
00362
return 0;
00363 }
00364
if ( paramType.isEmpty() ) {
00365 kdError() <<
"Parameter must have a type: " << dumpNode(e) <<
endl;
00366
return 0;
00367 }
00368
if ((paramType ==
"Int") || (paramType ==
"UInt"))
00369 {
00370
bool ok;
00371 paramMax = e.attribute(
"max").toInt(&ok);
00372
if (!ok)
00373 {
00374 kdError() <<
"Integer parameter must have a maximum (e.g. max=\"0\"): " << dumpNode(e) <<
endl;
00375
return 0;
00376 }
00377 }
00378
else if (paramType ==
"Enum")
00379 {
00380
QDomNode n2;
00381
for ( n2 = e.firstChild(); !n2.isNull(); n2 = n2.nextSibling() ) {
00382
QDomElement e2 = n2.toElement();
00383
if (e2.tagName() ==
"values")
00384 {
00385
QDomNode n3;
00386
for ( n3 = e2.firstChild(); !n3.isNull(); n3 = n3.nextSibling() ) {
00387
QDomElement e3 = n3.toElement();
00388
if (e3.tagName() ==
"value")
00389 {
00390 paramValues.append( e3.text() );
00391 }
00392 }
00393
break;
00394 }
00395 }
00396
if (paramValues.isEmpty())
00397 {
00398 kdError() <<
"No values specified for parameter '" << param <<
"'." <<
endl;
00399
return 0;
00400 }
00401 paramMax = paramValues.count()-1;
00402 }
00403
else
00404 {
00405 kdError() <<
"Parameter '" << param <<
"' has type " << paramType <<
" but must be of type int, uint or Enum." <<
endl;
00406
return 0;
00407 }
00408 }
00409
else if ( tag ==
"default" )
00410 {
00411
if (e.attribute(
"param").isEmpty())
00412 {
00413 defaultValue = e.text();
00414
if (e.attribute(
"code" ) ==
"true")
00415 defaultCode =
true;
00416 }
00417 }
00418
else if ( tag ==
"choices" ) {
00419
QDomNode n2;
00420
for( n2 = e.firstChild(); !n2.isNull(); n2 = n2.nextSibling() ) {
00421
QDomElement e2 = n2.toElement();
00422
if ( e2.tagName() ==
"choice" ) {
00423
QDomNode n3;
00424 CfgEntry::Choice choice;
00425 choice.name = e2.attribute(
"name" );
00426
if ( choice.name.isEmpty() ) {
00427 kdError() <<
"Tag <choice> requires attribute 'name'." <<
endl;
00428 }
00429
for( n3 = e2.firstChild(); !n3.isNull(); n3 = n3.nextSibling() ) {
00430
QDomElement e3 = n3.toElement();
00431
if ( e3.tagName() ==
"label" ) choice.label = e3.text();
00432
if ( e3.tagName() ==
"whatsthis" ) choice.whatsThis = e3.text();
00433 }
00434 choices.append( choice );
00435 }
00436 }
00437 }
00438 }
00439
00440
bool nameIsEmpty =
name.isEmpty();
00441
if ( nameIsEmpty &&
key.isEmpty() ) {
00442 kdError() <<
"Entry must have a name or a key: " << dumpNode(element) <<
endl;
00443
return 0;
00444 }
00445
00446
if (
key.isEmpty() ) {
00447
key =
name;
00448 }
00449
00450
if ( nameIsEmpty ) {
00451
name =
key;
00452
name.replace(
" ", QString::null );
00453 }
else if (
name.contains(
' ' ) ) {
00454 kdWarning()<<
"Entry '"<<
name<<
"' contains spaces! <name> elements can't contain speces!"<<
endl;
00455
name.remove(
' ' );
00456 }
00457
00458
if (
name.contains(
"$("))
00459 {
00460
if (param.isEmpty())
00461 {
00462 kdError() <<
"Name may not be parameterized: " <<
name <<
endl;
00463
return 0;
00464 }
00465 }
00466
else
00467 {
00468
if (!param.isEmpty())
00469 {
00470 kdError() <<
"Name must contain '$(" << param <<
")': " <<
name <<
endl;
00471
return 0;
00472 }
00473 }
00474
00475
if (
label.isEmpty() ) {
00476
label =
key;
00477 }
00478
00479
if ( type.isEmpty() ) type =
"String";
00480
00481
if (!param.isEmpty())
00482 {
00483
00484 paramName =
name;
00485
name.replace(
"$("+param+
")", QString::null);
00486
00487
for(
int i = 0; i <= paramMax; i++)
00488 {
00489 paramDefaultValues.append(QString::null);
00490 }
00491
00492
QDomNode n;
00493
for ( n = element.firstChild(); !n.isNull(); n = n.nextSibling() ) {
00494
QDomElement e = n.toElement();
00495
QString tag = e.tagName();
00496
if ( tag ==
"default" )
00497 {
00498
QString index = e.attribute(
"param");
00499
if (index.isEmpty())
00500
continue;
00501
00502
bool ok;
00503
int i = index.toInt(&ok);
00504
if (!ok)
00505 {
00506 i = paramValues.findIndex(index);
00507
if (i == -1)
00508 {
00509 kdError() <<
"Index '" << index <<
"' for default value is unknown." <<
endl;
00510
return 0;
00511 }
00512 }
00513
00514
if ((i < 0) || (i > paramMax))
00515 {
00516 kdError() <<
"Index '" << i <<
"' for default value is out of range [0, "<< paramMax<<
"]." <<
endl;
00517
return 0;
00518 }
00519
00520
QString tmpDefaultValue = e.text();
00521
00522
if (e.attribute(
"code" ) !=
"true")
00523 preProcessDefault(tmpDefaultValue, name, type, choices, code);
00524
00525 paramDefaultValues[i] = tmpDefaultValue;
00526 }
00527 }
00528 }
00529
00530
if (!validNameRegexp->exactMatch(name))
00531 {
00532
if (nameIsEmpty)
00533 kdError() <<
"The key '" <<
key <<
"' can not be used as name for the entry because "
00534
"it is not a valid name. You need to specify a valid name for this entry." <<
endl;
00535
else
00536 kdError() <<
"The name '" <<
name <<
"' is not a valid name for an entry." <<
endl;
00537
return 0;
00538 }
00539
00540
if (allNames.contains(name))
00541 {
00542
if (nameIsEmpty)
00543 kdError() <<
"The key '" <<
key <<
"' can not be used as name for the entry because "
00544
"it does not result in a unique name. You need to specify a unique name for this entry." <<
endl;
00545
else
00546 kdError() <<
"The name '" <<
name <<
"' is not unique." <<
endl;
00547
return 0;
00548 }
00549 allNames.append(name);
00550
00551
if (!defaultCode)
00552 {
00553 preProcessDefault(defaultValue, name, type, choices, code);
00554 }
00555
00556 CfgEntry *result =
new CfgEntry( group, type, key, name, label, whatsThis,
00557 code, defaultValue, choices,
00558 hidden ==
"true" );
00559
if (!param.isEmpty())
00560 {
00561 result->setParam(param);
00562 result->setParamName(paramName);
00563 result->setParamType(paramType);
00564 result->setParamValues(paramValues);
00565 result->setParamDefaultValues(paramDefaultValues);
00566 result->setParamMax(paramMax);
00567 }
00568 result->setMinValue(minValue);
00569 result->setMaxValue(maxValue);
00570
00571
return result;
00572 }
00573
00577
QString param(
const QString &type )
00578 {
00579
if ( type ==
"String" )
return "const QString &";
00580
else if ( type ==
"StringList" )
return "const QStringList &";
00581
else if ( type ==
"Font" )
return "const QFont &";
00582
else if ( type ==
"Rect" )
return "const QRect &";
00583
else if ( type ==
"Size" )
return "const QSize &";
00584
else if ( type ==
"Color" )
return "const QColor &";
00585
else if ( type ==
"Point" )
return "const QPoint &";
00586
else if ( type ==
"Int" )
return "int";
00587
else if ( type ==
"UInt" )
return "uint";
00588
else if ( type ==
"Bool" )
return "bool";
00589
else if ( type ==
"Double" )
return "double";
00590
else if ( type ==
"DateTime" )
return "const QDateTime &";
00591
else if ( type ==
"Int64" )
return "Q_INT64";
00592
else if ( type ==
"UInt64" )
return "Q_UINT64";
00593
else if ( type ==
"IntList" )
return "const QValueList<int> &";
00594
else if ( type ==
"Enum" )
return "int";
00595
else if ( type ==
"Path" )
return "const QString &";
00596
else if ( type ==
"PathList" )
return "const QStringList &";
00597
else if ( type ==
"Password" )
return "const QString &";
00598
else {
00599 kdError() <<
"kconfig_compiler does not support type \""<< type <<
"\""<<
endl;
00600
return "QString";
00601 }
00602 }
00603
00607
QString cppType(
const QString &type )
00608 {
00609
if ( type ==
"String" )
return "QString";
00610
else if ( type ==
"StringList" )
return "QStringList";
00611
else if ( type ==
"Font" )
return "QFont";
00612
else if ( type ==
"Rect" )
return "QRect";
00613
else if ( type ==
"Size" )
return "QSize";
00614
else if ( type ==
"Color" )
return "QColor";
00615
else if ( type ==
"Point" )
return "QPoint";
00616
else if ( type ==
"Int" )
return "int";
00617
else if ( type ==
"UInt" )
return "uint";
00618
else if ( type ==
"Bool" )
return "bool";
00619
else if ( type ==
"Double" )
return "double";
00620
else if ( type ==
"DateTime" )
return "QDateTime";
00621
else if ( type ==
"Int64" )
return "Q_INT64";
00622
else if ( type ==
"UInt64" )
return "Q_UINT64";
00623
else if ( type ==
"IntList" )
return "QValueList<int>";
00624
else if ( type ==
"Enum" )
return "int";
00625
else if ( type ==
"Path" )
return "QString";
00626
else if ( type ==
"PathList" )
return "QStringList";
00627
else if ( type ==
"Password" )
return "QString";
00628
else {
00629 kdError()<<
"kconfig_compiler does not support type \""<< type <<
"\""<<
endl;
00630
return "QString";
00631 }
00632 }
00633
00634
QString defaultValue(
const QString &type )
00635 {
00636
if ( type ==
"String" )
return "\"\"";
00637
else if ( type ==
"StringList" )
return "QStringList()";
00638
else if ( type ==
"Font" )
return "KGlobalSettings::generalFont()";
00639
else if ( type ==
"Rect" )
return "QRect()";
00640
else if ( type ==
"Size" )
return "QSize()";
00641
else if ( type ==
"Color" )
return "QColor(128, 128, 128)";
00642
else if ( type ==
"Point" )
return "QPoint()";
00643
else if ( type ==
"Int" )
return "0";
00644
else if ( type ==
"UInt" )
return "0";
00645
else if ( type ==
"Bool" )
return "false";
00646
else if ( type ==
"Double" )
return "0.0";
00647
else if ( type ==
"DateTime" )
return "QDateTime()";
00648
else if ( type ==
"Int64" )
return "0";
00649
else if ( type ==
"UInt64" )
return "0";
00650
else if ( type ==
"IntList" )
return "QValueList<int>()";
00651
else if ( type ==
"Enum" )
return "0";
00652
else if ( type ==
"Path" )
return "\"\"";
00653
else if ( type ==
"PathList" )
return "QStringList()";
00654
else if ( type ==
"Password" )
return "\"\"";
00655
else {
00656 kdWarning()<<
"Error, kconfig_compiler doesn't support the \""<< type <<
"\" type!"<<
endl;
00657
return "QString";
00658 }
00659 }
00660
00661
QString itemType(
const QString &type )
00662 {
00663
QString t;
00664
00665 t = type;
00666 t.replace( 0, 1, t.left( 1 ).upper() );
00667
00668
return t;
00669 }
00670
00671
static QString itemDeclaration(
const CfgEntry *e)
00672 {
00673
if (itemAccessors)
00674
return QString::null;
00675
00676
return " KConfigSkeleton::Item"+itemType( e->type() ) +
00677
" *item" + e->name() +
00678 ( (!e->param().isEmpty())?(
QString(
"[%1]").arg(e->paramMax()+1)) : QString::null) +
00679
";\n";
00680 }
00681
00682
static QString itemVar(
const CfgEntry *e)
00683 {
00684
if (itemAccessors)
00685
return varName( e->name() ) +
"Item";
00686
00687
return "item" + e->name();
00688
00689 }
00690
00691
QString newItem(
const QString &type,
const QString &name,
const QString &key,
00692
const QString &defaultValue,
const QString ¶m = QString::null)
00693 {
00694
QString t =
"new KConfigSkeleton::Item" + itemType( type ) +
00695
"( currentGroup(), " +
key +
", " + varName( name ) + param;
00696
if ( type ==
"Enum" ) t +=
", values" +
name;
00697
if ( !defaultValue.isEmpty() ) {
00698 t +=
", ";
00699
if ( type ==
"String" ) t += defaultValue;
00700
else t+= defaultValue;
00701 }
00702 t +=
" );";
00703
00704
return t;
00705 }
00706
00707
QString paramString(
const QString &s,
const CfgEntry *e,
int i)
00708 {
00709
QString result = s;
00710
QString needle =
"$("+e->param()+
")";
00711
if (result.contains(needle))
00712 {
00713
QString tmp;
00714
if (e->paramType() ==
"Enum")
00715 {
00716 tmp = e->paramValues()[i];
00717 }
00718
else
00719 {
00720 tmp = QString::number(i);
00721 }
00722
00723 result.replace(needle, tmp);
00724 }
00725
return result;
00726 }
00727
00728
QString paramString(
const QString &group,
const QValueList<Param> ¶meters)
00729 {
00730
QString paramString = group;
00731
QString arguments;
00732
int i = 1;
00733
for (
QValueList<Param>::ConstIterator it = parameters.begin();
00734 it != parameters.end(); ++it)
00735 {
00736
if (paramString.contains(
"$("+(*it).name+
")"))
00737 {
00738
QString tmp;
00739 tmp.sprintf(
"%%%d", i++);
00740 paramString.replace(
"$("+(*it).name+
")", tmp);
00741 arguments +=
".arg( mParam"+(*it).name+
" )";
00742 }
00743 }
00744
if (arguments.isEmpty())
00745
return "QString::fromLatin1( \""+group+
"\" )";
00746
00747
return "QString::fromLatin1( \""+paramString+
"\" )"+arguments;
00748 }
00749
00750
00751
QString userTextsFunctions( CfgEntry *e,
QString itemVarStr=QString::null,
QString i=QString::null )
00752 {
00753
QString txt;
00754
if (itemVarStr.isNull()) itemVarStr=itemVar(e);
00755
if ( !e->label().isEmpty() ) {
00756 txt +=
" " + itemVarStr +
"->setLabel( i18n(";
00757
if ( !e->param().isEmpty() )
00758 txt += quoteString(e->label().replace(
"$("+e->param()+
")", i));
00759
else
00760 txt+= quoteString(e->label());
00761 txt+=
") );\n";
00762 }
00763
if ( !e->whatsThis().isEmpty() ) {
00764 txt +=
" " + itemVarStr +
"->setWhatsThis( i18n(";
00765
if ( !e->param().isEmpty() )
00766 txt += quoteString(e->whatsThis().replace(
"$("+e->param()+
")", i));
00767
else
00768 txt+= quoteString(e->whatsThis());
00769 txt+=
") );\n";
00770 }
00771
return txt;
00772 }
00773
00774
int main(
int argc,
char **argv )
00775 {
00776
KAboutData aboutData(
"kconfig_compiler", I18N_NOOP(
"KDE .kcfg compiler"),
"0.3",
00777 I18N_NOOP(
"KConfig Compiler") , KAboutData::License_LGPL );
00778 aboutData.
addAuthor(
"Cornelius Schumacher", 0,
"schumacher@kde.org" );
00779 aboutData.
addAuthor(
"Waldo Bastian", 0,
"bastian@kde.org" );
00780 aboutData.
addAuthor(
"Zack Rusin", 0,
"zack@kde.org" );
00781 aboutData.
addCredit(
"Reinhold Kainhofer",
"Fix for parametrized entries",
00782
"reinhold@kainhofer.com",
"http://reinhold.kainhofer.com" );
00783
00784
KCmdLineArgs::init( argc, argv, &aboutData );
00785
KCmdLineArgs::addCmdLineOptions( options );
00786
00787
KInstance app( &aboutData );
00788
00789
KCmdLineArgs *args =
KCmdLineArgs::parsedArgs();
00790
00791
if ( args->
count() < 2 ) {
00792 kdError() <<
"Too few arguments." <<
endl;
00793
return 1;
00794 }
00795
if ( args->
count() > 2 ) {
00796 kdError() <<
"Too many arguments." <<
endl;
00797
return 1;
00798 }
00799
00800 validNameRegexp =
new QRegExp(
"[a-zA-Z_][a-zA-Z0-9_]*");
00801
00802
QString baseDir = QFile::decodeName(args->
getOption(
"directory"));
00803
if (!baseDir.endsWith(
"/"))
00804 baseDir.append(
"/");
00805
00806
QString inputFilename = args->
url( 0 ).
path();
00807
QString codegenFilename = args->
url( 1 ).
path();
00808
00809
if (!codegenFilename.endsWith(
".kcfgc"))
00810 {
00811 kdError() <<
"Codegen options file must have extension .kcfgc" <<
endl;
00812
return 1;
00813 }
00814
QString baseName = args->
url( 1 ).
fileName();
00815 baseName = baseName.left(baseName.length() - 6);
00816
00817
KSimpleConfig codegenConfig( codegenFilename,
true );
00818
00819
QString nameSpace = codegenConfig.
readEntry(
"NameSpace");
00820
QString className = codegenConfig.
readEntry(
"ClassName");
00821
QString inherits = codegenConfig.
readEntry(
"Inherits");
00822
QString visibility = codegenConfig.
readEntry(
"Visibility");
00823
if (!visibility.isEmpty()) visibility+=
" ";
00824
bool singleton = codegenConfig.
readBoolEntry(
"Singleton",
false);
00825
bool staticAccessors = singleton;
00826
bool customAddons = codegenConfig.
readBoolEntry(
"CustomAdditions");
00827
QString memberVariables = codegenConfig.
readEntry(
"MemberVariables");
00828
QStringList headerIncludes = codegenConfig.
readListEntry(
"IncludeFiles");
00829
QStringList mutators = codegenConfig.
readListEntry(
"Mutators");
00830
bool allMutators =
false;
00831
if ((mutators.count() == 1) && (mutators[0].lower() ==
"true"))
00832 allMutators =
true;
00833 itemAccessors = codegenConfig.
readBoolEntry(
"ItemAccessors",
false );
00834
bool setUserTexts = codegenConfig.
readBoolEntry(
"SetUserTexts",
false );
00835
00836 globalEnums = codegenConfig.
readBoolEntry(
"GlobalEnums",
false );
00837
00838
QFile input( inputFilename );
00839
00840
QDomDocument doc;
00841
QString errorMsg;
00842
int errorRow;
00843
int errorCol;
00844
if ( !doc.setContent( &input, &errorMsg, &errorRow, &errorCol ) ) {
00845 kdError() <<
"Unable to load document." <<
endl;
00846 kdError() <<
"Parse error in " << args->
url( 0 ).
fileName() <<
", line " << errorRow <<
", col " << errorCol <<
": " << errorMsg <<
endl;
00847
return 1;
00848 }
00849
00850
QDomElement cfgElement = doc.documentElement();
00851
00852
if ( cfgElement.isNull() ) {
00853 kdError() <<
"No document in kcfg file" <<
endl;
00854
return 1;
00855 }
00856
00857
QString cfgFileName;
00858
bool cfgFileNameArg =
false;
00859
QValueList<Param> parameters;
00860
QStringList includes;
00861
00862
QPtrList<CfgEntry> entries;
00863 entries.setAutoDelete(
true );
00864
00865
QDomNode n;
00866
for ( n = cfgElement.firstChild(); !n.isNull(); n = n.nextSibling() ) {
00867
QDomElement e = n.toElement();
00868
00869
QString tag = e.tagName();
00870
00871
if ( tag ==
"include" ) {
00872
QString includeFile = e.text();
00873
if (!includeFile.isEmpty())
00874 includes.append(includeFile);
00875
00876 }
else if ( tag ==
"kcfgfile" ) {
00877 cfgFileName = e.attribute(
"name" );
00878 cfgFileNameArg = e.attribute(
"arg" ).lower() ==
"true";
00879
QDomNode n2;
00880
for( n2 = e.firstChild(); !n2.isNull(); n2 = n2.nextSibling() ) {
00881
QDomElement e2 = n2.toElement();
00882
if ( e2.tagName() ==
"parameter" ) {
00883 Param p;
00884 p.name = e2.attribute(
"name" );
00885 p.type = e2.attribute(
"type" );
00886
if (p.type.isEmpty())
00887 p.type =
"String";
00888 parameters.append( p );
00889 }
00890 }
00891
00892 }
else if ( tag ==
"group" ) {
00893
QString group = e.attribute(
"name" );
00894
if ( group.isEmpty() ) {
00895 kdError() <<
"Group without name" <<
endl;
00896
return 1;
00897 }
00898
QDomNode n2;
00899
for( n2 = e.firstChild(); !n2.isNull(); n2 = n2.nextSibling() ) {
00900
QDomElement e2 = n2.toElement();
00901
if ( e2.tagName() !=
"entry" )
continue;
00902 CfgEntry *entry = parseEntry( group, e2 );
00903
if ( entry ) entries.append( entry );
00904
else {
00905 kdError() <<
"Can't parse entry." <<
endl;
00906
return 1;
00907 }
00908 }
00909 }
00910 }
00911
00912
if ( inherits.isEmpty() ) inherits =
"KConfigSkeleton";
00913
00914
if ( className.isEmpty() ) {
00915 kdError() <<
"Class name missing" <<
endl;
00916
return 1;
00917 }
00918
00919
if ( singleton && !parameters.isEmpty() ) {
00920 kdError() <<
"Singleton class can not have parameters" <<
endl;
00921
return 1;
00922 }
00923
00924
if ( !cfgFileName.isEmpty() && cfgFileNameArg)
00925 {
00926 kdError() <<
"Having both a fixed filename and a filename as argument is not possible." <<
endl;
00927
return 1;
00928 }
00929
00930
if ( entries.isEmpty() ) {
00931 kdWarning() <<
"No entries." <<
endl;
00932 }
00933
00934
#if 0
00935
CfgEntry *cfg;
00936
for( cfg = entries.first(); cfg; cfg = entries.next() ) {
00937 cfg->dump();
00938 }
00939
#endif
00940
00941
QString headerFileName = baseName +
".h";
00942
QString implementationFileName = baseName +
".cpp";
00943
QString cppPreamble;
00944
00945
QFile header( baseDir + headerFileName );
00946
if ( !header.open( IO_WriteOnly ) ) {
00947 kdError() <<
"Can't open '" << headerFileName <<
"for writing." <<
endl;
00948
return 1;
00949 }
00950
00951
QTextStream h( &header );
00952
00953 h <<
"// This file is generated by kconfig_compiler from " << args->
url(0).
fileName() <<
"." <<
endl;
00954 h <<
"// All changes you do to this file will be lost." <<
endl;
00955
00956 h <<
"#ifndef " << ( !nameSpace.isEmpty() ? nameSpace.upper() +
"_" :
"" )
00957 << className.upper() <<
"_H" <<
endl;
00958 h <<
"#define " << ( !nameSpace.isEmpty() ? nameSpace.upper() +
"_" :
"" )
00959 << className.upper() <<
"_H" <<
endl <<
endl;
00960
00961
00962 QStringList::ConstIterator it;
00963
for( it = headerIncludes.begin(); it != headerIncludes.end(); ++it ) {
00964 h <<
"#include <" << *it <<
">" <<
endl;
00965 }
00966
00967
if ( headerIncludes.count() > 0 ) h <<
endl;
00968
00969
if ( !singleton && cfgFileNameArg && parameters.isEmpty() )
00970 h <<
"#include <kglobal.h>" <<
endl;
00971
00972 h <<
"#include <kconfigskeleton.h>" <<
endl <<
endl;
00973
00974
if ( !nameSpace.isEmpty() )
00975 h <<
"namespace " << nameSpace <<
" {" <<
endl <<
endl;
00976
00977
00978 h <<
"class " << visibility << className <<
" : public " << inherits <<
endl;
00979 h <<
"{" <<
endl;
00980 h <<
" public:" <<
endl;
00981
00982
00983 CfgEntry *e;
00984
for( e = entries.first(); e; e = entries.next() ) {
00985
QValueList<CfgEntry::Choice> choices = e->choices();
00986
if ( !choices.isEmpty() ) {
00987
QStringList values;
00988
QValueList<CfgEntry::Choice>::ConstIterator itChoice;
00989
for( itChoice = choices.begin(); itChoice != choices.end(); ++itChoice ) {
00990 values.append( (*itChoice).name );
00991 }
00992
if ( globalEnums ) {
00993 h <<
" enum { " << values.join(
", " ) <<
" };" <<
endl;
00994 }
else {
00995 h <<
" class " << enumName(e->name()) <<
endl;
00996 h <<
" {" <<
endl;
00997 h <<
" public:" <<
endl;
00998 h <<
" enum type { " << values.join(
", " ) <<
", COUNT };" <<
endl;
00999 h <<
" };" <<
endl;
01000 }
01001 }
01002
QStringList values = e->paramValues();
01003
if ( !values.isEmpty() ) {
01004
if ( globalEnums ) {
01005 h <<
" enum { " << values.join(
", " ) <<
" };" <<
endl;
01006 h <<
" static const char* const " << enumName(e->param()) <<
"ToString[];" <<
endl;
01007 cppPreamble +=
"const char* const " + className +
"::" + enumName(e->param()) +
"ToString[] = " +
01008
"{ \"" + values.join(
"\", \"" ) +
"\" };\n";
01009 }
else {
01010 h <<
" class " << enumName(e->param()) <<
endl;
01011 h <<
" {" <<
endl;
01012 h <<
" public:" <<
endl;
01013 h <<
" enum type { " << values.join(
", " ) <<
", COUNT };" <<
endl;
01014 h <<
" static const char* const enumToString[];" <<
endl;
01015 h <<
" };" <<
endl;
01016 cppPreamble +=
"const char* const " + className +
"::" + enumName(e->param()) +
"::enumToString[] = " +
01017
"{ \"" + values.join(
"\", \"" ) +
"\" };\n";
01018 }
01019 }
01020 }
01021
01022 h <<
endl;
01023
01024
01025
if ( !singleton ) {
01026 h <<
" " << className <<
"(";
01027
if (cfgFileNameArg)
01028 h <<
" KSharedConfig::Ptr config" << (parameters.isEmpty() ?
" = KGlobal::sharedConfig()" :
", ");
01029
for (
QValueList<Param>::ConstIterator it = parameters.begin();
01030 it != parameters.end(); ++it)
01031 {
01032
if (it != parameters.begin())
01033 h <<
",";
01034 h <<
" " << param((*it).type) <<
" " << (*it).name;
01035 }
01036 h <<
" );" <<
endl;
01037 }
else {
01038 h <<
" static " << className <<
" *self();" <<
endl;
01039
if (cfgFileNameArg)
01040 h <<
" static void instance(const char * cfgfilename);" <<
endl;
01041 }
01042
01043
01044 h <<
" ~" << className <<
"();" <<
endl <<
endl;
01045
01046
QString This;
01047
QString Const;
01048
if (staticAccessors)
01049 This =
"self()->";
01050
else
01051 Const =
" const";
01052
01053
for( e = entries.first(); e; e = entries.next() ) {
01054
QString n = e->name();
01055
QString t = e->type();
01056
01057
01058
if (allMutators || mutators.contains(n))
01059 {
01060 h <<
" /**" <<
endl;
01061 h <<
" Set " << e->label() <<
endl;
01062 h <<
" */" <<
endl;
01063
if (staticAccessors)
01064 h <<
" static" <<
endl;
01065 h <<
" void " << setFunction(n) <<
"( ";
01066
if (!e->param().isEmpty())
01067 h << cppType(e->paramType()) <<
" i, ";
01068 h << param( t ) <<
" v )" <<
endl;
01069 h <<
" {" <<
endl;
01070 h <<
" if (!" << This <<
"isImmutable( QString::fromLatin1( \"";
01071
if (!e->param().isEmpty()) {
01072 h << e->paramName().replace(
"$("+e->param()+
")",
"%1") <<
"\" ).arg( ";
01073
if ( e->paramType() ==
"Enum" ) {
01074 h <<
"QString::fromLatin1( ";
01075
if (globalEnums)
01076 h << enumName(e->param()) <<
"ToString[i]";
01077
else
01078 h << enumName(e->param()) <<
"::enumToString[i]";
01079 h <<
" )";
01080 }
else {
01081 h <<
"i";
01082 }
01083 h <<
" )";
01084 }
else
01085 h << n <<
"\" )";
01086 h <<
" ))" <<
endl;
01087 h <<
" " << This << varName(n);
01088
if (!e->param().isEmpty())
01089 h <<
"[i]";
01090 h <<
" = v;" <<
endl;
01091 h <<
" }" <<
endl <<
endl;
01092 }
01093
01094
01095 h <<
" /**" <<
endl;
01096 h <<
" Get " << e->label() <<
endl;
01097 h <<
" */" <<
endl;
01098
if (staticAccessors)
01099 h <<
" static" <<
endl;
01100 h <<
" " << cppType(t) <<
" " << getFunction(n) <<
"(";
01101
if (!e->param().isEmpty())
01102 h <<
" " << cppType(e->paramType()) <<
" i ";
01103 h <<
")" << Const <<
endl;
01104 h <<
" {" <<
endl;
01105 h <<
" return " << This << varName(n);
01106
if (!e->param().isEmpty()) h <<
"[i]";
01107 h <<
";" <<
endl;
01108 h <<
" }" <<
endl;
01109
01110
01111
if ( itemAccessors ) {
01112 h <<
endl;
01113 h <<
" /**" <<
endl;
01114 h <<
" Get Item object corresponding to " << n <<
"()"
01115 <<
endl;
01116 h <<
" */" <<
endl;
01117 h <<
" Item" << itemType( e->type() ) <<
" *"
01118 << getFunction( n ) <<
"Item(";
01119
if (!e->param().isEmpty()) {
01120 h <<
" " << cppType(e->paramType()) <<
" i ";
01121 }
01122 h <<
")" <<
endl;
01123 h <<
" {" <<
endl;
01124 h <<
" return " << itemVar(e);
01125
if (!e->param().isEmpty()) h <<
"[i]";
01126 h <<
";" <<
endl;
01127 h <<
" }" <<
endl;
01128 }
01129
01130 h <<
endl;
01131 }
01132
01133
01134
if ( singleton ) {
01135 h <<
" static" <<
endl;
01136 h <<
" void writeConfig()" <<
endl;
01137 h <<
" {" <<
endl;
01138 h <<
" static_cast<KConfigSkeleton*>(self())->writeConfig();" <<
endl;
01139 h <<
" }" <<
endl;
01140 }
01141
01142 h <<
" protected:" <<
endl;
01143
01144
01145
if ( singleton ) {
01146 h <<
" " << className <<
"(";
01147
if ( cfgFileNameArg )
01148 h <<
"const char *arg";
01149 h <<
");" <<
endl;
01150 h <<
" static " << className <<
" *mSelf;" <<
endl <<
endl;
01151 }
01152
01153
01154
if ( !memberVariables.isEmpty() && memberVariables !=
"private" ) {
01155 h <<
" " << memberVariables <<
":" <<
endl;
01156 }
01157
01158
01159
for (
QValueList<Param>::ConstIterator it = parameters.begin();
01160 it != parameters.end(); ++it)
01161 {
01162 h <<
" " << cppType((*it).type) <<
" mParam" << (*it).name <<
";" <<
endl;
01163 }
01164
01165
QString group;
01166
for( e = entries.first(); e; e = entries.next() ) {
01167
if ( e->group() != group ) {
01168 group = e->group();
01169 h <<
endl;
01170 h <<
" // " << group <<
endl;
01171 }
01172 h <<
" " << cppType(e->type()) <<
" " << varName(e->name());
01173
if (!e->param().isEmpty())
01174 {
01175 h <<
QString(
"[%1]").arg(e->paramMax()+1);
01176 }
01177 h <<
";" <<
endl;
01178 }
01179
01180 h <<
endl <<
" private:" <<
endl;
01181
if ( itemAccessors ) {
01182
for( e = entries.first(); e; e = entries.next() ) {
01183 h <<
" Item" << itemType( e->type() ) <<
" *" << itemVar( e );
01184
if (!e->param().isEmpty() ) h <<
QString(
"[%1]").arg( e->paramMax()+1 );
01185 h <<
";" <<
endl;
01186 }
01187 }
01188
01189
if (customAddons)
01190 {
01191 h <<
" // Include custom additions" <<
endl;
01192 h <<
" #include \"" << filenameOnly(baseName) <<
"_addons.h\"" <<
endl;
01193 }
01194
01195 h <<
"};" <<
endl <<
endl;
01196
01197
if ( !nameSpace.isEmpty() ) h <<
"}" <<
endl <<
endl;
01198
01199 h <<
"#endif" <<
endl <<
endl;
01200
01201
01202 header.close();
01203
01204
QFile implementation( baseDir + implementationFileName );
01205
if ( !implementation.open( IO_WriteOnly ) ) {
01206 kdError() <<
"Can't open '" << implementationFileName <<
"for writing."
01207 <<
endl;
01208
return 1;
01209 }
01210
01211
QTextStream cpp( &implementation );
01212
01213
01214 cpp <<
"// This file is generated by kconfig_compiler from " << args->
url(0).
fileName() <<
"." <<
endl;
01215 cpp <<
"// All changes you do to this file will be lost." <<
endl <<
endl;
01216
01217 cpp <<
"#include \"" << headerFileName <<
"\"" <<
endl <<
endl;
01218
01219
if ( setUserTexts ) cpp <<
"#include <klocale.h>" <<
endl <<
endl;
01220
01221
01222
for( it = includes.begin(); it != includes.end(); ++it ) {
01223 cpp <<
"#include <" << *it <<
">" <<
endl;
01224 }
01225
01226
01227
if ( singleton )
01228 cpp <<
"#include <kstaticdeleter.h>" <<
endl <<
endl;
01229
if ( singleton && cfgFileNameArg )
01230 cpp <<
"#include <kdebug.h>" <<
endl <<
endl;
01231
01232
if ( !nameSpace.isEmpty() )
01233 cpp <<
"using namespace " << nameSpace <<
";" <<
endl <<
endl;
01234
01235
01236
if ( singleton ) {
01237 cpp << className <<
" *" << className <<
"::mSelf = 0;" <<
endl;
01238 cpp <<
"static KStaticDeleter<" << className <<
"> static" << className <<
"Deleter;" <<
endl <<
endl;
01239
01240 cpp << className <<
" *" << className <<
"::self()" <<
endl;
01241 cpp <<
"{" <<
endl;
01242
if ( cfgFileNameArg ) {
01243 cpp <<
" if (!mSelf)" <<
endl;
01244 cpp <<
" kdFatal() << \"you need to call " << className <<
"::instance before using\" << endl;" <<
endl;
01245 }
else {
01246 cpp <<
" if ( !mSelf ) {" <<
endl;
01247 cpp <<
" static" << className <<
"Deleter.setObject( mSelf, new " << className <<
"() );" <<
endl;
01248 cpp <<
" mSelf->readConfig();" <<
endl;
01249 cpp <<
" }" <<
endl <<
endl;
01250 }
01251 cpp <<
" return mSelf;" <<
endl;
01252 cpp <<
"}" <<
endl <<
endl;
01253
01254
if ( cfgFileNameArg ) {
01255 cpp <<
"void " << className <<
"::instance(const char *cfgfilename)" <<
endl;
01256 cpp <<
"{" <<
endl;
01257 cpp <<
" if (mSelf) {" <<
endl;
01258 cpp <<
" kdError() << \"" << className <<
"::instance called after the first use - ignoring\" << endl;" <<
endl;
01259 cpp <<
" return;" <<
endl;
01260 cpp <<
" }" <<
endl;
01261 cpp <<
" static" << className <<
"Deleter.setObject( mSelf, new " << className <<
"(cfgfilename) );" <<
endl;
01262 cpp <<
" mSelf->readConfig();" <<
endl;
01263 cpp <<
"}" <<
endl <<
endl;
01264 }
01265 }
01266
01267
if ( !cppPreamble.isEmpty() )
01268 cpp << cppPreamble <<
endl;
01269
01270
01271 cpp << className <<
"::" << className <<
"( ";
01272
if ( cfgFileNameArg ) {
01273
if ( !singleton )
01274 cpp <<
" KSharedConfig::Ptr config";
01275
else
01276 cpp <<
" const char *config";
01277 cpp << (parameters.isEmpty() ?
" " :
", ");
01278 }
01279
01280
for (
QValueList<Param>::ConstIterator it = parameters.begin();
01281 it != parameters.end(); ++it)
01282 {
01283
if (it != parameters.begin())
01284 cpp <<
",";
01285 cpp <<
" " << param((*it).type) <<
" " << (*it).name;
01286 }
01287 cpp <<
" )" <<
endl;
01288
01289 cpp <<
" : " << inherits <<
"(";
01290
if ( !cfgFileName.isEmpty() ) cpp <<
" QString::fromLatin1( \"" << cfgFileName <<
"\" ";
01291
if ( cfgFileNameArg ) cpp <<
" config ";
01292
if ( !cfgFileName.isEmpty() ) cpp <<
") ";
01293 cpp <<
")" <<
endl;
01294
01295
01296
for (
QValueList<Param>::ConstIterator it = parameters.begin();
01297 it != parameters.end(); ++it)
01298 {
01299 cpp <<
" , mParam" << (*it).name <<
"(" << (*it).name <<
")" <<
endl;
01300 }
01301
01302 cpp <<
"{" <<
endl;
01303
01304
01305
01306
if ( singleton )
01307 cpp <<
" mSelf = this;" <<
endl;
01308
01309 group = QString::null;
01310
for( e = entries.first(); e; e = entries.next() ) {
01311
if ( e->group() != group ) {
01312
if ( !group.isEmpty() ) cpp <<
endl;
01313 group = e->group();
01314 cpp <<
" setCurrentGroup( " << paramString(group, parameters) <<
" );" <<
endl <<
endl;
01315 }
01316
01317
QString key = paramString(e->key(), parameters);
01318
if ( !e->code().isEmpty())
01319 {
01320 cpp << e->code() <<
endl;
01321 }
01322
if ( e->type() ==
"Enum" ) {
01323 cpp <<
" QValueList<KConfigSkeleton::ItemEnum::Choice> values"
01324 << e->name() <<
";" <<
endl;
01325
QValueList<CfgEntry::Choice> choices = e->choices();
01326
QValueList<CfgEntry::Choice>::ConstIterator it;
01327
for( it = choices.begin(); it != choices.end(); ++it ) {
01328 cpp <<
" {" <<
endl;
01329 cpp <<
" KConfigSkeleton::ItemEnum::Choice choice;" <<
endl;
01330 cpp <<
" choice.name = QString::fromLatin1( \"" << (*it).name <<
"\" );" <<
endl;
01331
if ( setUserTexts ) {
01332
if ( !(*it).label.isEmpty() )
01333 cpp <<
" choice.label = i18n(" << quoteString((*it).label) <<
");" <<
endl;
01334
if ( !(*it).whatsThis.isEmpty() )
01335 cpp <<
" choice.whatsThis = i18n(" << quoteString((*it).whatsThis) <<
");" <<
endl;
01336 }
01337 cpp <<
" values" << e->name() <<
".append( choice );" <<
endl;
01338 cpp <<
" }" <<
endl;
01339 }
01340 }
01341 cpp << itemDeclaration(e);
01342
if (e->param().isEmpty())
01343 {
01344
01345 cpp <<
" " << itemVar(e) <<
" = "
01346 << newItem( e->type(), e->name(),
key, e->defaultValue() ) <<
endl;
01347
01348
if ( !e->minValue().isEmpty() )
01349 cpp <<
" " << itemVar(e) <<
"->setMinValue(" << e->minValue() <<
");" <<
endl;
01350
if ( !e->maxValue().isEmpty() )
01351 cpp <<
" " << itemVar(e) <<
"->setMaxValue(" << e->maxValue() <<
");" <<
endl;
01352
01353
if ( setUserTexts )
01354 cpp << userTextsFunctions( e );
01355
01356 cpp <<
" addItem( " << itemVar(e);
01357
QString quotedName = e->name();
01358 addQuotes( quotedName );
01359
if ( quotedName !=
key ) cpp <<
", QString::fromLatin1( \"" << e->name() <<
"\" )";
01360 cpp <<
" );" <<
endl;
01361 }
01362
else
01363 {
01364
01365
for(
int i = 0; i <= e->paramMax(); i++)
01366 {
01367
QString defaultStr;
01368
QString itemVarStr(itemVar(e)+
QString(
"[%1]").arg(i));
01369
01370
if ( !e->paramDefaultValue(i).isEmpty() )
01371 defaultStr = e->paramDefaultValue(i);
01372
else if ( !e->defaultValue().isEmpty() )
01373 defaultStr = paramString(e->defaultValue(), e, i);
01374
else
01375 defaultStr = defaultValue( e->type() );
01376
01377 cpp <<
" " << itemVarStr <<
" = "
01378 << newItem( e->type(), e->name(), paramString(key, e, i), defaultStr,
QString(
"[%1]").arg(i) )
01379 <<
endl;
01380
01381
if ( setUserTexts )
01382 cpp << userTextsFunctions( e, itemVarStr, e->paramName() );
01383
01384
01385
01386
01387
01388 cpp <<
" addItem( " << itemVarStr <<
", QString::fromLatin1( \"";
01389
if ( e->paramType()==
"Enum" )
01390 cpp << e->paramName().replace(
"$("+e->param()+
")",
"%1").arg(e->paramValues()[i] );
01391
else
01392 cpp << e->paramName().replace(
"$("+e->param()+
")",
"%1").arg(i);
01393 cpp <<
"\" ) );" <<
endl;
01394 }
01395 }
01396 }
01397
01398 cpp <<
"}" <<
endl <<
endl;
01399
01400
01401 cpp << className <<
"::~" << className <<
"()" <<
endl;
01402 cpp <<
"{" <<
endl;
01403
if ( singleton ) {
01404 cpp <<
" if ( mSelf == this )" <<
endl;
01405 cpp <<
" static" << className <<
"Deleter.setObject( mSelf, 0, false );" <<
endl;
01406 }
01407 cpp <<
"}" <<
endl <<
endl;
01408
01409 implementation.close();
01410 }