/* Copyright (C) 2004-2005 ian reinhart geiser */ #include #include #include #include #include #include #include #include #include #include #include #include #include static const char classHeader[] = "/**\n" "* This file was autogenerated by makekdewidgets. Any changes will be lost!\n" "* The generated code in this file is licensed under the same license that the\n" "* input file.\n" "*/\n" "#include \n" "#include \n" "#include \n" "#include \n" "#include \n"; static const char collClassDef[] = "class %CollName : public QObject, public QDesignerCustomWidgetCollectionInterface\n" "{\n" " Q_OBJECT\n" " Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)\n" "public:\n" " %CollName(QObject *parent = 0);\n" " virtual ~%CollName() {}\n" " QList customWidgets() const { return m_plugins; } \n" " \n" "private:\n" " QList m_plugins;\n" "};\n\n" "Q_EXPORT_PLUGIN2(%CollName, %CollName)\n\n"; static const char collClassImpl[] = "%CollName::%CollName(QObject *parent)\n" " : QObject(parent)" "{\n" " (void) new KComponentData(\"makekdewidgets\");\n" "%CollectionAdd\n" "}\n\n"; static const char classDef[] = "class %PluginName : public QObject, public QDesignerCustomWidgetInterface\n" "{\n" " Q_OBJECT\n" " Q_INTERFACES(QDesignerCustomWidgetInterface)\n" "public:\n" " %PluginName(QObject *parent = 0) :\n\t\tQObject(parent), mInitialized(false) {}\n" " virtual ~%PluginName() {}\n" " \n" " bool isContainer() const { return %IsContainer; }\n" " bool isInitialized() const { return mInitialized; }\n" " QIcon icon() const { return QIcon(QLatin1String(\"%IconName\")); }\n" " QString codeTemplate() const { return QLatin1String(\"%CodeTemplate\");}\n" " QString domXml() const { return %DomXml; }\n" " QString group() const { return QLatin1String(\"%Group\"); }\n" " QString includeFile() const { return QLatin1String(\"%IncludeFile\"); }\n" " QString name() const { return QLatin1String(\"%Class\"); }\n" " QString toolTip() const { return QLatin1String(\"%ToolTip\"); }\n" " QString whatsThis() const { return QLatin1String(\"%WhatsThis\"); }\n\n" " QWidget* createWidget( QWidget* parent ) \n\t{%CreateWidget\n\t}\n" " void initialize(QDesignerFormEditorInterface *core) \n\t{%Initialize\n\t}\n" "\n" "private:\n" " bool mInitialized;\n" "};\n\n"; static QString denamespace ( const QString &str ); static QString buildCollClass( KSettings &input, const QStringList& classes ); static QString buildWidgetClass( const QString &name, KSettings &input, const QString &group ); static QString buildWidgetInclude( const QString &name, KSettings &input ); static void buildFile( QTextStream &stream, const QString& group, const QString& fileName, const QString& pluginName ); int main( int argc, char **argv ) { new KComponentData( "makekdewidgets" ); KLocalizedString description = ki18n( "Builds Qt widget plugins from an ini style description file." ); const char version[] = "0.4"; KCmdLineOptions options; options.add("+file", ki18n( "Input file" ) ); options.add("o ", ki18n( "Output file" ) ); options.add("n ", ki18n( "Name of the plugin class to generate" ), "WidgetsPlugin" ); options.add("g ", ki18n( "Default widget group name to display in designer" ), "Custom" ); KAboutData about( "makekdewidgets", 0, ki18n( "makekdewidgets" ), version, description, KAboutData::License_GPL, ki18n("(C) 2004-2005 Ian Reinhart Geiser"), KLocalizedString(), 0, "geiseri@kde.org" ); about.addAuthor( ki18n("Ian Reinhart Geiser"), KLocalizedString(), "geiseri@kde.org" ); about.addAuthor( ki18n("Daniel Molkentin"), KLocalizedString(), "molkentin@kde.org" ); KCmdLineArgs::init( argc, argv, &about ); KCmdLineArgs::addCmdLineOptions( options ); KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); if ( args->count() < 1 ) { args->usage(); return ( 1 ); } QFileInfo fi( args->arg( args->count() - 1 ) ); QString outputFile = args->getOption( "o" ); QString pluginName = args->getOption( "n" ); QString group = args->getOption( "g" ); QString fileName = fi.absoluteFilePath(); if ( args->isSet( "o" ) ) { QFile output( outputFile ); if ( output.open( QIODevice::WriteOnly ) ) { QTextStream ts( &output ); buildFile( ts, group, fileName , pluginName ); QString mocFile = output.fileName(); mocFile.replace(".cpp", ".moc"); ts << QString( "#include <%1>\n" ).arg(mocFile) << endl; } output.close(); } else { QTextStream ts( stdout, QIODevice::WriteOnly ); buildFile( ts, group, fileName , pluginName ); } } void buildFile( QTextStream &ts, const QString& group, const QString& fileName, const QString& pluginName ) { KSettings input( fileName, KSettings::SimpleConfig ); QHash MainMap; MainMap.insert( "PluginName", input.value( "Global/PluginName", pluginName ).toString() ); MainMap.insert( "PluginNameLower", input.value( "Global/PluginName", pluginName ).toString().toLower() ); MainMap.insert( "Init", input.value( "Global/Init" ).toString() ); MainMap.insert( "Destroy", input.value( "Global/Destroy" ).toString() ); ts << classHeader << endl; QStringList includes = input.value( "Global/Includes" ).toStringList(); QStringList classes; #ifndef QT_KATIE foreach (const QString &key, input.allKeys()) { const QString &klass = key.split('/').at(0); if (classes.contains(klass)) continue; classes.append(klass); } #else foreach (const QString &key, input.keys()) { const QString klass = key.split('/').at(0); if (classes.contains(klass)) continue; classes.append(klass); } #endif classes.removeAll( "Global" ); foreach ( const QString &myInclude, classes ) { includes += buildWidgetInclude( myInclude, input ); } foreach ( const QString &myInclude, includes) { ts << "#include <" << myInclude << ">" << endl; } ts << QLatin1String("\n\n"); // Autogenerate widget defs here foreach ( const QString &myClass, classes ) { ts << buildWidgetClass( myClass, input, group ) << endl; } ts << buildCollClass( input, classes ); } QString denamespace ( const QString &str ) { QString denamespaced = str; denamespaced.remove("::"); return denamespaced; } QString buildCollClass( KSettings &input, const QStringList& classes ) { QHash defMap; defMap.insert( "CollName", input.value( "Global/PluginName" ).toString() ); QString genCode; foreach ( const QString &myClass, classes ) { genCode += QString("\t\tm_plugins.append( new %1(this) );\n").arg(denamespace( myClass ) +"Plugin"); } defMap.insert( "CollectionAdd", genCode ); QString str = KMacroExpander::expandMacros(collClassDef, defMap); str += KMacroExpander::expandMacros(collClassImpl, defMap); return str; } QString buildWidgetClass( const QString &name, KSettings &input, const QString &group ) { QHash defMap; defMap.insert( "Group", input.value( name + "/Group", group ).toString().replace( '\"', "\\\"" ) ); defMap.insert( "IconSet", input.value( name + "/IconSet", QString(name.toLower() + ".png") ).toString().replace( ':', '_' ) ); defMap.insert( "Pixmap", name.toLower().replace( ':', '_' ) + "_xpm" ); defMap.insert( "IncludeFile", input.value( name + "/IncludeFile", QString(name.toLower() + ".h") ).toString().remove( ':' ) ); defMap.insert( "ToolTip", input.value( name + "/ToolTip", QString(name + " Widget") ).toString().replace( '\"', "\\\"" ) ); defMap.insert( "WhatsThis", input.value( name + "/WhatsThis", QString(name + " Widget") ).toString().replace( '\"', "\\\"" ) ); defMap.insert( "IsContainer", input.value( name + "/IsContainer", "false" ).toString() ); defMap.insert( "IconName", input.value( name + "/IconName", QString::fromLatin1(":/pics/%1.png").arg( denamespace( name ).toLower() ) ).toString() ); defMap.insert( "Class", name ); defMap.insert( "PluginName", denamespace( name ) + QLatin1String( "Plugin" ) ); // FIXME: ### make this more useful, i.e. outsource to separate file QString domXml = input.value( name + "/DomXML").toString(); // If domXml is empty then we shoud call base class function if ( domXml.isEmpty() ) { domXml = QLatin1String("QDesignerCustomWidgetInterface::domXml()"); } else { // Wrap domXml value into QLatin1String domXml = QString(QLatin1String("QLatin1String(\"%1\")")).arg(domXml.replace( '\"', "\\\"" )); } defMap.insert( "DomXml", domXml ); defMap.insert( "CodeTemplate", input.value( name + "/CodeTemplate" ).toString() ); defMap.insert( "CreateWidget", input.value( name + "/CreateWidget", QString( "\n\t\treturn new %1%2;" ) .arg( input.value( name + "/ImplClass", name ).toString() ) .arg( input.value( name + "/ConstructorArgs", "( parent )" ).toString() ) ).toString() ); defMap.insert( "Initialize", input.value( name + "/Initialize", "\n\t\tQ_UNUSED(core);\n\t\tif (mInitialized) return;\n\t\tmInitialized=true;" ).toString() ); return KMacroExpander::expandMacros( classDef, defMap ); } QString buildWidgetInclude( const QString &name, KSettings &input ) { return input.value( name + "/IncludeFile", QVariant(name.toLower() + ".h") ).toString(); }