/********************************************************************** ** Copyright (C) 2000 Trolltech AS. All rights reserved. ** ** This file is part of TQt 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. ** **********************************************************************/ #include #include "uic.h" #include "parser.h" #include "widgetdatabase.h" #include "domtool.h" #include #include #include #include #define NO_STATIC_COLORS #include #if TQT_VERSION < 0x030100 #include #endif static TQByteArray unzipXPM( TQString data, ulong& length ) { #if TQT_VERSION >= 0x030100 const int lengthOffset = 4; int baSize = data.length() / 2 + lengthOffset; uchar *ba = new uchar[ baSize ]; for ( int i = lengthOffset; i < baSize; ++i ) { char h = data[ 2 * (i-lengthOffset) ].latin1(); char l = data[ 2 * (i-lengthOffset) + 1 ].latin1(); uchar r = 0; if ( h <= '9' ) r += h - '0'; else r += h - 'a' + 10; r = r << 4; if ( l <= '9' ) r += l - '0'; else r += l - 'a' + 10; ba[ i ] = r; } // tqUncompress() expects the first 4 bytes to be the expected length of the // uncompressed data ba[0] = ( length & 0xff000000 ) >> 24; ba[1] = ( length & 0x00ff0000 ) >> 16; ba[2] = ( length & 0x0000ff00 ) >> 8; ba[3] = ( length & 0x000000ff ); TQByteArray baunzip = tqUncompress( ba, baSize ); delete[] ba; return baunzip; #else uchar *ba = new uchar[ data.length() / 2 ]; for ( int i = 0; i < (int)data.length() / 2; ++i ) { char h = data[ 2 * i ].latin1(); char l = data[ 2 * i + 1 ].latin1(); uchar r = 0; if ( h <= '9' ) r += h - '0'; else r += h - 'a' + 10; r = r << 4; if ( l <= '9' ) r += l - '0'; else r += l - 'a' + 10; ba[ i ] = r; } // I'm not sure this makes sense. Why couldn't the compressed data be // less than 20% of the original data? Maybe it's enough to trust the // `length' passed as an argument. Quoting the zlib header: // Upon entry, destLen is the total size of the destination // buffer, which must be large enough to hold the entire // uncompressed data. (The size of the uncompressed data must // have been saved previously by the compressor and transmitted // to the decompressor by some mechanism outside the scope of // this compression library.) // Which is the role of `length'. On the other hand this could prevent // crashes in some cases of slightly corrupt UIC files. if ( length < data.length() * 5 ) length = data.length() * 5; TQByteArray baunzip( length ); ::uncompress( (uchar*) baunzip.data(), &length, ba, data.length()/2 ); delete[] ba; return baunzip; #endif } /*! Creates an implementation ( cpp-file ) for the form given in \a e \sa createFormDecl(), createObjectImpl() */ void Uic::createFormImpl( const TQDomElement &e ) { TQDomElement n; TQDomNodeList nl; int i; TQString objClass = getClassName( e ); if ( objClass.isEmpty() ) return; TQString objName = getObjectName( e ); // generate local and local includes required TQStringList globalIncludes; TQStringList::Iterator it; TQStringList sqlClasses; TQStringList axwidgets, databrowsers; TQMap customWidgetIncludes; TQMap functionImpls; // find additional slots and functions TQStringList extraSlots; TQStringList extraSlotTypes; nl = e.parentNode().toElement().elementsByTagName( "slot" ); for ( i = 0; i < (int) nl.length(); i++ ) { n = nl.item(i).toElement(); if ( n.parentNode().toElement().tagName() != "slots" && n.parentNode().toElement().tagName() != "connections" ) continue; if ( n.attribute( "language", "C++" ) != "C++" ) continue; TQString slotName = n.firstChild().toText().data().stripWhiteSpace(); if ( slotName.endsWith( ";" ) ) slotName = slotName.left( slotName.length() - 1 ); extraSlots += Parser::cleanArgs(slotName); extraSlotTypes += n.attribute( "returnType", "void" ); } for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { if ( n.tagName() == "functions" ) { // compatibility for ( TQDomElement n2 = n.firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) { if ( n2.tagName() == "function" ) { TQString fname = n2.attribute( "name" ); fname = Parser::cleanArgs( fname ); functionImpls.insert( fname, n2.firstChild().toText().data() ); } } } } // additional includes (local or global ) and forward declaractions nl = e.parentNode().toElement().elementsByTagName( "include" ); for ( i = 0; i < (int) nl.length(); i++ ) { TQDomElement n2 = nl.item(i).toElement(); TQString s = n2.firstChild().toText().data(); if ( n2.attribute( "location" ) != "local" ) { if ( s.right( 5 ) == ".ui.h" && !TQFile::exists( s ) ) continue; if ( n2.attribute( "impldecl", "in implementation" ) != "in implementation" ) continue; globalIncludes += s; } } // do the local includes afterwards, since global includes have priority on clashes TQFileInfo fi(fileName); for ( i = 0; i < (int) nl.length(); i++ ) { TQDomElement n2 = nl.item(i).toElement(); TQString s = n2.firstChild().toText().data(); if ( n2.attribute( "location" ) == "local" &&!globalIncludes.contains( s ) ) { if ( s.right( 5 ) != ".ui.h" ) continue; if ( !TQFile::exists( s ) ) { s = fi.dirPath() + "/" + s; if ( !TQFile::exists( s ) ) continue; } if ( TQFile::exists( s ) ) { TQFile f(s); f.open(IO_ReadOnly); TQTextStream headerStream(&f); TQString line; TQString functionText; TQString functionName; TQRegExp rx("void .*::(.*\\(.*\\))"); int pos, inFunction = 0; while (line = headerStream.readLine()) { pos = rx.search(line); if (pos > -1) { if (inFunction) functionImpls.insert(Parser::cleanArgs(functionName),functionText); functionName = rx.cap(1); functionText = ""; inFunction = 1; } functionText += line + "\n"; } if (inFunction) functionImpls.insert(Parser::cleanArgs(functionName),functionText); } } } // additional custom widget headers nl = e.parentNode().toElement().elementsByTagName( "header" ); for ( i = 0; i < (int) nl.length(); i++ ) { TQDomElement n2 = nl.item(i).toElement(); TQString s = n2.firstChild().toText().data(); if ( n2.attribute( "location" ) != "local" ) globalIncludes += s; } // includes for child widgets for ( it = tags.begin(); it != tags.end(); ++it ) { nl = e.parentNode().toElement().elementsByTagName( *it ); for ( i = 1; i < (int) nl.length(); i++ ) { // start at 1, 0 is the toplevel widget TQString name = getClassName( nl.item(i).toElement() ); if ( name == "Spacer" ) { globalIncludes += "tqlayout.h"; globalIncludes += "tqapplication.h"; continue; } if ( name.mid( 1 ) == "ListView" ) globalIncludes += "tqheader.h"; else if ( name == "TQAxWidget" ) axwidgets += getObjectName(nl.item(i).toElement()); else if ( name == "TQDataBrowser" ) databrowsers += getObjectName(nl.item(i).toElement()); if ( name != objClass ) { int wid = WidgetDatabase::idFromClassName( name ); TQMap::Iterator it = customWidgetIncludes.find( name ); if ( it == customWidgetIncludes.end() ) globalIncludes += WidgetDatabase::includeFile( wid ); } } } if (globalIncludes.findIndex("tqtable.h") >= 0) out << indent << "from PyTQt.tqttable import TQTable" << endl; if (!axwidgets.empty()) out << indent << "from PyTQt.tqtaxcontainer import TQAxWidget" << endl; if (globalIncludes.findIndex("tqextscintilla.h") >= 0) out << indent << "from PyTQt.tqtext import TQextScintilla" << endl; registerDatabases( e ); dbConnections = unique( dbConnections ); if ( dbConnections.count() ) sqlClasses += "TQSqlDatabase"; if ( dbCursors.count() ) sqlClasses += "TQSqlCursor"; bool dbForm = FALSE; if ( dbForms[ "(default)" ].count() ) dbForm = TRUE; bool subDbForms = FALSE; for ( it = dbConnections.begin(); it != dbConnections.end(); ++it ) { if ( !(*it).isEmpty() && (*it) != "(default)" ) { if ( dbForms[ (*it) ].count() ) { subDbForms = TRUE; break; } } } if ( dbForm || subDbForms ) { sqlClasses += "TQSqlForm"; sqlClasses += "TQSqlRecord"; } if (globalIncludes.findIndex("tqdatatable.h") >= 0) sqlClasses += "TQDataTable"; if (globalIncludes.findIndex("tqtableview.h") >= 0) sqlClasses += "TQTableView"; if (globalIncludes.findIndex("tqdatabrowser.h") >= 0) sqlClasses += "TQDataBrowser"; if (globalIncludes.findIndex("tqdataview.h") >= 0) sqlClasses += "TQDataView"; if ( !sqlClasses.empty() ) { out << indent << "from PyTQt.tqtsql import"; const char *sep = " "; for ( it = sqlClasses.begin(); it != sqlClasses.end(); ++it ) { out << sep << (*it); sep = ", "; } out << endl; } // Add any code from the comments. if (!pyCode.isEmpty()) out << pyCode; out << endl; // find out what images are required TQStringList requiredImages; static const char *imgTags[] = { "pixmap", "iconset", 0 }; for ( i = 0; imgTags[i] != 0; i++ ) { nl = e.parentNode().toElement().elementsByTagName( imgTags[i] ); for ( int j = 0; j < (int) nl.length(); j++ ) { TQDomNode nn = nl.item(j); while ( nn.parentNode() != e.parentNode() ) nn = nn.parentNode(); if ( nn.nodeName() != "customwidgets" ) requiredImages += nl.item(j).firstChild().toText().data(); } } // register the object and unify its name objName = registerObject( objName ); TQStringList images; TQStringList xpmImages; if ( pixmapLoaderFunction.isEmpty() && !externPixmaps ) { // create images for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { if ( n.tagName() == "images" ) { nl = n.elementsByTagName( "image" ); for ( i = 0; i < (int) nl.length(); i++ ) { TQString img = registerObject( nl.item(i).toElement().attribute( "name" ) ); if ( !requiredImages.contains( img ) ) continue; TQDomElement tmp = nl.item(i).firstChild().toElement(); if ( tmp.tagName() != "data" ) continue; TQString format = tmp.attribute("format", "PNG" ); TQString data = tmp.firstChild().toText().data(); if ( format == "XPM.GZ" ) { xpmImages += img; ulong length = tmp.attribute("length").toULong(); TQByteArray baunzip = unzipXPM( data, length ); length = baunzip.size(); // shouldn't we test the initial `length' against the // resulting `length' to catch corrupt UIC files? int a = 0; out << indent << img << "_data = [" << endl; while ( baunzip[a] != '\"' ) a++; for ( ; a < (int) length; a++ ) { char ch; if ((ch = baunzip[a]) == '}') { out << endl << "]"; break; } out << ch; } out << endl; } else { images += img; out << indent << img << "_data = \\" << endl; ++indent; out << indent << "\""; int a ; for ( a = 0; a < (int) (data.length()/2)-1; a++ ) { out << "\\x" << TQString(data[2*a]) << TQString(data[2*a+1]); if ( a % 12 == 11 ) out << "\" \\" << endl << indent << "\""; } out << "\\x" << TQString(data[2*a]) << TQString(data[2*a+1]) << "\"" << endl; --indent; } } } } out << endl; } else if ( externPixmaps ) { #if TQT_VERSION >= 0x030100 pixmapLoaderFunction = "TQPixmap.fromMimeSource"; #else out << indent << "def uic_load_pixmap_" << objName << "(name):" << endl; ++indent; out << indent << "pix = TQPixmap()" << endl; out << indent << "m = TQMimeSourceFactory.defaultFactory().data(name)" << endl; out << endl; out << indent << "if m:" << endl; ++indent; out << indent << "TQImageDrag.decode(m,pix)" << endl; --indent; out << endl; out << indent << "return pix" << endl; --indent; out << endl; out << endl; pixmapLoaderFunction = "uic_load_pixmap_" + objName; #endif } // constructor(s) out << indent << "class " << nameOfClass << "(" << objClass << "):" << endl; ++indent; if ( objClass == "TQDialog" || objClass == "TQWizard" ) { out << indent << "def __init__(self,parent = None,name = None,modal = 0,fl = 0):" << endl; ++indent; out << indent << objClass << ".__init__(self,parent,name,modal,fl)" << endl; } else if ( objClass == "TQWidget" ) { out << indent << "def __init__(self,parent = None,name = None,fl = 0):" << endl; ++indent; out << indent << objClass << ".__init__(self,parent,name,fl)" << endl; } else if ( objClass == "TQMainWindow" ) { out << indent << "def __init__(self,parent = None,name = None,fl = 0):" << endl; ++indent; out << indent << objClass << ".__init__(self,parent,name,fl)" << endl; out << indent << "self.statusBar()" << endl; isMainWindow = TRUE; } else { out << indent << "def __init__(self,parent = None,name = None):" << endl; ++indent; out << indent << objClass << ".__init__(self,parent,name)" << endl; } out << endl; // create pixmaps for all images if ( !images.isEmpty() ) { TQStringList::Iterator it; for ( it = images.begin(); it != images.end(); ++it ) { out << indent << "self." << (*it) << " = TQPixmap()" << endl; out << indent << "self." << (*it) << ".loadFromData(" << (*it) << "_data,\"PNG\")" << endl; } } // create pixmaps for all images if ( !xpmImages.isEmpty() ) { for ( it = xpmImages.begin(); it != xpmImages.end(); ++it ) { out << indent << "self." << (*it) << " = TQPixmap(" << (*it) << "_data)" << endl; } out << endl; } // set the properties TQSize geometry( 0, 0 ); for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { if ( n.tagName() == "property" ) { bool stdset = stdsetdef; if ( n.hasAttribute( "stdset" ) ) stdset = toBool( n.attribute( "stdset" ) ); TQString prop = n.attribute("name"); TQDomElement n2 = n.firstChild().toElement(); TQString value = setObjectProperty( objClass, TQString::null, prop, n2, stdset ); if ( value.isEmpty() ) continue; if ( prop == "geometry" && n2.tagName() == "rect") { TQDomElement n3 = n2.firstChild().toElement(); while ( !n3.isNull() ) { if ( n3.tagName() == "width" ) geometry.setWidth( n3.firstChild().toText().data().toInt() ); else if ( n3.tagName() == "height" ) geometry.setHeight( n3.firstChild().toText().data().toInt() ); n3 = n3.nextSibling().toElement(); } } else { TQString call; if ( stdset ) call = "self." + mkStdSet( prop ) + "(" + value + ")"; else call = "self.setProperty(\"" + prop + "\",TQVariant(" + value + "))"; if ( n2.tagName() == "string" ) { trout << trindent << call << endl; } else if ( prop == "name" ) { out << indent << "if not name:" << endl; ++indent; out << indent << call << endl; --indent; out << endl; } else { out << indent << call << endl; } } } } out << endl; // create all children, some forms have special requirements if ( objClass == "TQWizard" ) { for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { if ( tags.contains( n.tagName() ) ) { TQString page = createObjectImpl( n, objClass, "self" ); TQString comment; TQString label = DomTool::readAttribute( n, "title", "", comment ).toString(); out << indent << "self.addPage(" << page << ",TQString(\"\"))" << endl; trout << trindent << "self.setTitle(" << page << ","<< trcall( label, comment ) << ")" << endl; TQVariant def( FALSE ); if ( DomTool::hasAttribute( n, "backEnabled" ) ) out << indent << "self.setBackEnabled(" << page << "," << mkBool( DomTool::readAttribute( n, "backEnabled", def).toBool() ) << ")" << endl; if ( DomTool::hasAttribute( n, "nextEnabled" ) ) out << indent << "self.setNextEnabled(" << page << "," << mkBool( DomTool::readAttribute( n, "nextEnabled", def).toBool() ) << ")" << endl; if ( DomTool::hasAttribute( n, "finishEnabled" ) ) out << indent << "self.setFinishEnabled(" << page << "," << mkBool( DomTool::readAttribute( n, "finishEnabled", def).toBool() ) << ")" << endl; if ( DomTool::hasAttribute( n, "helpEnabled" ) ) out << indent << "self.setHelpEnabled(" << page << "," << mkBool( DomTool::readAttribute( n, "helpEnabled", def).toBool() ) << ")" << endl; if ( DomTool::hasAttribute( n, "finish" ) ) out << indent << "self.setFinish( " << page << "," << mkBool( DomTool::readAttribute( n, "finish", def).toBool() ) << ")" << endl; } } } else { // standard widgets for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { if ( tags.contains( n.tagName() ) ) createObjectImpl( n, objName, "self" ); } } // database support dbConnections = unique( dbConnections ); if ( dbConnections.count() ) out << endl; for ( it = dbConnections.begin(); it != dbConnections.end(); ++it ) { if ( !(*it).isEmpty() && (*it) != "(default)") { out << indent << "self." << (*it) << "Connection = TQSqlDatabase.database(\"" <<(*it) << "\")" << endl; } } nl = e.parentNode().toElement().elementsByTagName( "widget" ); for ( i = 1; i < (int) nl.length(); i++ ) { // start at 1, 0 is the toplevel widget n = nl.item(i).toElement(); TQString s = getClassName( n ); if ( (dbForm || subDbForms) && (s == "TQDataBrowser" || s == "TQDataView") ) { TQString objName = getObjectName( n ); TQString tab = getDatabaseInfo( n, "table" ); TQString con = getDatabaseInfo( n, "connection" ); out << indent << objName << "Form = TQSqlForm(self,\"" << objName << "Form\")" << endl; TQDomElement n2; for ( n2 = n.firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) createFormImpl( n2, objName, con, tab ); out << indent << "self." << objName << ".setForm(" << objName << "Form)" << endl; } } // actions, toolbars, menubar bool needEndl = FALSE; for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { if ( n.tagName() == "actions" ) { if ( !needEndl ) out << endl; createActionImpl( n.firstChild().toElement(), "self" ); needEndl = TRUE; } } if ( needEndl ) out << endl; needEndl = FALSE; for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { if ( n.tagName() == "toolbars" ) { if ( !needEndl ) out << endl; createToolbarImpl( n, objClass, objName ); needEndl = TRUE; } } if ( needEndl ) out << endl; needEndl = FALSE; for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { if ( n.tagName() == "menubar" ) { if ( !needEndl ) out << endl; createMenuBarImpl( n, objClass, objName ); needEndl = TRUE; } } if ( needEndl ) out << endl; out << endl; out << indent << "self.languageChange()" << endl; out << endl; // take minimumSizeHint() into account, for height-for-width widgets if ( !geometry.isNull() ) { out << indent << "self.resize(TQSize(" << geometry.width() << "," << geometry.height() <<").expandedTo(self.minimumSizeHint()))" << endl; out << indent << "self.clearWState(TQt.WState_Polished)" << endl; } for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { if ( n.tagName() == "connections" ) { // setup signals and slots connections out << endl; nl = n.elementsByTagName( "connection" ); for ( i = 0; i < (int) nl.length(); i++ ) { TQString sender, receiver, signal, slot; for ( TQDomElement n2 = nl.item(i).firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) { if ( n2.tagName() == "sender" ) sender = n2.firstChild().toText().data(); else if ( n2.tagName() == "receiver" ) receiver = n2.firstChild().toText().data(); else if ( n2.tagName() == "signal" ) signal = n2.firstChild().toText().data(); else if ( n2.tagName() == "slot" ) slot = n2.firstChild().toText().data(); } if ( sender.isEmpty() || receiver.isEmpty() || signal.isEmpty() || slot.isEmpty() ) continue; if ( sender[0] == '<' || receiver[0] == '<' || signal[0] == '<' || slot[0] == '<' ) continue; sender = registeredName( sender ); receiver = registeredName( receiver ); // translate formwindow name to "self" if ( sender == objName ) sender = "self"; else sender = "self." + sender; bool isaxwidget = (axwidgets.findIndex(receiver) >= 0); bool isdatabrowser = (databrowsers.findIndex(receiver) >= 0); if ( receiver == objName ) receiver = "self"; else receiver = "self." + receiver; out << indent << "self.connect(" << sender << ",SIGNAL(\"" << signal << "\")," << receiver; // Normally we never use the SLOT() macro in case the // connection is to a method of a Python custom widget. The // exception is if the receiver is a TQAxWidget where it must be // used because the slots are dynamic. if (isaxwidget) out << ",SLOT(\"" << slot << "\")"; else { TQString mname = slot.left(slot.find('(')); // Rename slots that have different names in PyTQt. if (isdatabrowser && mname == "del") mname = "delOnCursor"; out << "." << mname; } out << ")" << endl; } } else if ( n.tagName() == "tabstops" ) { // setup tab order out << endl; TQString lastName; TQDomElement n2 = n.firstChild().toElement(); while ( !n2.isNull() ) { if ( n2.tagName() == "tabstop" ) { TQString name = n2.firstChild().toText().data(); name = registeredName( name ); if ( !lastName.isEmpty() ) out << indent << "self.setTabOrder(self." << lastName << ",self." << name << ")" << endl; lastName = name; } n2 = n2.nextSibling().toElement(); } } } // buddies bool firstBuddy = TRUE; for ( TQValueList::Iterator buddy = buddies.begin(); buddy != buddies.end(); ++buddy ) { if ( isObjectRegistered( (*buddy).buddy ) ) { if ( firstBuddy ) { out << endl; } out << indent << "self." << (*buddy).key << ".setBuddy(self." << registeredName( (*buddy).buddy ) << ")" << endl; firstBuddy = FALSE; } } if ( extraSlots.find( "init()" ) != extraSlots.end() ) out << endl << indent << "self.init()" << endl; // end of constructor --indent; // destructor if ( extraSlots.find( "destroy()" ) != extraSlots.end() ) { out << endl; out << indent << "def __del__(self):" << endl; ++indent; out << indent << "self.destroy()" << endl; --indent; } // handle application events if required bool needFontEventHandler = FALSE; bool needSqlTableEventHandler = FALSE; bool needSqlDataBrowserEventHandler = FALSE; nl = e.elementsByTagName( "widget" ); for ( i = 0; i < (int) nl.length(); i++ ) { if ( !DomTool::propertiesOfType( nl.item(i).toElement() , "font" ).isEmpty() ) needFontEventHandler = TRUE; TQString s = getClassName( nl.item(i).toElement() ); if ( s == "TQDataTable" || s == "TQDataBrowser" ) { if ( !isFrameworkCodeGenerated( nl.item(i).toElement() ) ) continue; if ( s == "TQDataTable" ) needSqlTableEventHandler = TRUE; if ( s == "TQDataBrowser" ) needSqlDataBrowserEventHandler = TRUE; } if ( needFontEventHandler && needSqlTableEventHandler && needSqlDataBrowserEventHandler ) break; } if ( needFontEventHandler && FALSE ) { // indent = "\t"; // increase indentation for if-clause below out << "/* " << endl; out << " * Main event handler. Reimplemented to handle" << endl; out << " * application font changes"; out << " */" << endl; out << "bool " << nameOfClass << "::event( TQEvent* ev )" << endl; out << "{" << endl; out << " bool ret = " << objClass << "::event( ev ); " << endl; if ( needFontEventHandler ) { ++indent; out << " if ( ev->type() == TQEvent::ApplicationFontChange ) {" << endl; for ( i = 0; i < (int) nl.length(); i++ ) { n = nl.item(i).toElement(); TQStringList list = DomTool::propertiesOfType( n, "font" ); for ( it = list.begin(); it != list.end(); ++it ) createExclusiveProperty( n, *it ); } out << " }" << endl; --indent; } out << "}" << endl; out << endl; } if ( needSqlTableEventHandler || needSqlDataBrowserEventHandler ) { out << endl; out << indent << "# Widget polish. Reimplemented to handle default data" << endl; if ( needSqlTableEventHandler ) out << indent << "# table initialization." << endl; if ( needSqlDataBrowserEventHandler ) out << indent << "# browser initialization." << endl; out << indent << "def polish(self):" << endl; ++indent; if ( needSqlTableEventHandler ) { for ( i = 0; i < (int) nl.length(); i++ ) { TQString s = getClassName( nl.item(i).toElement() ); if ( s == "TQDataTable" ) { n = nl.item(i).toElement(); TQString c = getObjectName( n ); TQString conn = getDatabaseInfo( n, "connection" ); TQString tab = getDatabaseInfo( n, "table" ); if ( !( conn.isEmpty() || tab.isEmpty() || !isFrameworkCodeGenerated( nl.item(i).toElement() ) ) ) { out << indent << "if self." << c << ":" << endl; ++indent; out << indent << "cursor = self." << c << ".sqlCursor()" << endl; out << endl; out << indent << "if not cursor:" << endl; ++indent; if ( conn == "(default)" ) out << indent << "cursor = TQSqlCursor(\"" << tab << "\")" << endl; else out << indent << "cursor = TQSqlCursor(\"" << tab << "\",1,self." << conn << "Connection)" << endl; out << indent << "if self." << c << ".isReadOnly():" << endl; ++indent; out << indent << "cursor.setMode(TQSqlCursor.ReadOnly)" << endl; --indent; out << indent << "self." << c << ".setSqlCursor(cursor,0,1)" << endl; --indent; out << endl; out << indent << "if not cursor.isActive():" << endl; ++indent; out << indent << "self." << c << ".refresh(TQDataTable.RefreshAll)" << endl; --indent; --indent; } } } } if ( needSqlDataBrowserEventHandler ) { nl = e.elementsByTagName( "widget" ); for ( i = 0; i < (int) nl.length(); i++ ) { TQString s = getClassName( nl.item(i).toElement() ); if ( s == "TQDataBrowser" ) { TQString obj = getObjectName( nl.item(i).toElement() ); TQString tab = getDatabaseInfo( nl.item(i).toElement(), "table" ); TQString conn = getDatabaseInfo( nl.item(i).toElement(), "connection" ); if ( !(tab.isEmpty() || !isFrameworkCodeGenerated( nl.item(i).toElement() ) ) ) { out << indent << "if self." << obj << ":" << endl; ++indent; out << indent << "if not self." << obj << ".sqlCursor():" << endl; ++indent; if ( conn == "(default)" ) out << indent << "cursor = TQSqlCursor(\"" << tab << "\")" << endl; else out << indent << "cursor = TQSqlCursor(\"" << tab << "\",1,self." << conn << "Connection)" << endl; out << indent << "self." << obj << ".setSqlCursor(cursor,1)" << endl; out << indent << "self." << obj << ".refresh()" << endl; out << indent << "self." << obj << ".first()" << endl; --indent; --indent; } } } } out << indent << objClass << ".polish(self)" << endl; --indent; } out << endl; out << endl; out << indent << "def languageChange(self):" << endl; uint old = indent.setIndent(0); out << languageChangeBody << endl; indent.setIndent(old); // create stubs for additional slots if necessary if ( !extraSlots.isEmpty() && writeFunctImpl ) { TQStringList::ConstIterator cit; for ( cit = extraSlots.begin(); cit != extraSlots.end(); ++cit ) { pySlot(cit); bool createWarning = TRUE; TQString fname = Parser::cleanArgs( *cit ); TQMap::Iterator fit = functionImpls.find( fname ); if ( fit != functionImpls.end() ) { int begin = (*fit).find( "{" ); TQString body = (*fit).mid( begin + 1, (*fit).findRev( "}" ) - begin - 1 ); createWarning = body.simplifyWhiteSpace().isEmpty(); if ( !createWarning ) { ++indent; TQString formatted_body = body.replace(TQRegExp("\n"), TQString("\n") + TQString(indent)); out << formatted_body << endl; --indent; } } if ( createWarning ) { out << endl; ++indent; if ( *cit != "init()" && *cit != "destroy()" ) out << indent << "print(\"" << nameOfClass << "." << (*cit) << ": Not implemented yet\")" << endl; else out << indent << "pass" << endl; --indent; } } } --indent; } /*! Creates form support implementation code for the widgets given in \a e. Traverses recursively over all children. */ void Uic::createFormImpl( const TQDomElement& e, const TQString& form, const TQString& connection, const TQString& table ) { if ( e.tagName() == "widget" && e.attribute( "class" ) != "TQDataTable" ) { TQString field = getDatabaseInfo( e, "field" ); if ( !field.isEmpty() ) { if ( isWidgetInTable( e, connection, table ) ) out << indent << form << "Form.insert(self." << getObjectName( e ) << "," << fixString( field ) << ")" << endl; } } TQDomElement n; for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { createFormImpl( n, form, connection, table ); } } // Generate a Python slot definition. void Uic::pySlot(TQStringList::ConstIterator &it) { out << endl; int astart = (*it).find('('); out << indent << "def " << (*it).left(astart) << "(self"; // We don't reproduce the argument names (if any) because we would have to // remove the types - too complicated for the moment, so we just count them // and give them names based on their position. TQString args = (*it).mid(astart + 1,(*it).find(')') - astart - 1).stripWhiteSpace(); if (!args.isEmpty()) { int nrargs = args.contains(',') + 1; for (int i = 0; i < nrargs; ++i) out << ",a" << i; } out << "):"; }