summaryrefslogtreecommitdiffstats
path: root/qtruby/rubylib/designer/rbuic/uic.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'qtruby/rubylib/designer/rbuic/uic.cpp')
-rw-r--r--qtruby/rubylib/designer/rbuic/uic.cpp1104
1 files changed, 1104 insertions, 0 deletions
diff --git a/qtruby/rubylib/designer/rbuic/uic.cpp b/qtruby/rubylib/designer/rbuic/uic.cpp
new file mode 100644
index 00000000..e4f8eed7
--- /dev/null
+++ b/qtruby/rubylib/designer/rbuic/uic.cpp
@@ -0,0 +1,1104 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+** Copyright (c) 2001 Phil Thompson <phil@river-bank.demon.co.uk>
+** Copyright (c) 2002 Germain Garand <germain@ebooksfrance.com>
+**
+** This file is part of Qt Designer.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+/*
+** 06/2002 : Initial release of puic, the PerlQt User Interface Compiler,
+** a work derivated from uic (the Qt User Interface Compiler)
+** and pyuic (the PyQt User Interface Compiler).
+**
+** G.Garand
+**
+** 08/2003 : Initial release of rbuic, the QtRuby User Interface Compiler,
+** a work derived from the PerlQt puic.
+**
+** Richard Dale
+**
+**********************************************************************/
+
+#include "uic.h"
+#include "parser.h"
+#include "widgetdatabase.h"
+#include "domtool.h"
+#include <qfile.h>
+#include <qstringlist.h>
+#include <qdatetime.h>
+#define NO_STATIC_COLORS
+#include <globaldefs.h>
+#include <qregexp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <zlib.h>
+
+bool Uic::hasKDEwidget = false;
+bool Uic::isMainWindow = false;
+RubyIndent Uic::indent;
+
+
+// Re-calculate the indent string based on the current number and nature of the
+// indent.
+void RubyIndent::calc()
+{
+ indstr.truncate(0);
+
+ for (uint i = current; i > 0; --i)
+ if (tabStop == 0)
+ indstr += '\t';
+ else
+ for (uint t = 0; t < tabStop; ++t)
+ indstr += ' ';
+}
+
+
+QString Uic::getComment( const QDomNode& n )
+{
+ QDomNode child = n.firstChild();
+ while ( !child.isNull() ) {
+ if ( child.toElement().tagName() == "comment" )
+ return child.toElement().firstChild().toText().data();
+ child = child.nextSibling();
+ }
+ return QString::null;
+}
+
+QString Uic::mkBool( bool b )
+{
+ return b? "true" : "false";
+}
+
+QString Uic::mkBool( const QString& s )
+{
+ return mkBool( s == "true" || s == "1" );
+}
+
+bool Uic::toBool( const QString& s )
+{
+ return s == "true" || s.toInt() != 0;
+}
+
+QString Uic::fixString( const QString &str )
+{
+ QString s( str );
+ s.replace( QRegExp( "\\\\" ), "\\\\" );
+ s.replace( QRegExp( "\"" ), "\\\"" );
+ s.replace( QRegExp( "\r?\n" ), "\\n\" +\n" + indent + "\"" );
+ return "\"" + s + "\"";
+}
+
+QString Uic::trcall( const QString& sourceText, const QString& comment )
+{
+ if ( sourceText.isEmpty() && comment.isEmpty() )
+ return "nil";
+
+ if ( comment.isEmpty() )
+ return trmacro + "(" + fixString( sourceText ) + ")";
+ return trmacro + "(" + fixString( sourceText ) + "," + fixString( comment ) + ")";
+}
+
+QString Uic::mkStdSet( const QString& prop )
+{
+ return QString( "set" ) + prop[0].upper() + prop.mid(1);
+}
+
+
+
+bool Uic::isEmptyFunction( const QString& fname )
+{
+ QMap<QString, QString>::Iterator fit = functionImpls.find( Parser::cleanArgs( fname ) );
+ if ( fit != functionImpls.end() ) {
+ int begin = (*fit).find( "{" );
+ QString body = (*fit).mid( begin + 1, (*fit).findRev( "}" ) - begin - 1 );
+ return body.simplifyWhiteSpace().isEmpty();
+ }
+ // For now ruby functions are always empty, until a rubyeditor Qt Designer plugin exists..
+ return true;
+}
+
+
+
+/*!
+ \class Uic uic.h
+ \brief User Interface Compiler
+
+ The class Uic encapsulates the user interface compiler (uic).
+ */
+Uic::Uic( const QString &fn, QTextStream &outStream, QDomDocument doc,
+ bool subcl, const QString &trm, const QString& subClass,
+ bool omitForwardDecls, QString &uicClass, bool useKDE )
+ : out( outStream ), trout( &languageChangeBody ),
+ trmacro( trm ), nofwd( omitForwardDecls )
+{
+ Uic::hasKDEwidget = useKDE;
+ fileName = fn;
+ writeSlotImpl = true;
+ defMargin = BOXLAYOUT_DEFAULT_MARGIN;
+ defSpacing = BOXLAYOUT_DEFAULT_SPACING;
+ externPixmaps = false;
+
+ item_used = cg_used = pal_used = 0;
+
+ layouts << "hbox" << "vbox" << "grid";
+ tags = layouts;
+ tags << "widget";
+
+ pixmapLoaderFunction = getPixmapLoaderFunction( doc.firstChild().toElement() );
+ nameOfClass = getFormClassName( doc.firstChild().toElement() );
+
+ uiFileVersion = doc.firstChild().toElement().attribute("version");
+ stdsetdef = toBool( doc.firstChild().toElement().attribute("stdsetdef") );
+
+ QDomElement e = doc.firstChild().firstChild().toElement();
+ QDomElement widget;
+ while ( !e.isNull() ) {
+ if ( e.tagName() == "widget" ) {
+ widget = e;
+ } else if ( e.tagName() == "pixmapinproject" ) {
+ externPixmaps = true;
+ } else if ( e.tagName() == "layoutdefaults" ) {
+ defSpacing = e.attribute( "spacing", QString::number( defSpacing ) ).toInt();
+ defMargin = e.attribute( "margin", QString::number( defMargin ) ).toInt();
+ }
+ e = e.nextSibling().toElement();
+ }
+ e = widget;
+
+ if ( nameOfClass.isEmpty() )
+ nameOfClass = getObjectName( e );
+
+ uicClass = nameOfClass;
+
+ if ( subcl ) {
+ createSubImpl( e, subClass );
+ } else {
+ createFormImpl( e );
+ }
+}
+
+/*! Extracts a pixmap loader function from \a e
+ */
+QString Uic::getPixmapLoaderFunction( const QDomElement& e )
+{
+ QDomElement n;
+ for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) {
+ if ( n.tagName() == "pixmapfunction" )
+ return n.firstChild().toText().data();
+ }
+ return QString::null;
+}
+
+
+/*! Extracts the forms class name from \a e
+ */
+QString Uic::getFormClassName( const QDomElement& e )
+{
+ QDomElement n;
+ QString cn;
+ for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) {
+ if ( n.tagName() == "class" ) {
+ QString s = n.firstChild().toText().data();
+ int i;
+ while ( ( i = s.find(' ' )) != -1 )
+ s[i] = '_';
+ cn = s;
+ }
+ }
+ return cn;
+}
+
+/*! Extracts a Ruby class name from \a e.
+ */
+QString Uic::getClassName( const QDomElement& e )
+{
+ QString s = e.attribute( "class" );
+ if ( s.isEmpty() && e.tagName() == "toolbar" )
+ s = "Qt::ToolBar";
+ else if ( s.isEmpty() && e.tagName() == "menubar" )
+ s = "Qt::MenuBar";
+ else
+ {
+ QRegExp r("^([QK])(\\S+)");
+ if( r.search( s ) != -1 ) {
+ if (r.cap(1) == "K") {
+ hasKDEwidget = true;
+ s = "KDE::" + r.cap(2);
+ } else {
+ if (s.startsWith("Qext")) {
+ s = "Qext::" + r.cap(2).mid(4);
+ } else {
+ s = "Qt::" + r.cap(2);
+ }
+ }
+ }
+ }
+ return s;
+}
+
+
+
+/*! Returns TRUE if database framework code is generated, else FALSE.
+*/
+
+bool Uic::isFrameworkCodeGenerated( const QDomElement& e )
+{
+ QDomElement n = getObjectProperty( e, "frameworkCode" );
+ if ( n.attribute("name") == "frameworkCode" &&
+ !DomTool::elementToVariant( n.firstChild().toElement(), QVariant( true, 0 ) ).toBool() )
+ return false;
+ return true;
+}
+
+/*! Extracts an object name from \a e. It's stored in the 'name'
+ property.
+ */
+QString Uic::getObjectName( const QDomElement& e )
+{
+ QDomElement n = getObjectProperty( e, "name" );
+ if ( n.firstChild().toElement().tagName() == "cstring" )
+ return n.firstChild().toElement().firstChild().toText().data();
+ return QString::null;
+}
+
+/*! Extracts an layout name from \a e. It's stored in the 'name'
+ property of the preceeding sibling (the first child of a QLayoutWidget).
+ */
+QString Uic::getLayoutName( const QDomElement& e )
+{
+ QDomElement p = e.parentNode().toElement();
+ QString tail = QString::null;
+
+ if ( getClassName(p) != "Qt::LayoutWidget" )
+ tail = "Layout";
+
+ QDomElement n = getObjectProperty( p, "name" );
+ if ( n.firstChild().toElement().tagName() == "cstring" )
+ return n.firstChild().toElement().firstChild().toText().data() + tail;
+ return e.tagName();
+}
+
+
+QString Uic::getDatabaseInfo( const QDomElement& e, const QString& tag )
+{
+ QDomElement n;
+ QDomElement n1;
+ int child = 0;
+ // database info is a stringlist stored in this order
+ if ( tag == "connection" )
+ child = 0;
+ else if ( tag == "table" )
+ child = 1;
+ else if ( tag == "field" )
+ child = 2;
+ else
+ return QString::null;
+ n = getObjectProperty( e, "database" );
+ if ( n.firstChild().toElement().tagName() == "stringlist" ) {
+ // find correct stringlist entry
+ QDomElement n1 = n.firstChild().firstChild().toElement();
+ for ( int i = 0; i < child && !n1.isNull(); ++i )
+ n1 = n1.nextSibling().toElement();
+ if ( n1.isNull() )
+ return QString::null;
+ return n1.firstChild().toText().data();
+ }
+ return QString::null;
+}
+
+
+void Uic::registerLayouts( const QDomElement &e )
+{
+ if ( layouts.contains(e.tagName()) )
+ createObjectDecl(e);
+
+ QDomNodeList nl = e.childNodes();
+ for ( int i = 0; i < (int) nl.length(); ++i )
+ registerLayouts( nl.item(i).toElement() );
+}
+
+
+/*!
+ Returns include file for class \a className or a null string.
+ */
+QString Uic::getInclude( const QString& className )
+{
+ int wid = WidgetDatabase::idFromClassName( className );
+ if ( wid != -1 )
+ return WidgetDatabase::includeFile( wid );
+ return QString::null;
+}
+
+void Uic::createActionDecl( const QDomElement& e )
+{
+ QString objName = getObjectName( e );
+ if ( objName.isEmpty() )
+ return;
+ out << indent << objName << endl;
+ if ( e.tagName() == "actiongroup" ) {
+ for ( QDomElement n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) {
+ if ( n.tagName() == "action" || n.tagName() == "actiongroup" )
+ createActionDecl( n );
+ }
+ }
+}
+
+void Uic::createActionImpl( const QDomElement &n, const QString &parent )
+{
+ for ( QDomElement ae = n; !ae.isNull(); ae = ae.nextSibling().toElement() ) {
+ QString objName = registerObject( getObjectName( ae ) );
+ if ( ae.tagName() == "action" )
+ out << indent << objName << "= Qt::Action.new(" << parent << ", \"" << objName.mid(1) << "\")" << endl;
+ else if ( ae.tagName() == "actiongroup" )
+ out << indent << objName << "= Qt::ActionGroup.new(" << parent << ", \"" << objName.mid(1) << "\")" << endl;
+ else
+ continue;
+ bool subActionsDone = false;
+ bool hasMenuText = false;
+ QString actionText;
+ for ( QDomElement n2 = ae.firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) {
+ if ( n2.tagName() == "property" ) {
+ bool stdset = stdsetdef;
+ if ( n2.hasAttribute( "stdset" ) )
+ stdset = toBool( n2.attribute( "stdset" ) );
+ QString prop = n2.attribute("name");
+ if ( prop == "name" )
+ continue;
+ QString value = setObjectProperty( "Qt::Action", objName, prop, n2.firstChild().toElement(), stdset );
+ if ( value.isEmpty() )
+ continue;
+
+ QString call = objName + ".";
+ if ( stdset ) {
+ call += mkStdSet( prop ) + "(" + value + ")";
+ } else {
+ call += "setProperty( \"" + prop + "\", ";
+ call += "Qt::Variant.new(" + value + "))";
+ }
+
+ if (prop == "menuText")
+ hasMenuText = true;
+ else if (prop == "text")
+ actionText = value;
+
+ if ( n2.firstChild().toElement().tagName() == "string" ) {
+ trout << indent << call << endl;
+ } else {
+ out << indent << call << endl;
+ }
+ } else if ( !subActionsDone && ( n2.tagName() == "actiongroup" || n2.tagName() == "action" ) ) {
+ createActionImpl( n2, objName );
+ subActionsDone = true;
+ }
+ }
+ // workaround for loading pre-3.3 files expecting bogus QAction behavior
+ if (!hasMenuText && !actionText.isEmpty() && uiFileVersion < "3.3")
+ trout << indent << objName << ".setMenuText(" << actionText << ")" << endl;
+ }
+}
+
+QString get_dock( const QString &d )
+{
+ if ( d == "0" )
+ return "DockUnmanaged";
+ if ( d == "1" )
+ return "DockTornOff";
+ if ( d == "2" )
+ return "DockTop";
+ if ( d == "3" )
+ return "DockBottom";
+ if ( d == "4" )
+ return "DockRight";
+ if ( d == "5" )
+ return "DockLeft";
+ if ( d == "6" )
+ return "DockMinimized";
+ return "";
+}
+
+void Uic::createToolbarImpl( const QDomElement &n, const QString &parentClass, const QString &parent )
+{
+ QDomNodeList nl = n.elementsByTagName( "toolbar" );
+ for ( int i = 0; i < (int) nl.length(); i++ ) {
+ QDomElement ae = nl.item( i ).toElement();
+ QString dock = get_dock( ae.attribute( "dock" ) );
+ QString objName = "@" + getObjectName( ae );
+ out << indent << objName << " = Qt::ToolBar.new(\"\", self, " << dock << ")" << endl;
+ createObjectImpl( ae, parentClass, parent );
+ for ( QDomElement n2 = ae.firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) {
+ if ( n2.tagName() == "action" ) {
+ out << indent << "@" << n2.attribute( "name" ) << ".addTo( " << objName << " )" << endl;
+ } else if ( n2.tagName() == "separator" ) {
+ out << indent << objName << ".addSeparator;" << endl;
+ } else if ( n2.tagName() == "widget" ) {
+ if ( n2.attribute( "class" ) != "Spacer" ) {
+ createObjectImpl( n2, "Qt::ToolBar", objName );
+ } else {
+ QString child = createSpacerImpl( n2, parentClass, parent, objName );
+ out << indent << "Qt::Application.sendPostedEvents( " << objName
+ << ", Qt::Event::ChildInserted)" << endl;
+ out << indent << objName << ".boxLayout().addItem(" << child << ")" << endl;
+ }
+ }
+ }
+ }
+}
+
+void Uic::createMenuBarImpl( const QDomElement &n, const QString &parentClass, const QString &parent )
+{
+ QString objName = "@" + getObjectName( n );
+ out << indent << objName << " = Qt::MenuBar.new( self, \"" << objName.mid(1) << "\" )" << endl;
+ createObjectImpl( n, parentClass, parent );
+ int i = 0;
+ QDomElement c = n.firstChild().toElement();
+ while ( !c.isNull() ) {
+ if ( c.tagName() == "item" ) {
+ QString itemName = "@" + c.attribute( "name" );
+ out << endl;
+ out << indent << itemName << " = Qt::PopupMenu.new( self )" << endl;
+ createPopupMenuImpl( c, parentClass, itemName );
+ out << indent << objName << ".insertItem( \"\", " << itemName << ", " << i << " )" << endl;
+ QString findItem(objName + ".findItem(%1)");
+ findItem = findItem.arg(i);
+ trout << indent << "if !" << findItem << ".nil?" << endl;
+ trout << indent << indent << findItem << ".setText( " << trcall( c.attribute( "text" ) ) << " )" << endl;
+ trout << indent << "end" << endl;
+ } else if ( c.tagName() == "separator" ) {
+ out << endl;
+ out << indent << objName << ".insertSeparator( " << i << " )" << endl;
+ }
+ c = c.nextSibling().toElement();
+ i++;
+ }
+}
+
+void Uic::createPopupMenuImpl( const QDomElement &e, const QString &parentClass, const QString &parent )
+{
+ int i = 0;
+ for ( QDomElement n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) {
+ if ( n.tagName() == "action" || n.tagName() == "actiongroup" ) {
+ QDomElement n2 = n.nextSibling().toElement();
+ if ( n2.tagName() == "item" ) { // the action has a sub menu
+ QString itemName = "@" + n2.attribute( "name" );
+ QString itemText = n2.attribute( "text" );
+ out << indent << itemName << " = Qt::PopupMenu.new( self )" << endl;
+ out << indent << indent << parent << ".insertItem( @" << n.attribute( "name" ) << ".iconSet(),";
+ out << trcall( itemText ) << ", " << itemName << " )" << endl;
+ trout << indent << parent << ".changeItem( " << parent << ".idAt( " << i << " ), ";
+ trout << trcall( itemText ) << " )" << endl;
+ createPopupMenuImpl( n2, parentClass, itemName );
+ n = n2;
+ } else {
+ out << indent << "@" << n.attribute( "name" ) << ".addTo( " << parent << " )" << endl;
+ }
+ } else if ( n.tagName() == "separator" ) {
+ out << indent << parent << ".insertSeparator()" << endl;
+ }
+ ++i;
+ }
+}
+
+/*!
+ Creates implementation of an listbox item tag.
+*/
+
+QString Uic::createListBoxItemImpl( const QDomElement &e, const QString &parent,
+ QString *value )
+{
+ QDomElement n = e.firstChild().toElement();
+ QString txt;
+ QString com;
+ QString pix;
+ while ( !n.isNull() ) {
+ if ( n.tagName() == "property" ) {
+ QString attrib = n.attribute("name");
+ QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() );
+ if ( attrib == "text" ) {
+ txt = v.toString();
+ com = getComment( n );
+ } else if ( attrib == "pixmap" ) {
+ pix = v.toString();
+ if (!pix.isEmpty()) {
+ pix.prepend("@");
+ }
+ if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) {
+ pix.prepend( pixmapLoaderFunction + "(" + QString( externPixmaps ? "\"" : "" ) );
+ pix.append( QString( externPixmaps ? "\"" : "" ) + ")" );
+ }
+ }
+ }
+ n = n.nextSibling().toElement();
+ }
+
+ if ( value )
+ *value = trcall( txt, com );
+
+ if ( pix.isEmpty() )
+ return parent + ".insertItem(" + trcall( txt, com ) + ")";
+
+ return parent + ".insertItem(" + pix + ", " + trcall( txt, com ) + ")";
+}
+
+/*!
+ Creates implementation of an iconview item tag.
+*/
+
+QString Uic::createIconViewItemImpl( const QDomElement &e, const QString &parent )
+{
+ QDomElement n = e.firstChild().toElement();
+ QString txt;
+ QString com;
+ QString pix;
+ while ( !n.isNull() ) {
+ if ( n.tagName() == "property" ) {
+ QString attrib = n.attribute("name");
+ QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() );
+ if ( attrib == "text" ) {
+ txt = v.toString();
+ com = getComment( n );
+ } else if ( attrib == "pixmap" ) {
+ pix = v.toString();
+ if (!pix.isEmpty()) {
+ pix.prepend("@");
+ }
+ if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) {
+ pix.prepend( pixmapLoaderFunction + "(" + QString( externPixmaps ? "\"" : "" ) );
+ pix.append( QString( externPixmaps ? "\"" : "" ) + ")" );
+ }
+ }
+ }
+ n = n.nextSibling().toElement();
+ }
+
+ if ( pix.isEmpty() )
+ return "Qt::IconViewItem.new(" + parent + ", " + trcall( txt, com ) + ")";
+ else
+ return "Qt::IconViewItem.new(" + parent + ", " + trcall( txt, com ) + ", " + pix + ")";
+}
+
+/*!
+ Creates implementation of an listview item tag.
+*/
+
+QString Uic::createListViewItemImpl( const QDomElement &e, const QString &parent,
+ const QString &parentItem )
+{
+ QString s;
+
+ QDomElement n = e.firstChild().toElement();
+
+ bool hasChildren = e.elementsByTagName( "item" ).count() > 0;
+ QString item;
+
+ if ( hasChildren ) {
+ item = registerObject( "item" );
+ s = indent + item + " = ";
+ } else {
+ if (! item_used) {
+ // This is here to make the ruby generated names for 'item',
+ // the same as the original C++
+ item = registerObject( "item" );
+ item_used = true;
+ }
+ item = "item";
+ s = indent + item + " = ";
+ }
+
+ if ( !parentItem.isEmpty() )
+ s += "Qt::ListViewItem.new(" + parentItem + ", " + lastItem + ")\n";
+ else
+ s += "Qt::ListViewItem.new(" + parent + ", " + lastItem + ")\n";
+
+ QStringList textes;
+ QStringList pixmaps;
+ while ( !n.isNull() ) {
+ if ( n.tagName() == "property" ) {
+ QString attrib = n.attribute("name");
+ QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() );
+ if ( attrib == "text" )
+ textes << v.toString();
+ else if ( attrib == "pixmap" ) {
+ QString pix = v.toString();
+ if (!pix.isEmpty()) {
+ pix.prepend("@");
+ }
+ if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) {
+ pix.prepend( pixmapLoaderFunction + "(" + QString( externPixmaps ? "\"" : "" ) );
+ pix.append( QString( externPixmaps ? "\"" : "" ) + ")" );
+ }
+ pixmaps << pix;
+ }
+ } else if ( n.tagName() == "item" ) {
+ s += indent + item + ".setOpen(true)\n";
+ s += createListViewItemImpl( n, parent, item );
+ }
+ n = n.nextSibling().toElement();
+ }
+
+ for ( int i = 0; i < (int)textes.count(); ++i ) {
+ if ( !textes[ i ].isEmpty() )
+ s += indent + item + ".setText(" + QString::number( i ) + ", " + trcall( textes[ i ] ) + ")\n";
+ if ( !pixmaps[ i ].isEmpty() )
+ s += indent + item + ".setPixmap(" + QString::number( i ) + ", " + pixmaps[ i ] + ")\n";
+ }
+
+ lastItem = item;
+ return s;
+}
+
+/*!
+ Creates implementation of an listview column tag.
+*/
+
+QString Uic::createListViewColumnImpl( const QDomElement &e, const QString &parent,
+ QString *value )
+{
+ QDomElement n = e.firstChild().toElement();
+ QString txt;
+ QString com;
+ QString pix;
+ bool clickable = false, resizeable = false;
+ while ( !n.isNull() ) {
+ if ( n.tagName() == "property" ) {
+ QString attrib = n.attribute("name");
+ QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() );
+ if ( attrib == "text" ) {
+ txt = v.toString();
+ com = getComment( n );
+ } else if ( attrib == "pixmap" ) {
+ pix = v.toString();
+ if (!pix.isEmpty()) {
+ pix.prepend("@");
+ }
+ if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) {
+ pix.prepend( pixmapLoaderFunction + "(" + QString( externPixmaps ? "\"" : "" ) );
+ pix.append( QString( externPixmaps ? "\"" : "" ) + ")" );
+ }
+ } else if ( attrib == "clickable" )
+ clickable = v.toBool();
+ else if ( attrib == "resizable" || attrib == "resizeable" )
+ resizeable = v.toBool();
+ }
+ n = n.nextSibling().toElement();
+ }
+
+ if ( value )
+ *value = trcall( txt, com );
+
+ QString s;
+ s = indent + parent + ".addColumn(" + trcall( txt, com ) + ")\n";
+ if ( !pix.isEmpty() )
+ s += indent + parent + ".header().setLabel(" + parent + ".header().count() - 1," + pix + ", " + trcall( txt, com ) + ")\n";
+ if ( !clickable )
+ s += indent + parent + ".header().setClickEnabled( false, " + parent + ".header().count() - 1 )\n";
+ if ( !resizeable )
+ s += indent + parent + ".header().setResizeEnabled( false, " + parent + ".header().count() - 1 )\n";
+
+ return s;
+}
+
+QString Uic::createTableRowColumnImpl( const QDomElement &e, const QString &parent,
+ QString *value )
+{
+ QString objClass = getClassName( e.parentNode().toElement() );
+ QDomElement n = e.firstChild().toElement();
+ QString txt;
+ QString com;
+ QString pix;
+ QString field;
+ bool isRow = e.tagName() == "row";
+ while ( !n.isNull() ) {
+ if ( n.tagName() == "property" ) {
+ QString attrib = n.attribute("name");
+ QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() );
+ if ( attrib == "text" ) {
+ txt = v.toString();
+ com = getComment( n );
+ } else if ( attrib == "pixmap" ) {
+ pix = v.toString();
+ if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) {
+ pix.prepend( pixmapLoaderFunction + "(" + QString( externPixmaps ? "\"" : "" ) );
+ pix.append( QString( externPixmaps ? "\"" : "" ) + ")" );
+ }
+ } else if ( attrib == "field" )
+ field = v.toString();
+ }
+ n = n.nextSibling().toElement();
+ }
+
+ if ( value )
+ *value = trcall( txt, com );
+
+ // ### This generated code sucks! We have to set the number of
+ // rows/cols before and then only do setLabel/()
+ // ### careful, though, since QDataTable has an API which makes this code pretty good
+
+ QString s;
+ if ( isRow ) {
+ s = indent + parent + ".setNumRows(" + parent + ".numRows() + 1 )\n";
+ if ( pix.isEmpty() )
+ s += indent + parent + ".verticalHeader().setLabel(" + parent + ".numRows() - 1, "
+ + trcall( txt, com ) + ")\n";
+ else
+ s += indent + parent + ".verticalHeader().setLabel(" + parent + ".numRows() - 1, Qt::IconSet.new(@"
+ + pix + " ), " + trcall( txt, com ) + ")\n";
+ } else {
+ if ( objClass == "Qt::Table" ) {
+ s = indent + parent + ".setNumCols(" + parent + ".numCols() + 1)\n";
+ if ( pix.isEmpty() )
+ s += indent + parent + ".horizontalHeader().setLabel(" + parent + ".numCols() - 1, "
+ + trcall( txt, com ) + ")\n";
+ else
+ s += indent + parent + ".horizontalHeader().setLabel(" + parent + ".numCols() - 1, Qt::IconSet.new(@"
+ + pix + " ), " + trcall( txt, com ) + ")\n";
+ } else if ( objClass == "Qt::DataTable" ) {
+ if ( !txt.isEmpty() && !field.isEmpty() ) {
+ if ( pix.isEmpty() )
+ out << indent << parent << ".addColumn(" << fixString( field ) << ", " << trcall( txt, com ) << ")" << endl;
+ else
+ out << indent << parent << ".addColumn(" << fixString( field ) << ", " << trcall( txt, com ) << ", Qt::IconSet.new(@" << pix << "))" << endl;
+ }
+ }
+ }
+ return s;
+}
+
+/*!
+ Creates the implementation of a layout tag. Called from createObjectImpl().
+ */
+QString Uic::createLayoutImpl( const QDomElement &e, const QString& parentClass, const QString& parent, const QString& layout )
+{
+ QDomElement n;
+ QString objClass, objName;
+ objClass = e.tagName();
+
+ QString qlayout = "Qt::VBoxLayout.new";
+ if ( objClass == "hbox" )
+ qlayout = "Qt::HBoxLayout.new";
+ else if ( objClass == "grid" )
+ qlayout = "Qt::GridLayout.new";
+
+ bool isGrid = e.tagName() == "grid" ;
+ objName = registerObject( getLayoutName( e ) );
+ layoutObjects += objName;
+
+ QString margin = DomTool::readProperty( e, "margin", defMargin ).toString();
+ QString spacing = DomTool::readProperty( e, "spacing", defSpacing ).toString();
+ QString resizeMode = DomTool::readProperty( e, "resizeMode", QString::null ).toString();
+
+ QString optcells;
+ if ( isGrid )
+ optcells = "1, 1, ";
+ if ( (parentClass == "Qt::GroupBox" || parentClass == "Qt::ButtonGroup") && layout.isEmpty() ) {
+ // special case for group box
+ out << indent << parent << ".setColumnLayout( 0, Qt::Vertical )" << endl;
+ out << indent << parent << ".layout().setSpacing(" << spacing << ")" << endl;
+ out << indent << parent << ".layout().setMargin(" << margin << ")" << endl;
+ out << indent << objName << " = " << qlayout << "(" << parent << ".layout() )" << endl;
+ out << indent << objName << ".setAlignment( AlignTop )" << endl;
+ } else {
+ out << indent << objName << " = " << qlayout << "(";
+ if ( layout.isEmpty() )
+ out << parent;
+ else {
+ out << "nil";
+ if ( !DomTool::hasProperty( e, "margin" ) )
+ margin = "0";
+ }
+ out << ", " << optcells << margin << ", " << spacing << ", '" << objName.mid(1) << "')" << endl;
+ }
+ if ( !resizeMode.isEmpty() )
+ out << indent << objName << ".setResizeMode( Qt::Layout::" << resizeMode << " )" << endl;
+
+ if ( !isGrid ) {
+ for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) {
+ if ( n.tagName() == "spacer" ) {
+ QString child = createSpacerImpl( n, parentClass, parent, objName );
+ out << indent << objName << ".addItem(" << child << ")" << endl;
+ } else if ( tags.contains( n.tagName() ) ) {
+ QString child = createObjectImpl( n, parentClass, parent, objName );
+ if ( isLayout( child ) )
+ out << indent << objName << ".addLayout(" << child << ")" << endl;
+ else
+ out << indent << objName << ".addWidget(" << child << ")" << endl;
+ }
+ }
+ } else {
+ for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) {
+ QDomElement ae = n;
+ int row = ae.attribute( "row" ).toInt();
+ int col = ae.attribute( "column" ).toInt();
+ int rowspan = ae.attribute( "rowspan" ).toInt();
+ int colspan = ae.attribute( "colspan" ).toInt();
+ if ( rowspan < 1 )
+ rowspan = 1;
+ if ( colspan < 1 )
+ colspan = 1;
+ if ( n.tagName() == "spacer" ) {
+ QString child = createSpacerImpl( n, parentClass, parent, objName );
+ if ( rowspan * colspan != 1 )
+ out << indent << objName << ".addMultiCell(" << child << ", "
+ << row << ", " << row + rowspan - 1 << ", " << col << ", " << col + colspan - 1 << ")" << endl;
+ else
+ out << indent << objName << ".addItem(" << child << ", "
+ << row << ", " << col << ")" << endl;
+ } else if ( tags.contains( n.tagName() ) ) {
+ QString child = createObjectImpl( n, parentClass, parent, objName );
+ out << endl;
+ QString o = "Widget";
+ if ( isLayout( child ) )
+ o = "Layout";
+ if ( rowspan * colspan != 1 )
+ out << indent << objName << ".addMultiCell" << o << "(" << child << ", "
+ << row << ", " << row + rowspan - 1 << ", " << col << ", " << col + colspan - 1 << ")" << endl;
+ else
+ out << indent << objName << ".add" << o << "(" << child << ", "
+ << row << ", " << col << ")" << endl;
+ }
+ }
+ }
+
+ return objName;
+}
+
+
+
+QString Uic::createSpacerImpl( const QDomElement &e, const QString& /*parentClass*/, const QString& /*parent*/, const QString& /*layout*/)
+{
+ QDomElement n;
+ QString objClass, objName;
+ objClass = e.tagName();
+ objName = registerObject( getObjectName( e ) );
+
+ QSize size = DomTool::readProperty( e, "sizeHint", QSize( 0, 0 ) ).toSize();
+ QString sizeType = DomTool::readProperty( e, "sizeType", "Expanding" ).toString();
+ bool isVspacer = DomTool::readProperty( e, "orientation", "Horizontal" ) == "Vertical";
+
+ if ( sizeType != "Expanding" && sizeType != "MinimumExpanding" &&
+ DomTool::hasProperty( e, "geometry" ) ) { // compatibility Qt 2.2
+ QRect geom = DomTool::readProperty( e, "geometry", QRect(0,0,0,0) ).toRect();
+ size = geom.size();
+ }
+
+ if ( isVspacer )
+ out << indent << objName << " = Qt::SpacerItem.new("
+ << size.width() << ", " << size.height()
+ << ", Qt::SizePolicy::Minimum, Qt::SizePolicy::" << sizeType << ")" << endl;
+ else
+ out << indent << objName << " = Qt::SpacerItem.new("
+ << size.width() << ", " << size.height()
+ << ", Qt::SizePolicy::" << sizeType << ", Qt::SizePolicy::Minimum)" << endl;
+
+ return objName;
+}
+
+static const char* const ColorRole[] = {
+ "Foreground", "Button", "Light", "Midlight", "Dark", "Mid",
+ "Text", "BrightText", "ButtonText", "Base", "Background", "Shadow",
+ "Highlight", "HighlightedText", "Link", "LinkVisited", 0
+};
+
+
+/*!
+ Creates a colorgroup with name \a name from the color group \a cg
+ */
+void Uic::createColorGroupImpl( const QString& name, const QDomElement& e )
+{
+ QColorGroup cg;
+ int r = -1;
+ QDomElement n = e.firstChild().toElement();
+ QString color;
+ while ( !n.isNull() ) {
+ if ( n.tagName() == "color" ) {
+ r++;
+ QColor col = DomTool::readColor( n );
+ color = "Qt::Color.new(%1,%2,%3)";
+ color = color.arg( col.red() ).arg( col.green() ).arg( col.blue() );
+ if ( col == white )
+ color = "white";
+ else if ( col == black )
+ color = "black";
+ if ( n.nextSibling().toElement().tagName() != "pixmap" ) {
+ out << indent << name << ".setColor(Qt::ColorGroup::" << ColorRole[r] << ", " << color << ")" << endl;
+ }
+ } else if ( n.tagName() == "pixmap" ) {
+ QString pixmap = n.firstChild().toText().data();
+ pixmap.prepend("@");
+ if ( !pixmapLoaderFunction.isEmpty() ) {
+ pixmap.prepend( pixmapLoaderFunction + "(" + QString( externPixmaps ? "\"" : "" ) );
+ pixmap.append( QString( externPixmaps ? "\"" : "" ) + ")" );
+ }
+ out << indent << name << ".setBrush(Qt::ColorGroup::"
+ << ColorRole[r] << ", Qt::Brush.new(" << color << ", " << pixmap << "))" << endl;
+ }
+ n = n.nextSibling().toElement();
+ }
+}
+
+/*!
+ Auxiliary function to load a color group. The colorgroup must not
+ contain pixmaps.
+ */
+QColorGroup Uic::loadColorGroup( const QDomElement &e )
+{
+ QColorGroup cg;
+ int r = -1;
+ QDomElement n = e.firstChild().toElement();
+ QColor col;
+ while ( !n.isNull() ) {
+ if ( n.tagName() == "color" ) {
+ r++;
+ cg.setColor( (QColorGroup::ColorRole)r, (col = DomTool::readColor( n ) ) );
+ }
+ n = n.nextSibling().toElement();
+ }
+ return cg;
+}
+
+/*! Returns TRUE if the widget properties specify that it belongs to
+ the database \a connection and \a table.
+*/
+
+bool Uic::isWidgetInTable( const QDomElement& e, const QString& connection, const QString& table )
+{
+ QString conn = getDatabaseInfo( e, "connection" );
+ QString tab = getDatabaseInfo( e, "table" );
+ if ( conn == connection && tab == table )
+ return true;
+ return false;
+}
+
+/*!
+ Registers all database connections, cursors and forms.
+*/
+
+void Uic::registerDatabases( const QDomElement& e )
+{
+ QDomElement n;
+ QDomNodeList nl;
+ int i;
+ nl = e.parentNode().toElement().elementsByTagName( "widget" );
+ for ( i = 0; i < (int) nl.length(); ++i ) {
+ n = nl.item(i).toElement();
+ QString conn = getDatabaseInfo( n, "connection" );
+ QString tab = getDatabaseInfo( n, "table" );
+ QString fld = getDatabaseInfo( n, "field" );
+ if ( !conn.isNull() ) {
+ dbConnections += conn;
+ if ( !tab.isNull() ) {
+ dbCursors[conn] += tab;
+ if ( !fld.isNull() )
+ dbForms[conn] += tab;
+ }
+ }
+ }
+}
+
+/*!
+ Registers an object with name \a name.
+
+ The returned name is a valid variable identifier, as similar to \a
+ name as possible and guaranteed to be unique within the form.
+
+ \sa registeredName(), isObjectRegistered()
+ */
+QString Uic::registerObject( const QString& name )
+{
+ if ( objectNames.isEmpty() ) {
+ // some temporary variables we need
+ objectNames += "img";
+ objectNames += "item";
+ objectNames += "cg";
+ objectNames += "pal";
+ }
+ QString result("@");
+ result += name;
+ int i;
+ while ( ( i = result.find(' ' )) != -1 ) {
+ result[i] = '_';
+ }
+
+ if ( objectNames.contains( result ) ) {
+ int i = 2;
+ while ( objectNames.contains( result + "_" + QString::number(i) ) )
+ i++;
+ result += "_";
+ result += QString::number(i);
+ }
+ objectNames += result;
+ objectMapper.insert( name, result );
+ return result;
+}
+
+/*!
+ Returns the registered name for the original name \a name
+ or \a name if \a name wasn't registered.
+
+ \sa registerObject(), isObjectRegistered()
+ */
+QString Uic::registeredName( const QString& name )
+{
+ if ( !objectMapper.contains( name ) )
+ return name;
+ return objectMapper[name];
+}
+
+/*!
+ Returns whether the object \a name was registered yet or not.
+ */
+bool Uic::isObjectRegistered( const QString& name )
+{
+ return objectMapper.contains( name );
+}
+
+
+/*!
+ Unifies the entries in stringlist \a list. Should really be a QStringList feature.
+ */
+QStringList Uic::unique( const QStringList& list )
+{
+ QStringList result;
+ if ( list.isEmpty() )
+ return result;
+ QStringList l = list;
+ l.sort();
+ result += l.first();
+ for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) {
+ if ( *it != result.last() )
+ result += *it;
+ }
+ return result;
+}
+
+
+
+/*!
+ Creates an instance of class \a objClass, with parent \a parent and name \a objName
+ */
+QString Uic::createObjectInstance( const QString& objClass, const QString& parent, const QString& objName )
+{
+
+ if ( objClass.mid( 4 ) == "ComboBox" ) {
+ return objClass + ".new(false, " + parent + ", \"" + objName.mid(1) + "\")";
+ }
+ return objClass + ".new(" + parent + ", \"" + objName.mid(1) + "\")";
+}
+
+bool Uic::isLayout( const QString& name ) const
+{
+ return layoutObjects.contains( name );
+}