You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1105 lines
34 KiB
1105 lines
34 KiB
/**********************************************************************
|
|
** 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 <tqfile.h>
|
|
#include <tqstringlist.h>
|
|
#include <tqdatetime.h>
|
|
#define NO_STATIC_COLORS
|
|
#include <globaldefs.h>
|
|
#include <tqregexp.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 += ' ';
|
|
}
|
|
|
|
|
|
TQString Uic::getComment( const TQDomNode& n )
|
|
{
|
|
TQDomNode child = n.firstChild();
|
|
while ( !child.isNull() ) {
|
|
if ( child.toElement().tagName() == "comment" )
|
|
return child.toElement().firstChild().toText().data();
|
|
child = child.nextSibling();
|
|
}
|
|
return TQString::null;
|
|
}
|
|
|
|
TQString Uic::mkBool( bool b )
|
|
{
|
|
return b? "true" : "false";
|
|
}
|
|
|
|
TQString Uic::mkBool( const TQString& s )
|
|
{
|
|
return mkBool( s == "true" || s == "1" );
|
|
}
|
|
|
|
bool Uic::toBool( const TQString& s )
|
|
{
|
|
return s == "true" || s.toInt() != 0;
|
|
}
|
|
|
|
TQString Uic::fixString( const TQString &str )
|
|
{
|
|
TQString s( str );
|
|
s.replace( TQRegExp( "\\\\" ), "\\\\" );
|
|
s.replace( TQRegExp( "\"" ), "\\\"" );
|
|
s.replace( TQRegExp( "\r?\n" ), "\\n\" +\n" + indent + "\"" );
|
|
return "\"" + s + "\"";
|
|
}
|
|
|
|
TQString Uic::trcall( const TQString& sourceText, const TQString& comment )
|
|
{
|
|
if ( sourceText.isEmpty() && comment.isEmpty() )
|
|
return "nil";
|
|
|
|
if ( comment.isEmpty() )
|
|
return trmacro + "(" + fixString( sourceText ) + ")";
|
|
return trmacro + "(" + fixString( sourceText ) + "," + fixString( comment ) + ")";
|
|
}
|
|
|
|
TQString Uic::mkStdSet( const TQString& prop )
|
|
{
|
|
return TQString( "set" ) + prop[0].upper() + prop.mid(1);
|
|
}
|
|
|
|
|
|
|
|
bool Uic::isEmptyFunction( const TQString& fname )
|
|
{
|
|
TQMap<TQString, TQString>::Iterator fit = functionImpls.find( Parser::cleanArgs( fname ) );
|
|
if ( fit != functionImpls.end() ) {
|
|
int begin = (*fit).find( "{" );
|
|
TQString 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 TQString &fn, TQTextStream &outStream, TQDomDocument doc,
|
|
bool subcl, const TQString &trm, const TQString& subClass,
|
|
bool omitForwardDecls, TQString &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") );
|
|
|
|
TQDomElement e = doc.firstChild().firstChild().toElement();
|
|
TQDomElement 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", TQString::number( defSpacing ) ).toInt();
|
|
defMargin = e.attribute( "margin", TQString::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
|
|
*/
|
|
TQString Uic::getPixmapLoaderFunction( const TQDomElement& e )
|
|
{
|
|
TQDomElement n;
|
|
for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) {
|
|
if ( n.tagName() == "pixmapfunction" )
|
|
return n.firstChild().toText().data();
|
|
}
|
|
return TQString::null;
|
|
}
|
|
|
|
|
|
/*! Extracts the forms class name from \a e
|
|
*/
|
|
TQString Uic::getFormClassName( const TQDomElement& e )
|
|
{
|
|
TQDomElement n;
|
|
TQString cn;
|
|
for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) {
|
|
if ( n.tagName() == "class" ) {
|
|
TQString 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.
|
|
*/
|
|
TQString Uic::getClassName( const TQDomElement& e )
|
|
{
|
|
TQString s = e.attribute( "class" );
|
|
if ( s.isEmpty() && e.tagName() == "toolbar" )
|
|
s = "TQt::ToolBar";
|
|
else if ( s.isEmpty() && e.tagName() == "menubar" )
|
|
s = "TQt::MenuBar";
|
|
else
|
|
{
|
|
TQRegExp 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 = "TQt::" + r.cap(2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return s;
|
|
}
|
|
|
|
|
|
|
|
/*! Returns TRUE if database framework code is generated, else FALSE.
|
|
*/
|
|
|
|
bool Uic::isFrameworkCodeGenerated( const TQDomElement& e )
|
|
{
|
|
TQDomElement n = getObjectProperty( e, "frameworkCode" );
|
|
if ( n.attribute("name") == "frameworkCode" &&
|
|
!DomTool::elementToVariant( n.firstChild().toElement(), TQVariant( true, 0 ) ).toBool() )
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
/*! Extracts an object name from \a e. It's stored in the 'name'
|
|
property.
|
|
*/
|
|
TQString Uic::getObjectName( const TQDomElement& e )
|
|
{
|
|
TQDomElement n = getObjectProperty( e, "name" );
|
|
if ( n.firstChild().toElement().tagName() == "cstring" )
|
|
return n.firstChild().toElement().firstChild().toText().data();
|
|
return TQString::null;
|
|
}
|
|
|
|
/*! Extracts an layout name from \a e. It's stored in the 'name'
|
|
property of the preceeding sibling (the first child of a TQLayoutWidget).
|
|
*/
|
|
TQString Uic::getLayoutName( const TQDomElement& e )
|
|
{
|
|
TQDomElement p = e.parentNode().toElement();
|
|
TQString tail = TQString::null;
|
|
|
|
if ( getClassName(p) != "TQt::LayoutWidget" )
|
|
tail = "Layout";
|
|
|
|
TQDomElement n = getObjectProperty( p, "name" );
|
|
if ( n.firstChild().toElement().tagName() == "cstring" )
|
|
return n.firstChild().toElement().firstChild().toText().data() + tail;
|
|
return e.tagName();
|
|
}
|
|
|
|
|
|
TQString Uic::getDatabaseInfo( const TQDomElement& e, const TQString& tag )
|
|
{
|
|
TQDomElement n;
|
|
TQDomElement 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 TQString::null;
|
|
n = getObjectProperty( e, "database" );
|
|
if ( n.firstChild().toElement().tagName() == "stringlist" ) {
|
|
// find correct stringlist entry
|
|
TQDomElement n1 = n.firstChild().firstChild().toElement();
|
|
for ( int i = 0; i < child && !n1.isNull(); ++i )
|
|
n1 = n1.nextSibling().toElement();
|
|
if ( n1.isNull() )
|
|
return TQString::null;
|
|
return n1.firstChild().toText().data();
|
|
}
|
|
return TQString::null;
|
|
}
|
|
|
|
|
|
void Uic::registerLayouts( const TQDomElement &e )
|
|
{
|
|
if ( layouts.contains(e.tagName()) )
|
|
createObjectDecl(e);
|
|
|
|
TQDomNodeList 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.
|
|
*/
|
|
TQString Uic::getInclude( const TQString& className )
|
|
{
|
|
int wid = WidgetDatabase::idFromClassName( className );
|
|
if ( wid != -1 )
|
|
return WidgetDatabase::includeFile( wid );
|
|
return TQString::null;
|
|
}
|
|
|
|
void Uic::createActionDecl( const TQDomElement& e )
|
|
{
|
|
TQString objName = getObjectName( e );
|
|
if ( objName.isEmpty() )
|
|
return;
|
|
out << indent << objName << endl;
|
|
if ( e.tagName() == "actiongroup" ) {
|
|
for ( TQDomElement n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) {
|
|
if ( n.tagName() == "action" || n.tagName() == "actiongroup" )
|
|
createActionDecl( n );
|
|
}
|
|
}
|
|
}
|
|
|
|
void Uic::createActionImpl( const TQDomElement &n, const TQString &parent )
|
|
{
|
|
for ( TQDomElement ae = n; !ae.isNull(); ae = ae.nextSibling().toElement() ) {
|
|
TQString objName = registerObject( getObjectName( ae ) );
|
|
if ( ae.tagName() == "action" )
|
|
out << indent << objName << "= TQt::Action.new(" << parent << ", \"" << objName.mid(1) << "\")" << endl;
|
|
else if ( ae.tagName() == "actiongroup" )
|
|
out << indent << objName << "= TQt::ActionGroup.new(" << parent << ", \"" << objName.mid(1) << "\")" << endl;
|
|
else
|
|
continue;
|
|
bool subActionsDone = false;
|
|
bool hasMenuText = false;
|
|
TQString actionText;
|
|
for ( TQDomElement 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" ) );
|
|
TQString prop = n2.attribute("name");
|
|
if ( prop == "name" )
|
|
continue;
|
|
TQString value = setObjectProperty( "TQt::Action", objName, prop, n2.firstChild().toElement(), stdset );
|
|
if ( value.isEmpty() )
|
|
continue;
|
|
|
|
TQString call = objName + ".";
|
|
if ( stdset ) {
|
|
call += mkStdSet( prop ) + "(" + value + ")";
|
|
} else {
|
|
call += "setProperty( \"" + prop + "\", ";
|
|
call += "TQt::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 TQAction behavior
|
|
if (!hasMenuText && !actionText.isEmpty() && uiFileVersion < "3.3")
|
|
trout << indent << objName << ".setMenuText(" << actionText << ")" << endl;
|
|
}
|
|
}
|
|
|
|
TQString get_dock( const TQString &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 TQDomElement &n, const TQString &parentClass, const TQString &parent )
|
|
{
|
|
TQDomNodeList nl = n.elementsByTagName( "toolbar" );
|
|
for ( int i = 0; i < (int) nl.length(); i++ ) {
|
|
TQDomElement ae = nl.item( i ).toElement();
|
|
TQString dock = get_dock( ae.attribute( "dock" ) );
|
|
TQString objName = "@" + getObjectName( ae );
|
|
out << indent << objName << " = TQt::ToolBar.new(\"\", self, " << dock << ")" << endl;
|
|
createObjectImpl( ae, parentClass, parent );
|
|
for ( TQDomElement 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, "TQt::ToolBar", objName );
|
|
} else {
|
|
TQString child = createSpacerImpl( n2, parentClass, parent, objName );
|
|
out << indent << "TQt::Application.sendPostedEvents( " << objName
|
|
<< ", TQt::Event::ChildInserted)" << endl;
|
|
out << indent << objName << ".boxLayout().addItem(" << child << ")" << endl;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Uic::createMenuBarImpl( const TQDomElement &n, const TQString &parentClass, const TQString &parent )
|
|
{
|
|
TQString objName = "@" + getObjectName( n );
|
|
out << indent << objName << " = TQt::MenuBar.new( self, \"" << objName.mid(1) << "\" )" << endl;
|
|
createObjectImpl( n, parentClass, parent );
|
|
int i = 0;
|
|
TQDomElement c = n.firstChild().toElement();
|
|
while ( !c.isNull() ) {
|
|
if ( c.tagName() == "item" ) {
|
|
TQString itemName = "@" + c.attribute( "name" );
|
|
out << endl;
|
|
out << indent << itemName << " = TQt::PopupMenu.new( self )" << endl;
|
|
createPopupMenuImpl( c, parentClass, itemName );
|
|
out << indent << objName << ".insertItem( \"\", " << itemName << ", " << i << " )" << endl;
|
|
TQString 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 TQDomElement &e, const TQString &parentClass, const TQString &parent )
|
|
{
|
|
int i = 0;
|
|
for ( TQDomElement n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) {
|
|
if ( n.tagName() == "action" || n.tagName() == "actiongroup" ) {
|
|
TQDomElement n2 = n.nextSibling().toElement();
|
|
if ( n2.tagName() == "item" ) { // the action has a sub menu
|
|
TQString itemName = "@" + n2.attribute( "name" );
|
|
TQString itemText = n2.attribute( "text" );
|
|
out << indent << itemName << " = TQt::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.
|
|
*/
|
|
|
|
TQString Uic::createListBoxItemImpl( const TQDomElement &e, const TQString &parent,
|
|
TQString *value )
|
|
{
|
|
TQDomElement n = e.firstChild().toElement();
|
|
TQString txt;
|
|
TQString com;
|
|
TQString pix;
|
|
while ( !n.isNull() ) {
|
|
if ( n.tagName() == "property" ) {
|
|
TQString attrib = n.attribute("name");
|
|
TQVariant v = DomTool::elementToVariant( n.firstChild().toElement(), TQVariant() );
|
|
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 + "(" + TQString( externPixmaps ? "\"" : "" ) );
|
|
pix.append( TQString( 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.
|
|
*/
|
|
|
|
TQString Uic::createIconViewItemImpl( const TQDomElement &e, const TQString &parent )
|
|
{
|
|
TQDomElement n = e.firstChild().toElement();
|
|
TQString txt;
|
|
TQString com;
|
|
TQString pix;
|
|
while ( !n.isNull() ) {
|
|
if ( n.tagName() == "property" ) {
|
|
TQString attrib = n.attribute("name");
|
|
TQVariant v = DomTool::elementToVariant( n.firstChild().toElement(), TQVariant() );
|
|
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 + "(" + TQString( externPixmaps ? "\"" : "" ) );
|
|
pix.append( TQString( externPixmaps ? "\"" : "" ) + ")" );
|
|
}
|
|
}
|
|
}
|
|
n = n.nextSibling().toElement();
|
|
}
|
|
|
|
if ( pix.isEmpty() )
|
|
return "TQt::IconViewItem.new(" + parent + ", " + trcall( txt, com ) + ")";
|
|
else
|
|
return "TQt::IconViewItem.new(" + parent + ", " + trcall( txt, com ) + ", " + pix + ")";
|
|
}
|
|
|
|
/*!
|
|
Creates implementation of an listview item tag.
|
|
*/
|
|
|
|
TQString Uic::createListViewItemImpl( const TQDomElement &e, const TQString &parent,
|
|
const TQString &parentItem )
|
|
{
|
|
TQString s;
|
|
|
|
TQDomElement n = e.firstChild().toElement();
|
|
|
|
bool hasChildren = e.elementsByTagName( "item" ).count() > 0;
|
|
TQString 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 += "TQt::ListViewItem.new(" + parentItem + ", " + lastItem + ")\n";
|
|
else
|
|
s += "TQt::ListViewItem.new(" + parent + ", " + lastItem + ")\n";
|
|
|
|
TQStringList textes;
|
|
TQStringList pixmaps;
|
|
while ( !n.isNull() ) {
|
|
if ( n.tagName() == "property" ) {
|
|
TQString attrib = n.attribute("name");
|
|
TQVariant v = DomTool::elementToVariant( n.firstChild().toElement(), TQVariant() );
|
|
if ( attrib == "text" )
|
|
textes << v.toString();
|
|
else if ( attrib == "pixmap" ) {
|
|
TQString pix = v.toString();
|
|
if (!pix.isEmpty()) {
|
|
pix.prepend("@");
|
|
}
|
|
if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) {
|
|
pix.prepend( pixmapLoaderFunction + "(" + TQString( externPixmaps ? "\"" : "" ) );
|
|
pix.append( TQString( 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(" + TQString::number( i ) + ", " + trcall( textes[ i ] ) + ")\n";
|
|
if ( !pixmaps[ i ].isEmpty() )
|
|
s += indent + item + ".setPixmap(" + TQString::number( i ) + ", " + pixmaps[ i ] + ")\n";
|
|
}
|
|
|
|
lastItem = item;
|
|
return s;
|
|
}
|
|
|
|
/*!
|
|
Creates implementation of an listview column tag.
|
|
*/
|
|
|
|
TQString Uic::createListViewColumnImpl( const TQDomElement &e, const TQString &parent,
|
|
TQString *value )
|
|
{
|
|
TQDomElement n = e.firstChild().toElement();
|
|
TQString txt;
|
|
TQString com;
|
|
TQString pix;
|
|
bool clickable = false, resizeable = false;
|
|
while ( !n.isNull() ) {
|
|
if ( n.tagName() == "property" ) {
|
|
TQString attrib = n.attribute("name");
|
|
TQVariant v = DomTool::elementToVariant( n.firstChild().toElement(), TQVariant() );
|
|
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 + "(" + TQString( externPixmaps ? "\"" : "" ) );
|
|
pix.append( TQString( 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 );
|
|
|
|
TQString 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;
|
|
}
|
|
|
|
TQString Uic::createTableRowColumnImpl( const TQDomElement &e, const TQString &parent,
|
|
TQString *value )
|
|
{
|
|
TQString objClass = getClassName( e.parentNode().toElement() );
|
|
TQDomElement n = e.firstChild().toElement();
|
|
TQString txt;
|
|
TQString com;
|
|
TQString pix;
|
|
TQString field;
|
|
bool isRow = e.tagName() == "row";
|
|
while ( !n.isNull() ) {
|
|
if ( n.tagName() == "property" ) {
|
|
TQString attrib = n.attribute("name");
|
|
TQVariant v = DomTool::elementToVariant( n.firstChild().toElement(), TQVariant() );
|
|
if ( attrib == "text" ) {
|
|
txt = v.toString();
|
|
com = getComment( n );
|
|
} else if ( attrib == "pixmap" ) {
|
|
pix = v.toString();
|
|
if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) {
|
|
pix.prepend( pixmapLoaderFunction + "(" + TQString( externPixmaps ? "\"" : "" ) );
|
|
pix.append( TQString( 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 TQDataTable has an API which makes this code pretty good
|
|
|
|
TQString 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, TQt::IconSet.new(@"
|
|
+ pix + " ), " + trcall( txt, com ) + ")\n";
|
|
} else {
|
|
if ( objClass == "TQt::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, TQt::IconSet.new(@"
|
|
+ pix + " ), " + trcall( txt, com ) + ")\n";
|
|
} else if ( objClass == "TQt::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 ) << ", TQt::IconSet.new(@" << pix << "))" << endl;
|
|
}
|
|
}
|
|
}
|
|
return s;
|
|
}
|
|
|
|
/*!
|
|
Creates the implementation of a layout tag. Called from createObjectImpl().
|
|
*/
|
|
TQString Uic::createLayoutImpl( const TQDomElement &e, const TQString& parentClass, const TQString& parent, const TQString& layout )
|
|
{
|
|
TQDomElement n;
|
|
TQString objClass, objName;
|
|
objClass = e.tagName();
|
|
|
|
TQString qlayout = "TQt::VBoxLayout.new";
|
|
if ( objClass == "hbox" )
|
|
qlayout = "TQt::HBoxLayout.new";
|
|
else if ( objClass == "grid" )
|
|
qlayout = "TQt::GridLayout.new";
|
|
|
|
bool isGrid = e.tagName() == "grid" ;
|
|
objName = registerObject( getLayoutName( e ) );
|
|
layoutObjects += objName;
|
|
|
|
TQString margin = DomTool::readProperty( e, "margin", defMargin ).toString();
|
|
TQString spacing = DomTool::readProperty( e, "spacing", defSpacing ).toString();
|
|
TQString resizeMode = DomTool::readProperty( e, "resizeMode", TQString::null ).toString();
|
|
|
|
TQString optcells;
|
|
if ( isGrid )
|
|
optcells = "1, 1, ";
|
|
if ( (parentClass == "TQt::GroupBox" || parentClass == "TQt::ButtonGroup") && layout.isEmpty() ) {
|
|
// special case for group box
|
|
out << indent << parent << ".setColumnLayout( 0, TQt::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( TQt::Layout::" << resizeMode << " )" << endl;
|
|
|
|
if ( !isGrid ) {
|
|
for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) {
|
|
if ( n.tagName() == "spacer" ) {
|
|
TQString child = createSpacerImpl( n, parentClass, parent, objName );
|
|
out << indent << objName << ".addItem(" << child << ")" << endl;
|
|
} else if ( tags.contains( n.tagName() ) ) {
|
|
TQString 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() ) {
|
|
TQDomElement 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" ) {
|
|
TQString 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() ) ) {
|
|
TQString child = createObjectImpl( n, parentClass, parent, objName );
|
|
out << endl;
|
|
TQString 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;
|
|
}
|
|
|
|
|
|
|
|
TQString Uic::createSpacerImpl( const TQDomElement &e, const TQString& /*parentClass*/, const TQString& /*parent*/, const TQString& /*layout*/)
|
|
{
|
|
TQDomElement n;
|
|
TQString objClass, objName;
|
|
objClass = e.tagName();
|
|
objName = registerObject( getObjectName( e ) );
|
|
|
|
TQSize size = DomTool::readProperty( e, "sizeHint", TQSize( 0, 0 ) ).toSize();
|
|
TQString 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
|
|
TQRect geom = DomTool::readProperty( e, "geometry", TQRect(0,0,0,0) ).toRect();
|
|
size = geom.size();
|
|
}
|
|
|
|
if ( isVspacer )
|
|
out << indent << objName << " = TQt::SpacerItem.new("
|
|
<< size.width() << ", " << size.height()
|
|
<< ", TQt::SizePolicy::Minimum, TQt::SizePolicy::" << sizeType << ")" << endl;
|
|
else
|
|
out << indent << objName << " = TQt::SpacerItem.new("
|
|
<< size.width() << ", " << size.height()
|
|
<< ", TQt::SizePolicy::" << sizeType << ", TQt::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 TQString& name, const TQDomElement& e )
|
|
{
|
|
TQColorGroup cg;
|
|
int r = -1;
|
|
TQDomElement n = e.firstChild().toElement();
|
|
TQString color;
|
|
while ( !n.isNull() ) {
|
|
if ( n.tagName() == "color" ) {
|
|
r++;
|
|
TQColor col = DomTool::readColor( n );
|
|
color = "TQt::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(TQt::ColorGroup::" << ColorRole[r] << ", " << color << ")" << endl;
|
|
}
|
|
} else if ( n.tagName() == "pixmap" ) {
|
|
TQString pixmap = n.firstChild().toText().data();
|
|
pixmap.prepend("@");
|
|
if ( !pixmapLoaderFunction.isEmpty() ) {
|
|
pixmap.prepend( pixmapLoaderFunction + "(" + TQString( externPixmaps ? "\"" : "" ) );
|
|
pixmap.append( TQString( externPixmaps ? "\"" : "" ) + ")" );
|
|
}
|
|
out << indent << name << ".setBrush(TQt::ColorGroup::"
|
|
<< ColorRole[r] << ", TQt::Brush.new(" << color << ", " << pixmap << "))" << endl;
|
|
}
|
|
n = n.nextSibling().toElement();
|
|
}
|
|
}
|
|
|
|
/*!
|
|
Auxiliary function to load a color group. The colorgroup must not
|
|
contain pixmaps.
|
|
*/
|
|
TQColorGroup Uic::loadColorGroup( const TQDomElement &e )
|
|
{
|
|
TQColorGroup cg;
|
|
int r = -1;
|
|
TQDomElement n = e.firstChild().toElement();
|
|
TQColor col;
|
|
while ( !n.isNull() ) {
|
|
if ( n.tagName() == "color" ) {
|
|
r++;
|
|
cg.setColor( (TQColorGroup::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 TQDomElement& e, const TQString& connection, const TQString& table )
|
|
{
|
|
TQString conn = getDatabaseInfo( e, "connection" );
|
|
TQString tab = getDatabaseInfo( e, "table" );
|
|
if ( conn == connection && tab == table )
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
/*!
|
|
Registers all database connections, cursors and forms.
|
|
*/
|
|
|
|
void Uic::registerDatabases( const TQDomElement& e )
|
|
{
|
|
TQDomElement n;
|
|
TQDomNodeList nl;
|
|
int i;
|
|
nl = e.parentNode().toElement().elementsByTagName( "widget" );
|
|
for ( i = 0; i < (int) nl.length(); ++i ) {
|
|
n = nl.item(i).toElement();
|
|
TQString conn = getDatabaseInfo( n, "connection" );
|
|
TQString tab = getDatabaseInfo( n, "table" );
|
|
TQString 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()
|
|
*/
|
|
TQString Uic::registerObject( const TQString& name )
|
|
{
|
|
if ( objectNames.isEmpty() ) {
|
|
// some temporary variables we need
|
|
objectNames += "img";
|
|
objectNames += "item";
|
|
objectNames += "cg";
|
|
objectNames += "pal";
|
|
}
|
|
TQString result("@");
|
|
result += name;
|
|
int i;
|
|
while ( ( i = result.find(' ' )) != -1 ) {
|
|
result[i] = '_';
|
|
}
|
|
|
|
if ( objectNames.contains( result ) ) {
|
|
int i = 2;
|
|
while ( objectNames.contains( result + "_" + TQString::number(i) ) )
|
|
i++;
|
|
result += "_";
|
|
result += TQString::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()
|
|
*/
|
|
TQString Uic::registeredName( const TQString& 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 TQString& name )
|
|
{
|
|
return objectMapper.contains( name );
|
|
}
|
|
|
|
|
|
/*!
|
|
Unifies the entries in stringlist \a list. Should really be a TQStringList feature.
|
|
*/
|
|
TQStringList Uic::unique( const TQStringList& list )
|
|
{
|
|
TQStringList result;
|
|
if ( list.isEmpty() )
|
|
return result;
|
|
TQStringList l = list;
|
|
l.sort();
|
|
result += l.first();
|
|
for ( TQStringList::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
|
|
*/
|
|
TQString Uic::createObjectInstance( const TQString& objClass, const TQString& parent, const TQString& 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 TQString& name ) const
|
|
{
|
|
return layoutObjects.contains( name );
|
|
}
|