28 #undef QT_NO_CAST_FROM_ASCII
30 #include <QtCore/QCoreApplication>
31 #include <QtCore/QFile>
32 #include <QtCore/QFileInfo>
33 #include <QtCore/QSettings>
34 #include <QtCore/QTextStream>
35 #include <QtXml/QDomAttr>
36 #include <QtCore/QRegExp>
37 #include <QtCore/QStringList>
45 QTextStream cout(stdout);
46 QTextStream cerr(stderr);
52 directory = QChar::fromLatin1(
'.');
54 for (
int i = 1; i < args.count(); ++i) {
55 if (args.at(i) == QLatin1String(
"-d") || args.at(i) == QLatin1String(
"--directory")) {
56 if (i + 1 > args.count()) {
57 cerr << args.at(i) <<
" needs an argument" << endl;
60 directory = args.at(++i);
61 }
else if (args.at(i).startsWith(QLatin1String(
"-d"))) {
62 directory = args.at(i).mid(2);
63 }
else if (args.at(i) == QLatin1String(
"--help") || args.at(i) == QLatin1String(
"-h")) {
64 cout <<
"Options:" << endl;
65 cout <<
" -L --license Display software license" << endl;
66 cout <<
" -d, --directory <dir> Directory to generate files in [.]" << endl;
67 cout <<
" -h, --help Display this help" << endl;
69 cout <<
"Arguments:" << endl;
70 cout <<
" file.kcfg Input kcfg XML file" << endl;
71 cout <<
" file.kcfgc Code generation options file" << endl;
73 }
else if (args.at(i) == QLatin1String(
"--license") || args.at(i) == QLatin1String(
"-L")) {
74 cout <<
"Copyright 2003 Cornelius Schumacher, Waldo Bastian, Zack Rusin," << endl;
75 cout <<
" Reinhold Kainhofer, Duncan Mac-Vicar P., Harald Fernengel" << endl;
76 cout <<
"This program comes with ABSOLUTELY NO WARRANTY." << endl;
77 cout <<
"You may redistribute copies of this program" << endl;
78 cout <<
"under the terms of the GNU Library Public License." << endl;
79 cout <<
"For more information about these matters, see the file named COPYING." << endl;
81 }
else if (args.at(i).startsWith(QLatin1Char(
'-'))) {
82 cerr <<
"Unknown option: " << args.at(i) << endl;
84 }
else if (fileCount == 0) {
87 }
else if (fileCount == 1) {
91 cerr <<
"Too many arguments" << endl;
96 cerr <<
"Too few arguments" << endl;
112 CfgConfig(
const QString &codegenFilename )
115 QSettings codegenConfig(codegenFilename, QSettings::IniFormat);
117 nameSpace = codegenConfig.value(
"NameSpace").toString();
118 className = codegenConfig.value(
"ClassName").toString();
119 if ( className.isEmpty() ) {
120 cerr <<
"Class name missing" << endl;
123 inherits = codegenConfig.value(
"Inherits").toString();
124 if ( inherits.isEmpty() ) inherits =
"KConfigSkeleton";
125 visibility = codegenConfig.value(
"Visibility").toString();
126 if ( !visibility.isEmpty() ) visibility +=
' ';
127 forceStringFilename = codegenConfig.value(
"ForceStringFilename",
false).toBool();
128 singleton = codegenConfig.value(
"Singleton",
false).toBool();
129 staticAccessors = singleton;
130 customAddons = codegenConfig.value(
"CustomAdditions",
false).toBool();
131 memberVariables = codegenConfig.value(
"MemberVariables").toString();
132 dpointer = (memberVariables ==
"dpointer");
133 headerIncludes = codegenConfig.value(
"IncludeFiles",
QStringList()).toStringList();
134 sourceIncludes = codegenConfig.value(
"SourceIncludeFiles",
QStringList()).toStringList();
135 mutators = codegenConfig.value(
"Mutators",
QStringList()).toStringList();
136 allMutators = ((mutators.count() == 1) && (mutators.at(0).toLower() ==
"true"));
137 itemAccessors = codegenConfig.value(
"ItemAccessors",
false).toBool();
138 setUserTexts = codegenConfig.value(
"SetUserTexts",
false).toBool();
139 defaultGetters = codegenConfig.value(
"DefaultValueGetters",
QStringList()).toStringList();
140 allDefaultGetters = (defaultGetters.count() == 1) && (defaultGetters.at(0).toLower() ==
"true");
141 globalEnums = codegenConfig.value(
"GlobalEnums",
false).toBool();
142 useEnumTypes = codegenConfig.value(
"UseEnumTypes",
false).toBool();
151 bool forceStringFilename;
153 bool staticAccessors;
162 bool allDefaultGetters;
170 struct SignalArguments
180 QList<SignalArguments> arguments;
201 Choices(
const QList<Choice> &d,
const QString &n,
const QString &p )
202 :
prefix(p), choices(d), mName(n)
204 int i = n.indexOf(QLatin1String(
"::"));
206 mExternalQual = n.left(i + 2);
209 QList<Choice> choices;
210 const QString& name()
const {
return mName; }
211 const QString& externalQualifier()
const {
return mExternalQual; }
212 bool external()
const {
return !mExternalQual.isEmpty(); }
223 : mGroup( group ), mType( type ), mKey( key ), mName( name ),
224 mContext( context ), mLabel( label ), mToolTip( toolTip ), mWhatsThis( whatsThis ),
225 mCode( code ), mDefaultValue( defaultValue ), mChoices( choices ),
226 mSignalList(signalList), mHidden( hidden )
233 void setType(
const QString &type ) { mType = type; }
234 QString type()
const {
return mType; }
236 void setKey(
const QString &key ) { mKey = key; }
237 QString key()
const {
return mKey; }
239 void setName(
const QString &name ) { mName = name; }
240 QString name()
const {
return mName; }
242 void setContext(
const QString &context ) { mContext = context; }
243 QString context()
const {
return mContext; }
245 void setLabel(
const QString &label ) { mLabel = label; }
246 QString label()
const {
return mLabel; }
248 void setToolTip(
const QString &toolTip ) { mToolTip = toolTip; }
249 QString toolTip()
const {
return mToolTip; }
251 void setWhatsThis(
const QString &whatsThis ) { mWhatsThis = whatsThis; }
252 QString whatsThis()
const {
return mWhatsThis; }
254 void setDefaultValue(
const QString &d ) { mDefaultValue = d; }
257 void setCode(
const QString &d ) { mCode = d; }
258 QString code()
const {
return mCode; }
260 void setMinValue(
const QString &d ) { mMin = d; }
261 QString minValue()
const {
return mMin; }
263 void setMaxValue(
const QString &d ) { mMax = d; }
264 QString maxValue()
const {
return mMax; }
266 void setParam(
const QString &d ) { mParam = d; }
269 void setParamName(
const QString &d ) { mParamName = d; }
270 QString paramName()
const {
return mParamName; }
272 void setParamType(
const QString &d ) { mParamType = d; }
273 QString paramType()
const {
return mParamType; }
275 void setChoices(
const QList<Choice> &d,
const QString &n,
const QString &p ) { mChoices = Choices( d, n, p ); }
276 Choices choices()
const {
return mChoices; }
278 void setParamValues(
const QStringList &d ) { mParamValues = d; }
279 QStringList paramValues()
const {
return mParamValues; }
281 void setParamDefaultValues(
const QStringList &d ) { mParamDefaultValues = d; }
282 QString paramDefaultValue(
int i)
const {
return mParamDefaultValues[i]; }
284 void setParamMax(
int d ) { mParamMax = d; }
285 int paramMax()
const {
return mParamMax; }
287 void setSignalList(
const QList<Signal> &value ) { mSignalList = value; }
288 QList<Signal> signalList()
const {
return mSignalList; }
290 bool hidden()
const {
return mHidden; }
294 cerr <<
"<entry>" << endl;
295 cerr <<
" group: " << mGroup << endl;
296 cerr <<
" type: " << mType << endl;
297 cerr <<
" key: " << mKey << endl;
298 cerr <<
" name: " << mName << endl;
299 cerr <<
" context: " << mContext << endl;
300 cerr <<
" label: " << mLabel << endl;
302 cerr <<
" code: " << mCode << endl;
305 if (!
param().isEmpty())
307 cerr <<
" param name: "<< mParamName << endl;
308 cerr <<
" param type: "<< mParamType << endl;
309 cerr <<
" paramvalues: " << mParamValues.join(QChar::fromLatin1(
':')) << endl;
311 cerr <<
" default: " << mDefaultValue << endl;
312 cerr <<
" hidden: " << mHidden << endl;
313 cerr <<
" min: " << mMin << endl;
314 cerr <<
" max: " << mMax << endl;
315 cerr <<
"</entry>" << endl;
333 QList<Signal> mSignalList;
354 if ( !cfg.dpointer ) {
355 result = QChar::fromLatin1(
'm') + n;
356 result[1] = result[1].toUpper();
360 result[0] = result[0].toLower();
368 if ( cfg.dpointer ) {
369 result =
"d->"+
varName(n, cfg);
379 QString result = QString::fromLatin1(
"Enum") + n;
380 result[4] = result[4].toUpper();
387 if ( result.isEmpty() )
389 result = QString::fromLatin1(
"Enum") + n;
390 result[4] = result[4].toUpper();
397 QString result = e->choices().name();
398 if ( result.isEmpty() )
400 result = QString::fromLatin1(
"Enum") + e->name();
402 result += QString::fromLatin1(
"::type");
403 result[4] = result[4].toUpper();
411 if ( result.isEmpty() )
413 result = QString::fromLatin1(
"Enum") + n + QString::fromLatin1(
"::");
414 result[4] = result[4].toUpper();
416 else if ( c.external() )
417 result = c.externalQualifier();
425 QString result = QString::fromLatin1(
"set") + n;
426 result[3] = result[3].toUpper();
428 if ( !className.isEmpty() )
429 result = className + QString::fromLatin1(
"::") + result;
435 QString result = QString::fromLatin1(
"default") + n + QString::fromLatin1(
"Value");
436 result[7] = result[7].toUpper();
438 if ( !className.isEmpty() )
439 result = className + QString::fromLatin1(
"::") + result;
446 result[0] = result[0].toLower();
448 if ( !className.isEmpty() )
449 result = className + QString::fromLatin1(
"::") + result;
456 if ( !s.startsWith( QLatin1Char(
'"') ) )
457 s.prepend( QLatin1Char(
'"') );
458 if ( !s.endsWith( QLatin1Char(
'"') ) )
459 s.append( QLatin1Char(
'"') );
465 r.replace( QLatin1Char(
'\\'), QLatin1String(
"\\\\") );
466 r.replace( QLatin1Char(
'\"'), QLatin1String(
"\\\"") );
467 r.remove( QLatin1Char(
'\r') );
468 r.replace( QLatin1Char(
'\n'), QLatin1String(
"\\n\"\n\"") );
469 return QLatin1Char(
'\"') + r + QLatin1Char(
'\"');
475 for(
int i = s.length(); i--;)
476 if (s[i].unicode() > 127) isAscii =
false;
479 return QString::fromLatin1(
"QLatin1String( ") +
quoteString(s) + QString::fromLatin1(
" )");
481 return QString::fromLatin1(
"QString::fromUtf8( ") +
quoteString(s) + QString::fromLatin1(
" )");
487 QTextStream s(&msg, QIODevice::WriteOnly );
490 msg = msg.simplified();
491 if (msg.length() > 40)
492 return msg.left(37) + QString::fromLatin1(
"...");
498 int i = path.lastIndexOf(QRegExp(QLatin1String(
"[/\\]")));
500 return path.mid(i+1);
507 result = QString::fromLatin1(
"signal") + signalName;
508 result[6] = result[6].toUpper();
515 const CfgEntry::Choices &choices,
516 QString &code,
const CfgConfig &cfg )
518 if ( type == QLatin1String(
"String") && !defaultValue.isEmpty() ) {
521 }
else if ( type == QLatin1String(
"Path") && !defaultValue.isEmpty() ) {
523 }
else if ( type == QLatin1String(
"Url") && !defaultValue.isEmpty() ) {
524 defaultValue = QString::fromLatin1(
"KUrl( ") +
literalString(defaultValue) + QLatin1Char(
')');
525 }
else if ( ( type == QLatin1String(
"UrlList") || type == QLatin1String(
"StringList") || type == QLatin1String(
"PathList")) && !defaultValue.isEmpty() ) {
526 QTextStream cpp( &code, QIODevice::WriteOnly | QIODevice::Append );
530 cpp <<
" QStringList default" << name <<
";" << endl;
531 const QStringList defaults = defaultValue.split(QLatin1Char(
','));
532 QStringList::ConstIterator it;
533 for( it = defaults.constBegin(); it != defaults.constEnd(); ++it ) {
534 cpp <<
" default" << name <<
".append( ";
535 if( type ==
"UrlList" ) {
538 cpp <<
"QString::fromUtf8( \"" << *it <<
"\" ) ";
539 if( type == QLatin1String(
"UrlList") ) {
544 defaultValue = QString::fromLatin1(
"default") + name;
546 }
else if ( type == QLatin1String(
"Color") && !defaultValue.isEmpty() ) {
547 QRegExp colorRe(QLatin1String(
"\\d+,\\s*\\d+,\\s*\\d+(,\\s*\\d+)?"));
548 if (colorRe.exactMatch(defaultValue))
550 defaultValue = QLatin1String(
"QColor( ") + defaultValue + QLatin1String(
" )");
554 defaultValue = QLatin1String(
"QColor( \"") + defaultValue + QLatin1String(
"\" )");
557 }
else if ( type == QLatin1String(
"Enum") ) {
558 QList<CfgEntry::Choice>::ConstIterator it;
559 for( it = choices.choices.constBegin(); it != choices.choices.constEnd(); ++it ) {
560 if ( (*it).name == defaultValue ) {
561 if ( cfg.globalEnums && choices.name().isEmpty() )
562 defaultValue.prepend( choices.prefix );
569 }
else if ( type == QLatin1String(
"IntList") ) {
570 QTextStream cpp( &code, QIODevice::WriteOnly | QIODevice::Append );
574 cpp <<
" QList<int> default" << name <<
";" << endl;
575 if (!defaultValue.isEmpty())
577 const QStringList defaults = defaultValue.split( QLatin1Char(
',') );
578 QStringList::ConstIterator it;
579 for( it = defaults.constBegin(); it != defaults.constEnd(); ++it ) {
580 cpp <<
" default" << name <<
".append( " << *it <<
" );"
584 defaultValue = QString::fromLatin1(
"default") + name;
591 bool defaultCode =
false;
592 QString type = element.attribute(
"type" );
593 QString name = element.attribute(
"name" );
594 QString key = element.attribute(
"key" );
595 QString hidden = element.attribute(
"hidden" );
596 QString context = element.attribute(
"context" );
605 CfgEntry::Choices choices;
606 QList<Signal> signalList;
613 for ( QDomElement e = element.firstChildElement(); !e.isNull(); e = e.nextSiblingElement() ) {
615 if ( tag ==
"label" ) {
617 context = e.attribute(
"context" );
619 else if ( tag ==
"tooltip" ) {
621 context = e.attribute(
"context" );
623 else if ( tag ==
"whatsthis" ) {
624 whatsThis = e.text();
625 context = e.attribute(
"context" );
627 else if ( tag ==
"min" ) minValue = e.text();
628 else if ( tag ==
"max" ) maxValue = e.text();
629 else if ( tag ==
"code" ) code = e.text();
630 else if ( tag ==
"parameter" )
632 param = e.attribute(
"name" );
633 paramType = e.attribute(
"type" );
634 if ( param.isEmpty() ) {
635 cerr <<
"Parameter must have a name: " <<
dumpNode(e) << endl;
638 if ( paramType.isEmpty() ) {
639 cerr <<
"Parameter must have a type: " <<
dumpNode(e) << endl;
642 if ((paramType ==
"Int") || (paramType ==
"UInt"))
645 paramMax = e.attribute(
"max").toInt(&ok);
648 cerr <<
"Integer parameter must have a maximum (e.g. max=\"0\"): "
653 else if (paramType ==
"Enum")
655 for ( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) {
656 if (e2.tagName() ==
"values")
658 for ( QDomElement e3 = e2.firstChildElement(); !e3.isNull(); e3 = e3.nextSiblingElement() ) {
659 if (e3.tagName() ==
"value")
661 paramValues.append( e3.text() );
667 if (paramValues.isEmpty())
669 cerr <<
"No values specified for parameter '" << param
673 paramMax = paramValues.count()-1;
677 cerr <<
"Parameter '" << param <<
"' has type " << paramType
678 <<
" but must be of type int, uint or Enum." << endl;
682 else if ( tag ==
"default" )
684 if (e.attribute(
"param").isEmpty())
686 defaultValue = e.text();
687 if (e.attribute(
"code" ) ==
"true")
691 else if ( tag ==
"choices" ) {
692 QString name = e.attribute(
"name" );
694 QList<CfgEntry::Choice> chlist;
695 for( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) {
696 if ( e2.tagName() ==
"choice" ) {
697 CfgEntry::Choice choice;
698 choice.name = e2.attribute(
"name" );
699 if ( choice.name.isEmpty() ) {
700 cerr <<
"Tag <choice> requires attribute 'name'." << endl;
702 for( QDomElement e3 = e2.firstChildElement(); !e3.isNull(); e3 = e3.nextSiblingElement() ) {
703 if ( e3.tagName() ==
"label" ) {
704 choice.label = e3.text();
705 choice.context = e3.attribute(
"context" );
707 if ( e3.tagName() ==
"tooltip" ) {
708 choice.toolTip = e3.text();
709 choice.context = e3.attribute(
"context" );
711 if ( e3.tagName() ==
"whatsthis" ) {
712 choice.whatsThis = e3.text();
713 choice.context = e3.attribute(
"context" );
716 chlist.append( choice );
719 choices = CfgEntry::Choices( chlist, name, prefix );
721 else if ( tag ==
"emit" ) {
724 signal.name = e.attribute(
"signal" );
725 signalList.append( signal);
730 bool nameIsEmpty = name.isEmpty();
731 if ( nameIsEmpty && key.isEmpty() ) {
732 cerr <<
"Entry must have a name or a key: " <<
dumpNode(element) << endl;
736 if ( key.isEmpty() ) {
743 }
else if ( name.contains(
' ' ) ) {
744 cout<<
"Entry '"<<name<<
"' contains spaces! <name> elements can not contain spaces!"<<endl;
748 if (name.contains(
"$("))
752 cerr <<
"Name may not be parameterized: " << name << endl;
758 if (!param.isEmpty())
760 cerr <<
"Name must contain '$(" << param <<
")': " << name << endl;
765 if ( label.isEmpty() ) {
769 if ( type.isEmpty() ) type =
"String";
771 if (!param.isEmpty())
775 name.remove(
"$("+param+
')');
777 for(
int i = 0; i <= paramMax; i++)
779 paramDefaultValues.append(
QString());
782 for ( QDomElement e = element.firstChildElement(); !e.isNull(); e = e.nextSiblingElement() ) {
784 if ( tag ==
"default" )
786 QString index = e.attribute(
"param");
791 int i = index.toInt(&ok);
794 i = paramValues.indexOf(index);
797 cerr <<
"Index '" << index <<
"' for default value is unknown." << endl;
802 if ((i < 0) || (i > paramMax))
804 cerr <<
"Index '" << i <<
"' for default value is out of range [0, "<< paramMax<<
"]." << endl;
808 QString tmpDefaultValue = e.text();
810 if (e.attribute(
"code" ) !=
"true")
813 paramDefaultValues[i] = tmpDefaultValue;
821 cerr <<
"The key '" << key <<
"' can not be used as name for the entry because "
822 "it is not a valid name. You need to specify a valid name for this entry." << endl;
824 cerr <<
"The name '" << name <<
"' is not a valid name for an entry." << endl;
828 if (allNames.contains(name))
831 cerr <<
"The key '" << key <<
"' can not be used as name for the entry because "
832 "it does not result in a unique name. You need to specify a unique name for this entry." << endl;
834 cerr <<
"The name '" << name <<
"' is not unique." << endl;
837 allNames.append(name);
844 CfgEntry *result =
new CfgEntry( group, type, key, name, context, label, toolTip, whatsThis,
845 code, defaultValue, choices, signalList,
847 if (!param.isEmpty())
849 result->setParam(param);
850 result->setParamName(paramName);
851 result->setParamType(paramType);
852 result->setParamValues(paramValues);
853 result->setParamDefaultValues(paramDefaultValues);
854 result->setParamMax(paramMax);
856 result->setMinValue(minValue);
857 result->setMaxValue(maxValue);
864 if ( type ==
"UInt" )
return true;
865 if ( type ==
"ULongLong" )
return true;
874 const QString type = t.toLower();
875 if ( type ==
"string" )
return "const QString &";
876 else if ( type ==
"stringlist" )
return "const QStringList &";
877 else if ( type ==
"font" )
return "const QFont &";
878 else if ( type ==
"rect" )
return "const QRect &";
879 else if ( type ==
"size" )
return "const QSize &";
880 else if ( type ==
"color" )
return "const QColor &";
881 else if ( type ==
"point" )
return "const QPoint &";
882 else if ( type ==
"int" )
return "int";
883 else if ( type ==
"uint" )
return "uint";
884 else if ( type ==
"bool" )
return "bool";
885 else if ( type ==
"double" )
return "double";
886 else if ( type ==
"datetime" )
return "const QDateTime &";
887 else if ( type ==
"longlong" )
return "qint64";
888 else if ( type ==
"ulonglong" )
return "quint64";
889 else if ( type ==
"intlist" )
return "const QList<int> &";
890 else if ( type ==
"enum" )
return "int";
891 else if ( type ==
"path" )
return "const QString &";
892 else if ( type ==
"pathlist" )
return "const QStringList &";
893 else if ( type ==
"password" )
return "const QString &";
894 else if ( type ==
"url" )
return "const KUrl &";
895 else if ( type ==
"urllist" )
return "const KUrl::List &";
897 cerr <<
"kconfig_compiler does not support type \""<< type <<
"\""<<endl;
907 const QString type = t.toLower();
908 if ( type ==
"string" )
return "QString";
909 else if ( type ==
"stringlist" )
return "QStringList";
910 else if ( type ==
"font" )
return "QFont";
911 else if ( type ==
"rect" )
return "QRect";
912 else if ( type ==
"size" )
return "QSize";
913 else if ( type ==
"color" )
return "QColor";
914 else if ( type ==
"point" )
return "QPoint";
915 else if ( type ==
"int" )
return "int";
916 else if ( type ==
"uint" )
return "uint";
917 else if ( type ==
"bool" )
return "bool";
918 else if ( type ==
"double" )
return "double";
919 else if ( type ==
"datetime" )
return "QDateTime";
920 else if ( type ==
"longlong" )
return "qint64";
921 else if ( type ==
"ulonglong" )
return "quint64";
922 else if ( type ==
"intlist" )
return "QList<int>";
923 else if ( type ==
"enum" )
return "int";
924 else if ( type ==
"path" )
return "QString";
925 else if ( type ==
"pathlist" )
return "QStringList";
926 else if ( type ==
"password" )
return "QString";
927 else if ( type ==
"url" )
return "KUrl";
928 else if ( type ==
"urllist" )
return "KUrl::List";
930 cerr<<
"kconfig_compiler does not support type \""<< type <<
"\""<<endl;
937 const QString type = t.toLower();
938 if ( type ==
"string" )
return "\"\"";
939 else if ( type ==
"stringlist" )
return "QStringList()";
940 else if ( type ==
"font" )
return "QFont()";
941 else if ( type ==
"rect" )
return "QRect()";
942 else if ( type ==
"size" )
return "QSize()";
943 else if ( type ==
"color" )
return "QColor(128, 128, 128)";
944 else if ( type ==
"point" )
return "QPoint()";
945 else if ( type ==
"int" )
return "0";
946 else if ( type ==
"uint" )
return "0";
947 else if ( type ==
"bool" )
return "false";
948 else if ( type ==
"double" )
return "0.0";
949 else if ( type ==
"datedime" )
return "QDateTime()";
950 else if ( type ==
"longlong" )
return "0";
951 else if ( type ==
"ulonglong" )
return "0";
952 else if ( type ==
"intlist" )
return "QList<int>()";
953 else if ( type ==
"enum" )
return "0";
954 else if ( type ==
"path" )
return "\"\"";
955 else if ( type ==
"pathlist" )
return "QStringList()";
956 else if ( type ==
"password" )
return "\"\"";
957 else if ( type ==
"url" )
return "KUrl()";
958 else if ( type ==
"urllist" )
return "KUrl::List()";
960 cerr<<
"Error, kconfig_compiler does not support the \""<< type <<
"\" type!"<<endl;
970 t.replace( 0, 1, t.left( 1 ).toUpper() );
977 if (cfg.itemAccessors)
981 fCap[0] = fCap[0].toUpper();
982 return " "+cfg.inherits+
"::Item"+
itemType( e->type() ) +
984 ( (!e->param().isEmpty())?(
QString(
"[%1]").arg(e->paramMax()+1)) :
QString()) +
994 if (cfg.itemAccessors)
998 result =
'm' + e->name() +
"Item";
999 result[1] = result[1].toUpper();
1003 result = e->name() +
"Item";
1004 result[0] = result[0].toLower();
1009 result =
"item" + e->name();
1010 result[4] = result[4].toUpper();
1018 if ( cfg.dpointer ) {
1019 result =
"d->"+
itemVar(e, cfg);
1031 "( currentGroup(), " + key +
", " +
varPath( name, cfg ) +
param;
1032 if ( type ==
"Enum" ) t +=
", values" + name;
1033 if ( !defaultValue.isEmpty() ) {
1046 QString needle =
"$("+e->param()+
')';
1047 if (result.contains(needle))
1050 if (e->paramType() ==
"Enum")
1052 tmp = e->paramValues()[i];
1056 tmp = QString::number(i);
1059 result.replace(needle, tmp);
1069 for (QList<Param>::ConstIterator it = parameters.constBegin();
1070 it != parameters.constEnd(); ++it)
1072 if (paramString.contains(
"$("+(*it).name+
')'))
1075 tmp.sprintf(
"%%%d", i++);
1076 paramString.replace(
"$("+(*it).name+
')', tmp);
1077 arguments +=
".arg( mParam"+(*it).name+
" )";
1080 if (arguments.isEmpty())
1081 return "QLatin1String( \""+group+
"\" )";
1083 return "QString( QLatin1String( \""+paramString+
"\" ) )"+arguments;
1090 if (itemVarStr.isNull()) itemVarStr=
itemPath(e, cfg);
1091 if ( !e->label().isEmpty() ) {
1092 txt +=
" " + itemVarStr +
"->setLabel( ";
1093 if ( !e->context().isEmpty() )
1094 txt +=
"i18nc(" +
quoteString(e->context()) +
", ";
1097 if ( !e->param().isEmpty() )
1098 txt +=
quoteString(e->label().replace(
"$("+e->param()+
')', i));
1103 if ( !e->toolTip().isEmpty() ) {
1104 txt +=
" " + itemVarStr +
"->setToolTip( ";
1105 if ( !e->context().isEmpty() )
1106 txt +=
"i18nc(" +
quoteString(e->context()) +
", ";
1109 if ( !e->param().isEmpty() )
1110 txt +=
quoteString(e->toolTip().replace(
"$("+e->param()+
')', i));
1115 if ( !e->whatsThis().isEmpty() ) {
1116 txt +=
" " + itemVarStr +
"->setWhatsThis( ";
1117 if ( !e->context().isEmpty() )
1118 txt +=
"i18nc(" +
quoteString(e->context()) +
", ";
1121 if ( !e->param().isEmpty() )
1122 txt +=
quoteString(e->whatsThis().replace(
"$("+e->param()+
')', i));
1136 QTextStream out(&result, QIODevice::WriteOnly);
1139 bool useEnumType = cfg.useEnumTypes && t ==
"Enum";
1143 out <<
"static_cast<" <<
enumType(e, globalEnums) <<
">(";
1144 out << This <<
varPath(n, cfg);
1145 if (!e->param().isEmpty())
1160 QTextStream out(&result, QIODevice::WriteOnly);
1164 if (!e->minValue().isEmpty())
1166 if (e->minValue() !=
"0" || !
isUnsigned(t)) {
1167 out <<
"if (v < " << e->minValue() <<
")" << endl;
1170 out <<
": value \" << v << \" is less than the minimum value of ";
1171 out << e->minValue()<<
"\";" << endl;
1172 out <<
" v = " << e->minValue() <<
";" << endl;
1177 if (!e->maxValue().isEmpty())
1179 out << endl <<
"if (v > " << e->maxValue() <<
")" << endl;
1182 out <<
": value \" << v << \" is greater than the maximum value of ";
1183 out << e->maxValue()<<
"\";" << endl;
1184 out <<
" v = " << e->maxValue() <<
";" << endl;
1185 out <<
"}" << endl << endl;
1188 out <<
"if (!" << This <<
"isImmutable( QString::fromLatin1( \"";
1189 if (!e->param().isEmpty())
1191 out << e->paramName().replace(
"$("+e->param()+
")",
"%1") <<
"\" ).arg( ";
1192 if ( e->paramType() ==
"Enum" ) {
1193 out <<
"QLatin1String( ";
1195 if (cfg.globalEnums)
1196 out <<
enumName(e->param()) <<
"ToString[i]";
1198 out <<
enumName(e->param()) <<
"::enumToString[i]";
1212 out <<
" ))" << (!e->signalList().empty() ?
" {" :
"") << endl;
1213 out <<
" " << This <<
varPath(n, cfg);
1214 if (!e->param().isEmpty())
1216 out <<
" = v;" << endl;
1218 if ( !e->signalList().empty() ) {
1219 foreach(
const Signal &signal, e->signalList()) {
1220 out <<
" " << This <<
varPath(
"settingsChanged", cfg) <<
" |= " <<
signalEnumName(signal.name) <<
";" << endl;
1234 QTextStream out(&result, QIODevice::WriteOnly);
1237 if (!e->param().isEmpty()) {
1238 out <<
" switch (i) {" << endl;
1239 for (
int i = 0; i <= e->paramMax(); ++i) {
1240 if (!e->paramDefaultValue(i).isEmpty()) {
1241 out <<
" case " << i <<
": return " << e->paramDefaultValue(i) <<
';' << endl;
1244 out <<
" default:" << endl;
1245 out <<
" return " << e->defaultValue().replace(
"$("+e->param()+
')',
"i") <<
';' << endl;
1246 out <<
" }" << endl;
1248 out <<
" return " << e->defaultValue() <<
';';
1260 QTextStream out(&result, QIODevice::WriteOnly);
1262 out <<
"return " <<
itemPath(e, cfg);
1263 if (!e->param().isEmpty()) out <<
"[i]";
1273 QTextStream out(&result, QIODevice::WriteOnly);
1274 QTextStream in(&text, QIODevice::ReadOnly);
1276 while ( !in.atEnd() )
1278 currLine = in.readLine();
1279 if (!currLine.isEmpty())
1280 for (
int i=0; i < spaces; i++)
1282 out << currLine << endl;
1291 if ( !p_ns.isEmpty() ) {
1292 const QStringList nameSpaces = p_ns.split(
"::" );
1293 foreach (
const QString &ns, nameSpaces )
1294 p_out <<
"namespace " << ns <<
" {" << endl;
1303 if ( !p_ns.isEmpty() ) {
1304 const int namespaceCount = p_ns.count(
"::" ) + 1;
1305 for (
int i = 0; i < namespaceCount; ++i )
1306 p_out <<
"}" << endl;
1314 QCoreApplication app(argc, argv);
1318 QString directoryName, inputFilename, codegenFilename;
1319 parseArgs(app.arguments(), directoryName, inputFilename, codegenFilename);
1321 QString baseDir = directoryName;
1323 if (!baseDir.endsWith(
'/') && !baseDir.endsWith(
'\\'))
1325 if (!baseDir.endsWith(
'/'))
1327 baseDir.append(
"/");
1329 if (!codegenFilename.endsWith(QLatin1String(
".kcfgc")))
1331 cerr <<
"Codegen options file must have extension .kcfgc" << endl;
1334 QString baseName = QFileInfo(codegenFilename).fileName();
1335 baseName = baseName.left(baseName.length() - 6);
1337 CfgConfig cfg = CfgConfig( codegenFilename );
1339 QFile input( inputFilename );
1345 if ( !doc.setContent( &input, &errorMsg, &errorRow, &errorCol ) ) {
1346 cerr <<
"Unable to load document." << endl;
1347 cerr <<
"Parse error in " << inputFilename <<
", line " << errorRow <<
", col " << errorCol <<
": " << errorMsg << endl;
1351 QDomElement cfgElement = doc.documentElement();
1353 if ( cfgElement.isNull() ) {
1354 cerr <<
"No document in kcfg file" << endl;
1359 bool cfgFileNameArg =
false;
1360 QList<Param> parameters;
1361 QList<Signal> signalList;
1363 bool hasSignals =
false;
1365 QList<CfgEntry*> entries;
1367 for ( QDomElement e = cfgElement.firstChildElement(); !e.isNull(); e = e.nextSiblingElement() ) {
1370 if ( tag ==
"include" ) {
1371 QString includeFile = e.text();
1372 if (!includeFile.isEmpty())
1373 includes.append(includeFile);
1375 }
else if ( tag ==
"kcfgfile" ) {
1376 cfgFileName = e.attribute(
"name" );
1377 cfgFileNameArg = e.attribute(
"arg" ).toLower() ==
"true";
1378 for( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) {
1379 if ( e2.tagName() ==
"parameter" ) {
1381 p.name = e2.attribute(
"name" );
1382 p.type = e2.attribute(
"type" );
1383 if (p.type.isEmpty())
1385 parameters.append( p );
1389 }
else if ( tag ==
"group" ) {
1391 if ( group.isEmpty() ) {
1392 cerr <<
"Group without name" << endl;
1395 for( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) {
1396 if ( e2.tagName() !=
"entry" )
continue;
1397 CfgEntry *entry =
parseEntry( group, e2, cfg );
1398 if ( entry ) entries.append( entry );
1400 cerr <<
"Can not parse entry." << endl;
1405 else if ( tag ==
"signal" ) {
1406 QString signalName = e.attribute(
"name" );
1407 if ( signalName.isEmpty() ) {
1408 cerr <<
"Signal without name." << endl;
1412 theSignal.name = signalName;
1414 for( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) {
1415 if ( e2.tagName() ==
"argument") {
1416 SignalArguments argument;
1417 argument.type = e2.attribute(
"type");
1418 if ( argument.type.isEmpty() ) {
1419 cerr <<
"Signal argument without type." << endl;
1422 argument.variableName = e2.text();
1423 theSignal.arguments.append(argument);
1425 else if( e2.tagName() ==
"label") {
1426 theSignal.label = e2.text();
1429 signalList.append(theSignal);
1433 if ( cfg.className.isEmpty() ) {
1434 cerr <<
"Class name missing" << endl;
1438 if ( cfg.singleton && !parameters.isEmpty() ) {
1439 cerr <<
"Singleton class can not have parameters" << endl;
1443 if ( !cfgFileName.isEmpty() && cfgFileNameArg)
1445 cerr <<
"Having both a fixed filename and a filename as argument is not possible." << endl;
1449 if ( entries.isEmpty() ) {
1450 cerr <<
"No entries." << endl;
1455 for( cfg = entries.first(); cfg; cfg = entries.next() ) {
1460 hasSignals = !signalList.empty();
1461 QString headerFileName = baseName +
".h";
1462 QString implementationFileName = baseName +
".cpp";
1463 QString mocFileName = baseName +
".moc";
1466 QFile
header( baseDir + headerFileName );
1467 if ( !header.open( QIODevice::WriteOnly ) ) {
1468 cerr <<
"Can not open '" << baseDir << headerFileName <<
"for writing." << endl;
1472 QTextStream h( &header );
1474 h <<
"// This file is generated by kconfig_compiler from " << QFileInfo(inputFilename).fileName() <<
"." << endl;
1475 h <<
"// All changes you do to this file will be lost." << endl;
1477 h <<
"#ifndef " << ( !cfg.nameSpace.isEmpty() ?
QString (
QString(cfg.nameSpace).replace(
"::",
"_" ).toUpper() +
'_') :
"" )
1478 << cfg.className.toUpper() <<
"_H" << endl;
1479 h <<
"#define " << ( !cfg.nameSpace.isEmpty() ?
QString (
QString(cfg.nameSpace).replace(
"::",
"_" ).toUpper() +
'_') :
"" )
1480 << cfg.className.toUpper() <<
"_H" << endl << endl;
1483 QStringList::ConstIterator it;
1484 for( it = cfg.headerIncludes.constBegin(); it != cfg.headerIncludes.constEnd(); ++it ) {
1485 if ( (*it).startsWith(
'"') )
1486 h <<
"#include " << *it << endl;
1488 h <<
"#include <" << *it <<
">" << endl;
1491 if ( cfg.headerIncludes.count() > 0 ) h << endl;
1493 if ( !cfg.singleton && parameters.isEmpty() )
1494 h <<
"#include <kglobal.h>" << endl;
1496 if ( cfg.inherits==
"KCoreConfigSkeleton" ) {
1497 h <<
"#include <kcoreconfigskeleton.h>" << endl;
1499 h <<
"#include <kconfigskeleton.h>" << endl;
1502 h <<
"#include <kdebug.h>" << endl << endl;
1505 for( it = includes.constBegin(); it != includes.constEnd(); ++it ) {
1506 if ( (*it).startsWith(
'"') )
1507 h <<
"#include " << *it << endl;
1509 h <<
"#include <" << *it <<
">" << endl;
1516 h <<
"class " << cfg.className <<
"Private;" << endl << endl;
1519 h <<
"class " << cfg.visibility << cfg.className <<
" : public " << cfg.inherits << endl;
1524 h <<
" Q_OBJECT" << endl;
1525 h <<
" public:" << endl;
1528 QList<CfgEntry*>::ConstIterator itEntry;
1529 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
1530 const CfgEntry::Choices &choices = (*itEntry)->choices();
1531 const QList<CfgEntry::Choice> chlist = choices.choices;
1532 if ( !chlist.isEmpty() ) {
1534 QList<CfgEntry::Choice>::ConstIterator itChoice;
1535 for( itChoice = chlist.constBegin(); itChoice != chlist.constEnd(); ++itChoice ) {
1536 values.append( choices.prefix + (*itChoice).name );
1538 if ( choices.name().isEmpty() ) {
1539 if ( cfg.globalEnums ) {
1540 h <<
" enum " <<
enumName( (*itEntry)->name(), (*itEntry)->choices() ) <<
" { " << values.join(
", " ) <<
" };" << endl;
1543 h <<
" class " <<
enumName( (*itEntry)->name(), (*itEntry)->choices() ) << endl;
1545 h <<
" public:" << endl;
1546 h <<
" enum type { " << values.join(
", " ) <<
", COUNT };" << endl;
1549 }
else if ( !choices.external() ) {
1551 h <<
" enum " <<
enumName( (*itEntry)->name(), (*itEntry)->choices() ) <<
" { " << values.join(
", " ) <<
" };" << endl;
1554 const QStringList values = (*itEntry)->paramValues();
1555 if ( !values.isEmpty() ) {
1556 if ( cfg.globalEnums ) {
1560 h <<
" enum " <<
enumName( (*itEntry)->param() ) <<
" { " << values.join(
", " ) <<
" };" << endl;
1561 h <<
" static const char* const " <<
enumName( (*itEntry)->param() ) <<
"ToString[];" << endl;
1562 cppPreamble +=
"const char* const " + cfg.className +
"::" +
enumName( (*itEntry)->param() ) +
1563 "ToString[] = { \"" + values.join(
"\", \"" ) +
"\" };\n";
1565 h <<
" class " <<
enumName( (*itEntry)->param() ) << endl;
1567 h <<
" public:" << endl;
1568 h <<
" enum type { " << values.join(
", " ) <<
", COUNT };" << endl;
1569 h <<
" static const char* const enumToString[];" << endl;
1571 cppPreamble +=
"const char* const " + cfg.className +
"::" +
enumName( (*itEntry)->param() ) +
1572 "::enumToString[] = { \"" + values.join(
"\", \"" ) +
"\" };\n";
1577 h <<
"\n enum {" << endl;
1579 QList<Signal>::ConstIterator it, itEnd = signalList.constEnd();
1580 for ( it = signalList.constBegin(); it != itEnd; val <<= 1) {
1582 cerr <<
"Too many signals to create unique bit masks" << endl;
1585 Signal signal = *it;
1586 h <<
" " <<
signalEnumName(signal.name) <<
" = 0x" << hex << val;
1587 if ( ++it != itEnd )
1591 h <<
" };" << dec << endl;
1595 if ( !cfg.singleton ) {
1596 h <<
" " << cfg.className <<
"(";
1599 if(cfg.forceStringFilename)
1600 h <<
" const QString &cfgfilename"
1601 << (parameters.isEmpty() ?
" = QString()" :
", ");
1603 h <<
" KSharedConfig::Ptr config"
1604 << (parameters.isEmpty() ?
" = KGlobal::config()" :
", ");
1606 for (QList<Param>::ConstIterator it = parameters.constBegin();
1607 it != parameters.constEnd(); ++it)
1609 if (it != parameters.constBegin())
1611 h <<
" " <<
param((*it).type) <<
" " << (*it).name;
1615 h <<
" static " << cfg.className <<
" *self();" << endl;
1618 h <<
" static void instance(const QString& cfgfilename);" << endl;
1623 h <<
" ~" << cfg.className <<
"();" << endl << endl;
1626 if (cfg.staticAccessors)
1631 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
1632 QString n = (*itEntry)->name();
1633 QString t = (*itEntry)->type();
1636 if (cfg.allMutators || cfg.mutators.contains(n))
1638 h <<
" /**" << endl;
1639 h <<
" Set " << (*itEntry)->label() << endl;
1641 if (cfg.staticAccessors)
1642 h <<
" static" << endl;
1644 if (!(*itEntry)->param().isEmpty())
1645 h <<
cppType((*itEntry)->paramType()) <<
" i, ";
1646 if (cfg.useEnumTypes && t ==
"Enum")
1647 h <<
enumType(*itEntry, cfg.globalEnums);
1653 if ( !cfg.dpointer )
1655 h << endl <<
" {" << endl;
1666 h <<
" /**" << endl;
1667 h <<
" Get " << (*itEntry)->label() << endl;
1669 if (cfg.staticAccessors)
1670 h <<
" static" << endl;
1672 if (cfg.useEnumTypes && t ==
"Enum")
1673 h <<
enumType(*itEntry, cfg.globalEnums);
1677 if (!(*itEntry)->param().isEmpty())
1678 h <<
" " <<
cppType((*itEntry)->paramType()) <<
" i ";
1682 if ( !cfg.dpointer )
1684 h << endl <<
" {" << endl;
1694 if ((cfg.allDefaultGetters || cfg.defaultGetters.contains(n)) && !(*itEntry)->defaultValue().isEmpty()) {
1696 h <<
" /**" << endl;
1697 h <<
" Get " << (*itEntry)->label() <<
" default value" << endl;
1699 if (cfg.staticAccessors)
1700 h <<
" static" << endl;
1702 if (cfg.useEnumTypes && t ==
"Enum")
1703 h <<
enumType(*itEntry, cfg.globalEnums);
1707 if ( !(*itEntry)->param().isEmpty() )
1708 h <<
" " <<
cppType( (*itEntry)->paramType() ) <<
" i ";
1709 h <<
")" << Const << endl;
1712 if (cfg.useEnumTypes && t ==
"Enum")
1713 h <<
"static_cast<" <<
enumType(*itEntry, cfg.globalEnums) <<
">(";
1715 if ( !(*itEntry)->param().isEmpty() )
1718 if (cfg.useEnumTypes && t ==
"Enum")
1725 if ( cfg.itemAccessors ) {
1727 h <<
" /**" << endl;
1728 h <<
" Get Item object corresponding to " << n <<
"()"
1731 h <<
" Item" <<
itemType( (*itEntry)->type() ) <<
" *"
1733 if (!(*itEntry)->param().isEmpty()) {
1734 h <<
" " <<
cppType((*itEntry)->paramType()) <<
" i ";
1737 if ( !cfg.dpointer )
1739 h << endl <<
" {" << endl;
1757 foreach(
const Signal &signal, signalList) {
1759 if ( !signal.label.isEmpty() ) {
1760 h <<
" /**" << endl;
1761 h <<
" " << signal.label << endl;
1764 h <<
" void " << signal.name <<
"(";
1765 QList<SignalArguments>::ConstIterator it, itEnd = signal.arguments.constEnd();
1766 for ( it = signal.arguments.constBegin(); it != itEnd; ) {
1767 SignalArguments argument = *it;
1769 if ( cfg.useEnumTypes && argument.type ==
"Enum" ) {
1770 for (
int i = 0, end = entries.count(); i < end; ++i ) {
1771 if ( entries[i]->name() == argument.variableName ) {
1772 type =
enumType(entries[i], cfg.globalEnums);
1777 h << type <<
" " << argument.variableName;
1778 if ( ++it != itEnd ) {
1787 h <<
" protected:" << endl;
1790 if ( cfg.singleton ) {
1791 h <<
" " << cfg.className <<
"(";
1792 if ( cfgFileNameArg )
1793 h <<
"const QString& arg";
1795 h <<
" friend class " << cfg.className <<
"Helper;" << endl << endl;
1799 h <<
" virtual void usrWriteConfig();" << endl;
1803 if ( !cfg.memberVariables.isEmpty() && cfg.memberVariables !=
"private" && cfg.memberVariables !=
"dpointer") {
1804 h <<
" " << cfg.memberVariables <<
":" << endl;
1808 for (QList<Param>::ConstIterator it = parameters.constBegin();
1809 it != parameters.constEnd(); ++it)
1811 h <<
" " <<
cppType((*it).type) <<
" mParam" << (*it).name <<
";" << endl;
1814 if ( cfg.memberVariables !=
"dpointer" )
1817 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
1818 if ( (*itEntry)->group() !=
group ) {
1819 group = (*itEntry)->group();
1821 h <<
" // " << group << endl;
1823 h <<
" " <<
cppType( (*itEntry)->type() ) <<
" " <<
varName( (*itEntry)->name(), cfg );
1824 if ( !(*itEntry)->param().isEmpty() )
1826 h <<
QString(
"[%1]").arg( (*itEntry)->paramMax()+1 );
1830 if ( cfg.allDefaultGetters || cfg.defaultGetters.contains((*itEntry)->name()) )
1833 if (cfg.staticAccessors)
1836 if ( !(*itEntry)->param().isEmpty() )
1837 h <<
" " <<
cppType( (*itEntry)->paramType() ) <<
" i ";
1838 h <<
")" << Const <<
";" << endl;
1842 h << endl <<
" private:" << endl;
1843 if ( cfg.itemAccessors ) {
1844 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
1845 h <<
" Item" <<
itemType( (*itEntry)->type() ) <<
" *" <<
itemVar( *itEntry, cfg );
1846 if ( !(*itEntry)->param().isEmpty() ) h <<
QString(
"[%1]").arg( (*itEntry)->paramMax()+1 );
1851 h <<
" uint " <<
varName(
"settingsChanged", cfg) <<
";" << endl;
1857 h <<
" private:" << endl;
1858 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
1859 if ( cfg.allDefaultGetters || cfg.defaultGetters.contains((*itEntry)->name()) ) {
1861 if (cfg.staticAccessors)
1864 if ( !(*itEntry)->param().isEmpty() )
1865 h <<
" " <<
cppType( (*itEntry)->paramType() ) <<
" i ";
1866 h <<
")" << Const <<
";" << endl;
1869 h <<
" " + cfg.className +
"Private *d;" << endl;
1872 if (cfg.customAddons)
1874 h <<
" // Include custom additions" << endl;
1875 h <<
" #include \"" <<
filenameOnly(baseName) <<
"_addons.h\"" <<endl;
1878 h <<
"};" << endl << endl;
1882 h <<
"#endif" << endl << endl;
1887 QFile implementation( baseDir + implementationFileName );
1888 if ( !implementation.open( QIODevice::WriteOnly ) ) {
1889 cerr <<
"Can not open '" << implementationFileName <<
"for writing."
1894 QTextStream cpp( &implementation );
1897 cpp <<
"// This file is generated by kconfig_compiler from " << QFileInfo(inputFilename).fileName() <<
"." << endl;
1898 cpp <<
"// All changes you do to this file will be lost." << endl << endl;
1900 cpp <<
"#include \"" << headerFileName <<
"\"" << endl << endl;
1902 for( it = cfg.sourceIncludes.constBegin(); it != cfg.sourceIncludes.constEnd(); ++it ) {
1903 if ( (*it).startsWith(
'"') )
1904 cpp <<
"#include " << *it << endl;
1906 cpp <<
"#include <" << *it <<
">" << endl;
1909 if ( cfg.sourceIncludes.count() > 0 ) cpp << endl;
1911 if ( cfg.setUserTexts ) cpp <<
"#include <klocale.h>" << endl << endl;
1914 if ( cfg.singleton )
1915 cpp <<
"#include <kglobal.h>" << endl <<
"#include <QtCore/QFile>" << endl << endl;
1916 if ( cfg.singleton && cfgFileNameArg )
1917 cpp <<
"#include <kdebug.h>" << endl << endl;
1919 if ( !cfg.nameSpace.isEmpty() )
1920 cpp <<
"using namespace " << cfg.nameSpace <<
";" << endl << endl;
1928 cpp <<
"class " << cfg.className <<
"Private" << endl;
1930 cpp <<
" public:" << endl;
1931 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
1932 if ( (*itEntry)->group() !=
group ) {
1933 group = (*itEntry)->group();
1935 cpp <<
" // " <<
group << endl;
1937 cpp <<
" " <<
cppType( (*itEntry)->type() ) <<
" " <<
varName( (*itEntry)->name(), cfg );
1938 if ( !(*itEntry)->param().isEmpty() )
1940 cpp <<
QString(
"[%1]").arg( (*itEntry)->paramMax()+1 );
1944 cpp << endl <<
" // items" << endl;
1945 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
1946 cpp <<
" "+cfg.inherits+
"::Item" <<
itemType( (*itEntry)->type() ) <<
" *" <<
itemVar( *itEntry, cfg );
1947 if ( !(*itEntry)->param().isEmpty() ) cpp <<
QString(
"[%1]").arg( (*itEntry)->paramMax()+1 );
1951 cpp <<
" uint " <<
varName(
"settingsChanged", cfg) <<
";" << endl;
1954 cpp <<
"};" << endl << endl;
1959 if ( cfg.singleton ) {
1961 cpp <<
"class " << cfg.className <<
"Helper" << endl;
1963 cpp <<
" public:" << endl;
1964 cpp <<
" " << cfg.className <<
"Helper() : q(0) {}" << endl;
1965 cpp <<
" ~" << cfg.className <<
"Helper() { delete q; }" << endl;
1966 cpp <<
" " << cfg.className <<
" *q;" << endl;
1967 cpp <<
"};" << endl;
1969 cpp <<
"K_GLOBAL_STATIC(" << cfg.className <<
"Helper, s_global" << cfg.className <<
")" << endl;
1971 cpp << cfg.className <<
" *" << cfg.className <<
"::self()" << endl;
1973 if ( cfgFileNameArg ) {
1974 cpp <<
" if (!s_global" << cfg.className <<
"->q)" << endl;
1975 cpp <<
" kFatal() << \"you need to call " << cfg.className <<
"::instance before using\";" << endl;
1977 cpp <<
" if (!s_global" << cfg.className <<
"->q) {" << endl;
1978 cpp <<
" new " << cfg.className <<
';' << endl;
1979 cpp <<
" s_global" << cfg.className <<
"->q->readConfig();" << endl;
1980 cpp <<
" }" << endl << endl;
1982 cpp <<
" return s_global" << cfg.className <<
"->q;" << endl;
1983 cpp <<
"}" << endl << endl;
1985 if ( cfgFileNameArg ) {
1986 cpp <<
"void " << cfg.className <<
"::instance(const QString& cfgfilename)" << endl;
1988 cpp <<
" if (s_global" << cfg.className <<
"->q) {" << endl;
1989 cpp <<
" kDebug() << \"" << cfg.className <<
"::instance called after the first use - ignoring\";" << endl;
1990 cpp <<
" return;" << endl;
1991 cpp <<
" }" << endl;
1992 cpp <<
" new " << cfg.className <<
"(cfgfilename);" << endl;
1993 cpp <<
" s_global" << cfg.className <<
"->q->readConfig();" << endl;
1994 cpp <<
"}" << endl << endl;
1998 if ( !cppPreamble.isEmpty() )
1999 cpp << cppPreamble << endl;
2002 cpp << cfg.className <<
"::" << cfg.className <<
"( ";
2003 if ( cfgFileNameArg ) {
2004 if ( !cfg.singleton && ! cfg.forceStringFilename)
2005 cpp <<
" KSharedConfig::Ptr config";
2007 cpp <<
" const QString& config";
2008 cpp << (parameters.isEmpty() ?
" " :
", ");
2011 for (QList<Param>::ConstIterator it = parameters.constBegin();
2012 it != parameters.constEnd(); ++it)
2014 if (it != parameters.constBegin())
2016 cpp <<
" " <<
param((*it).type) <<
" " << (*it).name;
2018 cpp <<
" )" << endl;
2020 cpp <<
" : " << cfg.inherits <<
"(";
2021 if ( !cfgFileName.isEmpty() ) cpp <<
" QLatin1String( \"" << cfgFileName <<
"\" ";
2022 if ( cfgFileNameArg ) cpp <<
" config ";
2023 if ( !cfgFileName.isEmpty() ) cpp <<
") ";
2027 for (QList<Param>::ConstIterator it = parameters.constBegin();
2028 it != parameters.constEnd(); ++it)
2030 cpp <<
" , mParam" << (*it).name <<
"(" << (*it).name <<
")" << endl;
2033 if ( hasSignals && !cfg.dpointer )
2034 cpp <<
" , " <<
varName(
"settingsChanged", cfg) <<
"(0)" << endl;
2040 cpp <<
" d = new " + cfg.className +
"Private;" << endl;
2042 cpp <<
" " <<
varPath(
"settingsChanged", cfg) <<
" = 0;" << endl;
2046 if (cfg.singleton) {
2047 cpp <<
" Q_ASSERT(!s_global" << cfg.className <<
"->q);" << endl;
2048 cpp <<
" s_global" << cfg.className <<
"->q = this;" << endl;
2053 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
2054 if ( (*itEntry)->group() !=
group ) {
2055 if ( !
group.isEmpty() ) cpp << endl;
2056 group = (*itEntry)->group();
2057 cpp <<
" setCurrentGroup( " <<
paramString(
group, parameters) <<
" );" << endl << endl;
2061 if ( !(*itEntry)->code().isEmpty() ) {
2062 cpp << (*itEntry)->code() << endl;
2064 if ( (*itEntry)->type() ==
"Enum" ) {
2065 cpp <<
" QList<"+cfg.inherits+
"::ItemEnum::Choice2> values"
2066 << (*itEntry)->name() <<
";" << endl;
2067 const QList<CfgEntry::Choice> choices = (*itEntry)->choices().choices;
2068 QList<CfgEntry::Choice>::ConstIterator it;
2069 for( it = choices.constBegin(); it != choices.constEnd(); ++it ) {
2070 cpp <<
" {" << endl;
2071 cpp <<
" "+cfg.inherits+
"::ItemEnum::Choice2 choice;" << endl;
2072 cpp <<
" choice.name = QLatin1String(\"" << (*it).name <<
"\");" << endl;
2073 if ( cfg.setUserTexts ) {
2074 if ( !(*it).label.isEmpty() ) {
2075 cpp <<
" choice.label = ";
2076 if ( !(*it).context.isEmpty() )
2077 cpp <<
"i18nc(" +
quoteString((*it).context) +
", ";
2082 if ( !(*it).toolTip.isEmpty() ) {
2083 cpp <<
" choice.toolTip = ";
2084 if ( !(*it).context.isEmpty() )
2085 cpp <<
"i18nc(" +
quoteString((*it).context) +
", ";
2088 cpp <<
quoteString((*it).toolTip) <<
");" << endl;
2090 if ( !(*it).whatsThis.isEmpty() ) {
2091 cpp <<
" choice.whatsThis = ";
2092 if ( !(*it).context.isEmpty() )
2093 cpp <<
"i18nc(" +
quoteString((*it).context) +
", ";
2096 cpp <<
quoteString((*it).whatsThis) <<
");" << endl;
2099 cpp <<
" values" << (*itEntry)->name() <<
".append( choice );" << endl;
2100 cpp <<
" }" << endl;
2107 if ( (*itEntry)->param().isEmpty() )
2110 cpp <<
" " <<
itemPath( *itEntry, cfg ) <<
" = "
2111 <<
newItem( (*itEntry)->type(), (*itEntry)->name(), key, (*itEntry)->defaultValue(), cfg ) << endl;
2113 if ( !(*itEntry)->minValue().isEmpty() )
2114 cpp <<
" " <<
itemPath( *itEntry, cfg ) <<
"->setMinValue(" << (*itEntry)->minValue() <<
");" << endl;
2115 if ( !(*itEntry)->maxValue().isEmpty() )
2116 cpp <<
" " <<
itemPath( *itEntry, cfg ) <<
"->setMaxValue(" << (*itEntry)->maxValue() <<
");" << endl;
2118 if ( cfg.setUserTexts )
2121 cpp <<
" addItem( " <<
itemPath( *itEntry, cfg );
2122 QString quotedName = (*itEntry)->name();
2124 if ( quotedName != key ) cpp <<
", QLatin1String( \"" << (*itEntry)->name() <<
"\" )";
2125 cpp <<
" );" << endl;
2130 for(
int i = 0; i <= (*itEntry)->paramMax(); i++)
2135 if ( !(*itEntry)->paramDefaultValue(i).isEmpty() )
2136 defaultStr = (*itEntry)->paramDefaultValue(i);
2137 else if ( !(*itEntry)->defaultValue().isEmpty() )
2138 defaultStr =
paramString( (*itEntry)->defaultValue(), (*itEntry), i );
2142 cpp <<
" " << itemVarStr <<
" = "
2143 <<
newItem( (*itEntry)->type(), (*itEntry)->name(),
paramString(key, *itEntry, i), defaultStr,cfg,
QString(
"[%1]").arg(i) )
2146 if ( cfg.setUserTexts )
2153 cpp <<
" addItem( " << itemVarStr <<
", QLatin1String( \"";
2154 if ( (*itEntry)->paramType()==
"Enum" )
2155 cpp << (*itEntry)->paramName().replace(
"$("+(*itEntry)->param()+
')',
"%1").arg((*itEntry)->paramValues()[i] );
2157 cpp << (*itEntry)->paramName().replace(
"$("+(*itEntry)->param()+
')',
"%1").arg(i);
2158 cpp <<
"\" ) );" << endl;
2163 cpp <<
"}" << endl << endl;
2168 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
2169 QString n = (*itEntry)->name();
2170 QString t = (*itEntry)->type();
2173 if (cfg.allMutators || cfg.mutators.contains(n))
2175 cpp <<
"void " <<
setFunction(n, cfg.className) <<
"( ";
2176 if ( !(*itEntry)->param().isEmpty() )
2177 cpp <<
cppType( (*itEntry)->paramType() ) <<
" i, ";
2178 if (cfg.useEnumTypes && t ==
"Enum")
2179 cpp <<
enumType(*itEntry, cfg.globalEnums);
2182 cpp <<
" v )" << endl;
2187 cpp <<
"}" << endl << endl;
2191 if (cfg.useEnumTypes && t ==
"Enum")
2192 cpp <<
enumType(*itEntry, cfg.globalEnums);
2195 cpp <<
" " <<
getFunction(n, cfg.className) <<
"(";
2196 if ( !(*itEntry)->param().isEmpty() )
2197 cpp <<
" " <<
cppType( (*itEntry)->paramType() ) <<
" i ";
2198 cpp <<
")" << Const << endl;
2203 cpp <<
"}" << endl << endl;
2208 if ( cfg.itemAccessors )
2211 cpp << cfg.inherits+
"::Item" <<
itemType( (*itEntry)->type() ) <<
" *"
2213 if ( !(*itEntry)->param().isEmpty() ) {
2214 cpp <<
" " <<
cppType( (*itEntry)->paramType() ) <<
" i ";
2227 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
2228 QString n = (*itEntry)->name();
2229 QString t = (*itEntry)->type();
2232 if (( cfg.allDefaultGetters || cfg.defaultGetters.contains(n) ) && !(*itEntry)->defaultValue().isEmpty() ) {
2234 if ( !(*itEntry)->param().isEmpty() )
2235 cpp <<
" " <<
cppType( (*itEntry)->paramType() ) <<
" i ";
2236 cpp <<
")" << Const << endl;
2239 cpp <<
"}" << endl << endl;
2244 cpp << cfg.className <<
"::~" << cfg.className <<
"()" << endl;
2246 if ( cfg.singleton ) {
2248 cpp <<
" delete d;" << endl;
2249 cpp <<
" if (!s_global" << cfg.className <<
".isDestroyed()) {" << endl;
2250 cpp <<
" s_global" << cfg.className <<
"->q = 0;" << endl;
2251 cpp <<
" }" << endl;
2253 cpp <<
"}" << endl << endl;
2256 cpp <<
"void " << cfg.className <<
"::" <<
"usrWriteConfig()" << endl;
2258 cpp <<
" " << cfg.inherits <<
"::usrWriteConfig();" << endl << endl;
2259 foreach(
const Signal &signal, signalList) {
2260 cpp <<
" if ( " <<
varPath(
"settingsChanged", cfg) <<
" & " <<
signalEnumName(signal.name) <<
" ) " << endl;
2261 cpp <<
" emit " << signal.name <<
"(";
2262 QList<SignalArguments>::ConstIterator it, itEnd = signal.arguments.constEnd();
2263 for ( it = signal.arguments.constBegin(); it != itEnd; ) {
2264 SignalArguments argument = *it;
2266 if ( cfg.useEnumTypes && argument.type ==
"Enum" ) {
2267 for (
int i = 0, end = entries.count(); i < end; ++i ) {
2268 if ( entries[i]->name() == argument.variableName ) {
2269 cpp <<
"static_cast<" <<
enumType(entries[i], cfg.globalEnums) <<
">(";
2275 cpp <<
varPath(argument.variableName, cfg);
2278 if ( ++it != itEnd )
2281 cpp <<
");" << endl << endl;
2283 cpp <<
" " <<
varPath(
"settingsChanged", cfg) <<
" = 0;" << endl;
2290 cpp <<
"#include \"" << mocFileName <<
"\"" << endl;
2295 qDeleteAll( entries );
2297 implementation.close();