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
202 :
prefix(p), choices(d), mName(n)
204 int i = n.indexOf(QLatin1String(
"::"));
206 mExternalQual = n.left(i + 2);
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 mLabelContext( labelContext ), mLabel( label ), mToolTipContext( toolTipContext ), mToolTip( toolTip ),
225 mWhatsThisContext( whatsThisContext ), mWhatsThis( whatsThis ),
226 mCode( code ), mDefaultValue( defaultValue ), mChoices( choices ),
227 mSignalList(signalList), mHidden( hidden )
234 void setType(
const QString &type ) { mType = type; }
235 QString type()
const {
return mType; }
237 void setKey(
const QString &key ) { mKey = key; }
238 QString key()
const {
return mKey; }
240 void setName(
const QString &name ) { mName = name; }
241 QString name()
const {
return mName; }
243 void setLabelContext(
const QString &labelContext ) { mLabelContext = labelContext; }
244 QString labelContext()
const {
return mLabelContext; }
246 void setLabel(
const QString &label ) { mLabel = label; }
247 QString label()
const {
return mLabel; }
249 void setToolTipContext(
const QString &toolTipContext ) { mToolTipContext = toolTipContext; }
250 QString toolTipContext()
const {
return mToolTipContext; }
252 void setToolTip(
const QString &toolTip ) { mToolTip = toolTip; }
253 QString toolTip()
const {
return mToolTip; }
255 void setWhatsThisContext(
const QString &whatsThisContext ) { mWhatsThisContext = whatsThisContext; }
256 QString whatsThisContext()
const {
return mWhatsThisContext; }
258 void setWhatsThis(
const QString &whatsThis ) { mWhatsThis = whatsThis; }
259 QString whatsThis()
const {
return mWhatsThis; }
261 void setDefaultValue(
const QString &d ) { mDefaultValue = d; }
264 void setCode(
const QString &d ) { mCode = d; }
265 QString code()
const {
return mCode; }
267 void setMinValue(
const QString &d ) { mMin = d; }
268 QString minValue()
const {
return mMin; }
270 void setMaxValue(
const QString &d ) { mMax = d; }
271 QString maxValue()
const {
return mMax; }
273 void setParam(
const QString &d ) { mParam = d; }
276 void setParamName(
const QString &d ) { mParamName = d; }
277 QString paramName()
const {
return mParamName; }
279 void setParamType(
const QString &d ) { mParamType = d; }
280 QString paramType()
const {
return mParamType; }
283 Choices choices()
const {
return mChoices; }
285 void setParamValues(
const QStringList &d ) { mParamValues = d; }
286 QStringList paramValues()
const {
return mParamValues; }
288 void setParamDefaultValues(
const QStringList &d ) { mParamDefaultValues = d; }
289 QString paramDefaultValue(
int i)
const {
return mParamDefaultValues[i]; }
291 void setParamMax(
int d ) { mParamMax = d; }
292 int paramMax()
const {
return mParamMax; }
294 void setSignalList(
const QList<Signal> &value ) { mSignalList = value; }
297 bool hidden()
const {
return mHidden; }
301 cerr <<
"<entry>" << endl;
302 cerr <<
" group: " << mGroup << endl;
303 cerr <<
" type: " << mType << endl;
304 cerr <<
" key: " << mKey << endl;
305 cerr <<
" name: " << mName << endl;
306 cerr <<
" label context: " << mLabelContext << endl;
307 cerr <<
" label: " << mLabel << endl;
309 cerr <<
" code: " << mCode << endl;
312 if (!
param().isEmpty())
314 cerr <<
" param name: "<< mParamName << endl;
315 cerr <<
" param type: "<< mParamType << endl;
316 cerr <<
" paramvalues: " << mParamValues.join(QChar::fromLatin1(
':')) << endl;
318 cerr <<
" default: " << mDefaultValue << endl;
319 cerr <<
" hidden: " << mHidden << endl;
320 cerr <<
" min: " << mMin << endl;
321 cerr <<
" max: " << mMax << endl;
322 cerr <<
"</entry>" << endl;
363 if ( !cfg.dpointer ) {
364 result = QChar::fromLatin1(
'm') + n;
365 result[1] = result[1].toUpper();
369 result[0] = result[0].toLower();
377 if ( cfg.dpointer ) {
378 result =
"d->"+
varName(n, cfg);
388 QString result = QString::fromLatin1(
"Enum") + n;
389 result[4] = result[4].toUpper();
396 if ( result.isEmpty() )
398 result = QString::fromLatin1(
"Enum") + n;
399 result[4] = result[4].toUpper();
406 QString result = e->choices().name();
407 if ( result.isEmpty() )
409 result = QString::fromLatin1(
"Enum") + e->name();
411 result += QString::fromLatin1(
"::type");
412 result[4] = result[4].toUpper();
420 if ( result.isEmpty() )
422 result = QString::fromLatin1(
"Enum") + n + QString::fromLatin1(
"::");
423 result[4] = result[4].toUpper();
425 else if ( c.external() )
426 result = c.externalQualifier();
434 QString result = QString::fromLatin1(
"set") + n;
435 result[3] = result[3].toUpper();
437 if ( !className.isEmpty() )
438 result = className + QString::fromLatin1(
"::") + result;
444 QString result = QString::fromLatin1(
"default") + n + QString::fromLatin1(
"Value");
445 result[7] = result[7].toUpper();
447 if ( !className.isEmpty() )
448 result = className + QString::fromLatin1(
"::") + result;
455 result[0] = result[0].toLower();
457 if ( !className.isEmpty() )
458 result = className + QString::fromLatin1(
"::") + result;
465 if ( !s.startsWith( QLatin1Char(
'"') ) )
466 s.prepend( QLatin1Char(
'"') );
467 if ( !s.endsWith( QLatin1Char(
'"') ) )
468 s.append( QLatin1Char(
'"') );
474 r.replace( QLatin1Char(
'\\'), QLatin1String(
"\\\\") );
475 r.replace( QLatin1Char(
'\"'), QLatin1String(
"\\\"") );
476 r.remove( QLatin1Char(
'\r') );
477 r.replace( QLatin1Char(
'\n'), QLatin1String(
"\\n\"\n\"") );
478 return QLatin1Char(
'\"') + r + QLatin1Char(
'\"');
484 for(
int i = s.length(); i--;)
485 if (s[i].unicode() > 127) isAscii =
false;
488 return QString::fromLatin1(
"QLatin1String( ") +
quoteString(s) + QString::fromLatin1(
" )");
490 return QString::fromLatin1(
"QString::fromUtf8( ") +
quoteString(s) + QString::fromLatin1(
" )");
496 QTextStream s(&msg, QIODevice::WriteOnly );
499 msg = msg.simplified();
500 if (msg.length() > 40)
501 return msg.left(37) + QString::fromLatin1(
"...");
507 int i = path.lastIndexOf(QRegExp(QLatin1String(
"[/\\]")));
509 return path.mid(i+1);
516 result = QString::fromLatin1(
"signal") + signalName;
517 result[6] = result[6].toUpper();
524 const CfgEntry::Choices &choices,
525 QString &code,
const CfgConfig &cfg )
527 if ( type == QLatin1String(
"String") && !defaultValue.isEmpty() ) {
530 }
else if ( type == QLatin1String(
"Path") && !defaultValue.isEmpty() ) {
532 }
else if ( type == QLatin1String(
"Url") && !defaultValue.isEmpty() ) {
533 defaultValue = QString::fromLatin1(
"KUrl( ") +
literalString(defaultValue) + QLatin1Char(
')');
534 }
else if ( ( type == QLatin1String(
"UrlList") || type == QLatin1String(
"StringList") || type == QLatin1String(
"PathList")) && !defaultValue.isEmpty() ) {
535 QTextStream cpp( &code, QIODevice::WriteOnly | QIODevice::Append );
539 if( type ==
"UrlList" ) {
540 cpp <<
" KUrl::List default" << name <<
";" << endl;
542 cpp <<
" QStringList default" << name <<
";" << endl;
544 const QStringList defaults = defaultValue.split(QLatin1Char(
','));
545 QStringList::ConstIterator it;
546 for( it = defaults.constBegin(); it != defaults.constEnd(); ++it ) {
547 cpp <<
" default" << name <<
".append( ";
548 if( type ==
"UrlList" ) {
551 cpp <<
"QString::fromUtf8( \"" << *it <<
"\" ) ";
552 if( type == QLatin1String(
"UrlList") ) {
557 defaultValue = QString::fromLatin1(
"default") + name;
559 }
else if ( type == QLatin1String(
"Color") && !defaultValue.isEmpty() ) {
560 QRegExp colorRe(QLatin1String(
"\\d+,\\s*\\d+,\\s*\\d+(,\\s*\\d+)?"));
561 if (colorRe.exactMatch(defaultValue))
563 defaultValue = QLatin1String(
"QColor( ") + defaultValue + QLatin1String(
" )");
567 defaultValue = QLatin1String(
"QColor( \"") + defaultValue + QLatin1String(
"\" )");
570 }
else if ( type == QLatin1String(
"Enum") ) {
572 for( it = choices.choices.constBegin(); it != choices.choices.constEnd(); ++it ) {
573 if ( (*it).name == defaultValue ) {
574 if ( cfg.globalEnums && choices.name().isEmpty() )
575 defaultValue.prepend( choices.prefix );
582 }
else if ( type == QLatin1String(
"IntList") ) {
583 QTextStream cpp( &code, QIODevice::WriteOnly | QIODevice::Append );
587 cpp <<
" QList<int> default" << name <<
";" << endl;
588 if (!defaultValue.isEmpty())
590 const QStringList defaults = defaultValue.split( QLatin1Char(
',') );
591 QStringList::ConstIterator it;
592 for( it = defaults.constBegin(); it != defaults.constEnd(); ++it ) {
593 cpp <<
" default" << name <<
".append( " << *it <<
" );"
597 defaultValue = QString::fromLatin1(
"default") + name;
604 bool defaultCode =
false;
605 QString type = element.attribute(
"type" );
606 QString name = element.attribute(
"name" );
607 QString key = element.attribute(
"key" );
608 QString hidden = element.attribute(
"hidden" );
620 CfgEntry::Choices choices;
628 for ( QDomElement e = element.firstChildElement(); !e.isNull(); e = e.nextSiblingElement() ) {
630 if ( tag ==
"label" ) {
632 labelContext = e.attribute(
"context" );
634 else if ( tag ==
"tooltip" ) {
636 toolTipContext = e.attribute(
"context" );
638 else if ( tag ==
"whatsthis" ) {
639 whatsThis = e.text();
640 whatsThisContext = e.attribute(
"context" );
642 else if ( tag ==
"min" ) minValue = e.text();
643 else if ( tag ==
"max" ) maxValue = e.text();
644 else if ( tag ==
"code" ) code = e.text();
645 else if ( tag ==
"parameter" )
647 param = e.attribute(
"name" );
648 paramType = e.attribute(
"type" );
649 if ( param.isEmpty() ) {
650 cerr <<
"Parameter must have a name: " <<
dumpNode(e) << endl;
653 if ( paramType.isEmpty() ) {
654 cerr <<
"Parameter must have a type: " <<
dumpNode(e) << endl;
657 if ((paramType ==
"Int") || (paramType ==
"UInt"))
660 paramMax = e.attribute(
"max").toInt(&ok);
663 cerr <<
"Integer parameter must have a maximum (e.g. max=\"0\"): "
668 else if (paramType ==
"Enum")
670 for ( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) {
671 if (e2.tagName() ==
"values")
673 for ( QDomElement e3 = e2.firstChildElement(); !e3.isNull(); e3 = e3.nextSiblingElement() ) {
674 if (e3.tagName() ==
"value")
676 paramValues.append( e3.text() );
682 if (paramValues.isEmpty())
684 cerr <<
"No values specified for parameter '" << param
688 paramMax = paramValues.count()-1;
692 cerr <<
"Parameter '" << param <<
"' has type " << paramType
693 <<
" but must be of type int, uint or Enum." << endl;
697 else if ( tag ==
"default" )
699 if (e.attribute(
"param").isEmpty())
701 defaultValue = e.text();
702 if (e.attribute(
"code" ) ==
"true")
706 else if ( tag ==
"choices" ) {
707 QString name = e.attribute(
"name" );
710 for( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) {
711 if ( e2.tagName() ==
"choice" ) {
712 CfgEntry::Choice choice;
713 choice.name = e2.attribute(
"name" );
714 if ( choice.name.isEmpty() ) {
715 cerr <<
"Tag <choice> requires attribute 'name'." << endl;
717 for( QDomElement e3 = e2.firstChildElement(); !e3.isNull(); e3 = e3.nextSiblingElement() ) {
718 if ( e3.tagName() ==
"label" ) {
719 choice.label = e3.text();
720 choice.context = e3.attribute(
"context" );
722 if ( e3.tagName() ==
"tooltip" ) {
723 choice.toolTip = e3.text();
724 choice.context = e3.attribute(
"context" );
726 if ( e3.tagName() ==
"whatsthis" ) {
727 choice.whatsThis = e3.text();
728 choice.context = e3.attribute(
"context" );
731 chlist.append( choice );
734 choices = CfgEntry::Choices( chlist, name, prefix );
736 else if ( tag ==
"emit" ) {
739 signal.name = e.attribute(
"signal" );
740 signalList.append( signal);
745 bool nameIsEmpty = name.isEmpty();
746 if ( nameIsEmpty && key.isEmpty() ) {
747 cerr <<
"Entry must have a name or a key: " <<
dumpNode(element) << endl;
751 if ( key.isEmpty() ) {
758 }
else if ( name.contains(
' ' ) ) {
759 cout<<
"Entry '"<<name<<
"' contains spaces! <name> elements can not contain spaces!"<<endl;
763 if (name.contains(
"$("))
767 cerr <<
"Name may not be parameterized: " << name << endl;
773 if (!param.isEmpty())
775 cerr <<
"Name must contain '$(" << param <<
")': " << name << endl;
780 if ( label.isEmpty() ) {
784 if ( type.isEmpty() ) type =
"String";
786 if (!param.isEmpty())
790 name.remove(
"$("+param+
')');
792 for(
int i = 0; i <= paramMax; i++)
794 paramDefaultValues.append(
QString());
797 for ( QDomElement e = element.firstChildElement(); !e.isNull(); e = e.nextSiblingElement() ) {
799 if ( tag ==
"default" )
801 QString index = e.attribute(
"param");
806 int i = index.toInt(&ok);
809 i = paramValues.indexOf(index);
812 cerr <<
"Index '" << index <<
"' for default value is unknown." << endl;
817 if ((i < 0) || (i > paramMax))
819 cerr <<
"Index '" << i <<
"' for default value is out of range [0, "<< paramMax<<
"]." << endl;
823 QString tmpDefaultValue = e.text();
825 if (e.attribute(
"code" ) !=
"true")
828 paramDefaultValues[i] = tmpDefaultValue;
836 cerr <<
"The key '" << key <<
"' can not be used as name for the entry because "
837 "it is not a valid name. You need to specify a valid name for this entry." << endl;
839 cerr <<
"The name '" << name <<
"' is not a valid name for an entry." << endl;
843 if (allNames.contains(name))
846 cerr <<
"The key '" << key <<
"' can not be used as name for the entry because "
847 "it does not result in a unique name. You need to specify a unique name for this entry." << endl;
849 cerr <<
"The name '" << name <<
"' is not unique." << endl;
852 allNames.append(name);
859 CfgEntry *result =
new CfgEntry( group, type, key, name, labelContext, label, toolTipContext, toolTip, whatsThisContext, whatsThis,
860 code, defaultValue, choices, signalList,
862 if (!param.isEmpty())
864 result->setParam(param);
865 result->setParamName(paramName);
866 result->setParamType(paramType);
867 result->setParamValues(paramValues);
868 result->setParamDefaultValues(paramDefaultValues);
869 result->setParamMax(paramMax);
871 result->setMinValue(minValue);
872 result->setMaxValue(maxValue);
879 if ( type ==
"UInt" )
return true;
880 if ( type ==
"ULongLong" )
return true;
889 const QString type = t.toLower();
890 if ( type ==
"string" )
return "const QString &";
891 else if ( type ==
"stringlist" )
return "const QStringList &";
892 else if ( type ==
"font" )
return "const QFont &";
893 else if ( type ==
"rect" )
return "const QRect &";
894 else if ( type ==
"size" )
return "const QSize &";
895 else if ( type ==
"color" )
return "const QColor &";
896 else if ( type ==
"point" )
return "const QPoint &";
897 else if ( type ==
"int" )
return "int";
898 else if ( type ==
"uint" )
return "uint";
899 else if ( type ==
"bool" )
return "bool";
900 else if ( type ==
"double" )
return "double";
901 else if ( type ==
"datetime" )
return "const QDateTime &";
902 else if ( type ==
"longlong" )
return "qint64";
903 else if ( type ==
"ulonglong" )
return "quint64";
904 else if ( type ==
"intlist" )
return "const QList<int> &";
905 else if ( type ==
"enum" )
return "int";
906 else if ( type ==
"path" )
return "const QString &";
907 else if ( type ==
"pathlist" )
return "const QStringList &";
908 else if ( type ==
"password" )
return "const QString &";
909 else if ( type ==
"url" )
return "const KUrl &";
910 else if ( type ==
"urllist" )
return "const KUrl::List &";
912 cerr <<
"kconfig_compiler does not support type \""<< type <<
"\""<<endl;
922 const QString type = t.toLower();
923 if ( type ==
"string" )
return "QString";
924 else if ( type ==
"stringlist" )
return "QStringList";
925 else if ( type ==
"font" )
return "QFont";
926 else if ( type ==
"rect" )
return "QRect";
927 else if ( type ==
"size" )
return "QSize";
928 else if ( type ==
"color" )
return "QColor";
929 else if ( type ==
"point" )
return "QPoint";
930 else if ( type ==
"int" )
return "int";
931 else if ( type ==
"uint" )
return "uint";
932 else if ( type ==
"bool" )
return "bool";
933 else if ( type ==
"double" )
return "double";
934 else if ( type ==
"datetime" )
return "QDateTime";
935 else if ( type ==
"longlong" )
return "qint64";
936 else if ( type ==
"ulonglong" )
return "quint64";
937 else if ( type ==
"intlist" )
return "QList<int>";
938 else if ( type ==
"enum" )
return "int";
939 else if ( type ==
"path" )
return "QString";
940 else if ( type ==
"pathlist" )
return "QStringList";
941 else if ( type ==
"password" )
return "QString";
942 else if ( type ==
"url" )
return "KUrl";
943 else if ( type ==
"urllist" )
return "KUrl::List";
945 cerr<<
"kconfig_compiler does not support type \""<< type <<
"\""<<endl;
952 const QString type = t.toLower();
953 if ( type ==
"string" )
return "\"\"";
954 else if ( type ==
"stringlist" )
return "QStringList()";
955 else if ( type ==
"font" )
return "QFont()";
956 else if ( type ==
"rect" )
return "QRect()";
957 else if ( type ==
"size" )
return "QSize()";
958 else if ( type ==
"color" )
return "QColor(128, 128, 128)";
959 else if ( type ==
"point" )
return "QPoint()";
960 else if ( type ==
"int" )
return "0";
961 else if ( type ==
"uint" )
return "0";
962 else if ( type ==
"bool" )
return "false";
963 else if ( type ==
"double" )
return "0.0";
964 else if ( type ==
"datetime" )
return "QDateTime()";
965 else if ( type ==
"longlong" )
return "0";
966 else if ( type ==
"ulonglong" )
return "0";
967 else if ( type ==
"intlist" )
return "QList<int>()";
968 else if ( type ==
"enum" )
return "0";
969 else if ( type ==
"path" )
return "\"\"";
970 else if ( type ==
"pathlist" )
return "QStringList()";
971 else if ( type ==
"password" )
return "\"\"";
972 else if ( type ==
"url" )
return "KUrl()";
973 else if ( type ==
"urllist" )
return "KUrl::List()";
975 cerr<<
"Error, kconfig_compiler does not support the \""<< type <<
"\" type!"<<endl;
985 t.replace( 0, 1, t.left( 1 ).toUpper() );
992 if (cfg.itemAccessors)
996 fCap[0] = fCap[0].toUpper();
997 return " "+cfg.inherits+
"::Item"+
itemType( e->type() ) +
999 ( (!e->param().isEmpty())?(
QString(
"[%1]").arg(e->paramMax()+1)) :
QString()) +
1009 if (cfg.itemAccessors)
1011 if ( !cfg.dpointer )
1013 result =
'm' + e->name() +
"Item";
1014 result[1] = result[1].toUpper();
1018 result = e->name() +
"Item";
1019 result[0] = result[0].toLower();
1024 result =
"item" + e->name();
1025 result[4] = result[4].toUpper();
1033 if ( cfg.dpointer ) {
1034 result =
"d->"+
itemVar(e, cfg);
1046 "( currentGroup(), " + key +
", " +
varPath( name, cfg ) +
param;
1047 if ( type ==
"Enum" ) t +=
", values" + name;
1048 if ( !defaultValue.isEmpty() ) {
1061 QString needle =
"$("+e->param()+
')';
1062 if (result.contains(needle))
1065 if (e->paramType() ==
"Enum")
1067 tmp = e->paramValues()[i];
1071 tmp = QString::number(i);
1074 result.replace(needle, tmp);
1085 it != parameters.constEnd(); ++it)
1087 if (paramString.contains(
"$("+(*it).name+
')'))
1090 tmp.sprintf(
"%%%d", i++);
1091 paramString.replace(
"$("+(*it).name+
')', tmp);
1092 arguments +=
".arg( mParam"+(*it).name+
" )";
1095 if (arguments.isEmpty())
1096 return "QLatin1String( \""+group+
"\" )";
1098 return "QString( QLatin1String( \""+paramString+
"\" ) )"+arguments;
1105 if (itemVarStr.isNull()) itemVarStr=
itemPath(e, cfg);
1106 if ( !e->label().isEmpty() ) {
1107 txt +=
" " + itemVarStr +
"->setLabel( ";
1108 if ( !e->labelContext().isEmpty() )
1109 txt +=
"i18nc(" +
quoteString(e->labelContext()) +
", ";
1112 if ( !e->param().isEmpty() )
1113 txt +=
quoteString(e->label().replace(
"$("+e->param()+
')', i));
1118 if ( !e->toolTip().isEmpty() ) {
1119 txt +=
" " + itemVarStr +
"->setToolTip( ";
1120 if ( !e->toolTipContext().isEmpty() )
1121 txt +=
"i18nc(" +
quoteString(e->toolTipContext()) +
", ";
1124 if ( !e->param().isEmpty() )
1125 txt +=
quoteString(e->toolTip().replace(
"$("+e->param()+
')', i));
1130 if ( !e->whatsThis().isEmpty() ) {
1131 txt +=
" " + itemVarStr +
"->setWhatsThis( ";
1132 if ( !e->whatsThisContext().isEmpty() )
1133 txt +=
"i18nc(" +
quoteString(e->whatsThisContext()) +
", ";
1136 if ( !e->param().isEmpty() )
1137 txt +=
quoteString(e->whatsThis().replace(
"$("+e->param()+
')', i));
1151 QTextStream out(&result, QIODevice::WriteOnly);
1154 bool useEnumType = cfg.useEnumTypes && t ==
"Enum";
1158 out <<
"static_cast<" <<
enumType(e, globalEnums) <<
">(";
1159 out << This <<
varPath(n, cfg);
1160 if (!e->param().isEmpty())
1175 QTextStream out(&result, QIODevice::WriteOnly);
1179 if (!e->minValue().isEmpty())
1181 if (e->minValue() !=
"0" || !
isUnsigned(t)) {
1182 out <<
"if (v < " << e->minValue() <<
")" << endl;
1185 out <<
": value \" << v << \" is less than the minimum value of ";
1186 out << e->minValue()<<
"\";" << endl;
1187 out <<
" v = " << e->minValue() <<
";" << endl;
1192 if (!e->maxValue().isEmpty())
1194 out << endl <<
"if (v > " << e->maxValue() <<
")" << endl;
1197 out <<
": value \" << v << \" is greater than the maximum value of ";
1198 out << e->maxValue()<<
"\";" << endl;
1199 out <<
" v = " << e->maxValue() <<
";" << endl;
1200 out <<
"}" << endl << endl;
1203 out <<
"if (!" << This <<
"isImmutable( QString::fromLatin1( \"";
1204 if (!e->param().isEmpty())
1206 out << e->paramName().replace(
"$("+e->param()+
")",
"%1") <<
"\" ).arg( ";
1207 if ( e->paramType() ==
"Enum" ) {
1208 out <<
"QLatin1String( ";
1210 if (cfg.globalEnums)
1211 out <<
enumName(e->param()) <<
"ToString[i]";
1213 out <<
enumName(e->param()) <<
"::enumToString[i]";
1227 out <<
" ))" << (!e->signalList().empty() ?
" {" :
"") << endl;
1228 out <<
" " << This <<
varPath(n, cfg);
1229 if (!e->param().isEmpty())
1231 out <<
" = v;" << endl;
1233 if ( !e->signalList().empty() ) {
1234 foreach(
const Signal &signal, e->signalList()) {
1235 out <<
" " << This <<
varPath(
"settingsChanged", cfg) <<
" |= " <<
signalEnumName(signal.name) <<
";" << endl;
1249 QTextStream out(&result, QIODevice::WriteOnly);
1252 if (!e->param().isEmpty()) {
1253 out <<
" switch (i) {" << endl;
1254 for (
int i = 0; i <= e->paramMax(); ++i) {
1255 if (!e->paramDefaultValue(i).isEmpty()) {
1256 out <<
" case " << i <<
": return " << e->paramDefaultValue(i) <<
';' << endl;
1259 out <<
" default:" << endl;
1260 out <<
" return " << e->defaultValue().replace(
"$("+e->param()+
')',
"i") <<
';' << endl;
1261 out <<
" }" << endl;
1263 out <<
" return " << e->defaultValue() <<
';';
1275 QTextStream out(&result, QIODevice::WriteOnly);
1277 out <<
"return " <<
itemPath(e, cfg);
1278 if (!e->param().isEmpty()) out <<
"[i]";
1288 QTextStream out(&result, QIODevice::WriteOnly);
1289 QTextStream in(&text, QIODevice::ReadOnly);
1291 while ( !in.atEnd() )
1293 currLine = in.readLine();
1294 if (!currLine.isEmpty())
1295 for (
int i=0; i < spaces; i++)
1297 out << currLine << endl;
1306 if ( !p_ns.isEmpty() ) {
1307 const QStringList nameSpaces = p_ns.split(
"::" );
1308 foreach (
const QString &ns, nameSpaces )
1309 p_out <<
"namespace " << ns <<
" {" << endl;
1318 if ( !p_ns.isEmpty() ) {
1319 const int namespaceCount = p_ns.count(
"::" ) + 1;
1320 for (
int i = 0; i < namespaceCount; ++i )
1321 p_out <<
"}" << endl;
1329 QCoreApplication app(argc, argv);
1333 QString directoryName, inputFilename, codegenFilename;
1334 parseArgs(app.arguments(), directoryName, inputFilename, codegenFilename);
1336 QString baseDir = directoryName;
1338 if (!baseDir.endsWith(
'/') && !baseDir.endsWith(
'\\'))
1340 if (!baseDir.endsWith(
'/'))
1342 baseDir.append(
"/");
1344 if (!codegenFilename.endsWith(QLatin1String(
".kcfgc")))
1346 cerr <<
"Codegen options file must have extension .kcfgc" << endl;
1349 QString baseName = QFileInfo(codegenFilename).fileName();
1350 baseName = baseName.left(baseName.length() - 6);
1352 CfgConfig cfg = CfgConfig( codegenFilename );
1354 QFile input( inputFilename );
1360 if ( !doc.setContent( &input, &errorMsg, &errorRow, &errorCol ) ) {
1361 cerr <<
"Unable to load document." << endl;
1362 cerr <<
"Parse error in " << inputFilename <<
", line " << errorRow <<
", col " << errorCol <<
": " << errorMsg << endl;
1366 QDomElement cfgElement = doc.documentElement();
1368 if ( cfgElement.isNull() ) {
1369 cerr <<
"No document in kcfg file" << endl;
1374 bool cfgFileNameArg =
false;
1378 bool hasSignals =
false;
1382 for ( QDomElement e = cfgElement.firstChildElement(); !e.isNull(); e = e.nextSiblingElement() ) {
1385 if ( tag ==
"include" ) {
1386 QString includeFile = e.text();
1387 if (!includeFile.isEmpty())
1388 includes.append(includeFile);
1390 }
else if ( tag ==
"kcfgfile" ) {
1391 cfgFileName = e.attribute(
"name" );
1392 cfgFileNameArg = e.attribute(
"arg" ).toLower() ==
"true";
1393 for( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) {
1394 if ( e2.tagName() ==
"parameter" ) {
1396 p.name = e2.attribute(
"name" );
1397 p.type = e2.attribute(
"type" );
1398 if (p.type.isEmpty())
1400 parameters.append( p );
1404 }
else if ( tag ==
"group" ) {
1406 if ( group.isEmpty() ) {
1407 cerr <<
"Group without name" << endl;
1410 for( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) {
1411 if ( e2.tagName() !=
"entry" )
continue;
1412 CfgEntry *entry =
parseEntry( group, e2, cfg );
1413 if ( entry ) entries.append( entry );
1415 cerr <<
"Can not parse entry." << endl;
1420 else if ( tag ==
"signal" ) {
1421 QString signalName = e.attribute(
"name" );
1422 if ( signalName.isEmpty() ) {
1423 cerr <<
"Signal without name." << endl;
1427 theSignal.name = signalName;
1429 for( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) {
1430 if ( e2.tagName() ==
"argument") {
1431 SignalArguments argument;
1432 argument.type = e2.attribute(
"type");
1433 if ( argument.type.isEmpty() ) {
1434 cerr <<
"Signal argument without type." << endl;
1437 argument.variableName = e2.text();
1438 theSignal.arguments.append(argument);
1440 else if( e2.tagName() ==
"label") {
1441 theSignal.label = e2.text();
1444 signalList.append(theSignal);
1448 if ( cfg.className.isEmpty() ) {
1449 cerr <<
"Class name missing" << endl;
1453 if ( cfg.singleton && !parameters.isEmpty() ) {
1454 cerr <<
"Singleton class can not have parameters" << endl;
1458 if ( !cfgFileName.isEmpty() && cfgFileNameArg)
1460 cerr <<
"Having both a fixed filename and a filename as argument is not possible." << endl;
1464 if ( entries.isEmpty() ) {
1465 cerr <<
"No entries." << endl;
1470 for( cfg = entries.first(); cfg; cfg = entries.next() ) {
1475 hasSignals = !signalList.empty();
1476 QString headerFileName = baseName +
".h";
1477 QString implementationFileName = baseName +
".cpp";
1478 QString mocFileName = baseName +
".moc";
1481 QFile
header( baseDir + headerFileName );
1482 if ( !header.open( QIODevice::WriteOnly ) ) {
1483 cerr <<
"Can not open '" << baseDir << headerFileName <<
"for writing." << endl;
1487 QTextStream h( &header );
1489 h <<
"// This file is generated by kconfig_compiler from " << QFileInfo(inputFilename).fileName() <<
"." << endl;
1490 h <<
"// All changes you do to this file will be lost." << endl;
1492 h <<
"#ifndef " << ( !cfg.nameSpace.isEmpty() ?
QString (
QString(cfg.nameSpace).replace(
"::",
"_" ).toUpper() +
'_') :
"" )
1493 << cfg.className.toUpper() <<
"_H" << endl;
1494 h <<
"#define " << ( !cfg.nameSpace.isEmpty() ?
QString (
QString(cfg.nameSpace).replace(
"::",
"_" ).toUpper() +
'_') :
"" )
1495 << cfg.className.toUpper() <<
"_H" << endl << endl;
1498 QStringList::ConstIterator it;
1499 for( it = cfg.headerIncludes.constBegin(); it != cfg.headerIncludes.constEnd(); ++it ) {
1500 if ( (*it).startsWith(
'"') )
1501 h <<
"#include " << *it << endl;
1503 h <<
"#include <" << *it <<
">" << endl;
1506 if ( cfg.headerIncludes.count() > 0 ) h << endl;
1508 if ( !cfg.singleton && parameters.isEmpty() )
1509 h <<
"#include <kglobal.h>" << endl;
1511 if ( cfg.inherits==
"KCoreConfigSkeleton" ) {
1512 h <<
"#include <kcoreconfigskeleton.h>" << endl;
1514 h <<
"#include <kconfigskeleton.h>" << endl;
1517 h <<
"#include <kdebug.h>" << endl << endl;
1520 for( it = includes.constBegin(); it != includes.constEnd(); ++it ) {
1521 if ( (*it).startsWith(
'"') )
1522 h <<
"#include " << *it << endl;
1524 h <<
"#include <" << *it <<
">" << endl;
1531 h <<
"class " << cfg.className <<
"Private;" << endl << endl;
1534 h <<
"class " << cfg.visibility << cfg.className <<
" : public " << cfg.inherits << endl;
1539 h <<
" Q_OBJECT" << endl;
1540 h <<
" public:" << endl;
1544 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
1545 const CfgEntry::Choices &choices = (*itEntry)->choices();
1547 if ( !chlist.isEmpty() ) {
1550 for( itChoice = chlist.constBegin(); itChoice != chlist.constEnd(); ++itChoice ) {
1551 values.append( choices.prefix + (*itChoice).name );
1553 if ( choices.name().isEmpty() ) {
1554 if ( cfg.globalEnums ) {
1555 h <<
" enum " <<
enumName( (*itEntry)->name(), (*itEntry)->choices() ) <<
" { " << values.join(
", " ) <<
" };" << endl;
1558 h <<
" class " <<
enumName( (*itEntry)->name(), (*itEntry)->choices() ) << endl;
1560 h <<
" public:" << endl;
1561 h <<
" enum type { " << values.join(
", " ) <<
", COUNT };" << endl;
1564 }
else if ( !choices.external() ) {
1566 h <<
" enum " <<
enumName( (*itEntry)->name(), (*itEntry)->choices() ) <<
" { " << values.join(
", " ) <<
" };" << endl;
1569 const QStringList values = (*itEntry)->paramValues();
1570 if ( !values.isEmpty() ) {
1571 if ( cfg.globalEnums ) {
1575 h <<
" enum " <<
enumName( (*itEntry)->param() ) <<
" { " << values.join(
", " ) <<
" };" << endl;
1576 h <<
" static const char* const " <<
enumName( (*itEntry)->param() ) <<
"ToString[];" << endl;
1577 cppPreamble +=
"const char* const " + cfg.className +
"::" +
enumName( (*itEntry)->param() ) +
1578 "ToString[] = { \"" + values.join(
"\", \"" ) +
"\" };\n";
1580 h <<
" class " <<
enumName( (*itEntry)->param() ) << endl;
1582 h <<
" public:" << endl;
1583 h <<
" enum type { " << values.join(
", " ) <<
", COUNT };" << endl;
1584 h <<
" static const char* const enumToString[];" << endl;
1586 cppPreamble +=
"const char* const " + cfg.className +
"::" +
enumName( (*itEntry)->param() ) +
1587 "::enumToString[] = { \"" + values.join(
"\", \"" ) +
"\" };\n";
1592 h <<
"\n enum {" << endl;
1595 for ( it = signalList.constBegin(); it != itEnd; val <<= 1) {
1597 cerr <<
"Too many signals to create unique bit masks" << endl;
1600 Signal signal = *it;
1601 h <<
" " <<
signalEnumName(signal.name) <<
" = 0x" << hex << val;
1602 if ( ++it != itEnd )
1606 h <<
" };" << dec << endl;
1610 if ( !cfg.singleton ) {
1611 h <<
" " << cfg.className <<
"(";
1614 if(cfg.forceStringFilename)
1615 h <<
" const QString &cfgfilename"
1616 << (parameters.isEmpty() ?
" = QString()" :
", ");
1618 h <<
" KSharedConfig::Ptr config"
1619 << (parameters.isEmpty() ?
" = KGlobal::config()" :
", ");
1622 it != parameters.constEnd(); ++it)
1624 if (it != parameters.constBegin())
1626 h <<
" " <<
param((*it).type) <<
" " << (*it).name;
1630 h <<
" static " << cfg.className <<
" *self();" << endl;
1633 h <<
" static void instance(const QString& cfgfilename);" << endl;
1638 h <<
" ~" << cfg.className <<
"();" << endl << endl;
1641 if (cfg.staticAccessors)
1646 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
1647 QString n = (*itEntry)->name();
1648 QString t = (*itEntry)->type();
1651 if (cfg.allMutators || cfg.mutators.contains(n))
1653 h <<
" /**" << endl;
1654 h <<
" Set " << (*itEntry)->label() << endl;
1656 if (cfg.staticAccessors)
1657 h <<
" static" << endl;
1659 if (!(*itEntry)->param().isEmpty())
1660 h <<
cppType((*itEntry)->paramType()) <<
" i, ";
1661 if (cfg.useEnumTypes && t ==
"Enum")
1662 h <<
enumType(*itEntry, cfg.globalEnums);
1668 if ( !cfg.dpointer )
1670 h << endl <<
" {" << endl;
1681 h <<
" /**" << endl;
1682 h <<
" Get " << (*itEntry)->label() << endl;
1684 if (cfg.staticAccessors)
1685 h <<
" static" << endl;
1687 if (cfg.useEnumTypes && t ==
"Enum")
1688 h <<
enumType(*itEntry, cfg.globalEnums);
1692 if (!(*itEntry)->param().isEmpty())
1693 h <<
" " <<
cppType((*itEntry)->paramType()) <<
" i ";
1697 if ( !cfg.dpointer )
1699 h << endl <<
" {" << endl;
1709 if ((cfg.allDefaultGetters || cfg.defaultGetters.contains(n)) && !(*itEntry)->defaultValue().isEmpty()) {
1711 h <<
" /**" << endl;
1712 h <<
" Get " << (*itEntry)->label() <<
" default value" << endl;
1714 if (cfg.staticAccessors)
1715 h <<
" static" << endl;
1717 if (cfg.useEnumTypes && t ==
"Enum")
1718 h <<
enumType(*itEntry, cfg.globalEnums);
1722 if ( !(*itEntry)->param().isEmpty() )
1723 h <<
" " <<
cppType( (*itEntry)->paramType() ) <<
" i ";
1724 h <<
")" << Const << endl;
1727 if (cfg.useEnumTypes && t ==
"Enum")
1728 h <<
"static_cast<" <<
enumType(*itEntry, cfg.globalEnums) <<
">(";
1730 if ( !(*itEntry)->param().isEmpty() )
1733 if (cfg.useEnumTypes && t ==
"Enum")
1740 if ( cfg.itemAccessors ) {
1742 h <<
" /**" << endl;
1743 h <<
" Get Item object corresponding to " << n <<
"()"
1746 h <<
" Item" <<
itemType( (*itEntry)->type() ) <<
" *"
1748 if (!(*itEntry)->param().isEmpty()) {
1749 h <<
" " <<
cppType((*itEntry)->paramType()) <<
" i ";
1752 if ( !cfg.dpointer )
1754 h << endl <<
" {" << endl;
1772 foreach(
const Signal &signal, signalList) {
1774 if ( !signal.label.isEmpty() ) {
1775 h <<
" /**" << endl;
1776 h <<
" " << signal.label << endl;
1779 h <<
" void " << signal.name <<
"(";
1781 for ( it = signal.arguments.constBegin(); it != itEnd; ) {
1782 SignalArguments argument = *it;
1784 if ( cfg.useEnumTypes && argument.type ==
"Enum" ) {
1785 for (
int i = 0, end = entries.count(); i < end; ++i ) {
1786 if ( entries[i]->name() == argument.variableName ) {
1787 type =
enumType(entries[i], cfg.globalEnums);
1792 h << type <<
" " << argument.variableName;
1793 if ( ++it != itEnd ) {
1802 h <<
" protected:" << endl;
1805 if ( cfg.singleton ) {
1806 h <<
" " << cfg.className <<
"(";
1807 if ( cfgFileNameArg )
1808 h <<
"const QString& arg";
1810 h <<
" friend class " << cfg.className <<
"Helper;" << endl << endl;
1814 h <<
" virtual void usrWriteConfig();" << endl;
1818 if ( !cfg.memberVariables.isEmpty() && cfg.memberVariables !=
"private" && cfg.memberVariables !=
"dpointer") {
1819 h <<
" " << cfg.memberVariables <<
":" << endl;
1824 it != parameters.constEnd(); ++it)
1826 h <<
" " <<
cppType((*it).type) <<
" mParam" << (*it).name <<
";" << endl;
1829 if ( cfg.memberVariables !=
"dpointer" )
1832 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
1833 if ( (*itEntry)->group() !=
group ) {
1834 group = (*itEntry)->group();
1836 h <<
" // " << group << endl;
1838 h <<
" " <<
cppType( (*itEntry)->type() ) <<
" " <<
varName( (*itEntry)->name(), cfg );
1839 if ( !(*itEntry)->param().isEmpty() )
1841 h <<
QString(
"[%1]").arg( (*itEntry)->paramMax()+1 );
1845 if ( cfg.allDefaultGetters || cfg.defaultGetters.contains((*itEntry)->name()) )
1848 if (cfg.staticAccessors)
1851 if ( !(*itEntry)->param().isEmpty() )
1852 h <<
" " <<
cppType( (*itEntry)->paramType() ) <<
" i ";
1853 h <<
")" << Const <<
";" << endl;
1857 h << endl <<
" private:" << endl;
1858 if ( cfg.itemAccessors ) {
1859 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
1860 h <<
" Item" <<
itemType( (*itEntry)->type() ) <<
" *" <<
itemVar( *itEntry, cfg );
1861 if ( !(*itEntry)->param().isEmpty() ) h <<
QString(
"[%1]").arg( (*itEntry)->paramMax()+1 );
1866 h <<
" uint " <<
varName(
"settingsChanged", cfg) <<
";" << endl;
1872 h <<
" private:" << endl;
1873 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
1874 if ( cfg.allDefaultGetters || cfg.defaultGetters.contains((*itEntry)->name()) ) {
1876 if (cfg.staticAccessors)
1879 if ( !(*itEntry)->param().isEmpty() )
1880 h <<
" " <<
cppType( (*itEntry)->paramType() ) <<
" i ";
1881 h <<
")" << Const <<
";" << endl;
1884 h <<
" " + cfg.className +
"Private *d;" << endl;
1887 if (cfg.customAddons)
1889 h <<
" // Include custom additions" << endl;
1890 h <<
" #include \"" <<
filenameOnly(baseName) <<
"_addons.h\"" <<endl;
1893 h <<
"};" << endl << endl;
1897 h <<
"#endif" << endl << endl;
1902 QFile implementation( baseDir + implementationFileName );
1903 if ( !implementation.open( QIODevice::WriteOnly ) ) {
1904 cerr <<
"Can not open '" << implementationFileName <<
"for writing."
1909 QTextStream cpp( &implementation );
1912 cpp <<
"// This file is generated by kconfig_compiler from " << QFileInfo(inputFilename).fileName() <<
"." << endl;
1913 cpp <<
"// All changes you do to this file will be lost." << endl << endl;
1915 cpp <<
"#include \"" << headerFileName <<
"\"" << endl << endl;
1917 for( it = cfg.sourceIncludes.constBegin(); it != cfg.sourceIncludes.constEnd(); ++it ) {
1918 if ( (*it).startsWith(
'"') )
1919 cpp <<
"#include " << *it << endl;
1921 cpp <<
"#include <" << *it <<
">" << endl;
1924 if ( cfg.sourceIncludes.count() > 0 ) cpp << endl;
1926 if ( cfg.setUserTexts ) cpp <<
"#include <klocale.h>" << endl << endl;
1929 if ( cfg.singleton )
1930 cpp <<
"#include <kglobal.h>" << endl <<
"#include <QtCore/QFile>" << endl << endl;
1931 if ( cfg.singleton && cfgFileNameArg )
1932 cpp <<
"#include <kdebug.h>" << endl << endl;
1934 if ( !cfg.nameSpace.isEmpty() )
1935 cpp <<
"using namespace " << cfg.nameSpace <<
";" << endl << endl;
1943 cpp <<
"class " << cfg.className <<
"Private" << endl;
1945 cpp <<
" public:" << endl;
1946 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
1947 if ( (*itEntry)->group() !=
group ) {
1948 group = (*itEntry)->group();
1950 cpp <<
" // " <<
group << endl;
1952 cpp <<
" " <<
cppType( (*itEntry)->type() ) <<
" " <<
varName( (*itEntry)->name(), cfg );
1953 if ( !(*itEntry)->param().isEmpty() )
1955 cpp <<
QString(
"[%1]").arg( (*itEntry)->paramMax()+1 );
1959 cpp << endl <<
" // items" << endl;
1960 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
1961 cpp <<
" "+cfg.inherits+
"::Item" <<
itemType( (*itEntry)->type() ) <<
" *" <<
itemVar( *itEntry, cfg );
1962 if ( !(*itEntry)->param().isEmpty() ) cpp <<
QString(
"[%1]").arg( (*itEntry)->paramMax()+1 );
1966 cpp <<
" uint " <<
varName(
"settingsChanged", cfg) <<
";" << endl;
1969 cpp <<
"};" << endl << endl;
1974 if ( cfg.singleton ) {
1976 cpp <<
"class " << cfg.className <<
"Helper" << endl;
1978 cpp <<
" public:" << endl;
1979 cpp <<
" " << cfg.className <<
"Helper() : q(0) {}" << endl;
1980 cpp <<
" ~" << cfg.className <<
"Helper() { delete q; }" << endl;
1981 cpp <<
" " << cfg.className <<
" *q;" << endl;
1982 cpp <<
"};" << endl;
1984 cpp <<
"K_GLOBAL_STATIC(" << cfg.className <<
"Helper, s_global" << cfg.className <<
")" << endl;
1986 cpp << cfg.className <<
" *" << cfg.className <<
"::self()" << endl;
1988 if ( cfgFileNameArg ) {
1989 cpp <<
" if (!s_global" << cfg.className <<
"->q)" << endl;
1990 cpp <<
" kFatal() << \"you need to call " << cfg.className <<
"::instance before using\";" << endl;
1992 cpp <<
" if (!s_global" << cfg.className <<
"->q) {" << endl;
1993 cpp <<
" new " << cfg.className <<
';' << endl;
1994 cpp <<
" s_global" << cfg.className <<
"->q->readConfig();" << endl;
1995 cpp <<
" }" << endl << endl;
1997 cpp <<
" return s_global" << cfg.className <<
"->q;" << endl;
1998 cpp <<
"}" << endl << endl;
2000 if ( cfgFileNameArg ) {
2001 cpp <<
"void " << cfg.className <<
"::instance(const QString& cfgfilename)" << endl;
2003 cpp <<
" if (s_global" << cfg.className <<
"->q) {" << endl;
2004 cpp <<
" kDebug() << \"" << cfg.className <<
"::instance called after the first use - ignoring\";" << endl;
2005 cpp <<
" return;" << endl;
2006 cpp <<
" }" << endl;
2007 cpp <<
" new " << cfg.className <<
"(cfgfilename);" << endl;
2008 cpp <<
" s_global" << cfg.className <<
"->q->readConfig();" << endl;
2009 cpp <<
"}" << endl << endl;
2013 if ( !cppPreamble.isEmpty() )
2014 cpp << cppPreamble << endl;
2017 cpp << cfg.className <<
"::" << cfg.className <<
"( ";
2018 if ( cfgFileNameArg ) {
2019 if ( !cfg.singleton && ! cfg.forceStringFilename)
2020 cpp <<
" KSharedConfig::Ptr config";
2022 cpp <<
" const QString& config";
2023 cpp << (parameters.isEmpty() ?
" " :
", ");
2027 it != parameters.constEnd(); ++it)
2029 if (it != parameters.constBegin())
2031 cpp <<
" " <<
param((*it).type) <<
" " << (*it).name;
2033 cpp <<
" )" << endl;
2035 cpp <<
" : " << cfg.inherits <<
"(";
2036 if ( !cfgFileName.isEmpty() ) cpp <<
" QLatin1String( \"" << cfgFileName <<
"\" ";
2037 if ( cfgFileNameArg ) cpp <<
" config ";
2038 if ( !cfgFileName.isEmpty() ) cpp <<
") ";
2043 it != parameters.constEnd(); ++it)
2045 cpp <<
" , mParam" << (*it).name <<
"(" << (*it).name <<
")" << endl;
2048 if ( hasSignals && !cfg.dpointer )
2049 cpp <<
" , " <<
varName(
"settingsChanged", cfg) <<
"(0)" << endl;
2055 cpp <<
" d = new " + cfg.className +
"Private;" << endl;
2057 cpp <<
" " <<
varPath(
"settingsChanged", cfg) <<
" = 0;" << endl;
2061 if (cfg.singleton) {
2062 cpp <<
" Q_ASSERT(!s_global" << cfg.className <<
"->q);" << endl;
2063 cpp <<
" s_global" << cfg.className <<
"->q = this;" << endl;
2068 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
2069 if ( (*itEntry)->group() !=
group ) {
2070 if ( !
group.isEmpty() ) cpp << endl;
2071 group = (*itEntry)->group();
2072 cpp <<
" setCurrentGroup( " <<
paramString(
group, parameters) <<
" );" << endl << endl;
2076 if ( !(*itEntry)->code().isEmpty() ) {
2077 cpp << (*itEntry)->code() << endl;
2079 if ( (*itEntry)->type() ==
"Enum" ) {
2080 cpp <<
" QList<"+cfg.inherits+
"::ItemEnum::Choice2> values"
2081 << (*itEntry)->name() <<
";" << endl;
2084 for( it = choices.constBegin(); it != choices.constEnd(); ++it ) {
2085 cpp <<
" {" << endl;
2086 cpp <<
" "+cfg.inherits+
"::ItemEnum::Choice2 choice;" << endl;
2087 cpp <<
" choice.name = QLatin1String(\"" << (*it).name <<
"\");" << endl;
2088 if ( cfg.setUserTexts ) {
2089 if ( !(*it).label.isEmpty() ) {
2090 cpp <<
" choice.label = ";
2091 if ( !(*it).context.isEmpty() )
2092 cpp <<
"i18nc(" +
quoteString((*it).context) +
", ";
2097 if ( !(*it).toolTip.isEmpty() ) {
2098 cpp <<
" choice.toolTip = ";
2099 if ( !(*it).context.isEmpty() )
2100 cpp <<
"i18nc(" +
quoteString((*it).context) +
", ";
2103 cpp <<
quoteString((*it).toolTip) <<
");" << endl;
2105 if ( !(*it).whatsThis.isEmpty() ) {
2106 cpp <<
" choice.whatsThis = ";
2107 if ( !(*it).context.isEmpty() )
2108 cpp <<
"i18nc(" +
quoteString((*it).context) +
", ";
2111 cpp <<
quoteString((*it).whatsThis) <<
");" << endl;
2114 cpp <<
" values" << (*itEntry)->name() <<
".append( choice );" << endl;
2115 cpp <<
" }" << endl;
2122 if ( (*itEntry)->param().isEmpty() )
2125 cpp <<
" " <<
itemPath( *itEntry, cfg ) <<
" = "
2126 <<
newItem( (*itEntry)->type(), (*itEntry)->name(), key, (*itEntry)->defaultValue(), cfg ) << endl;
2128 if ( !(*itEntry)->minValue().isEmpty() )
2129 cpp <<
" " <<
itemPath( *itEntry, cfg ) <<
"->setMinValue(" << (*itEntry)->minValue() <<
");" << endl;
2130 if ( !(*itEntry)->maxValue().isEmpty() )
2131 cpp <<
" " <<
itemPath( *itEntry, cfg ) <<
"->setMaxValue(" << (*itEntry)->maxValue() <<
");" << endl;
2133 if ( cfg.setUserTexts )
2136 cpp <<
" addItem( " <<
itemPath( *itEntry, cfg );
2137 QString quotedName = (*itEntry)->name();
2139 if ( quotedName != key ) cpp <<
", QLatin1String( \"" << (*itEntry)->name() <<
"\" )";
2140 cpp <<
" );" << endl;
2145 for(
int i = 0; i <= (*itEntry)->paramMax(); i++)
2150 if ( !(*itEntry)->paramDefaultValue(i).isEmpty() )
2151 defaultStr = (*itEntry)->paramDefaultValue(i);
2152 else if ( !(*itEntry)->defaultValue().isEmpty() )
2153 defaultStr =
paramString( (*itEntry)->defaultValue(), (*itEntry), i );
2157 cpp <<
" " << itemVarStr <<
" = "
2158 <<
newItem( (*itEntry)->type(), (*itEntry)->name(),
paramString(key, *itEntry, i), defaultStr,cfg,
QString(
"[%1]").arg(i) )
2161 if ( cfg.setUserTexts )
2168 cpp <<
" addItem( " << itemVarStr <<
", QLatin1String( \"";
2169 if ( (*itEntry)->paramType()==
"Enum" )
2170 cpp << (*itEntry)->paramName().replace(
"$("+(*itEntry)->param()+
')',
"%1").arg((*itEntry)->paramValues()[i] );
2172 cpp << (*itEntry)->paramName().replace(
"$("+(*itEntry)->param()+
')',
"%1").arg(i);
2173 cpp <<
"\" ) );" << endl;
2178 cpp <<
"}" << endl << endl;
2183 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
2184 QString n = (*itEntry)->name();
2185 QString t = (*itEntry)->type();
2188 if (cfg.allMutators || cfg.mutators.contains(n))
2190 cpp <<
"void " <<
setFunction(n, cfg.className) <<
"( ";
2191 if ( !(*itEntry)->param().isEmpty() )
2192 cpp <<
cppType( (*itEntry)->paramType() ) <<
" i, ";
2193 if (cfg.useEnumTypes && t ==
"Enum")
2194 cpp <<
enumType(*itEntry, cfg.globalEnums);
2197 cpp <<
" v )" << endl;
2202 cpp <<
"}" << endl << endl;
2206 if (cfg.useEnumTypes && t ==
"Enum")
2207 cpp <<
enumType(*itEntry, cfg.globalEnums);
2210 cpp <<
" " <<
getFunction(n, cfg.className) <<
"(";
2211 if ( !(*itEntry)->param().isEmpty() )
2212 cpp <<
" " <<
cppType( (*itEntry)->paramType() ) <<
" i ";
2213 cpp <<
")" << Const << endl;
2218 cpp <<
"}" << endl << endl;
2223 if ( cfg.itemAccessors )
2226 cpp << cfg.inherits+
"::Item" <<
itemType( (*itEntry)->type() ) <<
" *"
2228 if ( !(*itEntry)->param().isEmpty() ) {
2229 cpp <<
" " <<
cppType( (*itEntry)->paramType() ) <<
" i ";
2242 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
2243 QString n = (*itEntry)->name();
2244 QString t = (*itEntry)->type();
2247 if (( cfg.allDefaultGetters || cfg.defaultGetters.contains(n) ) && !(*itEntry)->defaultValue().isEmpty() ) {
2249 if ( !(*itEntry)->param().isEmpty() )
2250 cpp <<
" " <<
cppType( (*itEntry)->paramType() ) <<
" i ";
2251 cpp <<
")" << Const << endl;
2254 cpp <<
"}" << endl << endl;
2259 cpp << cfg.className <<
"::~" << cfg.className <<
"()" << endl;
2261 if ( cfg.singleton ) {
2263 cpp <<
" delete d;" << endl;
2264 cpp <<
" if (!s_global" << cfg.className <<
".isDestroyed()) {" << endl;
2265 cpp <<
" s_global" << cfg.className <<
"->q = 0;" << endl;
2266 cpp <<
" }" << endl;
2268 cpp <<
"}" << endl << endl;
2271 cpp <<
"void " << cfg.className <<
"::" <<
"usrWriteConfig()" << endl;
2273 cpp <<
" " << cfg.inherits <<
"::usrWriteConfig();" << endl << endl;
2274 foreach(
const Signal &signal, signalList) {
2275 cpp <<
" if ( " <<
varPath(
"settingsChanged", cfg) <<
" & " <<
signalEnumName(signal.name) <<
" ) " << endl;
2276 cpp <<
" emit " << signal.name <<
"(";
2278 for ( it = signal.arguments.constBegin(); it != itEnd; ) {
2279 SignalArguments argument = *it;
2281 if ( cfg.useEnumTypes && argument.type ==
"Enum" ) {
2282 for (
int i = 0, end = entries.count(); i < end; ++i ) {
2283 if ( entries[i]->name() == argument.variableName ) {
2284 cpp <<
"static_cast<" <<
enumType(entries[i], cfg.globalEnums) <<
">(";
2290 cpp <<
varPath(argument.variableName, cfg);
2293 if ( ++it != itEnd )
2296 cpp <<
");" << endl << endl;
2298 cpp <<
" " <<
varPath(
"settingsChanged", cfg) <<
" = 0;" << endl;
2305 cpp <<
"#include \"" << mocFileName <<
"\"" << endl;
2310 qDeleteAll( entries );
2312 implementation.close();
static void preProcessDefault(QString &defaultValue, const QString &name, const QString &type, const CfgEntry::Choices &choices, QString &code, const CfgConfig &cfg)
QString userTextsFunctions(CfgEntry *e, const CfgConfig &cfg, QString itemVarStr=QString(), QString i=QString())
QString param(const QString &t)
Return parameter declaration for given type.
QString paramString(const QString &s, const CfgEntry *e, int i)
static QString filenameOnly(const QString &path)
QString memberMutatorBody(CfgEntry *e, const CfgConfig &cfg)
static QString itemVar(const CfgEntry *e, const CfgConfig &cfg)
QRegExp * validNameRegexp
static QString getDefaultFunction(const QString &n, const QString &className=QString())
CfgEntry * parseEntry(const QString &group, const QDomElement &element, const CfgConfig &cfg)
static QString setFunction(const QString &n, const QString &className=QString())
static QString varPath(const QString &n, const CfgConfig &cfg)
QString indent(QString text, int spaces)
void endNamespaces(const QString &p_ns, QTextStream &p_out)
static QString literalString(const QString &s)
static bool isUnsigned(const QString &type)
QString itemAccessorBody(CfgEntry *e, const CfgConfig &cfg)
QString memberAccessorBody(CfgEntry *e, bool globalEnums, const CfgConfig &cfg)
static void addQuotes(QString &s)
void beginNamespaces(const QString &p_ns, QTextStream &p_out)
static QString dumpNode(const QDomNode &node)
QString cppType(const QString &t)
Actual C++ storage type for given type.
QString itemType(const QString &type)
static QString itemDeclaration(const CfgEntry *e, const CfgConfig &cfg)
static QString varName(const QString &n, const CfgConfig &cfg)
QString memberGetDefaultBody(CfgEntry *e)
static QString signalEnumName(const QString &signalName)
static QString itemPath(const CfgEntry *e, const CfgConfig &cfg)
static void parseArgs(const QStringList &args, QString &directory, QString &file1, QString &file2)
QString newItem(const QString &type, const QString &name, const QString &key, const QString &defaultValue, const CfgConfig &cfg, const QString ¶m=QString())
static QString enumName(const QString &n)
int main(int argc, char **argv)
static QString getFunction(const QString &n, const QString &className=QString())
static QString enumTypeQualifier(const QString &n, const CfgEntry::Choices &c)
QString defaultValue(const QString &t)
static QString quoteString(const QString &s)
static QString enumType(const CfgEntry *e, bool globalEnums)