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 cpp <<
" QStringList default" << name <<
";" << endl;
540 const QStringList defaults = defaultValue.split(QLatin1Char(
','));
541 QStringList::ConstIterator it;
542 for( it = defaults.constBegin(); it != defaults.constEnd(); ++it ) {
543 cpp <<
" default" << name <<
".append( ";
544 if( type ==
"UrlList" ) {
547 cpp <<
"QString::fromUtf8( \"" << *it <<
"\" ) ";
548 if( type == QLatin1String(
"UrlList") ) {
553 defaultValue = QString::fromLatin1(
"default") + name;
555 }
else if ( type == QLatin1String(
"Color") && !defaultValue.isEmpty() ) {
556 QRegExp colorRe(QLatin1String(
"\\d+,\\s*\\d+,\\s*\\d+(,\\s*\\d+)?"));
557 if (colorRe.exactMatch(defaultValue))
559 defaultValue = QLatin1String(
"QColor( ") + defaultValue + QLatin1String(
" )");
563 defaultValue = QLatin1String(
"QColor( \"") + defaultValue + QLatin1String(
"\" )");
566 }
else if ( type == QLatin1String(
"Enum") ) {
568 for( it = choices.choices.constBegin(); it != choices.choices.constEnd(); ++it ) {
569 if ( (*it).name == defaultValue ) {
570 if ( cfg.globalEnums && choices.name().isEmpty() )
571 defaultValue.prepend( choices.prefix );
578 }
else if ( type == QLatin1String(
"IntList") ) {
579 QTextStream cpp( &code, QIODevice::WriteOnly | QIODevice::Append );
583 cpp <<
" QList<int> default" << name <<
";" << endl;
584 if (!defaultValue.isEmpty())
586 const QStringList defaults = defaultValue.split( QLatin1Char(
',') );
587 QStringList::ConstIterator it;
588 for( it = defaults.constBegin(); it != defaults.constEnd(); ++it ) {
589 cpp <<
" default" << name <<
".append( " << *it <<
" );"
593 defaultValue = QString::fromLatin1(
"default") + name;
600 bool defaultCode =
false;
601 QString type = element.attribute(
"type" );
602 QString name = element.attribute(
"name" );
603 QString key = element.attribute(
"key" );
604 QString hidden = element.attribute(
"hidden" );
616 CfgEntry::Choices choices;
624 for ( QDomElement e = element.firstChildElement(); !e.isNull(); e = e.nextSiblingElement() ) {
626 if ( tag ==
"label" ) {
628 labelContext = e.attribute(
"context" );
630 else if ( tag ==
"tooltip" ) {
632 toolTipContext = e.attribute(
"context" );
634 else if ( tag ==
"whatsthis" ) {
635 whatsThis = e.text();
636 whatsThisContext = e.attribute(
"context" );
638 else if ( tag ==
"min" ) minValue = e.text();
639 else if ( tag ==
"max" ) maxValue = e.text();
640 else if ( tag ==
"code" ) code = e.text();
641 else if ( tag ==
"parameter" )
643 param = e.attribute(
"name" );
644 paramType = e.attribute(
"type" );
645 if ( param.isEmpty() ) {
646 cerr <<
"Parameter must have a name: " <<
dumpNode(e) << endl;
649 if ( paramType.isEmpty() ) {
650 cerr <<
"Parameter must have a type: " <<
dumpNode(e) << endl;
653 if ((paramType ==
"Int") || (paramType ==
"UInt"))
656 paramMax = e.attribute(
"max").toInt(&ok);
659 cerr <<
"Integer parameter must have a maximum (e.g. max=\"0\"): "
664 else if (paramType ==
"Enum")
666 for ( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) {
667 if (e2.tagName() ==
"values")
669 for ( QDomElement e3 = e2.firstChildElement(); !e3.isNull(); e3 = e3.nextSiblingElement() ) {
670 if (e3.tagName() ==
"value")
672 paramValues.append( e3.text() );
678 if (paramValues.isEmpty())
680 cerr <<
"No values specified for parameter '" << param
684 paramMax = paramValues.count()-1;
688 cerr <<
"Parameter '" << param <<
"' has type " << paramType
689 <<
" but must be of type int, uint or Enum." << endl;
693 else if ( tag ==
"default" )
695 if (e.attribute(
"param").isEmpty())
697 defaultValue = e.text();
698 if (e.attribute(
"code" ) ==
"true")
702 else if ( tag ==
"choices" ) {
703 QString name = e.attribute(
"name" );
706 for( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) {
707 if ( e2.tagName() ==
"choice" ) {
708 CfgEntry::Choice choice;
709 choice.name = e2.attribute(
"name" );
710 if ( choice.name.isEmpty() ) {
711 cerr <<
"Tag <choice> requires attribute 'name'." << endl;
713 for( QDomElement e3 = e2.firstChildElement(); !e3.isNull(); e3 = e3.nextSiblingElement() ) {
714 if ( e3.tagName() ==
"label" ) {
715 choice.label = e3.text();
716 choice.context = e3.attribute(
"context" );
718 if ( e3.tagName() ==
"tooltip" ) {
719 choice.toolTip = e3.text();
720 choice.context = e3.attribute(
"context" );
722 if ( e3.tagName() ==
"whatsthis" ) {
723 choice.whatsThis = e3.text();
724 choice.context = e3.attribute(
"context" );
727 chlist.append( choice );
730 choices = CfgEntry::Choices( chlist, name, prefix );
732 else if ( tag ==
"emit" ) {
735 signal.name = e.attribute(
"signal" );
736 signalList.append( signal);
741 bool nameIsEmpty = name.isEmpty();
742 if ( nameIsEmpty && key.isEmpty() ) {
743 cerr <<
"Entry must have a name or a key: " <<
dumpNode(element) << endl;
747 if ( key.isEmpty() ) {
754 }
else if ( name.contains(
' ' ) ) {
755 cout<<
"Entry '"<<name<<
"' contains spaces! <name> elements can not contain spaces!"<<endl;
759 if (name.contains(
"$("))
763 cerr <<
"Name may not be parameterized: " << name << endl;
769 if (!param.isEmpty())
771 cerr <<
"Name must contain '$(" << param <<
")': " << name << endl;
776 if ( label.isEmpty() ) {
780 if ( type.isEmpty() ) type =
"String";
782 if (!param.isEmpty())
786 name.remove(
"$("+param+
')');
788 for(
int i = 0; i <= paramMax; i++)
790 paramDefaultValues.append(
QString());
793 for ( QDomElement e = element.firstChildElement(); !e.isNull(); e = e.nextSiblingElement() ) {
795 if ( tag ==
"default" )
797 QString index = e.attribute(
"param");
802 int i = index.toInt(&ok);
805 i = paramValues.indexOf(index);
808 cerr <<
"Index '" << index <<
"' for default value is unknown." << endl;
813 if ((i < 0) || (i > paramMax))
815 cerr <<
"Index '" << i <<
"' for default value is out of range [0, "<< paramMax<<
"]." << endl;
819 QString tmpDefaultValue = e.text();
821 if (e.attribute(
"code" ) !=
"true")
824 paramDefaultValues[i] = tmpDefaultValue;
832 cerr <<
"The key '" << key <<
"' can not be used as name for the entry because "
833 "it is not a valid name. You need to specify a valid name for this entry." << endl;
835 cerr <<
"The name '" << name <<
"' is not a valid name for an entry." << endl;
839 if (allNames.contains(name))
842 cerr <<
"The key '" << key <<
"' can not be used as name for the entry because "
843 "it does not result in a unique name. You need to specify a unique name for this entry." << endl;
845 cerr <<
"The name '" << name <<
"' is not unique." << endl;
848 allNames.append(name);
855 CfgEntry *result =
new CfgEntry( group, type, key, name, labelContext, label, toolTipContext, toolTip, whatsThisContext, whatsThis,
856 code, defaultValue, choices, signalList,
858 if (!param.isEmpty())
860 result->setParam(param);
861 result->setParamName(paramName);
862 result->setParamType(paramType);
863 result->setParamValues(paramValues);
864 result->setParamDefaultValues(paramDefaultValues);
865 result->setParamMax(paramMax);
867 result->setMinValue(minValue);
868 result->setMaxValue(maxValue);
875 if ( type ==
"UInt" )
return true;
876 if ( type ==
"ULongLong" )
return true;
885 const QString type = t.toLower();
886 if ( type ==
"string" )
return "const QString &";
887 else if ( type ==
"stringlist" )
return "const QStringList &";
888 else if ( type ==
"font" )
return "const QFont &";
889 else if ( type ==
"rect" )
return "const QRect &";
890 else if ( type ==
"size" )
return "const QSize &";
891 else if ( type ==
"color" )
return "const QColor &";
892 else if ( type ==
"point" )
return "const QPoint &";
893 else if ( type ==
"int" )
return "int";
894 else if ( type ==
"uint" )
return "uint";
895 else if ( type ==
"bool" )
return "bool";
896 else if ( type ==
"double" )
return "double";
897 else if ( type ==
"datetime" )
return "const QDateTime &";
898 else if ( type ==
"longlong" )
return "qint64";
899 else if ( type ==
"ulonglong" )
return "quint64";
900 else if ( type ==
"intlist" )
return "const QList<int> &";
901 else if ( type ==
"enum" )
return "int";
902 else if ( type ==
"path" )
return "const QString &";
903 else if ( type ==
"pathlist" )
return "const QStringList &";
904 else if ( type ==
"password" )
return "const QString &";
905 else if ( type ==
"url" )
return "const KUrl &";
906 else if ( type ==
"urllist" )
return "const KUrl::List &";
908 cerr <<
"kconfig_compiler does not support type \""<< type <<
"\""<<endl;
918 const QString type = t.toLower();
919 if ( type ==
"string" )
return "QString";
920 else if ( type ==
"stringlist" )
return "QStringList";
921 else if ( type ==
"font" )
return "QFont";
922 else if ( type ==
"rect" )
return "QRect";
923 else if ( type ==
"size" )
return "QSize";
924 else if ( type ==
"color" )
return "QColor";
925 else if ( type ==
"point" )
return "QPoint";
926 else if ( type ==
"int" )
return "int";
927 else if ( type ==
"uint" )
return "uint";
928 else if ( type ==
"bool" )
return "bool";
929 else if ( type ==
"double" )
return "double";
930 else if ( type ==
"datetime" )
return "QDateTime";
931 else if ( type ==
"longlong" )
return "qint64";
932 else if ( type ==
"ulonglong" )
return "quint64";
933 else if ( type ==
"intlist" )
return "QList<int>";
934 else if ( type ==
"enum" )
return "int";
935 else if ( type ==
"path" )
return "QString";
936 else if ( type ==
"pathlist" )
return "QStringList";
937 else if ( type ==
"password" )
return "QString";
938 else if ( type ==
"url" )
return "KUrl";
939 else if ( type ==
"urllist" )
return "KUrl::List";
941 cerr<<
"kconfig_compiler does not support type \""<< type <<
"\""<<endl;
948 const QString type = t.toLower();
949 if ( type ==
"string" )
return "\"\"";
950 else if ( type ==
"stringlist" )
return "QStringList()";
951 else if ( type ==
"font" )
return "QFont()";
952 else if ( type ==
"rect" )
return "QRect()";
953 else if ( type ==
"size" )
return "QSize()";
954 else if ( type ==
"color" )
return "QColor(128, 128, 128)";
955 else if ( type ==
"point" )
return "QPoint()";
956 else if ( type ==
"int" )
return "0";
957 else if ( type ==
"uint" )
return "0";
958 else if ( type ==
"bool" )
return "false";
959 else if ( type ==
"double" )
return "0.0";
960 else if ( type ==
"datedime" )
return "QDateTime()";
961 else if ( type ==
"longlong" )
return "0";
962 else if ( type ==
"ulonglong" )
return "0";
963 else if ( type ==
"intlist" )
return "QList<int>()";
964 else if ( type ==
"enum" )
return "0";
965 else if ( type ==
"path" )
return "\"\"";
966 else if ( type ==
"pathlist" )
return "QStringList()";
967 else if ( type ==
"password" )
return "\"\"";
968 else if ( type ==
"url" )
return "KUrl()";
969 else if ( type ==
"urllist" )
return "KUrl::List()";
971 cerr<<
"Error, kconfig_compiler does not support the \""<< type <<
"\" type!"<<endl;
981 t.replace( 0, 1, t.left( 1 ).toUpper() );
988 if (cfg.itemAccessors)
992 fCap[0] = fCap[0].toUpper();
993 return " "+cfg.inherits+
"::Item"+
itemType( e->type() ) +
995 ( (!e->param().isEmpty())?(
QString(
"[%1]").arg(e->paramMax()+1)) :
QString()) +
1005 if (cfg.itemAccessors)
1007 if ( !cfg.dpointer )
1009 result =
'm' + e->name() +
"Item";
1010 result[1] = result[1].toUpper();
1014 result = e->name() +
"Item";
1015 result[0] = result[0].toLower();
1020 result =
"item" + e->name();
1021 result[4] = result[4].toUpper();
1029 if ( cfg.dpointer ) {
1030 result =
"d->"+
itemVar(e, cfg);
1042 "( currentGroup(), " + key +
", " +
varPath( name, cfg ) +
param;
1043 if ( type ==
"Enum" ) t +=
", values" + name;
1044 if ( !defaultValue.isEmpty() ) {
1057 QString needle =
"$("+e->param()+
')';
1058 if (result.contains(needle))
1061 if (e->paramType() ==
"Enum")
1063 tmp = e->paramValues()[i];
1067 tmp = QString::number(i);
1070 result.replace(needle, tmp);
1081 it != parameters.constEnd(); ++it)
1083 if (paramString.contains(
"$("+(*it).name+
')'))
1086 tmp.sprintf(
"%%%d", i++);
1087 paramString.replace(
"$("+(*it).name+
')', tmp);
1088 arguments +=
".arg( mParam"+(*it).name+
" )";
1091 if (arguments.isEmpty())
1092 return "QLatin1String( \""+group+
"\" )";
1094 return "QString( QLatin1String( \""+paramString+
"\" ) )"+arguments;
1101 if (itemVarStr.isNull()) itemVarStr=
itemPath(e, cfg);
1102 if ( !e->label().isEmpty() ) {
1103 txt +=
" " + itemVarStr +
"->setLabel( ";
1104 if ( !e->labelContext().isEmpty() )
1105 txt +=
"i18nc(" +
quoteString(e->labelContext()) +
", ";
1108 if ( !e->param().isEmpty() )
1109 txt +=
quoteString(e->label().replace(
"$("+e->param()+
')', i));
1114 if ( !e->toolTip().isEmpty() ) {
1115 txt +=
" " + itemVarStr +
"->setToolTip( ";
1116 if ( !e->toolTipContext().isEmpty() )
1117 txt +=
"i18nc(" +
quoteString(e->toolTipContext()) +
", ";
1120 if ( !e->param().isEmpty() )
1121 txt +=
quoteString(e->toolTip().replace(
"$("+e->param()+
')', i));
1126 if ( !e->whatsThis().isEmpty() ) {
1127 txt +=
" " + itemVarStr +
"->setWhatsThis( ";
1128 if ( !e->whatsThisContext().isEmpty() )
1129 txt +=
"i18nc(" +
quoteString(e->whatsThisContext()) +
", ";
1132 if ( !e->param().isEmpty() )
1133 txt +=
quoteString(e->whatsThis().replace(
"$("+e->param()+
')', i));
1147 QTextStream out(&result, QIODevice::WriteOnly);
1150 bool useEnumType = cfg.useEnumTypes && t ==
"Enum";
1154 out <<
"static_cast<" <<
enumType(e, globalEnums) <<
">(";
1155 out << This <<
varPath(n, cfg);
1156 if (!e->param().isEmpty())
1171 QTextStream out(&result, QIODevice::WriteOnly);
1175 if (!e->minValue().isEmpty())
1177 if (e->minValue() !=
"0" || !
isUnsigned(t)) {
1178 out <<
"if (v < " << e->minValue() <<
")" << endl;
1181 out <<
": value \" << v << \" is less than the minimum value of ";
1182 out << e->minValue()<<
"\";" << endl;
1183 out <<
" v = " << e->minValue() <<
";" << endl;
1188 if (!e->maxValue().isEmpty())
1190 out << endl <<
"if (v > " << e->maxValue() <<
")" << endl;
1193 out <<
": value \" << v << \" is greater than the maximum value of ";
1194 out << e->maxValue()<<
"\";" << endl;
1195 out <<
" v = " << e->maxValue() <<
";" << endl;
1196 out <<
"}" << endl << endl;
1199 out <<
"if (!" << This <<
"isImmutable( QString::fromLatin1( \"";
1200 if (!e->param().isEmpty())
1202 out << e->paramName().replace(
"$("+e->param()+
")",
"%1") <<
"\" ).arg( ";
1203 if ( e->paramType() ==
"Enum" ) {
1204 out <<
"QLatin1String( ";
1206 if (cfg.globalEnums)
1207 out <<
enumName(e->param()) <<
"ToString[i]";
1209 out <<
enumName(e->param()) <<
"::enumToString[i]";
1223 out <<
" ))" << (!e->signalList().empty() ?
" {" :
"") << endl;
1224 out <<
" " << This <<
varPath(n, cfg);
1225 if (!e->param().isEmpty())
1227 out <<
" = v;" << endl;
1229 if ( !e->signalList().empty() ) {
1230 foreach(
const Signal &signal, e->signalList()) {
1231 out <<
" " << This <<
varPath(
"settingsChanged", cfg) <<
" |= " <<
signalEnumName(signal.name) <<
";" << endl;
1245 QTextStream out(&result, QIODevice::WriteOnly);
1248 if (!e->param().isEmpty()) {
1249 out <<
" switch (i) {" << endl;
1250 for (
int i = 0; i <= e->paramMax(); ++i) {
1251 if (!e->paramDefaultValue(i).isEmpty()) {
1252 out <<
" case " << i <<
": return " << e->paramDefaultValue(i) <<
';' << endl;
1255 out <<
" default:" << endl;
1256 out <<
" return " << e->defaultValue().replace(
"$("+e->param()+
')',
"i") <<
';' << endl;
1257 out <<
" }" << endl;
1259 out <<
" return " << e->defaultValue() <<
';';
1271 QTextStream out(&result, QIODevice::WriteOnly);
1273 out <<
"return " <<
itemPath(e, cfg);
1274 if (!e->param().isEmpty()) out <<
"[i]";
1284 QTextStream out(&result, QIODevice::WriteOnly);
1285 QTextStream in(&text, QIODevice::ReadOnly);
1287 while ( !in.atEnd() )
1289 currLine = in.readLine();
1290 if (!currLine.isEmpty())
1291 for (
int i=0; i < spaces; i++)
1293 out << currLine << endl;
1302 if ( !p_ns.isEmpty() ) {
1303 const QStringList nameSpaces = p_ns.split(
"::" );
1304 foreach (
const QString &ns, nameSpaces )
1305 p_out <<
"namespace " << ns <<
" {" << endl;
1314 if ( !p_ns.isEmpty() ) {
1315 const int namespaceCount = p_ns.count(
"::" ) + 1;
1316 for (
int i = 0; i < namespaceCount; ++i )
1317 p_out <<
"}" << endl;
1325 QCoreApplication app(argc, argv);
1329 QString directoryName, inputFilename, codegenFilename;
1330 parseArgs(app.arguments(), directoryName, inputFilename, codegenFilename);
1332 QString baseDir = directoryName;
1334 if (!baseDir.endsWith(
'/') && !baseDir.endsWith(
'\\'))
1336 if (!baseDir.endsWith(
'/'))
1338 baseDir.append(
"/");
1340 if (!codegenFilename.endsWith(QLatin1String(
".kcfgc")))
1342 cerr <<
"Codegen options file must have extension .kcfgc" << endl;
1345 QString baseName = QFileInfo(codegenFilename).fileName();
1346 baseName = baseName.left(baseName.length() - 6);
1348 CfgConfig cfg = CfgConfig( codegenFilename );
1350 QFile input( inputFilename );
1356 if ( !doc.setContent( &input, &errorMsg, &errorRow, &errorCol ) ) {
1357 cerr <<
"Unable to load document." << endl;
1358 cerr <<
"Parse error in " << inputFilename <<
", line " << errorRow <<
", col " << errorCol <<
": " << errorMsg << endl;
1362 QDomElement cfgElement = doc.documentElement();
1364 if ( cfgElement.isNull() ) {
1365 cerr <<
"No document in kcfg file" << endl;
1370 bool cfgFileNameArg =
false;
1374 bool hasSignals =
false;
1378 for ( QDomElement e = cfgElement.firstChildElement(); !e.isNull(); e = e.nextSiblingElement() ) {
1381 if ( tag ==
"include" ) {
1382 QString includeFile = e.text();
1383 if (!includeFile.isEmpty())
1384 includes.append(includeFile);
1386 }
else if ( tag ==
"kcfgfile" ) {
1387 cfgFileName = e.attribute(
"name" );
1388 cfgFileNameArg = e.attribute(
"arg" ).toLower() ==
"true";
1389 for( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) {
1390 if ( e2.tagName() ==
"parameter" ) {
1392 p.name = e2.attribute(
"name" );
1393 p.type = e2.attribute(
"type" );
1394 if (p.type.isEmpty())
1396 parameters.append( p );
1400 }
else if ( tag ==
"group" ) {
1402 if ( group.isEmpty() ) {
1403 cerr <<
"Group without name" << endl;
1406 for( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) {
1407 if ( e2.tagName() !=
"entry" )
continue;
1408 CfgEntry *entry =
parseEntry( group, e2, cfg );
1409 if ( entry ) entries.append( entry );
1411 cerr <<
"Can not parse entry." << endl;
1416 else if ( tag ==
"signal" ) {
1417 QString signalName = e.attribute(
"name" );
1418 if ( signalName.isEmpty() ) {
1419 cerr <<
"Signal without name." << endl;
1423 theSignal.name = signalName;
1425 for( QDomElement e2 = e.firstChildElement(); !e2.isNull(); e2 = e2.nextSiblingElement() ) {
1426 if ( e2.tagName() ==
"argument") {
1427 SignalArguments argument;
1428 argument.type = e2.attribute(
"type");
1429 if ( argument.type.isEmpty() ) {
1430 cerr <<
"Signal argument without type." << endl;
1433 argument.variableName = e2.text();
1434 theSignal.arguments.append(argument);
1436 else if( e2.tagName() ==
"label") {
1437 theSignal.label = e2.text();
1440 signalList.append(theSignal);
1444 if ( cfg.className.isEmpty() ) {
1445 cerr <<
"Class name missing" << endl;
1449 if ( cfg.singleton && !parameters.isEmpty() ) {
1450 cerr <<
"Singleton class can not have parameters" << endl;
1454 if ( !cfgFileName.isEmpty() && cfgFileNameArg)
1456 cerr <<
"Having both a fixed filename and a filename as argument is not possible." << endl;
1460 if ( entries.isEmpty() ) {
1461 cerr <<
"No entries." << endl;
1466 for( cfg = entries.first(); cfg; cfg = entries.next() ) {
1471 hasSignals = !signalList.empty();
1472 QString headerFileName = baseName +
".h";
1473 QString implementationFileName = baseName +
".cpp";
1474 QString mocFileName = baseName +
".moc";
1477 QFile
header( baseDir + headerFileName );
1478 if ( !header.open( QIODevice::WriteOnly ) ) {
1479 cerr <<
"Can not open '" << baseDir << headerFileName <<
"for writing." << endl;
1483 QTextStream h( &header );
1485 h <<
"// This file is generated by kconfig_compiler from " << QFileInfo(inputFilename).fileName() <<
"." << endl;
1486 h <<
"// All changes you do to this file will be lost." << endl;
1488 h <<
"#ifndef " << ( !cfg.nameSpace.isEmpty() ?
QString (
QString(cfg.nameSpace).replace(
"::",
"_" ).toUpper() +
'_') :
"" )
1489 << cfg.className.toUpper() <<
"_H" << endl;
1490 h <<
"#define " << ( !cfg.nameSpace.isEmpty() ?
QString (
QString(cfg.nameSpace).replace(
"::",
"_" ).toUpper() +
'_') :
"" )
1491 << cfg.className.toUpper() <<
"_H" << endl << endl;
1494 QStringList::ConstIterator it;
1495 for( it = cfg.headerIncludes.constBegin(); it != cfg.headerIncludes.constEnd(); ++it ) {
1496 if ( (*it).startsWith(
'"') )
1497 h <<
"#include " << *it << endl;
1499 h <<
"#include <" << *it <<
">" << endl;
1502 if ( cfg.headerIncludes.count() > 0 ) h << endl;
1504 if ( !cfg.singleton && parameters.isEmpty() )
1505 h <<
"#include <kglobal.h>" << endl;
1507 if ( cfg.inherits==
"KCoreConfigSkeleton" ) {
1508 h <<
"#include <kcoreconfigskeleton.h>" << endl;
1510 h <<
"#include <kconfigskeleton.h>" << endl;
1513 h <<
"#include <kdebug.h>" << endl << endl;
1516 for( it = includes.constBegin(); it != includes.constEnd(); ++it ) {
1517 if ( (*it).startsWith(
'"') )
1518 h <<
"#include " << *it << endl;
1520 h <<
"#include <" << *it <<
">" << endl;
1527 h <<
"class " << cfg.className <<
"Private;" << endl << endl;
1530 h <<
"class " << cfg.visibility << cfg.className <<
" : public " << cfg.inherits << endl;
1535 h <<
" Q_OBJECT" << endl;
1536 h <<
" public:" << endl;
1540 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
1541 const CfgEntry::Choices &choices = (*itEntry)->choices();
1543 if ( !chlist.isEmpty() ) {
1546 for( itChoice = chlist.constBegin(); itChoice != chlist.constEnd(); ++itChoice ) {
1547 values.append( choices.prefix + (*itChoice).name );
1549 if ( choices.name().isEmpty() ) {
1550 if ( cfg.globalEnums ) {
1551 h <<
" enum " <<
enumName( (*itEntry)->name(), (*itEntry)->choices() ) <<
" { " << values.join(
", " ) <<
" };" << endl;
1554 h <<
" class " <<
enumName( (*itEntry)->name(), (*itEntry)->choices() ) << endl;
1556 h <<
" public:" << endl;
1557 h <<
" enum type { " << values.join(
", " ) <<
", COUNT };" << endl;
1560 }
else if ( !choices.external() ) {
1562 h <<
" enum " <<
enumName( (*itEntry)->name(), (*itEntry)->choices() ) <<
" { " << values.join(
", " ) <<
" };" << endl;
1565 const QStringList values = (*itEntry)->paramValues();
1566 if ( !values.isEmpty() ) {
1567 if ( cfg.globalEnums ) {
1571 h <<
" enum " <<
enumName( (*itEntry)->param() ) <<
" { " << values.join(
", " ) <<
" };" << endl;
1572 h <<
" static const char* const " <<
enumName( (*itEntry)->param() ) <<
"ToString[];" << endl;
1573 cppPreamble +=
"const char* const " + cfg.className +
"::" +
enumName( (*itEntry)->param() ) +
1574 "ToString[] = { \"" + values.join(
"\", \"" ) +
"\" };\n";
1576 h <<
" class " <<
enumName( (*itEntry)->param() ) << endl;
1578 h <<
" public:" << endl;
1579 h <<
" enum type { " << values.join(
", " ) <<
", COUNT };" << endl;
1580 h <<
" static const char* const enumToString[];" << endl;
1582 cppPreamble +=
"const char* const " + cfg.className +
"::" +
enumName( (*itEntry)->param() ) +
1583 "::enumToString[] = { \"" + values.join(
"\", \"" ) +
"\" };\n";
1588 h <<
"\n enum {" << endl;
1591 for ( it = signalList.constBegin(); it != itEnd; val <<= 1) {
1593 cerr <<
"Too many signals to create unique bit masks" << endl;
1596 Signal signal = *it;
1597 h <<
" " <<
signalEnumName(signal.name) <<
" = 0x" << hex << val;
1598 if ( ++it != itEnd )
1602 h <<
" };" << dec << endl;
1606 if ( !cfg.singleton ) {
1607 h <<
" " << cfg.className <<
"(";
1610 if(cfg.forceStringFilename)
1611 h <<
" const QString &cfgfilename"
1612 << (parameters.isEmpty() ?
" = QString()" :
", ");
1614 h <<
" KSharedConfig::Ptr config"
1615 << (parameters.isEmpty() ?
" = KGlobal::config()" :
", ");
1618 it != parameters.constEnd(); ++it)
1620 if (it != parameters.constBegin())
1622 h <<
" " <<
param((*it).type) <<
" " << (*it).name;
1626 h <<
" static " << cfg.className <<
" *self();" << endl;
1629 h <<
" static void instance(const QString& cfgfilename);" << endl;
1634 h <<
" ~" << cfg.className <<
"();" << endl << endl;
1637 if (cfg.staticAccessors)
1642 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
1643 QString n = (*itEntry)->name();
1644 QString t = (*itEntry)->type();
1647 if (cfg.allMutators || cfg.mutators.contains(n))
1649 h <<
" /**" << endl;
1650 h <<
" Set " << (*itEntry)->label() << endl;
1652 if (cfg.staticAccessors)
1653 h <<
" static" << endl;
1655 if (!(*itEntry)->param().isEmpty())
1656 h <<
cppType((*itEntry)->paramType()) <<
" i, ";
1657 if (cfg.useEnumTypes && t ==
"Enum")
1658 h <<
enumType(*itEntry, cfg.globalEnums);
1664 if ( !cfg.dpointer )
1666 h << endl <<
" {" << endl;
1677 h <<
" /**" << endl;
1678 h <<
" Get " << (*itEntry)->label() << endl;
1680 if (cfg.staticAccessors)
1681 h <<
" static" << endl;
1683 if (cfg.useEnumTypes && t ==
"Enum")
1684 h <<
enumType(*itEntry, cfg.globalEnums);
1688 if (!(*itEntry)->param().isEmpty())
1689 h <<
" " <<
cppType((*itEntry)->paramType()) <<
" i ";
1693 if ( !cfg.dpointer )
1695 h << endl <<
" {" << endl;
1705 if ((cfg.allDefaultGetters || cfg.defaultGetters.contains(n)) && !(*itEntry)->defaultValue().isEmpty()) {
1707 h <<
" /**" << endl;
1708 h <<
" Get " << (*itEntry)->label() <<
" default value" << endl;
1710 if (cfg.staticAccessors)
1711 h <<
" static" << endl;
1713 if (cfg.useEnumTypes && t ==
"Enum")
1714 h <<
enumType(*itEntry, cfg.globalEnums);
1718 if ( !(*itEntry)->param().isEmpty() )
1719 h <<
" " <<
cppType( (*itEntry)->paramType() ) <<
" i ";
1720 h <<
")" << Const << endl;
1723 if (cfg.useEnumTypes && t ==
"Enum")
1724 h <<
"static_cast<" <<
enumType(*itEntry, cfg.globalEnums) <<
">(";
1726 if ( !(*itEntry)->param().isEmpty() )
1729 if (cfg.useEnumTypes && t ==
"Enum")
1736 if ( cfg.itemAccessors ) {
1738 h <<
" /**" << endl;
1739 h <<
" Get Item object corresponding to " << n <<
"()"
1742 h <<
" Item" <<
itemType( (*itEntry)->type() ) <<
" *"
1744 if (!(*itEntry)->param().isEmpty()) {
1745 h <<
" " <<
cppType((*itEntry)->paramType()) <<
" i ";
1748 if ( !cfg.dpointer )
1750 h << endl <<
" {" << endl;
1768 foreach(
const Signal &signal, signalList) {
1770 if ( !signal.label.isEmpty() ) {
1771 h <<
" /**" << endl;
1772 h <<
" " << signal.label << endl;
1775 h <<
" void " << signal.name <<
"(";
1777 for ( it = signal.arguments.constBegin(); it != itEnd; ) {
1778 SignalArguments argument = *it;
1780 if ( cfg.useEnumTypes && argument.type ==
"Enum" ) {
1781 for (
int i = 0, end = entries.count(); i < end; ++i ) {
1782 if ( entries[i]->name() == argument.variableName ) {
1783 type =
enumType(entries[i], cfg.globalEnums);
1788 h << type <<
" " << argument.variableName;
1789 if ( ++it != itEnd ) {
1798 h <<
" protected:" << endl;
1801 if ( cfg.singleton ) {
1802 h <<
" " << cfg.className <<
"(";
1803 if ( cfgFileNameArg )
1804 h <<
"const QString& arg";
1806 h <<
" friend class " << cfg.className <<
"Helper;" << endl << endl;
1810 h <<
" virtual void usrWriteConfig();" << endl;
1814 if ( !cfg.memberVariables.isEmpty() && cfg.memberVariables !=
"private" && cfg.memberVariables !=
"dpointer") {
1815 h <<
" " << cfg.memberVariables <<
":" << endl;
1820 it != parameters.constEnd(); ++it)
1822 h <<
" " <<
cppType((*it).type) <<
" mParam" << (*it).name <<
";" << endl;
1825 if ( cfg.memberVariables !=
"dpointer" )
1828 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
1829 if ( (*itEntry)->group() !=
group ) {
1830 group = (*itEntry)->group();
1832 h <<
" // " << group << endl;
1834 h <<
" " <<
cppType( (*itEntry)->type() ) <<
" " <<
varName( (*itEntry)->name(), cfg );
1835 if ( !(*itEntry)->param().isEmpty() )
1837 h <<
QString(
"[%1]").arg( (*itEntry)->paramMax()+1 );
1841 if ( cfg.allDefaultGetters || cfg.defaultGetters.contains((*itEntry)->name()) )
1844 if (cfg.staticAccessors)
1847 if ( !(*itEntry)->param().isEmpty() )
1848 h <<
" " <<
cppType( (*itEntry)->paramType() ) <<
" i ";
1849 h <<
")" << Const <<
";" << endl;
1853 h << endl <<
" private:" << endl;
1854 if ( cfg.itemAccessors ) {
1855 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
1856 h <<
" Item" <<
itemType( (*itEntry)->type() ) <<
" *" <<
itemVar( *itEntry, cfg );
1857 if ( !(*itEntry)->param().isEmpty() ) h <<
QString(
"[%1]").arg( (*itEntry)->paramMax()+1 );
1862 h <<
" uint " <<
varName(
"settingsChanged", cfg) <<
";" << endl;
1868 h <<
" private:" << endl;
1869 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
1870 if ( cfg.allDefaultGetters || cfg.defaultGetters.contains((*itEntry)->name()) ) {
1872 if (cfg.staticAccessors)
1875 if ( !(*itEntry)->param().isEmpty() )
1876 h <<
" " <<
cppType( (*itEntry)->paramType() ) <<
" i ";
1877 h <<
")" << Const <<
";" << endl;
1880 h <<
" " + cfg.className +
"Private *d;" << endl;
1883 if (cfg.customAddons)
1885 h <<
" // Include custom additions" << endl;
1886 h <<
" #include \"" <<
filenameOnly(baseName) <<
"_addons.h\"" <<endl;
1889 h <<
"};" << endl << endl;
1893 h <<
"#endif" << endl << endl;
1898 QFile implementation( baseDir + implementationFileName );
1899 if ( !implementation.open( QIODevice::WriteOnly ) ) {
1900 cerr <<
"Can not open '" << implementationFileName <<
"for writing."
1905 QTextStream cpp( &implementation );
1908 cpp <<
"// This file is generated by kconfig_compiler from " << QFileInfo(inputFilename).fileName() <<
"." << endl;
1909 cpp <<
"// All changes you do to this file will be lost." << endl << endl;
1911 cpp <<
"#include \"" << headerFileName <<
"\"" << endl << endl;
1913 for( it = cfg.sourceIncludes.constBegin(); it != cfg.sourceIncludes.constEnd(); ++it ) {
1914 if ( (*it).startsWith(
'"') )
1915 cpp <<
"#include " << *it << endl;
1917 cpp <<
"#include <" << *it <<
">" << endl;
1920 if ( cfg.sourceIncludes.count() > 0 ) cpp << endl;
1922 if ( cfg.setUserTexts ) cpp <<
"#include <klocale.h>" << endl << endl;
1925 if ( cfg.singleton )
1926 cpp <<
"#include <kglobal.h>" << endl <<
"#include <QtCore/QFile>" << endl << endl;
1927 if ( cfg.singleton && cfgFileNameArg )
1928 cpp <<
"#include <kdebug.h>" << endl << endl;
1930 if ( !cfg.nameSpace.isEmpty() )
1931 cpp <<
"using namespace " << cfg.nameSpace <<
";" << endl << endl;
1939 cpp <<
"class " << cfg.className <<
"Private" << endl;
1941 cpp <<
" public:" << endl;
1942 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
1943 if ( (*itEntry)->group() !=
group ) {
1944 group = (*itEntry)->group();
1946 cpp <<
" // " <<
group << endl;
1948 cpp <<
" " <<
cppType( (*itEntry)->type() ) <<
" " <<
varName( (*itEntry)->name(), cfg );
1949 if ( !(*itEntry)->param().isEmpty() )
1951 cpp <<
QString(
"[%1]").arg( (*itEntry)->paramMax()+1 );
1955 cpp << endl <<
" // items" << endl;
1956 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
1957 cpp <<
" "+cfg.inherits+
"::Item" <<
itemType( (*itEntry)->type() ) <<
" *" <<
itemVar( *itEntry, cfg );
1958 if ( !(*itEntry)->param().isEmpty() ) cpp <<
QString(
"[%1]").arg( (*itEntry)->paramMax()+1 );
1962 cpp <<
" uint " <<
varName(
"settingsChanged", cfg) <<
";" << endl;
1965 cpp <<
"};" << endl << endl;
1970 if ( cfg.singleton ) {
1972 cpp <<
"class " << cfg.className <<
"Helper" << endl;
1974 cpp <<
" public:" << endl;
1975 cpp <<
" " << cfg.className <<
"Helper() : q(0) {}" << endl;
1976 cpp <<
" ~" << cfg.className <<
"Helper() { delete q; }" << endl;
1977 cpp <<
" " << cfg.className <<
" *q;" << endl;
1978 cpp <<
"};" << endl;
1980 cpp <<
"K_GLOBAL_STATIC(" << cfg.className <<
"Helper, s_global" << cfg.className <<
")" << endl;
1982 cpp << cfg.className <<
" *" << cfg.className <<
"::self()" << endl;
1984 if ( cfgFileNameArg ) {
1985 cpp <<
" if (!s_global" << cfg.className <<
"->q)" << endl;
1986 cpp <<
" kFatal() << \"you need to call " << cfg.className <<
"::instance before using\";" << endl;
1988 cpp <<
" if (!s_global" << cfg.className <<
"->q) {" << endl;
1989 cpp <<
" new " << cfg.className <<
';' << endl;
1990 cpp <<
" s_global" << cfg.className <<
"->q->readConfig();" << endl;
1991 cpp <<
" }" << endl << endl;
1993 cpp <<
" return s_global" << cfg.className <<
"->q;" << endl;
1994 cpp <<
"}" << endl << endl;
1996 if ( cfgFileNameArg ) {
1997 cpp <<
"void " << cfg.className <<
"::instance(const QString& cfgfilename)" << endl;
1999 cpp <<
" if (s_global" << cfg.className <<
"->q) {" << endl;
2000 cpp <<
" kDebug() << \"" << cfg.className <<
"::instance called after the first use - ignoring\";" << endl;
2001 cpp <<
" return;" << endl;
2002 cpp <<
" }" << endl;
2003 cpp <<
" new " << cfg.className <<
"(cfgfilename);" << endl;
2004 cpp <<
" s_global" << cfg.className <<
"->q->readConfig();" << endl;
2005 cpp <<
"}" << endl << endl;
2009 if ( !cppPreamble.isEmpty() )
2010 cpp << cppPreamble << endl;
2013 cpp << cfg.className <<
"::" << cfg.className <<
"( ";
2014 if ( cfgFileNameArg ) {
2015 if ( !cfg.singleton && ! cfg.forceStringFilename)
2016 cpp <<
" KSharedConfig::Ptr config";
2018 cpp <<
" const QString& config";
2019 cpp << (parameters.isEmpty() ?
" " :
", ");
2023 it != parameters.constEnd(); ++it)
2025 if (it != parameters.constBegin())
2027 cpp <<
" " <<
param((*it).type) <<
" " << (*it).name;
2029 cpp <<
" )" << endl;
2031 cpp <<
" : " << cfg.inherits <<
"(";
2032 if ( !cfgFileName.isEmpty() ) cpp <<
" QLatin1String( \"" << cfgFileName <<
"\" ";
2033 if ( cfgFileNameArg ) cpp <<
" config ";
2034 if ( !cfgFileName.isEmpty() ) cpp <<
") ";
2039 it != parameters.constEnd(); ++it)
2041 cpp <<
" , mParam" << (*it).name <<
"(" << (*it).name <<
")" << endl;
2044 if ( hasSignals && !cfg.dpointer )
2045 cpp <<
" , " <<
varName(
"settingsChanged", cfg) <<
"(0)" << endl;
2051 cpp <<
" d = new " + cfg.className +
"Private;" << endl;
2053 cpp <<
" " <<
varPath(
"settingsChanged", cfg) <<
" = 0;" << endl;
2057 if (cfg.singleton) {
2058 cpp <<
" Q_ASSERT(!s_global" << cfg.className <<
"->q);" << endl;
2059 cpp <<
" s_global" << cfg.className <<
"->q = this;" << endl;
2064 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
2065 if ( (*itEntry)->group() !=
group ) {
2066 if ( !
group.isEmpty() ) cpp << endl;
2067 group = (*itEntry)->group();
2068 cpp <<
" setCurrentGroup( " <<
paramString(
group, parameters) <<
" );" << endl << endl;
2072 if ( !(*itEntry)->code().isEmpty() ) {
2073 cpp << (*itEntry)->code() << endl;
2075 if ( (*itEntry)->type() ==
"Enum" ) {
2076 cpp <<
" QList<"+cfg.inherits+
"::ItemEnum::Choice2> values"
2077 << (*itEntry)->name() <<
";" << endl;
2080 for( it = choices.constBegin(); it != choices.constEnd(); ++it ) {
2081 cpp <<
" {" << endl;
2082 cpp <<
" "+cfg.inherits+
"::ItemEnum::Choice2 choice;" << endl;
2083 cpp <<
" choice.name = QLatin1String(\"" << (*it).name <<
"\");" << endl;
2084 if ( cfg.setUserTexts ) {
2085 if ( !(*it).label.isEmpty() ) {
2086 cpp <<
" choice.label = ";
2087 if ( !(*it).context.isEmpty() )
2088 cpp <<
"i18nc(" +
quoteString((*it).context) +
", ";
2093 if ( !(*it).toolTip.isEmpty() ) {
2094 cpp <<
" choice.toolTip = ";
2095 if ( !(*it).context.isEmpty() )
2096 cpp <<
"i18nc(" +
quoteString((*it).context) +
", ";
2099 cpp <<
quoteString((*it).toolTip) <<
");" << endl;
2101 if ( !(*it).whatsThis.isEmpty() ) {
2102 cpp <<
" choice.whatsThis = ";
2103 if ( !(*it).context.isEmpty() )
2104 cpp <<
"i18nc(" +
quoteString((*it).context) +
", ";
2107 cpp <<
quoteString((*it).whatsThis) <<
");" << endl;
2110 cpp <<
" values" << (*itEntry)->name() <<
".append( choice );" << endl;
2111 cpp <<
" }" << endl;
2118 if ( (*itEntry)->param().isEmpty() )
2121 cpp <<
" " <<
itemPath( *itEntry, cfg ) <<
" = "
2122 <<
newItem( (*itEntry)->type(), (*itEntry)->name(), key, (*itEntry)->defaultValue(), cfg ) << endl;
2124 if ( !(*itEntry)->minValue().isEmpty() )
2125 cpp <<
" " <<
itemPath( *itEntry, cfg ) <<
"->setMinValue(" << (*itEntry)->minValue() <<
");" << endl;
2126 if ( !(*itEntry)->maxValue().isEmpty() )
2127 cpp <<
" " <<
itemPath( *itEntry, cfg ) <<
"->setMaxValue(" << (*itEntry)->maxValue() <<
");" << endl;
2129 if ( cfg.setUserTexts )
2132 cpp <<
" addItem( " <<
itemPath( *itEntry, cfg );
2133 QString quotedName = (*itEntry)->name();
2135 if ( quotedName != key ) cpp <<
", QLatin1String( \"" << (*itEntry)->name() <<
"\" )";
2136 cpp <<
" );" << endl;
2141 for(
int i = 0; i <= (*itEntry)->paramMax(); i++)
2146 if ( !(*itEntry)->paramDefaultValue(i).isEmpty() )
2147 defaultStr = (*itEntry)->paramDefaultValue(i);
2148 else if ( !(*itEntry)->defaultValue().isEmpty() )
2149 defaultStr =
paramString( (*itEntry)->defaultValue(), (*itEntry), i );
2153 cpp <<
" " << itemVarStr <<
" = "
2154 <<
newItem( (*itEntry)->type(), (*itEntry)->name(),
paramString(key, *itEntry, i), defaultStr,cfg,
QString(
"[%1]").arg(i) )
2157 if ( cfg.setUserTexts )
2164 cpp <<
" addItem( " << itemVarStr <<
", QLatin1String( \"";
2165 if ( (*itEntry)->paramType()==
"Enum" )
2166 cpp << (*itEntry)->paramName().replace(
"$("+(*itEntry)->param()+
')',
"%1").arg((*itEntry)->paramValues()[i] );
2168 cpp << (*itEntry)->paramName().replace(
"$("+(*itEntry)->param()+
')',
"%1").arg(i);
2169 cpp <<
"\" ) );" << endl;
2174 cpp <<
"}" << endl << endl;
2179 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
2180 QString n = (*itEntry)->name();
2181 QString t = (*itEntry)->type();
2184 if (cfg.allMutators || cfg.mutators.contains(n))
2186 cpp <<
"void " <<
setFunction(n, cfg.className) <<
"( ";
2187 if ( !(*itEntry)->param().isEmpty() )
2188 cpp <<
cppType( (*itEntry)->paramType() ) <<
" i, ";
2189 if (cfg.useEnumTypes && t ==
"Enum")
2190 cpp <<
enumType(*itEntry, cfg.globalEnums);
2193 cpp <<
" v )" << endl;
2198 cpp <<
"}" << endl << endl;
2202 if (cfg.useEnumTypes && t ==
"Enum")
2203 cpp <<
enumType(*itEntry, cfg.globalEnums);
2206 cpp <<
" " <<
getFunction(n, cfg.className) <<
"(";
2207 if ( !(*itEntry)->param().isEmpty() )
2208 cpp <<
" " <<
cppType( (*itEntry)->paramType() ) <<
" i ";
2209 cpp <<
")" << Const << endl;
2214 cpp <<
"}" << endl << endl;
2219 if ( cfg.itemAccessors )
2222 cpp << cfg.inherits+
"::Item" <<
itemType( (*itEntry)->type() ) <<
" *"
2224 if ( !(*itEntry)->param().isEmpty() ) {
2225 cpp <<
" " <<
cppType( (*itEntry)->paramType() ) <<
" i ";
2238 for( itEntry = entries.constBegin(); itEntry != entries.constEnd(); ++itEntry ) {
2239 QString n = (*itEntry)->name();
2240 QString t = (*itEntry)->type();
2243 if (( cfg.allDefaultGetters || cfg.defaultGetters.contains(n) ) && !(*itEntry)->defaultValue().isEmpty() ) {
2245 if ( !(*itEntry)->param().isEmpty() )
2246 cpp <<
" " <<
cppType( (*itEntry)->paramType() ) <<
" i ";
2247 cpp <<
")" << Const << endl;
2250 cpp <<
"}" << endl << endl;
2255 cpp << cfg.className <<
"::~" << cfg.className <<
"()" << endl;
2257 if ( cfg.singleton ) {
2259 cpp <<
" delete d;" << endl;
2260 cpp <<
" if (!s_global" << cfg.className <<
".isDestroyed()) {" << endl;
2261 cpp <<
" s_global" << cfg.className <<
"->q = 0;" << endl;
2262 cpp <<
" }" << endl;
2264 cpp <<
"}" << endl << endl;
2267 cpp <<
"void " << cfg.className <<
"::" <<
"usrWriteConfig()" << endl;
2269 cpp <<
" " << cfg.inherits <<
"::usrWriteConfig();" << endl << endl;
2270 foreach(
const Signal &signal, signalList) {
2271 cpp <<
" if ( " <<
varPath(
"settingsChanged", cfg) <<
" & " <<
signalEnumName(signal.name) <<
" ) " << endl;
2272 cpp <<
" emit " << signal.name <<
"(";
2274 for ( it = signal.arguments.constBegin(); it != itEnd; ) {
2275 SignalArguments argument = *it;
2277 if ( cfg.useEnumTypes && argument.type ==
"Enum" ) {
2278 for (
int i = 0, end = entries.count(); i < end; ++i ) {
2279 if ( entries[i]->name() == argument.variableName ) {
2280 cpp <<
"static_cast<" <<
enumType(entries[i], cfg.globalEnums) <<
">(";
2286 cpp <<
varPath(argument.variableName, cfg);
2289 if ( ++it != itEnd )
2292 cpp <<
");" << endl << endl;
2294 cpp <<
" " <<
varPath(
"settingsChanged", cfg) <<
" = 0;" << endl;
2301 cpp <<
"#include \"" << mocFileName <<
"\"" << endl;
2306 qDeleteAll( entries );
2308 implementation.close();