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
00026
00027 #include <QtCore/QCoreApplication>
00028 #include <QtCore/QFile>
00029 #include <QtCore/QFileInfo>
00030 #include <QtCore/QSettings>
00031 #include <QtCore/QTextStream>
00032 #include <QtXml/QDomAttr>
00033 #include <QtCore/QRegExp>
00034 #include <QtCore/QStringList>
00035
00036 #include <ostream>
00037 #include <iostream>
00038 #include <stdlib.h>
00039
00040
00041 static inline std::ostream &operator<<(std::ostream &o, const QString &str)
00042 {
00043 o << str.toLocal8Bit().constData();
00044 return o;
00045 }
00046
00047 static void parseArgs(const QStringList &args, QString &directory, QString &file1, QString &file2)
00048 {
00049 int fileCount = 0;
00050 directory = ".";
00051
00052 for (int i = 1; i < args.count(); ++i) {
00053 if (args.at(i) == "-d" || args.at(i) == "--directory") {
00054 if (i + 1 > args.count()) {
00055 std::cerr << qPrintable(args.at(i)) << " needs an argument" << std::endl;
00056 exit(1);
00057 }
00058 directory = args.at(++i);
00059 } else if (args.at(i).startsWith("-d")) {
00060 directory = args.at(i).mid(2);
00061 } else if (args.at(i) == "--help" || args.at(i) == "-h") {
00062 std::cout << "Options:" << std::endl;
00063 std::cout << " -L --license Display software license" << std::endl;
00064 std::cout << " -d, --directory <dir> Directory to generate files in [.]" << std::endl;
00065 std::cout << " -h, --help Display this help" << std::endl;
00066 std::cout << std::endl;
00067 std::cout << "Arguments:" << std::endl;
00068 std::cout << " file.kcfg Input kcfg XML file" << std::endl;
00069 std::cout << " file.kcfgc Code generation options file" << std::endl;
00070 exit(0);
00071 } else if (args.at(i) == "--license" || args.at(i) == "-L") {
00072 std::cout << "Copyright 2003 Cornelius Schumacher, Waldo Bastian, Zack Rusin," << std::endl;
00073 std::cout << " Reinhold Kainhofer, Duncan Mac-Vicar P., Harald Fernengel" << std::endl;
00074 std::cout << "This program comes with ABSOLUTELY NO WARRANTY." << std::endl;
00075 std::cout << "You may redistribute copies of this program" << std::endl;
00076 std::cout << "under the terms of the GNU Library Public License." << std::endl;
00077 std::cout << "For more information about these matters, see the file named COPYING." << std::endl;
00078 exit(0);
00079 } else if (args.at(i).startsWith('-')) {
00080 std::cerr << "Unknown option: " << qPrintable(args.at(i)) << std::endl;
00081 exit(1);
00082 } else if (fileCount == 0) {
00083 file1 = args.at(i);
00084 ++fileCount;
00085 } else if (fileCount == 1) {
00086 file2 = args.at(i);
00087 ++fileCount;
00088 } else {
00089 std::cerr << "Too many arguments" << std::endl;
00090 exit(1);
00091 }
00092 }
00093 if (fileCount < 2) {
00094 std::cerr << "Too few arguments" << std::endl;
00095 exit(1);
00096 }
00097 }
00098
00099 bool globalEnums;
00100 bool useEnumTypes;
00101 bool itemAccessors;
00102 bool dpointer;
00103 QStringList allNames;
00104 QRegExp *validNameRegexp;
00105 QString This;
00106 QString Const;
00107
00108 struct SignalArguments
00109 {
00110 QString type;
00111 QString variableName;
00112 };
00113
00114 class Signal {
00115 public:
00116 QString name;
00117 QString label;
00118 QList<SignalArguments> arguments;
00119 };
00120
00121 class CfgEntry
00122 {
00123 public:
00124 struct Choice
00125 {
00126 QString name;
00127 QString context;
00128 QString label;
00129 QString toolTip;
00130 QString whatsThis;
00131 };
00132 class Choices
00133 {
00134 public:
00135 Choices() {}
00136 Choices( const QList<Choice> &d, const QString &n, const QString &p )
00137 : prefix(p), choices(d), mName(n)
00138 {
00139 int i = n.indexOf("::");
00140 if (i >= 0)
00141 mExternalQual = n.left(i + 2);
00142 }
00143 QString prefix;
00144 QList<Choice> choices;
00145 const QString& name() const { return mName; }
00146 const QString& externalQualifier() const { return mExternalQual; }
00147 bool external() const { return !mExternalQual.isEmpty(); }
00148 private:
00149 QString mName;
00150 QString mExternalQual;
00151 };
00152
00153 CfgEntry( const QString &group, const QString &type, const QString &key,
00154 const QString &name, const QString &context, const QString &label,
00155 const QString &toolTip, const QString &whatsThis, const QString &code,
00156 const QString &defaultValue, const Choices &choices, const QList<Signal> signalList,
00157 bool hidden )
00158 : mGroup( group ), mType( type ), mKey( key ), mName( name ),
00159 mContext( context ), mLabel( label ), mToolTip( toolTip ), mWhatsThis( whatsThis ),
00160 mCode( code ), mDefaultValue( defaultValue ), mChoices( choices ),
00161 mSignalList(signalList), mHidden( hidden )
00162 {
00163 }
00164
00165 void setGroup( const QString &group ) { mGroup = group; }
00166 QString group() const { return mGroup; }
00167
00168 void setType( const QString &type ) { mType = type; }
00169 QString type() const { return mType; }
00170
00171 void setKey( const QString &key ) { mKey = key; }
00172 QString key() const { return mKey; }
00173
00174 void setName( const QString &name ) { mName = name; }
00175 QString name() const { return mName; }
00176
00177 void setContext( const QString &context ) { mContext = context; }
00178 QString context() const { return mContext; }
00179
00180 void setLabel( const QString &label ) { mLabel = label; }
00181 QString label() const { return mLabel; }
00182
00183 void setToolTip( const QString &toolTip ) { mToolTip = toolTip; }
00184 QString toolTip() const { return mToolTip; }
00185
00186 void setWhatsThis( const QString &whatsThis ) { mWhatsThis = whatsThis; }
00187 QString whatsThis() const { return mWhatsThis; }
00188
00189 void setDefaultValue( const QString &d ) { mDefaultValue = d; }
00190 QString defaultValue() const { return mDefaultValue; }
00191
00192 void setCode( const QString &d ) { mCode = d; }
00193 QString code() const { return mCode; }
00194
00195 void setMinValue( const QString &d ) { mMin = d; }
00196 QString minValue() const { return mMin; }
00197
00198 void setMaxValue( const QString &d ) { mMax = d; }
00199 QString maxValue() const { return mMax; }
00200
00201 void setParam( const QString &d ) { mParam = d; }
00202 QString param() const { return mParam; }
00203
00204 void setParamName( const QString &d ) { mParamName = d; }
00205 QString paramName() const { return mParamName; }
00206
00207 void setParamType( const QString &d ) { mParamType = d; }
00208 QString paramType() const { return mParamType; }
00209
00210 void setChoices( const QList<Choice> &d, const QString &n, const QString &p ) { mChoices = Choices( d, n, p ); }
00211 Choices choices() const { return mChoices; }
00212
00213 void setParamValues( const QStringList &d ) { mParamValues = d; }
00214 QStringList paramValues() const { return mParamValues; }
00215
00216 void setParamDefaultValues( const QStringList &d ) { mParamDefaultValues = d; }
00217 QString paramDefaultValue(int i) const { return mParamDefaultValues[i]; }
00218
00219 void setParamMax( int d ) { mParamMax = d; }
00220 int paramMax() const { return mParamMax; }
00221
00222 void setSignalList( const QList<Signal> &value ) { mSignalList = value; }
00223 QList<Signal> signalList() const { return mSignalList; }
00224
00225 bool hidden() const { return mHidden; }
00226
00227 void dump() const
00228 {
00229 std::cerr << "<entry>" << std::endl;
00230 std::cerr << " group: " << qPrintable(mGroup) << std::endl;
00231 std::cerr << " type: " << qPrintable(mType) << std::endl;
00232 std::cerr << " key: " << qPrintable(mKey) << std::endl;
00233 std::cerr << " name: " << qPrintable(mName) << std::endl;
00234 std::cerr << " context: " << qPrintable(mContext) << std::endl;
00235 std::cerr << " label: " << qPrintable(mLabel) << std::endl;
00236
00237 std::cerr << " code: " << qPrintable(mCode) << std::endl;
00238
00239
00240 if (!param().isEmpty())
00241 {
00242 std::cerr << " param name: "<< qPrintable(mParamName) << std::endl;
00243 std::cerr << " param type: "<< qPrintable(mParamType) << std::endl;
00244 std::cerr << " paramvalues: " << qPrintable(mParamValues.join(":")) << std::endl;
00245 }
00246 std::cerr << " default: " << qPrintable(mDefaultValue) << std::endl;
00247 std::cerr << " hidden: " << mHidden << std::endl;
00248 std::cerr << " min: " << qPrintable(mMin) << std::endl;
00249 std::cerr << " max: " << qPrintable(mMax) << std::endl;
00250 std::cerr << "</entry>" << std::endl;
00251 }
00252
00253 private:
00254 QString mGroup;
00255 QString mType;
00256 QString mKey;
00257 QString mName;
00258 QString mContext;
00259 QString mLabel;
00260 QString mToolTip;
00261 QString mWhatsThis;
00262 QString mCode;
00263 QString mDefaultValue;
00264 QString mParam;
00265 QString mParamName;
00266 QString mParamType;
00267 Choices mChoices;
00268 QList<Signal> mSignalList;
00269 QStringList mParamValues;
00270 QStringList mParamDefaultValues;
00271 int mParamMax;
00272 bool mHidden;
00273 QString mMin;
00274 QString mMax;
00275 };
00276
00277 class Param {
00278 public:
00279 QString name;
00280 QString type;
00281 };
00282
00283
00284
00285
00286 static QString varName(const QString &n)
00287 {
00288 QString result;
00289 if ( !dpointer ) {
00290 result = 'm'+n;
00291 result[1] = result[1].toUpper();
00292 }
00293 else {
00294 result = n;
00295 result[0] = result[0].toLower();
00296 }
00297 return result;
00298 }
00299
00300 static QString varPath(const QString &n)
00301 {
00302 QString result;
00303 if ( dpointer ) {
00304 result = "d->"+varName(n);
00305 }
00306 else {
00307 result = varName(n);
00308 }
00309 return result;
00310 }
00311
00312 static QString enumName(const QString &n)
00313 {
00314 QString result = "Enum" + n;
00315 result[4] = result[4].toUpper();
00316 return result;
00317 }
00318
00319 static QString enumName(const QString &n, const CfgEntry::Choices &c)
00320 {
00321 QString result = c.name();
00322 if ( result.isEmpty() )
00323 {
00324 result = "Enum" + n;
00325 result[4] = result[4].toUpper();
00326 }
00327 return result;
00328 }
00329
00330 static QString enumType(const CfgEntry *e)
00331 {
00332 QString result = e->choices().name();
00333 if ( result.isEmpty() )
00334 {
00335 result = "Enum" + e->name() + "::type";
00336 result[4] = result[4].toUpper();
00337 }
00338 return result;
00339 }
00340
00341 static QString enumTypeQualifier(const QString &n, const CfgEntry::Choices &c)
00342 {
00343 QString result = c.name();
00344 if ( result.isEmpty() )
00345 {
00346 result = "Enum" + n + "::";
00347 result[4] = result[4].toUpper();
00348 }
00349 else if ( c.external() )
00350 result = c.externalQualifier();
00351 else
00352 result.clear();
00353 return result;
00354 }
00355
00356 static QString setFunction(const QString &n, const QString &className = QString())
00357 {
00358 QString result = "set"+n;
00359 result[3] = result[3].toUpper();
00360
00361 if ( !className.isEmpty() )
00362 result = className + "::" + result;
00363 return result;
00364 }
00365
00366
00367 static QString getFunction(const QString &n, const QString &className = QString())
00368 {
00369 QString result = n;
00370 result[0] = result[0].toLower();
00371
00372 if ( !className.isEmpty() )
00373 result = className + "::" + result;
00374 return result;
00375 }
00376
00377
00378 static void addQuotes( QString &s )
00379 {
00380 if ( !s.startsWith( '"' ) ) s.prepend( '"' );
00381 if ( !s.endsWith( '"' ) ) s.append( '"' );
00382 }
00383
00384 static QString quoteString( const QString &s )
00385 {
00386 QString r = s;
00387 r.replace( '\\', "\\\\" );
00388 r.replace( '\"', "\\\"" );
00389 r.remove( '\r' );
00390 r.replace( '\n', "\\n\"\n\"" );
00391 return '\"' + r + '\"';
00392 }
00393
00394 static QString literalString( const QString &s )
00395 {
00396 bool isAscii = true;
00397 for(int i = s.length(); i--;)
00398 if (s[i].unicode() > 127) isAscii = false;
00399
00400 if (isAscii)
00401 return "QLatin1String( " + quoteString(s) + " )";
00402 else
00403 return "QString::fromUtf8( " + quoteString(s) + " )";
00404 }
00405
00406 static QString dumpNode(const QDomNode &node)
00407 {
00408 QString msg;
00409 QTextStream s(&msg, QIODevice::WriteOnly );
00410 node.save(s, 0);
00411
00412 msg = msg.simplified();
00413 if (msg.length() > 40)
00414 return msg.left(37)+"...";
00415 return msg;
00416 }
00417
00418 static QString filenameOnly(const QString& path)
00419 {
00420 int i = path.lastIndexOf(QRegExp("[/\\]"));
00421 if (i >= 0)
00422 return path.mid(i+1);
00423 return path;
00424 }
00425
00426 static QString signalEnumName(const QString &signalName)
00427 {
00428 QString result;
00429 result = "signal" + signalName;
00430 result[6] = result[6].toUpper();
00431
00432 return result;
00433 }
00434
00435 static void preProcessDefault( QString &defaultValue, const QString &name,
00436 const QString &type,
00437 const CfgEntry::Choices &choices,
00438 QString &code )
00439 {
00440 if ( type == "String" && !defaultValue.isEmpty() ) {
00441 defaultValue = literalString(defaultValue);
00442
00443 } else if ( type == "Path" && !defaultValue.isEmpty() ) {
00444 defaultValue = literalString( defaultValue );
00445 } else if ( type == "Url" && !defaultValue.isEmpty() ) {
00446 defaultValue = "KUrl( " + literalString(defaultValue) + ")";
00447 } else if ( ( type == "UrlList" || type == "StringList" || type == "PathList") && !defaultValue.isEmpty() ) {
00448 QTextStream cpp( &code, QIODevice::WriteOnly | QIODevice::Append );
00449 if (!code.isEmpty())
00450 cpp << endl;
00451
00452 cpp << " QStringList default" << name << ";" << endl;
00453 const QStringList defaults = defaultValue.split( ',' );
00454 QStringList::ConstIterator it;
00455 for( it = defaults.constBegin(); it != defaults.constEnd(); ++it ) {
00456 cpp << " default" << name << ".append( ";
00457 if( type == "UrlList" ) {
00458 cpp << "KUrl(";
00459 }
00460 cpp << "QString::fromUtf8( \"" << *it << "\" ) ";
00461 if( type == "UrlList" ) {
00462 cpp << ") ";
00463 }
00464 cpp << ");" << endl;
00465 }
00466 defaultValue = "default" + name;
00467
00468 } else if ( type == "Color" && !defaultValue.isEmpty() ) {
00469 QRegExp colorRe("\\d+,\\s*\\d+,\\s*\\d+(,\\s*\\d+)?");
00470 if (colorRe.exactMatch(defaultValue))
00471 {
00472 defaultValue = "QColor( " + defaultValue + " )";
00473 }
00474 else
00475 {
00476 defaultValue = "QColor( \"" + defaultValue + "\" )";
00477 }
00478
00479 } else if ( type == "Enum" ) {
00480 QList<CfgEntry::Choice>::ConstIterator it;
00481 for( it = choices.choices.constBegin(); it != choices.choices.constEnd(); ++it ) {
00482 if ( (*it).name == defaultValue ) {
00483 if ( globalEnums && choices.name().isEmpty() )
00484 defaultValue.prepend( choices.prefix );
00485 else
00486 defaultValue.prepend( enumTypeQualifier(name, choices) + choices.prefix );
00487 break;
00488 }
00489 }
00490
00491 } else if ( type == "IntList" ) {
00492 QTextStream cpp( &code, QIODevice::WriteOnly | QIODevice::Append );
00493 if (!code.isEmpty())
00494 cpp << endl;
00495
00496 cpp << " QList<int> default" << name << ";" << endl;
00497 if (!defaultValue.isEmpty())
00498 {
00499 QStringList defaults = defaultValue.split( ',' );
00500 QStringList::ConstIterator it;
00501 for( it = defaults.constBegin(); it != defaults.constEnd(); ++it ) {
00502 cpp << " default" << name << ".append( " << *it << " );"
00503 << endl;
00504 }
00505 }
00506 defaultValue = "default" + name;
00507 }
00508 }
00509
00510
00511 CfgEntry *parseEntry( const QString &group, const QDomElement &element )
00512 {
00513 bool defaultCode = false;
00514 QString type = element.attribute( "type" );
00515 QString name = element.attribute( "name" );
00516 QString key = element.attribute( "key" );
00517 QString hidden = element.attribute( "hidden" );
00518 QString context = element.attribute( "context" );
00519 QString label;
00520 QString toolTip;
00521 QString whatsThis;
00522 QString defaultValue;
00523 QString code;
00524 QString param;
00525 QString paramName;
00526 QString paramType;
00527 CfgEntry::Choices choices;
00528 QList<Signal> signalList;
00529 QStringList paramValues;
00530 QStringList paramDefaultValues;
00531 QString minValue;
00532 QString maxValue;
00533 int paramMax = 0;
00534
00535 for ( QDomElement e = element.firstChildElement(); !e.isNull(); e = e.nextSiblingElement() ) {
00536 QString tag = e.tagName();
00537 if ( tag == "label" ) {
00538 label = e.text();
00539 context = e.attribute( "context" );
00540 }
00541 else if ( tag == "tooltip" ) {
00542 toolTip = e.text();
00543 context = e.attribute( "context" );
00544 }
00545 else if ( tag == "whatsthis" ) {
00546 whatsThis = e.text();
00547 context = e.attribute( "context" );
00548 }
00549 else if ( tag == "min" ) minValue = e.text();
00550 else if ( tag == "max" ) maxValue = e.text();
00551 else if ( tag == "code" ) code = e.text();
00552 else if ( tag == "parameter" )
00553 {
00554 param = e.attribute( "name" );
00555 paramType = e.attribute( "type" );
00556 if ( param.isEmpty() ) {
00557 std::cerr << "Parameter must have a name: " << qPrintable(dumpNode(e)) << std::endl;
00558 return 0;
00559 }
00560 if ( paramType.isEmpty() ) {
00561 std::cerr << "Parameter must have a type: " << qPrintable(dumpNode(e)) << std::endl;
00562 return 0;
00563 }
00564 if ((paramType == "Int") || (paramType == "UInt"))
00565 {
00566 bool ok;
00567 paramMax = e.attribute("max").toInt(&ok);
00568 if (!ok)
00569 {
00570 std::cerr << "Integer parameter must have a maximum (e.g. max=\"0\"): "
00571 << qPrintable(dumpNode(e)) << std::endl;
00572 return 0;
00573 }
00574 }
00575 else if (paramType == "Enum")
00576 {
00577 for ( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) {
00578 if (e2.tagName() == "values")
00579 {
00580 for ( QDomElement e3 = e2.firstChildElement(); !e3.isNull(); e3 = e3.nextSiblingElement() ) {
00581 if (e3.tagName() == "value")
00582 {
00583 paramValues.append( e3.text() );
00584 }
00585 }
00586 break;
00587 }
00588 }
00589 if (paramValues.isEmpty())
00590 {
00591 std::cerr << "No values specified for parameter '" << qPrintable(param)
00592 << "'." << std::endl;
00593 return 0;
00594 }
00595 paramMax = paramValues.count()-1;
00596 }
00597 else
00598 {
00599 std::cerr << "Parameter '" << qPrintable(param) << "' has type " << qPrintable(paramType)
00600 << " but must be of type int, uint or Enum." << std::endl;
00601 return 0;
00602 }
00603 }
00604 else if ( tag == "default" )
00605 {
00606 if (e.attribute("param").isEmpty())
00607 {
00608 defaultValue = e.text();
00609 if (e.attribute( "code" ) == "true")
00610 defaultCode = true;
00611 }
00612 }
00613 else if ( tag == "choices" ) {
00614 QString name = e.attribute( "name" );
00615 QString prefix = e.attribute( "prefix" );
00616 QList<CfgEntry::Choice> chlist;
00617 for( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) {
00618 if ( e2.tagName() == "choice" ) {
00619 CfgEntry::Choice choice;
00620 choice.name = e2.attribute( "name" );
00621 if ( choice.name.isEmpty() ) {
00622 std::cerr << "Tag <choice> requires attribute 'name'." << std::endl;
00623 }
00624 for( QDomElement e3 = e2.firstChildElement(); !e3.isNull(); e3 = e3.nextSiblingElement() ) {
00625 if ( e3.tagName() == "label" ) {
00626 choice.label = e3.text();
00627 choice.context = e3.attribute( "context" );
00628 }
00629 if ( e3.tagName() == "tooltip" ) {
00630 choice.toolTip = e3.text();
00631 choice.context = e3.attribute( "context" );
00632 }
00633 if ( e3.tagName() == "whatsthis" ) {
00634 choice.whatsThis = e3.text();
00635 choice.context = e3.attribute( "context" );
00636 }
00637 }
00638 chlist.append( choice );
00639 }
00640 }
00641 choices = CfgEntry::Choices( chlist, name, prefix );
00642 }
00643 else if ( tag == "emit" ) {
00644 QDomNode signalNode;
00645 Signal signal;
00646 signal.name = e.attribute( "signal" );
00647 signalList.append( signal);
00648 }
00649 }
00650
00651
00652 bool nameIsEmpty = name.isEmpty();
00653 if ( nameIsEmpty && key.isEmpty() ) {
00654 std::cerr << "Entry must have a name or a key: " << qPrintable(dumpNode(element)) << std::endl;
00655 return 0;
00656 }
00657
00658 if ( key.isEmpty() ) {
00659 key = name;
00660 }
00661
00662 if ( nameIsEmpty ) {
00663 name = key;
00664 name.remove( ' ' );
00665 } else if ( name.contains( ' ' ) ) {
00666 std::cout<<"Entry '"<<qPrintable(name)<<"' contains spaces! <name> elements can not contain spaces!"<<std::endl;
00667 name.remove( ' ' );
00668 }
00669
00670 if (name.contains("$("))
00671 {
00672 if (param.isEmpty())
00673 {
00674 std::cerr << "Name may not be parameterized: " << qPrintable(name) << std::endl;
00675 return 0;
00676 }
00677 }
00678 else
00679 {
00680 if (!param.isEmpty())
00681 {
00682 std::cerr << "Name must contain '$(" << qPrintable(param) << ")': " << qPrintable(name) << std::endl;
00683 return 0;
00684 }
00685 }
00686
00687 if ( label.isEmpty() ) {
00688 label = key;
00689 }
00690
00691 if ( type.isEmpty() ) type = "String";
00692
00693 if (!param.isEmpty())
00694 {
00695
00696 paramName = name;
00697 name.remove("$("+param+')');
00698
00699 for(int i = 0; i <= paramMax; i++)
00700 {
00701 paramDefaultValues.append(QString());
00702 }
00703
00704 for ( QDomElement e = element.firstChildElement(); !e.isNull(); e = e.nextSiblingElement() ) {
00705 QString tag = e.tagName();
00706 if ( tag == "default" )
00707 {
00708 QString index = e.attribute("param");
00709 if (index.isEmpty())
00710 continue;
00711
00712 bool ok;
00713 int i = index.toInt(&ok);
00714 if (!ok)
00715 {
00716 i = paramValues.indexOf(index);
00717 if (i == -1)
00718 {
00719 std::cerr << "Index '" << qPrintable(index) << "' for default value is unknown." << std::endl;
00720 return 0;
00721 }
00722 }
00723
00724 if ((i < 0) || (i > paramMax))
00725 {
00726 std::cerr << "Index '" << i << "' for default value is out of range [0, "<< paramMax<<"]." << std::endl;
00727 return 0;
00728 }
00729
00730 QString tmpDefaultValue = e.text();
00731
00732 if (e.attribute( "code" ) != "true")
00733 preProcessDefault(tmpDefaultValue, name, type, choices, code);
00734
00735 paramDefaultValues[i] = tmpDefaultValue;
00736 }
00737 }
00738 }
00739
00740 if (!validNameRegexp->exactMatch(name))
00741 {
00742 if (nameIsEmpty)
00743 std::cerr << "The key '" << qPrintable(key) << "' can not be used as name for the entry because "
00744 "it is not a valid name. You need to specify a valid name for this entry." << std::endl;
00745 else
00746 std::cerr << "The name '" << qPrintable(name) << "' is not a valid name for an entry." << std::endl;
00747 return 0;
00748 }
00749
00750 if (allNames.contains(name))
00751 {
00752 if (nameIsEmpty)
00753 std::cerr << "The key '" << qPrintable(key) << "' can not be used as name for the entry because "
00754 "it does not result in a unique name. You need to specify a unique name for this entry." << std::endl;
00755 else
00756 std::cerr << "The name '" << qPrintable(name) << "' is not unique." << std::endl;
00757 return 0;
00758 }
00759 allNames.append(name);
00760
00761 if (!defaultCode)
00762 {
00763 preProcessDefault(defaultValue, name, type, choices, code);
00764 }
00765
00766 CfgEntry *result = new CfgEntry( group, type, key, name, context, label, toolTip, whatsThis,
00767 code, defaultValue, choices, signalList,
00768 hidden == "true" );
00769 if (!param.isEmpty())
00770 {
00771 result->setParam(param);
00772 result->setParamName(paramName);
00773 result->setParamType(paramType);
00774 result->setParamValues(paramValues);
00775 result->setParamDefaultValues(paramDefaultValues);
00776 result->setParamMax(paramMax);
00777 }
00778 result->setMinValue(minValue);
00779 result->setMaxValue(maxValue);
00780
00781 return result;
00782 }
00783
00784 static bool isUnsigned(const QString& type)
00785 {
00786 if ( type == "UInt" ) return true;
00787 if ( type == "ULongLong" ) return true;
00788 return false;
00789 }
00790
00794 QString param( const QString &type )
00795 {
00796 if ( type == "String" ) return "const QString &";
00797 else if ( type == "StringList" ) return "const QStringList &";
00798 else if ( type == "Font" ) return "const QFont &";
00799 else if ( type == "Rect" ) return "const QRect &";
00800 else if ( type == "Size" ) return "const QSize &";
00801 else if ( type == "Color" ) return "const QColor &";
00802 else if ( type == "Point" ) return "const QPoint &";
00803 else if ( type == "Int" ) return "int";
00804 else if ( type == "UInt" ) return "uint";
00805 else if ( type == "Bool" ) return "bool";
00806 else if ( type == "Double" ) return "double";
00807 else if ( type == "DateTime" ) return "const QDateTime &";
00808 else if ( type == "LongLong" ) return "qint64";
00809 else if ( type == "ULongLong" ) return "quint64";
00810 else if ( type == "IntList" ) return "const QList<int> &";
00811 else if ( type == "Enum" ) return "int";
00812 else if ( type == "Path" ) return "const QString &";
00813 else if ( type == "PathList" ) return "const QStringList &";
00814 else if ( type == "Password" ) return "const QString &";
00815 else if ( type == "Url" ) return "const KUrl &";
00816 else if ( type == "UrlList" ) return "const KUrl::List &";
00817 else {
00818 std::cerr <<"kconfig_compiler does not support type \""<< type <<"\""<<std::endl;
00819 return "QString";
00820 }
00821 }
00822
00826 QString cppType( const QString &type )
00827 {
00828 if ( type == "String" ) return "QString";
00829 else if ( type == "StringList" ) return "QStringList";
00830 else if ( type == "Font" ) return "QFont";
00831 else if ( type == "Rect" ) return "QRect";
00832 else if ( type == "Size" ) return "QSize";
00833 else if ( type == "Color" ) return "QColor";
00834 else if ( type == "Point" ) return "QPoint";
00835 else if ( type == "Int" ) return "int";
00836 else if ( type == "UInt" ) return "uint";
00837 else if ( type == "Bool" ) return "bool";
00838 else if ( type == "Double" ) return "double";
00839 else if ( type == "DateTime" ) return "QDateTime";
00840 else if ( type == "LongLong" ) return "qint64";
00841 else if ( type == "ULongLong" ) return "quint64";
00842 else if ( type == "IntList" ) return "QList<int>";
00843 else if ( type == "Enum" ) return "int";
00844 else if ( type == "Path" ) return "QString";
00845 else if ( type == "PathList" ) return "QStringList";
00846 else if ( type == "Password" ) return "QString";
00847 else if ( type == "Url" ) return "KUrl";
00848 else if ( type == "UrlList" ) return "KUrl::List";
00849 else {
00850 std::cerr<<"kconfig_compiler does not support type \""<< type <<"\""<<std::endl;
00851 return "QString";
00852 }
00853 }
00854
00855 QString defaultValue( const QString &type )
00856 {
00857 if ( type == "String" ) return "\"\"";
00858 else if ( type == "StringList" ) return "QStringList()";
00859 else if ( type == "Font" ) return "QFont()";
00860 else if ( type == "Rect" ) return "QRect()";
00861 else if ( type == "Size" ) return "QSize()";
00862 else if ( type == "Color" ) return "QColor(128, 128, 128)";
00863 else if ( type == "Point" ) return "QPoint()";
00864 else if ( type == "Int" ) return "0";
00865 else if ( type == "UInt" ) return "0";
00866 else if ( type == "Bool" ) return "false";
00867 else if ( type == "Double" ) return "0.0";
00868 else if ( type == "DateTime" ) return "QDateTime()";
00869 else if ( type == "LongLong" ) return "0";
00870 else if ( type == "ULongLong" ) return "0";
00871 else if ( type == "IntList" ) return "QList<int>()";
00872 else if ( type == "Enum" ) return "0";
00873 else if ( type == "Path" ) return "\"\"";
00874 else if ( type == "PathList" ) return "QStringList()";
00875 else if ( type == "Password" ) return "\"\"";
00876 else if ( type == "Url" ) return "KUrl()";
00877 else if ( type == "UrlList" ) return "KUrl::List()";
00878 else {
00879 std::cerr<<"Error, kconfig_compiler does not support the \""<< type <<"\" type!"<<std::endl;
00880 return "QString";
00881 }
00882 }
00883
00884 QString itemType( const QString &type )
00885 {
00886 QString t;
00887
00888 t = type;
00889 t.replace( 0, 1, t.left( 1 ).toUpper() );
00890
00891 return t;
00892 }
00893
00894 static QString itemDeclaration(const CfgEntry *e)
00895 {
00896 if (itemAccessors)
00897 return QString();
00898
00899 QString fCap = e->name();
00900 fCap[0] = fCap[0].toUpper();
00901 return " KConfigSkeleton::Item"+itemType( e->type() ) +
00902 " *item" + fCap +
00903 ( (!e->param().isEmpty())?(QString("[%1]").arg(e->paramMax()+1)) : QString()) +
00904 ";\n";
00905 }
00906
00907
00908
00909
00910 static QString itemVar(const CfgEntry *e)
00911 {
00912 QString result;
00913 if (itemAccessors)
00914 {
00915 if ( !dpointer )
00916 {
00917 result = 'm' + e->name() + "Item";
00918 result[1] = result[1].toUpper();
00919 }
00920 else
00921 {
00922 result = e->name() + "Item";
00923 result[0] = result[0].toLower();
00924 }
00925 }
00926 else
00927 {
00928 result = "item" + e->name();
00929 result[4] = result[4].toUpper();
00930 }
00931 return result;
00932 }
00933
00934 static QString itemPath(const CfgEntry *e)
00935 {
00936 QString result;
00937 if ( dpointer ) {
00938 result = "d->"+itemVar(e);
00939 }
00940 else {
00941 result = itemVar(e);
00942 }
00943 return result;
00944 }
00945
00946 QString newItem( const QString &type, const QString &name, const QString &key,
00947 const QString &defaultValue, const QString ¶m = QString())
00948 {
00949 QString t = "new KConfigSkeleton::Item" + itemType( type ) +
00950 "( currentGroup(), " + key + ", " + varPath( name ) + param;
00951 if ( type == "Enum" ) t += ", values" + name;
00952 if ( !defaultValue.isEmpty() ) {
00953 t += ", ";
00954 if ( type == "String" ) t += defaultValue;
00955 else t+= defaultValue;
00956 }
00957 t += " );";
00958
00959 return t;
00960 }
00961
00962 QString paramString(const QString &s, const CfgEntry *e, int i)
00963 {
00964 QString result = s;
00965 QString needle = "$("+e->param()+')';
00966 if (result.contains(needle))
00967 {
00968 QString tmp;
00969 if (e->paramType() == "Enum")
00970 {
00971 tmp = e->paramValues()[i];
00972 }
00973 else
00974 {
00975 tmp = QString::number(i);
00976 }
00977
00978 result.replace(needle, tmp);
00979 }
00980 return result;
00981 }
00982
00983 QString paramString(const QString &group, const QList<Param> ¶meters)
00984 {
00985 QString paramString = group;
00986 QString arguments;
00987 int i = 1;
00988 for (QList<Param>::ConstIterator it = parameters.constBegin();
00989 it != parameters.constEnd(); ++it)
00990 {
00991 if (paramString.contains("$("+(*it).name+')'))
00992 {
00993 QString tmp;
00994 tmp.sprintf("%%%d", i++);
00995 paramString.replace("$("+(*it).name+')', tmp);
00996 arguments += ".arg( mParam"+(*it).name+" )";
00997 }
00998 }
00999 if (arguments.isEmpty())
01000 return "QLatin1String( \""+group+"\" )";
01001
01002 return "QString( QLatin1String( \""+paramString+"\" ) )"+arguments;
01003 }
01004
01005
01006 QString userTextsFunctions( CfgEntry *e, QString itemVarStr=QString(), QString i=QString() )
01007 {
01008 QString txt;
01009 if (itemVarStr.isNull()) itemVarStr=itemPath(e);
01010 if ( !e->label().isEmpty() ) {
01011 txt += " " + itemVarStr + "->setLabel( ";
01012 if ( !e->context().isEmpty() )
01013 txt += "i18nc(" + quoteString(e->context()) + ", ";
01014 else
01015 txt += "i18n(";
01016 if ( !e->param().isEmpty() )
01017 txt += quoteString(e->label().replace("$("+e->param()+')', i));
01018 else
01019 txt+= quoteString(e->label());
01020 txt+= ") );\n";
01021 }
01022 if ( !e->toolTip().isEmpty() ) {
01023 txt += " " + itemVarStr + "->setToolTip( ";
01024 if ( !e->context().isEmpty() )
01025 txt += "i18nc(" + quoteString(e->context()) + ", ";
01026 else
01027 txt += "i18n(";
01028 if ( !e->param().isEmpty() )
01029 txt += quoteString(e->toolTip().replace("$("+e->param()+')', i));
01030 else
01031 txt+= quoteString(e->toolTip());
01032 txt+=") );\n";
01033 }
01034 if ( !e->whatsThis().isEmpty() ) {
01035 txt += " " + itemVarStr + "->setWhatsThis( ";
01036 if ( !e->context().isEmpty() )
01037 txt += "i18nc(" + quoteString(e->context()) + ", ";
01038 else
01039 txt += "i18n(";
01040 if ( !e->param().isEmpty() )
01041 txt += quoteString(e->whatsThis().replace("$("+e->param()+')', i));
01042 else
01043 txt+= quoteString(e->whatsThis());
01044 txt+=") );\n";
01045 }
01046 return txt;
01047 }
01048
01049
01050
01051
01052 QString memberAccessorBody( CfgEntry *e )
01053 {
01054 QString result;
01055 QTextStream out(&result, QIODevice::WriteOnly);
01056 QString n = e->name();
01057 QString t = e->type();
01058 bool useEnumType = useEnumTypes && t == "Enum";
01059
01060 out << "return ";
01061 if (useEnumType)
01062 out << "static_cast<" << enumType(e) << ">(";
01063 out << This << varPath(n);
01064 if (!e->param().isEmpty())
01065 out << "[i]";
01066 if (useEnumType)
01067 out << ")";
01068 out << ";" << endl;
01069
01070 return result;
01071 }
01072
01073
01074
01075
01076 QString memberMutatorBody( CfgEntry *e )
01077 {
01078 QString result;
01079 QTextStream out(&result, QIODevice::WriteOnly);
01080 QString n = e->name();
01081 QString t = e->type();
01082
01083 if (!e->minValue().isEmpty())
01084 {
01085 if (e->minValue() != "0" || !isUnsigned(t)) {
01086 out << "if (v < " << e->minValue() << ")" << endl;
01087 out << "{" << endl;
01088 out << " kDebug() << \"" << setFunction(n);
01089 out << ": value \" << v << \" is less than the minimum value of ";
01090 out << e->minValue()<< "\" << endl;" << endl;
01091 out << " v = " << e->minValue() << ";" << endl;
01092 out << "}" << endl;
01093 }
01094 }
01095
01096 if (!e->maxValue().isEmpty())
01097 {
01098 out << endl << "if (v > " << e->maxValue() << ")" << endl;
01099 out << "{" << endl;
01100 out << " kDebug() << \"" << setFunction(n);
01101 out << ": value \" << v << \" is greater than the maximum value of ";
01102 out << e->maxValue()<< "\" << endl;" << endl;
01103 out << " v = " << e->maxValue() << ";" << endl;
01104 out << "}" << endl << endl;
01105 }
01106
01107 out << "if (!" << This << "isImmutable( QString::fromLatin1 ( \"";
01108 if (!e->param().isEmpty())
01109 {
01110 out << e->paramName().replace("$("+e->param()+")", "%1") << "\" ).arg( ";
01111 if ( e->paramType() == "Enum" ) {
01112 out << "QLatin1String( ";
01113
01114 if (globalEnums)
01115 out << enumName(e->param()) << "ToString[i]";
01116 else
01117 out << enumName(e->param()) << "::enumToString[i]";
01118
01119 out << " )";
01120 }
01121 else
01122 {
01123 out << "i";
01124 }
01125 out << " )";
01126 }
01127 else
01128 {
01129 out << n << "\" )";
01130 }
01131 out << " ))" << (!e->signalList().empty() ? " {" : "") << endl;
01132 out << " " << This << varPath(n);
01133 if (!e->param().isEmpty())
01134 out << "[i]";
01135 out << " = v;" << endl;
01136
01137 if ( !e->signalList().empty() ) {
01138 foreach(const Signal &signal, e->signalList()) {
01139 out << " " << This << varPath("settingsChanged") << " |= " << signalEnumName(signal.name) << ";" << endl;
01140 }
01141 out << "}" << endl;
01142 }
01143
01144 return result;
01145 }
01146
01147
01148
01149
01150 QString itemAccessorBody( CfgEntry *e )
01151 {
01152 QString result;
01153 QTextStream out(&result, QIODevice::WriteOnly);
01154
01155 out << "return " << itemPath(e);
01156 if (!e->param().isEmpty()) out << "[i]";
01157 out << ";" << endl;
01158
01159 return result;
01160 }
01161
01162
01163 QString indent(QString text, int spaces)
01164 {
01165 QString result;
01166 QTextStream out(&result, QIODevice::WriteOnly);
01167 QTextStream in(&text, QIODevice::ReadOnly);
01168 QString currLine;
01169 while ( !in.atEnd() )
01170 {
01171 currLine = in.readLine();
01172 if (!currLine.isEmpty())
01173 for (int i=0; i < spaces; i++)
01174 out << " ";
01175 out << currLine << endl;
01176 }
01177 return result;
01178 }
01179
01180
01181 int main( int argc, char **argv )
01182 {
01183 QCoreApplication app(argc, argv);
01184
01185 validNameRegexp = new QRegExp("[a-zA-Z_][a-zA-Z0-9_]*");
01186
01187 QString directoryName, inputFilename, codegenFilename;
01188 parseArgs(app.arguments(), directoryName, inputFilename, codegenFilename);
01189
01190 QString baseDir = directoryName;
01191 #ifdef Q_OS_WIN
01192 if (!baseDir.endsWith('/') && !baseDir.endsWith('\\'))
01193 #else
01194 if (!baseDir.endsWith('/'))
01195 #endif
01196 baseDir.append("/");
01197
01198 if (!codegenFilename.endsWith(".kcfgc"))
01199 {
01200 std::cerr << "Codegen options file must have extension .kcfgc" << std::endl;
01201 return 1;
01202 }
01203 QString baseName = QFileInfo(codegenFilename).fileName();
01204 baseName = baseName.left(baseName.length() - 6);
01205
01206 QSettings codegenConfig(codegenFilename, QSettings::IniFormat);
01207
01208 QString nameSpace = codegenConfig.value("NameSpace").toString();
01209 QString className = codegenConfig.value("ClassName").toString();
01210 QString inherits = codegenConfig.value("Inherits").toString();
01211 QString visibility = codegenConfig.value("Visibility").toString();
01212 if (!visibility.isEmpty()) visibility+=' ';
01213 bool forceStringFilename = codegenConfig.value("ForceStringFilename", false).toBool();
01214 bool singleton = codegenConfig.value("Singleton", false).toBool();
01215 bool staticAccessors = singleton;
01216
01217 bool customAddons = codegenConfig.value("CustomAdditions", false).toBool();
01218 QString memberVariables = codegenConfig.value("MemberVariables").toString();
01219 QStringList headerIncludes = codegenConfig.value("IncludeFiles", QStringList()).toStringList();
01220 QStringList sourceIncludes = codegenConfig.value("SourceIncludeFiles", QStringList()).toStringList();
01221 QStringList mutators = codegenConfig.value("Mutators", QStringList()).toStringList();
01222 bool allMutators = false;
01223 if ((mutators.count() == 1) && (mutators.at(0).toLower() == "true"))
01224 allMutators = true;
01225 itemAccessors = codegenConfig.value("ItemAccessors", false).toBool();
01226 bool setUserTexts = codegenConfig.value("SetUserTexts", false).toBool();
01227
01228 globalEnums = codegenConfig.value("GlobalEnums", false).toBool();
01229 useEnumTypes = codegenConfig.value("UseEnumTypes", false).toBool();
01230
01231 dpointer = (memberVariables == "dpointer");
01232
01233 QFile input( inputFilename );
01234
01235 QDomDocument doc;
01236 QString errorMsg;
01237 int errorRow;
01238 int errorCol;
01239 if ( !doc.setContent( &input, &errorMsg, &errorRow, &errorCol ) ) {
01240 std::cerr << "Unable to load document." << std::endl;
01241 std::cerr << "Parse error in " << inputFilename << ", line " << errorRow << ", col " << errorCol << ": " << errorMsg << std::endl;
01242 return 1;
01243 }
01244
01245 QDomElement cfgElement = doc.documentElement();
01246
01247 if ( cfgElement.isNull() ) {
01248 std::cerr << "No document in kcfg file" << std::endl;
01249 return 1;
01250 }
01251
01252 QString cfgFileName;
01253 bool cfgFileNameArg = false;
01254 QList<Param> parameters;
01255 QList<Signal> signalList;
01256 QStringList includes;
01257 bool hasSignals = false;
01258
01259 QList<CfgEntry*> entries;
01260
01261 for ( QDomElement e = cfgElement.firstChildElement(); !e.isNull(); e = e.nextSiblingElement() ) {
01262 QString tag = e.tagName();
01263
01264 if ( tag == "include" ) {
01265 QString includeFile = e.text();
01266 if (!includeFile.isEmpty())
01267 includes.append(includeFile);
01268
01269 } else if ( tag == "kcfgfile" ) {
01270 cfgFileName = e.attribute( "name" );
01271 cfgFileNameArg = e.attribute( "arg" ).toLower() == "true";
01272 for( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) {
01273 if ( e2.tagName() == "parameter" ) {
01274 Param p;
01275 p.name = e2.attribute( "name" );
01276 p.type = e2.attribute( "type" );
01277 if (p.type.isEmpty())
01278 p.type = "String";
01279 parameters.append( p );
01280 }
01281 }
01282
01283 } else if ( tag == "group" ) {
01284 QString group = e.attribute( "name" );
01285 if ( group.isEmpty() ) {
01286 std::cerr << "Group without name" << std::endl;
01287 return 1;
01288 }
01289 for( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) {
01290 if ( e2.tagName() != "entry" ) continue;
01291 CfgEntry *entry = parseEntry( group, e2 );
01292 if ( entry ) entries.append( entry );
01293 else {
01294 std::cerr << "Can not parse entry." << std::endl;
01295 return 1;
01296 }
01297 }
01298 }
01299 else if ( tag == "signal" ) {
01300 QString signalName = e.attribute( "name" );
01301 if ( signalName.isEmpty() ) {
01302 std::cerr << "Signal without name." << std::endl;
01303 return 1;
01304 }
01305 Signal theSignal;
01306 theSignal.name = signalName;
01307
01308 for( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) {
01309 if ( e2.tagName() == "argument") {
01310 SignalArguments argument;
01311 argument.type = e2.attribute("type");
01312 if ( argument.type.isEmpty() ) {
01313 std::cerr << "Signal argument without type." << std::endl;
01314 return 1;
01315 }
01316 argument.variableName = e2.text();
01317 theSignal.arguments.append(argument);
01318 }
01319 else if( e2.tagName() == "label") {
01320 theSignal.label = e2.text();
01321 }
01322 }
01323 signalList.append(theSignal);
01324 }
01325 }
01326
01327 if ( inherits.isEmpty() ) inherits = "KConfigSkeleton";
01328
01329 if ( className.isEmpty() ) {
01330 std::cerr << "Class name missing" << std::endl;
01331 return 1;
01332 }
01333
01334 if ( singleton && !parameters.isEmpty() ) {
01335 std::cerr << "Singleton class can not have parameters" << std::endl;
01336 return 1;
01337 }
01338
01339 if ( !cfgFileName.isEmpty() && cfgFileNameArg)
01340 {
01341 std::cerr << "Having both a fixed filename and a filename as argument is not possible." << std::endl;
01342 return 1;
01343 }
01344
01345 if ( entries.isEmpty() ) {
01346 std::cerr << "No entries." << std::endl;
01347 }
01348
01349 #if 0
01350 CfgEntry *cfg;
01351 for( cfg = entries.first(); cfg; cfg = entries.next() ) {
01352 cfg->dump();
01353 }
01354 #endif
01355
01356 hasSignals = !signalList.empty();
01357 QString headerFileName = baseName + ".h";
01358 QString implementationFileName = baseName + ".cpp";
01359 QString mocFileName = baseName + ".moc";
01360 QString cppPreamble;
01361
01362 QFile header( baseDir + headerFileName );
01363 if ( !header.open( QIODevice::WriteOnly ) ) {
01364 std::cerr << "Can not open '" << baseDir << headerFileName << "for writing." << std::endl;
01365 return 1;
01366 }
01367
01368 QTextStream h( &header );
01369
01370 h << "// This file is generated by kconfig_compiler from " << QFileInfo(inputFilename).fileName() << "." << endl;
01371 h << "// All changes you do to this file will be lost." << endl;
01372
01373 h << "#ifndef " << ( !nameSpace.isEmpty() ? nameSpace.toUpper() + '_' : "" )
01374 << className.toUpper() << "_H" << endl;
01375 h << "#define " << ( !nameSpace.isEmpty() ? nameSpace.toUpper() + '_' : "" )
01376 << className.toUpper() << "_H" << endl << endl;
01377
01378
01379 QStringList::ConstIterator it;
01380 for( it = headerIncludes.constBegin(); it != headerIncludes.constEnd(); ++it ) {
01381 if ( (*it).startsWith('"') )
01382 h << "#include " << *it << endl;
01383 else
01384 h << "#include <" << *it << ">" << endl;
01385 }
01386
01387 if ( headerIncludes.count() > 0 ) h << endl;
01388
01389 if ( !singleton && parameters.isEmpty() )
01390 h << "#include <kglobal.h>" << endl;
01391
01392 h << "#include <kconfigskeleton.h>" << endl;
01393 h << "#include <kdebug.h>" << endl << endl;
01394
01395
01396 for( it = includes.constBegin(); it != includes.constEnd(); ++it ) {
01397 if ( (*it).startsWith('"') )
01398 h << "#include " << *it << endl;
01399 else
01400 h << "#include <" << *it << ">" << endl;
01401 }
01402
01403 if ( !nameSpace.isEmpty() )
01404 h << "namespace " << nameSpace << " {" << endl << endl;
01405
01406
01407 if ( dpointer )
01408 h << "class " << className << "Private;" << endl << endl;
01409
01410
01411 h << "class " << visibility << className << " : public " << inherits << endl;
01412
01413 h << "{" << endl;
01414
01415 if( hasSignals )
01416 h << " Q_OBJECT" << endl;
01417 h << " public:" << endl;
01418
01419
01420 QList<CfgEntry*>::ConstIterator itEntry;
01421 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
01422 const CfgEntry::Choices &choices = (*itEntry)->choices();
01423 QList<CfgEntry::Choice> chlist = choices.choices;
01424 if ( !chlist.isEmpty() ) {
01425 QStringList values;
01426 QList<CfgEntry::Choice>::ConstIterator itChoice;
01427 for( itChoice = chlist.constBegin(); itChoice != chlist.constEnd(); ++itChoice ) {
01428 values.append( choices.prefix + (*itChoice).name );
01429 }
01430 if ( choices.name().isEmpty() ) {
01431 if ( globalEnums ) {
01432 h << " enum { " << values.join( ", " ) << " };" << endl;
01433 } else {
01434
01435 h << " class " << enumName( (*itEntry)->name(), (*itEntry)->choices() ) << endl;
01436 h << " {" << endl;
01437 h << " public:" << endl;
01438 h << " enum type { " << values.join( ", " ) << ", COUNT };" << endl;
01439 h << " };" << endl;
01440 }
01441 } else if ( !choices.external() ) {
01442
01443 h << " enum " << enumName( (*itEntry)->name(), (*itEntry)->choices() ) << " { " << values.join( ", " ) << " };" << endl;
01444 }
01445 }
01446 QStringList values = (*itEntry)->paramValues();
01447 if ( !values.isEmpty() ) {
01448 if ( globalEnums ) {
01449
01450
01451
01452 h << " enum { " << values.join( ", " ) << " };" << endl;
01453 h << " static const char* const " << enumName( (*itEntry)->param() ) << "ToString[];" << endl;
01454 cppPreamble += "const char* const " + className + "::" + enumName( (*itEntry)->param() ) +
01455 "ToString[] = { \"" + values.join( "\", \"" ) + "\" };\n";
01456 } else {
01457 h << " class " << enumName( (*itEntry)->param() ) << endl;
01458 h << " {" << endl;
01459 h << " public:" << endl;
01460 h << " enum type { " << values.join( ", " ) << ", COUNT };" << endl;
01461 h << " static const char* const enumToString[];" << endl;
01462 h << " };" << endl;
01463 cppPreamble += "const char* const " + className + "::" + enumName( (*itEntry)->param() ) +
01464 "::enumToString[] = { \"" + values.join( "\", \"" ) + "\" };\n";
01465 }
01466 }
01467 }
01468 if ( hasSignals ) {
01469 h << "\n enum {" << endl;
01470 unsigned val = 1;
01471 QList<Signal>::ConstIterator it, itEnd = signalList.constEnd();
01472 for ( it = signalList.constBegin(); it != itEnd; val <<= 1) {
01473 if ( !val ) {
01474 std::cerr << "Too many signals to create unique bit masks" << std::endl;
01475 exit(1);
01476 }
01477 Signal signal = *it;
01478 h << " " << signalEnumName(signal.name) << " = 0x" << hex << val;
01479 if ( ++it != itEnd )
01480 h << ",";
01481 h << endl;
01482 }
01483 h << " };" << dec << endl;
01484 }
01485 h << endl;
01486
01487 if ( !singleton ) {
01488 h << " " << className << "(";
01489 if (cfgFileNameArg)
01490 {
01491 if(forceStringFilename)
01492 h << " const QString &cfgfilename"
01493 << (parameters.isEmpty() ? " = QString()" : ", ");
01494 else
01495 h << " KSharedConfig::Ptr config"
01496 << (parameters.isEmpty() ? " = KGlobal::config()" : ", ");
01497 }
01498 for (QList<Param>::ConstIterator it = parameters.constBegin();
01499 it != parameters.constEnd(); ++it)
01500 {
01501 if (it != parameters.constBegin())
01502 h << ",";
01503 h << " " << param((*it).type) << " " << (*it).name;
01504 }
01505 h << " );" << endl;
01506 } else {
01507 h << " static " << className << " *self();" << endl;
01508 if (cfgFileNameArg)
01509 {
01510 h << " static void instance(const QString& cfgfilename);" << endl;
01511 }
01512 }
01513
01514
01515 h << " ~" << className << "();" << endl << endl;
01516
01517
01518 if (staticAccessors)
01519 This = "self()->";
01520 else
01521 Const = " const";
01522
01523 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
01524 QString n = (*itEntry)->name();
01525 QString t = (*itEntry)->type();
01526
01527
01528 if (allMutators || mutators.contains(n))
01529 {
01530 h << " /**" << endl;
01531 h << " Set " << (*itEntry)->label() << endl;
01532 h << " */" << endl;
01533 if (staticAccessors)
01534 h << " static" << endl;
01535 h << " void " << setFunction(n) << "( ";
01536 if (!(*itEntry)->param().isEmpty())
01537 h << cppType((*itEntry)->paramType()) << " i, ";
01538 if (useEnumTypes && t == "Enum")
01539 h << enumType(*itEntry);
01540 else
01541 h << param( t );
01542 h << " v )";
01543
01544
01545 if ( !dpointer )
01546 {
01547 h << endl << " {" << endl;
01548 h << indent(memberMutatorBody(*itEntry), 6 );
01549 h << " }" << endl;
01550 }
01551 else
01552 {
01553 h << ";" << endl;
01554 }
01555 }
01556 h << endl;
01557
01558 h << " /**" << endl;
01559 h << " Get " << (*itEntry)->label() << endl;
01560 h << " */" << endl;
01561 if (staticAccessors)
01562 h << " static" << endl;
01563 h << " ";
01564 if (useEnumTypes && t == "Enum")
01565 h << enumType(*itEntry);
01566 else
01567 h << cppType(t);
01568 h << " " << getFunction(n) << "(";
01569 if (!(*itEntry)->param().isEmpty())
01570 h << " " << cppType((*itEntry)->paramType()) <<" i ";
01571 h << ")" << Const;
01572
01573
01574 if ( !dpointer )
01575 {
01576 h << endl << " {" << endl;
01577 h << indent(memberAccessorBody((*itEntry)), 6 );
01578 h << " }" << endl;
01579 }
01580 else
01581 {
01582 h << ";" << endl;
01583 }
01584
01585
01586 if ( itemAccessors ) {
01587 h << endl;
01588 h << " /**" << endl;
01589 h << " Get Item object corresponding to " << n << "()"
01590 << endl;
01591 h << " */" << endl;
01592 h << " Item" << itemType( (*itEntry)->type() ) << " *"
01593 << getFunction( n ) << "Item(";
01594 if (!(*itEntry)->param().isEmpty()) {
01595 h << " " << cppType((*itEntry)->paramType()) << " i ";
01596 }
01597 h << ")";
01598 if (! dpointer )
01599 {
01600 h << endl << " {" << endl;
01601 h << indent( itemAccessorBody((*itEntry)), 6);
01602 h << " }" << endl;
01603 }
01604 else
01605 {
01606 h << ";" << endl;
01607 }
01608 }
01609
01610 h << endl;
01611 }
01612
01613
01614
01615 if( hasSignals ) {
01616 h << endl;
01617 h << " Q_SIGNALS:";
01618 foreach(const Signal &signal, signalList) {
01619 h << endl;
01620 if ( !signal.label.isEmpty() ) {
01621 h << " /**" << endl;
01622 h << " " << signal.label << endl;
01623 h << " */" << endl;
01624 }
01625 h << " void " << signal.name << "(";
01626 QList<SignalArguments>::ConstIterator it, itEnd = signal.arguments.constEnd();
01627 for ( it = signal.arguments.constBegin(); it != itEnd; ) {
01628 SignalArguments argument = *it;
01629 QString type = param(argument.type);
01630 if ( useEnumTypes && argument.type == "Enum" ) {
01631 for ( int i = 0, end = entries.count(); i < end; ++i ) {
01632 if ( entries[i]->name() == argument.variableName ) {
01633 type = enumType(entries[i]);
01634 break;
01635 }
01636 }
01637 }
01638 h << type << " " << argument.variableName;
01639 if ( ++it != itEnd ) {
01640 h << ", ";
01641 }
01642 }
01643 h << ");" << endl;
01644 }
01645 h << endl;
01646 }
01647
01648 h << " protected:" << endl;
01649
01650
01651 if ( singleton ) {
01652 h << " " << className << "(";
01653 if ( cfgFileNameArg )
01654 h << "const QString& arg";
01655 h << ");" << endl;
01656 h << " friend class " << className << "Helper;" << endl << endl;
01657 }
01658
01659 if ( hasSignals ) {
01660 h << " virtual void usrWriteConfig();" << endl;
01661 }
01662
01663
01664 if ( !memberVariables.isEmpty() && memberVariables != "private" && memberVariables != "dpointer") {
01665 h << " " << memberVariables << ":" << endl;
01666 }
01667
01668
01669 for (QList<Param>::ConstIterator it = parameters.constBegin();
01670 it != parameters.constEnd(); ++it)
01671 {
01672 h << " " << cppType((*it).type) << " mParam" << (*it).name << ";" << endl;
01673 }
01674
01675 if ( memberVariables != "dpointer" )
01676 {
01677 QString group;
01678 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
01679 if ( (*itEntry)->group() != group ) {
01680 group = (*itEntry)->group();
01681 h << endl;
01682 h << " // " << group << endl;
01683 }
01684 h << " " << cppType( (*itEntry)->type() ) << " " << varName( (*itEntry)->name() );
01685 if ( !(*itEntry)->param().isEmpty() )
01686 {
01687 h << QString("[%1]").arg( (*itEntry)->paramMax()+1 );
01688 }
01689 h << ";" << endl;
01690 }
01691
01692 h << endl << " private:" << endl;
01693 if ( itemAccessors ) {
01694 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
01695 h << " Item" << itemType( (*itEntry)->type() ) << " *" << itemVar( *itEntry );
01696 if ( !(*itEntry)->param().isEmpty() ) h << QString("[%1]").arg( (*itEntry)->paramMax()+1 );
01697 h << ";" << endl;
01698 }
01699 }
01700 if ( hasSignals )
01701 h << " uint " << varName("settingsChanged") << ";" << endl;
01702
01703 }
01704 else
01705 {
01706
01707 h << " private:" << endl;
01708 h << " " + className + "Private *d;" << endl;
01709 }
01710
01711 if (customAddons)
01712 {
01713 h << " // Include custom additions" << endl;
01714 h << " #include \"" << filenameOnly(baseName) << "_addons.h\"" <<endl;
01715 }
01716
01717 h << "};" << endl << endl;
01718
01719 if ( !nameSpace.isEmpty() ) h << "}" << endl << endl;
01720
01721 h << "#endif" << endl << endl;
01722
01723
01724 header.close();
01725
01726 QFile implementation( baseDir + implementationFileName );
01727 if ( !implementation.open( QIODevice::WriteOnly ) ) {
01728 std::cerr << "Can not open '" << qPrintable(implementationFileName) << "for writing."
01729 << std::endl;
01730 return 1;
01731 }
01732
01733 QTextStream cpp( &implementation );
01734
01735
01736 cpp << "// This file is generated by kconfig_compiler from " << QFileInfo(inputFilename).fileName() << "." << endl;
01737 cpp << "// All changes you do to this file will be lost." << endl << endl;
01738
01739 cpp << "#include \"" << headerFileName << "\"" << endl << endl;
01740
01741 for( it = sourceIncludes.constBegin(); it != sourceIncludes.constEnd(); ++it ) {
01742 if ( (*it).startsWith('"') )
01743 cpp << "#include " << *it << endl;
01744 else
01745 cpp << "#include <" << *it << ">" << endl;
01746 }
01747
01748 if ( sourceIncludes.count() > 0 ) cpp << endl;
01749
01750 if ( setUserTexts ) cpp << "#include <klocale.h>" << endl << endl;
01751
01752
01753 if ( singleton )
01754 cpp << "#include <kglobal.h>" << endl << "#include <QtCore/QFile>" << endl << endl;
01755 if ( singleton && cfgFileNameArg )
01756 cpp << "#include <kdebug.h>" << endl << endl;
01757
01758 if ( !nameSpace.isEmpty() )
01759 cpp << "using namespace " << nameSpace << ";" << endl << endl;
01760
01761 QString group;
01762
01763
01764 if ( dpointer )
01765 {
01766 if ( !nameSpace.isEmpty() )
01767 cpp << "namespace " << nameSpace << " {" << endl;
01768 cpp << "class " << className << "Private" << endl;
01769 cpp << "{" << endl;
01770 cpp << " public:" << endl;
01771 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
01772 if ( (*itEntry)->group() != group ) {
01773 group = (*itEntry)->group();
01774 cpp << endl;
01775 cpp << " // " << group << endl;
01776 }
01777 cpp << " " << cppType( (*itEntry)->type() ) << " " << varName( (*itEntry)->name() );
01778 if ( !(*itEntry)->param().isEmpty() )
01779 {
01780 cpp << QString("[%1]").arg( (*itEntry)->paramMax()+1 );
01781 }
01782 cpp << ";" << endl;
01783 }
01784 cpp << endl << " // items" << endl;
01785 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
01786 cpp << " KConfigSkeleton::Item" << itemType( (*itEntry)->type() ) << " *" << itemVar( *itEntry );
01787 if ( !(*itEntry)->param().isEmpty() ) cpp << QString("[%1]").arg( (*itEntry)->paramMax()+1 );
01788 cpp << ";" << endl;
01789 }
01790 if ( hasSignals ) {
01791 cpp << " uint " << varName("settingsChanged") << ";" << endl;
01792 }
01793
01794 cpp << "};" << endl << endl;
01795 if ( !nameSpace.isEmpty() )
01796 cpp << "}" << endl << endl;
01797 }
01798
01799
01800 if ( singleton ) {
01801 if( !nameSpace.isEmpty() )
01802 cpp << "namespace " << nameSpace << " {" << endl;
01803 cpp << "class " << className << "Helper" << endl;
01804 cpp << '{' << endl;
01805 cpp << " public:" << endl;
01806 cpp << " " << className << "Helper() : q(0) {}" << endl;
01807 cpp << " ~" << className << "Helper() { delete q; }" << endl;
01808 cpp << " " << className << " *q;" << endl;
01809 cpp << "};" << endl;
01810 if( !nameSpace.isEmpty() )
01811 cpp << "}" << endl;
01812 cpp << "K_GLOBAL_STATIC(" << className << "Helper, s_global" << className << ")" << endl;
01813
01814 cpp << className << " *" << className << "::self()" << endl;
01815 cpp << "{" << endl;
01816 if ( cfgFileNameArg ) {
01817 cpp << " if (!s_global" << className << "->q)" << endl;
01818 cpp << " kFatal() << \"you need to call " << className << "::instance before using\";" << endl;
01819 } else {
01820 cpp << " if (!s_global" << className << "->q) {" << endl;
01821 cpp << " new " << className << ';' << endl;
01822 cpp << " s_global" << className << "->q->readConfig();" << endl;
01823 cpp << " }" << endl << endl;
01824 }
01825 cpp << " return s_global" << className << "->q;" << endl;
01826 cpp << "}" << endl << endl;
01827
01828 if ( cfgFileNameArg ) {
01829 cpp << "void " << className << "::instance(const QString& cfgfilename)" << endl;
01830 cpp << "{" << endl;
01831 cpp << " if (s_global" << className << "->q) {" << endl;
01832 cpp << " kDebug() << \"" << className << "::instance called after the first use - ignoring\";" << endl;
01833 cpp << " return;" << endl;
01834 cpp << " }" << endl;
01835 cpp << " new " << className << "(cfgfilename);" << endl;
01836 cpp << " s_global" << className << "->q->readConfig();" << endl;
01837 cpp << "}" << endl << endl;
01838 }
01839 }
01840
01841 if ( !cppPreamble.isEmpty() )
01842 cpp << cppPreamble << endl;
01843
01844
01845 cpp << className << "::" << className << "( ";
01846 if ( cfgFileNameArg ) {
01847 if ( !singleton && ! forceStringFilename)
01848 cpp << " KSharedConfig::Ptr config";
01849 else
01850 cpp << " const QString& config";
01851 cpp << (parameters.isEmpty() ? " " : ", ");
01852 }
01853
01854 for (QList<Param>::ConstIterator it = parameters.constBegin();
01855 it != parameters.constEnd(); ++it)
01856 {
01857 if (it != parameters.constBegin())
01858 cpp << ",";
01859 cpp << " " << param((*it).type) << " " << (*it).name;
01860 }
01861 cpp << " )" << endl;
01862
01863 cpp << " : " << inherits << "(";
01864 if ( !cfgFileName.isEmpty() ) cpp << " QLatin1String( \"" << cfgFileName << "\" ";
01865 if ( cfgFileNameArg ) cpp << " config ";
01866 if ( !cfgFileName.isEmpty() ) cpp << ") ";
01867 cpp << ")" << endl;
01868
01869
01870 for (QList<Param>::ConstIterator it = parameters.constBegin();
01871 it != parameters.constEnd(); ++it)
01872 {
01873 cpp << " , mParam" << (*it).name << "(" << (*it).name << ")" << endl;
01874 }
01875
01876 if ( hasSignals && !dpointer )
01877 cpp << " , " << varName("settingsChanged") << "(0)" << endl;
01878
01879 cpp << "{" << endl;
01880
01881 if (dpointer)
01882 {
01883 cpp << " d = new " + className + "Private;" << endl;
01884 if (hasSignals)
01885 cpp << " " << varPath("settingsChanged") << " = 0;" << endl;
01886 }
01887
01888
01889 if (singleton) {
01890 cpp << " Q_ASSERT(!s_global" << className << "->q);" << endl;
01891 cpp << " s_global" << className << "->q = this;" << endl;
01892 }
01893
01894 group.clear();
01895
01896 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
01897 if ( (*itEntry)->group() != group ) {
01898 if ( !group.isEmpty() ) cpp << endl;
01899 group = (*itEntry)->group();
01900 cpp << " setCurrentGroup( " << paramString(group, parameters) << " );" << endl << endl;
01901 }
01902
01903 QString key = paramString( (*itEntry)->key(), parameters );
01904 if ( !(*itEntry)->code().isEmpty() ) {
01905 cpp << (*itEntry)->code() << endl;
01906 }
01907 if ( (*itEntry)->type() == "Enum" ) {
01908 cpp << " QList<KConfigSkeleton::ItemEnum::Choice2> values"
01909 << (*itEntry)->name() << ";" << endl;
01910 QList<CfgEntry::Choice> choices = (*itEntry)->choices().choices;
01911 QList<CfgEntry::Choice>::ConstIterator it;
01912 for( it = choices.constBegin(); it != choices.constEnd(); ++it ) {
01913 cpp << " {" << endl;
01914 cpp << " KConfigSkeleton::ItemEnum::Choice2 choice;" << endl;
01915 cpp << " choice.name = QLatin1String(\"" << (*it).name << "\");" << endl;
01916 if ( setUserTexts ) {
01917 if ( !(*it).label.isEmpty() ) {
01918 cpp << " choice.label = ";
01919 if ( !(*it).context.isEmpty() )
01920 cpp << "i18nc(" + quoteString((*it).context) + ", ";
01921 else
01922 cpp << "i18n(";
01923 cpp << quoteString((*it).label) << ");" << endl;
01924 }
01925 if ( !(*it).toolTip.isEmpty() ) {
01926 cpp << " choice.toolTip = ";
01927 if ( !(*it).context.isEmpty() )
01928 cpp << "i18nc(" + quoteString((*it).context) + ", ";
01929 else
01930 cpp << "i18n(";
01931 cpp << quoteString((*it).toolTip) << ");" << endl;
01932 }
01933 if ( !(*it).whatsThis.isEmpty() ) {
01934 cpp << " choice.whatsThis = ";
01935 if ( !(*it).context.isEmpty() )
01936 cpp << "i18nc(" + quoteString((*it).context) + ", ";
01937 else
01938 cpp << "i18n(";
01939 cpp << quoteString((*it).whatsThis) << ");" << endl;
01940 }
01941 }
01942 cpp << " values" << (*itEntry)->name() << ".append( choice );" << endl;
01943 cpp << " }" << endl;
01944 }
01945 }
01946
01947 if (!dpointer)
01948 cpp << itemDeclaration( *itEntry );
01949
01950 if ( (*itEntry)->param().isEmpty() )
01951 {
01952
01953 cpp << " " << itemPath( *itEntry ) << " = "
01954 << newItem( (*itEntry)->type(), (*itEntry)->name(), key, (*itEntry)->defaultValue() ) << endl;
01955
01956 if ( !(*itEntry)->minValue().isEmpty() )
01957 cpp << " " << itemPath( *itEntry ) << "->setMinValue(" << (*itEntry)->minValue() << ");" << endl;
01958 if ( !(*itEntry)->maxValue().isEmpty() )
01959 cpp << " " << itemPath( *itEntry ) << "->setMaxValue(" << (*itEntry)->maxValue() << ");" << endl;
01960
01961 if ( setUserTexts )
01962 cpp << userTextsFunctions( (*itEntry) );
01963
01964 cpp << " addItem( " << itemPath( *itEntry );
01965 QString quotedName = (*itEntry)->name();
01966 addQuotes( quotedName );
01967 if ( quotedName != key ) cpp << ", QLatin1String( \"" << (*itEntry)->name() << "\" )";
01968 cpp << " );" << endl;
01969 }
01970 else
01971 {
01972
01973 for(int i = 0; i <= (*itEntry)->paramMax(); i++)
01974 {
01975 QString defaultStr;
01976 QString itemVarStr(itemPath( *itEntry )+QString("[%1]").arg(i));
01977
01978 if ( !(*itEntry)->paramDefaultValue(i).isEmpty() )
01979 defaultStr = (*itEntry)->paramDefaultValue(i);
01980 else if ( !(*itEntry)->defaultValue().isEmpty() )
01981 defaultStr = paramString( (*itEntry)->defaultValue(), (*itEntry), i );
01982 else
01983 defaultStr = defaultValue( (*itEntry)->type() );
01984
01985 cpp << " " << itemVarStr << " = "
01986 << newItem( (*itEntry)->type(), (*itEntry)->name(), paramString(key, *itEntry, i), defaultStr, QString("[%1]").arg(i) )
01987 << endl;
01988
01989 if ( setUserTexts )
01990 cpp << userTextsFunctions( *itEntry, itemVarStr, (*itEntry)->paramName() );
01991
01992
01993
01994
01995
01996 cpp << " addItem( " << itemVarStr << ", QLatin1String( \"";
01997 if ( (*itEntry)->paramType()=="Enum" )
01998 cpp << (*itEntry)->paramName().replace( "$("+(*itEntry)->param()+')', "%1").arg((*itEntry)->paramValues()[i] );
01999 else
02000 cpp << (*itEntry)->paramName().replace( "$("+(*itEntry)->param()+')', "%1").arg(i);
02001 cpp << "\" ) );" << endl;
02002 }
02003 }
02004 }
02005
02006 cpp << "}" << endl << endl;
02007
02008 if (dpointer)
02009 {
02010
02011 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
02012 QString n = (*itEntry)->name();
02013 QString t = (*itEntry)->type();
02014
02015
02016 if (allMutators || mutators.contains(n))
02017 {
02018 cpp << "void " << setFunction(n, className) << "( ";
02019 if ( !(*itEntry)->param().isEmpty() )
02020 cpp << cppType( (*itEntry)->paramType() ) << " i, ";
02021 if (useEnumTypes && t == "Enum")
02022 cpp << enumType(*itEntry);
02023 else
02024 cpp << param( t );
02025 cpp << " v )";
02026
02027
02028 cpp << "{" << endl;
02029 cpp << indent(memberMutatorBody( *itEntry ), 6);
02030 cpp << "}" << endl << endl;
02031 }
02032
02033
02034 if (useEnumTypes && t == "Enum")
02035 cpp << enumType(*itEntry);
02036 else
02037 cpp << cppType(t);
02038 cpp << " " << getFunction(n, className) << "(";
02039 if ( !(*itEntry)->param().isEmpty() )
02040 cpp << " " << cppType( (*itEntry)->paramType() ) <<" i ";
02041 cpp << ")" << Const << endl;
02042
02043
02044 cpp << "{" << endl;
02045 cpp << indent(memberAccessorBody( *itEntry ), 2);
02046 cpp << "}" << endl << endl;
02047
02048
02049 if ( itemAccessors )
02050 {
02051 cpp << endl;
02052 cpp << "KConfigSkeleton::Item" << itemType( (*itEntry)->type() ) << " *"
02053 << getFunction( n, className ) << "Item(";
02054 if ( !(*itEntry)->param().isEmpty() ) {
02055 cpp << " " << cppType( (*itEntry)->paramType() ) << " i ";
02056 }
02057 cpp << ")" << endl;
02058 cpp << "{" << endl;
02059 cpp << indent(itemAccessorBody( *itEntry ), 2);
02060 cpp << "}" << endl;
02061 }
02062
02063 cpp << endl;
02064 }
02065 }
02066
02067
02068 cpp << className << "::~" << className << "()" << endl;
02069 cpp << "{" << endl;
02070 if ( singleton ) {
02071 if ( dpointer )
02072 cpp << " delete d;" << endl;
02073 cpp << " if (!s_global" << className << ".isDestroyed()) {" << endl;
02074 cpp << " s_global" << className << "->q = 0;" << endl;
02075 cpp << " }" << endl;
02076 }
02077 cpp << "}" << endl << endl;
02078
02079 if ( hasSignals ) {
02080 cpp << "void " << className << "::" << "usrWriteConfig()" << endl;
02081 cpp << "{" << endl;
02082 cpp << " " << inherits << "::usrWriteConfig();" << endl << endl;
02083 foreach(const Signal &signal, signalList) {
02084 cpp << " if ( " << varPath("settingsChanged") << " & " << signalEnumName(signal.name) << " ) " << endl;
02085 cpp << " emit " << signal.name << "(";
02086 QList<SignalArguments>::ConstIterator it, itEnd = signal.arguments.constEnd();
02087 for ( it = signal.arguments.constBegin(); it != itEnd; ) {
02088 SignalArguments argument = *it;
02089 bool cast = false;
02090 if ( useEnumTypes && argument.type == "Enum" ) {
02091 for ( int i = 0, end = entries.count(); i < end; ++i ) {
02092 if ( entries[i]->name() == argument.variableName ) {
02093 cpp << "static_cast<" << enumType(entries[i]) << ">(";
02094 cast = true;
02095 break;
02096 }
02097 }
02098 }
02099 cpp << varPath(argument.variableName);
02100 if ( cast )
02101 cpp << ")";
02102 if ( ++it != itEnd )
02103 cpp << ", ";
02104 }
02105 cpp << ");" << endl << endl;
02106 }
02107 cpp << " " << varPath("settingsChanged") << " = 0;" << endl;
02108 cpp << "}" << endl;
02109 }
02110
02111
02112 if( hasSignals ) {
02113 cpp << endl;
02114 cpp << "#include \"" << mocFileName << "\"" << endl;
02115 cpp << endl;
02116 }
02117
02118
02119 qDeleteAll( entries );
02120
02121 implementation.close();
02122 }