/**********************************************************************
** Copyright (C) 2000-2002 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.
**
**********************************************************************/
/* Modifications by Marc Britton (c) 2002 under GNU GPL, terms as above */

#include <kconfig.h>
#include <klibloader.h>

#include "kommanderfactory.h"
#include <kommanderplugin.h>

#ifdef QT_NO_SQL
#define TQT_NO_SQL
#endif // QT_NO_SQL

#include <tqfeatures.h>
#include "config.h"
#ifndef TQT_NO_SQL
#include "database2.h"
#endif
#include <tqdom.h>
#include <tqdir.h>
#include <tqlayout.h>
#include <tqmetaobject.h>
#include "domtool.h"
#include <tqapplication.h>
#include <tqtooltip.h>
#include <tqwhatsthis.h>
#include <tqobjectlist.h>
#include <tqpluginmanager_p.h>
#include <tqmime.h>
#include <tqdragobject.h>
#include <zlib.h>

#ifndef TQT_NO_SQL
#include <tqsqlrecord.h>
#include <tqsqldatabase.h>
#include <tqdatatable.h>
#endif

// include all TQt widgets we support
#include <tqpushbutton.h>
#include <tqtoolbutton.h>
#include <tqcheckbox.h>
#include <tqradiobutton.h>
#include <tqgroupbox.h>
#include <tqbuttongroup.h>
#include <tqiconview.h>
#include <tqheader.h>
#ifndef TQT_NO_TABLE
#include <tqtable.h>
#endif
#include <tqlistbox.h>
#include <tqlistview.h>
#include <tqlineedit.h>
#include <tqspinbox.h>
#include <tqmultilineedit.h>
#include <tqlabel.h>
#include <tqwidget.h>
#include <tqtabwidget.h>
#include <tqcombobox.h>
#include <tqdialog.h>
#include <tqwizard.h>
#include <tqlcdnumber.h>
#include <tqprogressbar.h>
#include <tqtextview.h>
#include <tqtextbrowser.h>
#include <tqdial.h>
#include <tqslider.h>
#include <tqframe.h>
#include <tqwidgetstack.h>
#include <tqtextedit.h>
#include <tqscrollbar.h>
#include <tqmainwindow.h>
#include <tqsplitter.h>
#include <tqaction.h>
#include <tqpopupmenu.h>
#include <tqmenubar.h>
#include <tqdatetimeedit.h>
#include <tqtoolbox.h>

#include <stdlib.h>
#include <kglobal.h>
#include <klocale.h>

#include "kmdrmainwindow.h"

TQPtrList<KommanderPlugin> widgetPlugins;

TQMap<TQWidget*, TQString> *qwf_functions = 0;
TQMap<TQWidget*, TQString> *qwf_forms = 0;
TQString *qwf_language = 0;
bool qwf_execute_code = true;
bool qwf_stays_on_top = false;
TQString *qwf_currFileName = 0L; //is this really used?

KommanderFactory::KommanderFactory()
    : dbControls( 0 ), usePixmapCollection( false )
{
    widgetPlugins.setAutoDelete( true );
    defSpacing = 6;
    defMargin = 11;
    if (!qwf_currFileName)
      qwf_currFileName = new TQString();
}

KommanderFactory::~KommanderFactory()
{
  delete qwf_currFileName;
  qwf_currFileName = 0L;
}

TQWidget *KommanderFactory::create( const TQString &uiFile, TQObject *connector, TQWidget *parent, const char *name )
{
    TQFile f( uiFile );
    if ( !f.open( IO_ReadOnly ) )
      return 0;

    if (!qwf_currFileName)
      qwf_currFileName = new TQString();
    *qwf_currFileName = uiFile;
    TQWidget *w = KommanderFactory::create( TQT_TQIODEVICE(&f), connector, parent, name );
    if ( !qwf_forms )
	qwf_forms = new TQMap<TQWidget*, TQString>;
    qwf_forms->insert( w, uiFile );
    return w;
}

TQWidget *KommanderFactory::create( TQIODevice *dev, TQObject *connector, TQWidget *parent, const char *name )
{
    TQDomDocument doc;
    TQString errMsg;
    int errLine;
    TQTextStream stream(dev);
    TQString content = stream.read();
    if (content.startsWith("#!"))
      content = content.mid(content.find('\n'));
    if ( !doc.setContent( content ) ) {
// 	tqDebug( TQString("Parse error: ") + errMsg + TQString(" in line %d"), errLine );
	return 0;
    }

    DomTool::fixDocument( doc );

    KommanderFactory *widgetFactory = new KommanderFactory;
    widgetFactory->toplevel = 0;

    TQDomElement e = doc.firstChild().toElement().firstChild().toElement();

    TQDomElement variables = e;
    while ( variables.tagName() != "variables" && !variables.isNull() )
	variables = variables.nextSibling().toElement();

    TQDomElement eltSlots = e;
    while ( eltSlots.tagName() != "slots" && !eltSlots.isNull() )
	eltSlots = eltSlots.nextSibling().toElement();

    TQDomElement connections = e;
    while ( connections.tagName() != "connections" && !connections.isNull() )
	connections = connections.nextSibling().toElement();

    TQDomElement imageCollection = e;
    while ( imageCollection.tagName() != "images" && !imageCollection.isNull() )
	imageCollection = imageCollection.nextSibling().toElement();

    TQDomElement tabOrder = e;
    while ( tabOrder.tagName() != "tabstops" && !tabOrder.isNull() )
	tabOrder = tabOrder.nextSibling().toElement();

    TQDomElement actions = e;
    while ( actions.tagName() != "actions" && !actions.isNull() )
	actions = actions.nextSibling().toElement();

    TQDomElement toolbars = e;
    while ( toolbars.tagName() != "toolbars" && !toolbars.isNull() )
	toolbars = toolbars.nextSibling().toElement();

    TQDomElement menubar = e;
    while ( menubar.tagName() != "menubar" && !menubar.isNull() )
	menubar = menubar.nextSibling().toElement();

    TQDomElement functions = e;
    while ( functions.tagName() != "functions" && !functions.isNull() )
	functions = functions.nextSibling().toElement();

    TQDomElement widget;
    while ( !e.isNull() ) {
	if ( e.tagName() == "widget" ) {
	    widget = e;
	} else if ( e.tagName() == "variable" ) { // compatibility with old betas
	    widgetFactory->variables << e.firstChild().toText().data();
	} else if ( e.tagName() == "pixmapinproject" ) {
	    widgetFactory->usePixmapCollection = true;
	} else if ( e.tagName() == "layoutdefaults" ) {
	    widgetFactory->defSpacing = e.attribute( "spacing", TQString::number( widgetFactory->defSpacing ) ).toInt();
	    widgetFactory->defMargin = e.attribute( "margin", TQString::number( widgetFactory->defMargin ) ).toInt();
	}
	e = e.nextSibling().toElement();
    }

    if ( !imageCollection.isNull() )
	widgetFactory->loadImageCollection( imageCollection );

    widgetFactory->createWidgetInternal( widget, parent, 0, widget.attribute("class", TQWIDGET_OBJECT_NAME_STRING) );
    TQWidget *w = widgetFactory->toplevel;
    if ( !w ) {
	delete widgetFactory;
	return 0;
    }

    if ( !variables.isNull() ) {
	for ( TQDomElement n = variables.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() )
	    if ( n.tagName() == "variable" )
		widgetFactory->variables << n.firstChild().toText().data();
    }
    if ( !eltSlots.isNull() ) {
	for ( TQDomElement n = eltSlots.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() )
	    if ( n.tagName() == "slot" ) {
		TQString s = n.firstChild().toText().data();
		widgetFactory->languageSlots.insert( s.left( s.find( "(" ) ) , n.attribute( "language", "C++" ) );
	    }
    }

    if ( !actions.isNull() )
	widgetFactory->loadActions( actions );
    if ( !toolbars.isNull() )
	widgetFactory->loadToolBars( toolbars );
    if ( !menubar.isNull() )
	widgetFactory->loadMenuBar( menubar );

    if ( !connections.isNull() )
	widgetFactory->loadConnections( connections, connector );
    if ( w && name && tqstrlen( name ) > 0 )
	w->setName( name );

    if ( !tabOrder.isNull() )
	widgetFactory->loadTabOrder( tabOrder );


    if ( widgetFactory->toplevel ) {
#ifndef TQT_NO_SQL
	TQMap<TQWidget*, SqlWidgetConnection>::Iterator cit = widgetFactory->sqlWidgetConnections.begin();
	for( ; cit != widgetFactory->sqlWidgetConnections.end(); ++cit ) {
	    if ( widgetFactory->noDatabaseWidgets.find( cit.key()->name() ) != widgetFactory->noDatabaseWidgets.end() )
		continue;
	    if ( cit.key()->inherits( "QDesignerDataBrowser2" ) )
		( (QDesignerDataBrowser2*)cit.key() )->initPreview( (*cit).conn, (*cit).table, cit.key(), *(*cit).dbControls );
	    else if ( cit.key()->inherits( "QDesignerDataView2" ) )
		( (QDesignerDataView2*)cit.key() )->initPreview( (*cit).conn, (*cit).table, cit.key(), *(*cit).dbControls );
	}

	for ( TQMap<TQString, TQStringList>::Iterator it = widgetFactory->dbTables.begin(); it != widgetFactory->dbTables.end(); ++it ) {
	    TQDataTable *table = (TQDataTable*)widgetFactory->toplevel->child( it.key(), TQDATATABLE_OBJECT_NAME_STRING );
	    if ( !table )
		continue;
	    if ( widgetFactory->noDatabaseWidgets.find( table->name() ) != widgetFactory->noDatabaseWidgets.end() )
		continue;
	    TQValueList<Field> fieldMap = *widgetFactory->fieldMaps.find( table );
	    TQString conn = (*it)[ 0 ];
	    TQSqlCursor* c = 0;
	    TQSqlDatabase *db = 0;
	    if ( conn.isEmpty() || conn == "(default)" ) {
		db = TQSqlDatabase::database();
		c = new TQSqlCursor( (*it)[ 1 ] );
	    } else {
		db = TQSqlDatabase::database( conn );
		c = new TQSqlCursor( (*it)[ 1 ], true, db );
	    }
	    if ( db ) {
		table->setSqlCursor( c, fieldMap.isEmpty(), true );
		table->refresh( TQDataTable::RefreshAll );
	    }
	}
#endif

    }

    for ( TQMap<TQString, TQString>::Iterator it = widgetFactory->buddies.begin(); it != widgetFactory->buddies.end(); ++it ) {
	TQLabel *label = (TQLabel*)widgetFactory->toplevel->child( it.key(), TQLABEL_OBJECT_NAME_STRING );
	TQWidget *buddy = (TQWidget*)widgetFactory->toplevel->child( *it, TQWIDGET_OBJECT_NAME_STRING );
	if ( label && buddy )
	    label->setBuddy( buddy );
    }

    delete widgetFactory;

    TQApplication::sendPostedEvents();

    return w;
}

void KommanderFactory::addPlugin( KommanderPlugin *plugin )
{
    widgetPlugins.append( plugin );
}

TQWidget *KommanderFactory::createWidget( const TQString &literalClassName, TQWidget *parent, const char *name )
{
  TQString className = literalClassName;

  // create widgets we know
  if (className == TQPUSHBUTTON_OBJECT_NAME_STRING)
    return new TQPushButton(parent, name);
  else if (className == TQTOOLBUTTON_OBJECT_NAME_STRING)
    return new TQToolButton(parent, name);
  else if (className == TQCHECKBOX_OBJECT_NAME_STRING)
    return new TQCheckBox(parent, name);
  else if (className == TQRADIOBUTTON_OBJECT_NAME_STRING)
    return new TQRadioButton(parent, name);
  else if (className == TQGROUPBOX_OBJECT_NAME_STRING)
    return new TQGroupBox(parent, name);
  else if (className == TQBUTTONGROUP_OBJECT_NAME_STRING)
    return new TQButtonGroup(parent, name);
  else if (className == TQICONVIEW_OBJECT_NAME_STRING)
  {
#if !defined(TQT_NO_ICONVIEW)
    return new TQIconView(parent, name);
#endif
  }
  else if (className == TQTABLE_OBJECT_NAME_STRING)
  {
#if !defined(TQT_NO_TABLE)
    return new TQTable(parent, name);
#endif
  }
  else if (className == TQLISTBOX_OBJECT_NAME_STRING)
    return new TQListBox(parent, name);
  else if (className == TQLISTVIEW_OBJECT_NAME_STRING)
    return new TQListView(parent, name);
  else if (className == TQLINEEDIT_OBJECT_NAME_STRING)
    return new TQLineEdit(parent, name);
  else if (className == TQSPINBOX_OBJECT_NAME_STRING)
    return new TQSpinBox(parent, name);
  else if (className == TQMULTILINEEDIT_OBJECT_NAME_STRING)
    return new TQMultiLineEdit(parent, name);
  else if (className == TQLABEL_OBJECT_NAME_STRING)
    return new TQLabel(parent, name);
  else if (className == TQLAYOUTWIDGET_OBJECT_NAME_STRING)
    return new TQWidget(parent, name);
  else if (className == TQTABWIDGET_OBJECT_NAME_STRING)
    return new TQTabWidget(parent, name);
  else if (className == TQCOMBOBOX_OBJECT_NAME_STRING)
    return new TQComboBox(false, parent, name);
  else if (className == TQWIDGET_OBJECT_NAME_STRING)
  {
    if (!qwf_stays_on_top)
      return new TQWidget(parent, name);
    return new TQWidget(parent, name, TQt::WStyle_StaysOnTop);
  }
  else if (className == TQDIALOG_OBJECT_NAME_STRING)
  {
    if (!qwf_stays_on_top)
      return new TQDialog(parent, name);
    return new TQDialog(parent, name, false, TQt::WStyle_StaysOnTop);
  }
  else if (className == TQWIZARD_OBJECT_NAME_STRING)
    return new TQWizard(parent, name);
  else if (className == TQLCDNUMBER_OBJECT_NAME_STRING)
    return new TQLCDNumber(parent, name);
  else if (className == TQPROGRESSBAR_OBJECT_NAME_STRING)
    return new TQProgressBar(parent, name);
  else if (className == TQTEXTVIEW_OBJECT_NAME_STRING)
    return new TQTextView(parent, name);
  else if (className == TQTEXTBROWSER_OBJECT_NAME_STRING)
    return new TQTextBrowser(parent, name);
  else if (className == TQDIAL_OBJECT_NAME_STRING)
    return new TQDial(parent, name);
  else if (className == TQSLIDER_OBJECT_NAME_STRING)
    return new TQSlider(parent, name);
  else if (className == TQFRAME_OBJECT_NAME_STRING)
    return new TQFrame(parent, name);
  else if (className == TQSPLITTER_OBJECT_NAME_STRING)
    return new TQSplitter(parent, name);
  else if (className == "Line")
  {
    TQFrame *f = new TQFrame(parent, name);
    f->setFrameStyle(TQFrame::HLine | TQFrame::Sunken);
    return f;
  }
  else if (className == TQTEXTEDIT_OBJECT_NAME_STRING)
    return new TQTextEdit(parent, name);
  else if (className == TQDATEEDIT_OBJECT_NAME_STRING)
    return new TQDateEdit(parent, name);
  else if (className == TQTIMEEDIT_OBJECT_NAME_STRING)
    return new TQTimeEdit(parent, name);
  else if (className == TQDATETIMEEDIT_OBJECT_NAME_STRING)
    return new TQDateTimeEdit(parent, name);
  else if (className == TQSCROLLBAR_OBJECT_NAME_STRING)
    return new TQScrollBar(parent, name);
  else if (className == TQPOPUPMENU_OBJECT_NAME_STRING)
    return new TQPopupMenu(parent, name);
  else if (className == TQWIDGETSTACK_OBJECT_NAME_STRING)
    return new TQWidgetStack(parent, name);
  else if (className == TQMAINWINDOW_OBJECT_NAME_STRING)
  {
    TQMainWindow *mw = 0;
    if (!qwf_stays_on_top)
      mw = new KmdrMainWindow(parent, name);
    else
      mw = new KmdrMainWindow(parent, name, TQt::WType_TopLevel | TQt::WStyle_StaysOnTop);
    mw->setCentralWidget(new TQWidget(mw, "qt_central_widget"));
    mw->centralWidget()->show();
    (void) mw->statusBar();
    return mw;
  }
#if !defined(TQT_NO_SQL)
  else if (className == TQDATATABLE_OBJECT_NAME_STRING)
    return new TQDataTable(parent, name);
  else if (className == TQDATABROWSER_OBJECT_NAME_STRING)
    return new QDesignerDataBrowser2(parent, name);
  else if (className == TQDATAVIEW_OBJECT_NAME_STRING)
    return new QDesignerDataView2(parent, name);
#endif

  // try to create it using the loaded kommander widget plugins
  //find the widget plugin which can create className
  for (KommanderPlugin * p = widgetPlugins.first(); p; p = widgetPlugins.next())
  {
    TQWidget *w = p->create(className, parent, name);
    if (w)
      return w;
  }

  // no success
  return 0;
}

static int num_plugins_loaded = 0;

int KommanderFactory::loadPlugins(bool force)
{
  if (num_plugins_loaded > 0 && !force)
    return num_plugins_loaded;

  num_plugins_loaded = 0;
  KConfig cfg("kommanderrc", true);
  TQStringList plugins = "libkommanderwidgets";
  plugins += cfg.readListEntry("plugins");
  TQStringList::Iterator it;
  KLibLoader *f = KLibLoader::self();
  for (it = plugins.begin(); it != plugins.end(); ++it)
  {
    KLibrary *l = f->library((*it).latin1());
    if (l)
    {
      if (l->hasSymbol("kommander_plugin"))
      {
        void *(*kommander_plugin) () = (void *(*)()) l->symbol("kommander_plugin");
        KommanderPlugin *p = (KommanderPlugin *) (*kommander_plugin) ();
        widgetPlugins.append(p);
        ++num_plugins_loaded;
      } else
      {
        tqWarning("KommanderFactory::loadPlugins - '%s' isn't a Kommander Plugin library, skipping.",
            l->fileName().latin1());
      }
    } else
    {
      tqWarning("KommanderFactory::loadPlugins - Can't load Kommander plugin library %s",
          (*it).latin1());
    }
  }
  //tqDebug("KommanderFactory::loadPlugins returning %d", num_plugins_loaded);
  return num_plugins_loaded;
}

FeatureList KommanderFactory::featureList()
{
    FeatureList features;
    for ( KommanderPlugin *p = widgetPlugins.first(); p ; p = widgetPlugins.next() )
    {
	TQStringList widgets = p->widgets();
	TQStringList::Iterator it;
	for( it = widgets.begin() ; it != widgets.end() ; ++it )
	{
	    TQString wn = *it;
	    features[wn] = KommanderWidgetInfo( p->group(wn), p->toolTip(wn),p->iconSet(wn), p->whatsThis(wn), p->isContainer(wn) );
	}
    }
    return features;
    //iterate through widgetPlugins, appending KommanderPlugin::widgets() to features
}

TQWidget *KommanderFactory::createWidgetInternal( const TQDomElement &e, TQWidget *parent, TQLayout* layout, const TQString &classNameArg )
{
    lastItem = 0;
    TQDomElement n = e.firstChild().toElement();
    TQWidget *w = 0; // the widget that got created
    TQObject *obj = 0; // gets the properties

    TQString className = classNameArg;

    int row = e.attribute( "row" ).toInt();
    int col = e.attribute( "column" ).toInt();
    int rowspan = e.attribute( "rowspan" ).toInt();
    int colspan = e.attribute( "colspan" ).toInt();
    if ( rowspan < 1 )
	rowspan = 1;
    if ( colspan < 1 )
	colspan = 1;
    if ( !className.isEmpty() ) {
	if ( !layout && className  == TQLAYOUTWIDGET_OBJECT_NAME_STRING )
	    className = TQWIDGET_OBJECT_NAME_STRING;
	if ( layout && className == TQLAYOUTWIDGET_OBJECT_NAME_STRING ) {
	    // hide layout widgets
	    w = parent;
	} else {
	    obj = TQT_TQOBJECT(KommanderFactory::createWidget( className, parent, 0 ));
	    if ( !obj )
	    {
		return 0;
	    }
	    w = (TQWidget*)obj;
	    if ( !toplevel )
		toplevel = w;
	    if ( w->inherits( TQMAINWINDOW_OBJECT_NAME_STRING ) )
		w = ( (TQMainWindow*)w )->centralWidget();
	    if ( layout ) {
		switch( layoutType( layout ) ) {
		case HBox:
		    ( (TQHBoxLayout*)layout )->addWidget( w );
		    break;
		case VBox:
		    ( (TQVBoxLayout*)layout )->addWidget( w );
		    break;
		case Grid:
		    ( (TQGridLayout*)layout )->addMultiCellWidget( w, row, row + rowspan - 1,
								  col, col + colspan - 1 );
		    break;
		default:
		    break;
		}
	    }

	    layout = 0;
	}
    }
    if (className == "Dialog")
       w->setProperty( "useInternalParser", false );

    while ( !n.isNull() ) {
	if ( n.tagName() == "spacer" ) {
	    createSpacer( n, layout );
	} else if ( n.tagName() == "widget" ) {
	    TQMap< TQString, TQString> *oldDbControls = dbControls;
	    createWidgetInternal( n, w, layout, n.attribute( "class", TQWIDGET_OBJECT_NAME_STRING ) );
	    dbControls = oldDbControls;
	} else if ( n.tagName() == "hbox" ) {
	    TQLayout *parentLayout = layout;
	    if ( layout && layout->inherits( TQGRIDLAYOUT_OBJECT_NAME_STRING ) )
		layout = createLayout( 0, 0, KommanderFactory::HBox );
	    else
		layout = createLayout( w, layout, KommanderFactory::HBox );
	    obj = TQT_TQOBJECT(layout);
	    n = n.firstChild().toElement();
	    if ( parentLayout && parentLayout->inherits( TQGRIDLAYOUT_OBJECT_NAME_STRING ) )
		( (TQGridLayout*)parentLayout )->addMultiCellLayout( layout, row, row + rowspan - 1, col, col + colspan - 1 );
	    continue;
	} else if ( n.tagName() == "grid" ) {
	    TQLayout *parentLayout = layout;
	    if ( layout && layout->inherits( TQGRIDLAYOUT_OBJECT_NAME_STRING ) )
		layout = createLayout( 0, 0, KommanderFactory::Grid );
	    else
		layout = createLayout( w, layout, KommanderFactory::Grid );
	    obj = TQT_TQOBJECT(layout);
	    n = n.firstChild().toElement();
	    if ( parentLayout && parentLayout->inherits( TQGRIDLAYOUT_OBJECT_NAME_STRING ) )
		( (TQGridLayout*)parentLayout )->addMultiCellLayout( layout, row, row + rowspan - 1, col, col + colspan - 1 );
	    continue;
	} else if ( n.tagName() == "vbox" ) {
	    TQLayout *parentLayout = layout;
	    if ( layout && layout->inherits( TQGRIDLAYOUT_OBJECT_NAME_STRING ) )
		layout = createLayout( 0, 0, KommanderFactory::VBox );
	    else
		layout = createLayout( w, layout, KommanderFactory::VBox );
	    obj = TQT_TQOBJECT(layout);
	    n = n.firstChild().toElement();
	    if ( parentLayout && parentLayout->inherits( TQGRIDLAYOUT_OBJECT_NAME_STRING ) )
		( (TQGridLayout*)parentLayout )->addMultiCellLayout( layout, row, row + rowspan - 1, col, col + colspan - 1 );
	    continue;
	} else if ( n.tagName() == "property" && obj ) {
	    setProperty( obj, n.attribute( "name" ), n.firstChild().toElement() );
	} else if ( n.tagName() == "attribute" && w ) {
	    TQString attrib = n.attribute( "name" );
	    TQVariant v = DomTool::elementToVariant( n.firstChild().toElement(), TQVariant() );
	    if ( parent->inherits( TQTABWIDGET_OBJECT_NAME_STRING ) ) {
		if ( attrib == "title" )
		    ( (TQTabWidget*)parent )->insertTab( w, translate(v.toString()) );
	    } else
        if ( parent->inherits( TQTOOLBOX_OBJECT_NAME_STRING ) ) {
        if ( attrib == "label" )
            ( (TQToolBox*)parent )->addItem( w, translate(v.toString()) );
        }else if ( parent->inherits( TQWIZARD_OBJECT_NAME_STRING ) ) {
		if ( attrib == "title" )
		    ( (TQWizard*)parent )->addPage( w, translate(v.toString()) );
	    }
	} else if ( n.tagName() == "item" ) {
	    createItem( n, w );
	} else if ( n.tagName() == "column" || n.tagName() == "row" ) {
	    createColumn( n, w );
	}

	n = n.nextSibling().toElement();
    }

    return w;
}

TQLayout *KommanderFactory::createLayout( TQWidget *widget, TQLayout*  layout, LayoutType type )
{
    int spacing = defSpacing;
    int margin = defMargin;

    if ( !layout && widget && widget->inherits( TQTABWIDGET_OBJECT_NAME_STRING ) )
	widget = ((TQTabWidget*)widget)->currentPage();
    if ( !layout && widget && widget->inherits( TQTOOLBOX_OBJECT_NAME_STRING ) )
    widget = ((TQToolBox*)widget)->currentItem();

    if ( !layout && widget && widget->inherits( TQWIZARD_OBJECT_NAME_STRING ) )
	widget = ((TQWizard*)widget)->currentPage();

    if ( !layout && widget && widget->inherits( TQWIDGETSTACK_OBJECT_NAME_STRING ) )
	widget = ((TQWidgetStack*)widget)->visibleWidget();

    if ( !layout && widget && widget->inherits( TQGROUPBOX_OBJECT_NAME_STRING ) ) {
	TQGroupBox *gb = (TQGroupBox*)widget;
	gb->setColumnLayout( 0, Qt::Vertical );
	gb->layout()->setMargin( 0 );
	gb->layout()->setSpacing( 0 );
	TQLayout *l;
	switch ( type ) {
	case HBox:
	    l = new TQHBoxLayout( gb->layout() );
	    l->setAlignment( TQt::AlignTop );
	    return l;
	case VBox:
	    l = new TQVBoxLayout( gb->layout(), spacing );
	    l->setAlignment( TQt::AlignTop );
	    return l;
	case Grid:
	    l = new TQGridLayout( gb->layout() );
	    l->setAlignment( TQt::AlignTop );
	    return l;
	default:
	    return 0;
	}
    } else {
	if ( layout ) {
	    TQLayout *l;
	    switch ( type ) {
	    case HBox:
		l = new TQHBoxLayout( layout );
		l->setSpacing( spacing );
		l->setMargin( margin );
		return l;
	    case VBox:
		l = new TQVBoxLayout( layout );
		l->setSpacing( spacing );
		l->setMargin( margin );
		return l;
	    case Grid: {
		l = new TQGridLayout( layout );
		l->setSpacing( spacing );
		l->setMargin( margin );
		return l;
	    }
	    default:
		return 0;
	    }
	} else {
	    TQLayout *l;
	    switch ( type ) {
	    case HBox:
		l = new TQHBoxLayout( widget );
		if ( !widget ) {
		    l->setMargin( margin );
		    l->setSpacing( spacing );
		}
		return l;
	    case VBox:
		l = new TQVBoxLayout( widget );
		if ( !widget ) {
		    l->setMargin( margin );
		    l->setSpacing( spacing );
		}
		return l;
	    case Grid: {
		l = new TQGridLayout( widget );
		if ( !widget ) {
		    l->setMargin( margin );
		    l->setSpacing( spacing );
		}
		return l;
	    }
	    default:
		return 0;
	    }
	}
    }
}

KommanderFactory::LayoutType KommanderFactory::layoutType( TQLayout *layout ) const
{
    if ( layout->inherits( TQHBOXLAYOUT_OBJECT_NAME_STRING ) )
	return HBox;
    else if ( layout->inherits( TQVBOXLAYOUT_OBJECT_NAME_STRING ) )
	return VBox;
    else if ( layout->inherits( TQGRIDLAYOUT_OBJECT_NAME_STRING ) )
	return Grid;
    return NoLayout;
}

void KommanderFactory::setProperty( TQObject* obj, const TQString &prop, const TQDomElement &e )
{
    const TQMetaProperty *p = obj->metaObject()->property( obj->metaObject()->findProperty( prop, true ), true );

    TQVariant defVariant;
    if ( e.tagName() == "font" ) {
	TQFont f( tqApp->font() );
	if ( obj->isWidgetType() && ( (TQWidget*)obj )->parentWidget() )
	    f = ( (TQWidget*)obj )->parentWidget()->font();
	defVariant = TQVariant( f );
    }

    TQString comment;
    TQVariant v( DomTool::elementToVariant( e, defVariant, comment ) );

    if ( e.tagName() == "pixmap" ) {
	TQPixmap pix = loadPixmap( e );
	if ( pix.isNull() )
	    return;
	v = TQVariant( pix );
    } else if ( e.tagName() == "iconset" ) {
	TQPixmap pix = loadPixmap( e );
	if ( pix.isNull() )
	    return;
	v = TQVariant( TQIconSet( pix ) );
    } else if ( e.tagName() == "image" ) {
	v = TQVariant( loadFromCollection( v.toString() ) );
    } else if ( e.tagName() == "string" ) {
	v = TQVariant( translate( v.asString(), comment ) );
    }

    if ( !p ) {
	if ( obj->isWidgetType() ) {
	    if ( prop == "toolTip" ) {
		if ( !v.toString().isEmpty() )
		    TQToolTip::add( (TQWidget*)obj, translate(v.toString()) );
	    } else if ( prop == "whatsThis" ) {
		if ( !v.toString().isEmpty() )
		    TQWhatsThis::add( (TQWidget*)obj, translate(v.toString()) );
	    }
#ifndef TQT_NO_SQL
	    if ( prop == "database" && !obj->inherits( TQDATAVIEW_OBJECT_NAME_STRING )
		 && !obj->inherits( TQDATABROWSER_OBJECT_NAME_STRING ) ) {
		TQStringList lst = DomTool::elementToVariant( e, TQVariant( TQStringList() ) ).toStringList();
		if ( lst.count() > 2 ) {
		    if ( dbControls )
			dbControls->insert( obj->name(), lst[ 2 ] );
		} else if ( lst.count() == 2 ) {
		    dbTables.insert( obj->name(), lst );
		}
	    } else if ( prop == "database" ) {
		TQStringList lst = DomTool::elementToVariant( e, TQVariant( TQStringList() ) ).toStringList();
		if ( lst.count() == 2 && obj->inherits( TQWIDGET_OBJECT_NAME_STRING ) ) {
		    SqlWidgetConnection conn( lst[ 0 ], lst[ 1 ] );
		    sqlWidgetConnections.insert( (TQWidget*)obj, conn );
		    dbControls = conn.dbControls;
		}
	    } else
#endif
		if ( prop == "buddy" ) {
		buddies.insert( obj->name(), v.toCString() );
	    } else if ( prop == "frameworkCode" ) {
		if ( !DomTool::elementToVariant( e, TQVariant( true, 0 ) ).toBool() ) {
		    noDatabaseWidgets << obj->name();
		}
	    } else if ( prop == "buttonGroupId" ) {
		if ( obj->inherits( TQBUTTON_OBJECT_NAME_STRING ) && obj->parent()->inherits( TQBUTTONGROUP_OBJECT_NAME_STRING ) )
		    ( (TQButtonGroup*)obj->parent() )->insert( (TQButton*)obj, v.toInt() );
	    }

	    return;
	}
    }

    if ( e.tagName() == "palette" ) {
	TQDomElement n = e.firstChild().toElement();
	TQPalette p;
	while ( !n.isNull() ) {
	    TQColorGroup cg;
	    if ( n.tagName() == "active" ) {
		cg = loadColorGroup( n );
		p.setActive( cg );
	    } else if ( n.tagName() == "inactive" ) {
		cg = loadColorGroup( n );
		p.setInactive( cg );
	    } else if ( n.tagName() == "disabled" ) {
		cg = loadColorGroup( n );
		p.setDisabled( cg );
	    }
	    n = n.nextSibling().toElement();
	}
	v = TQPalette( p );
    } else if ( e.tagName() == "enum" && p && p->isEnumType() ) {
	TQString key( v.toString() );
	v = TQVariant( p->keyToValue( key ) );
    } else if ( e.tagName() == "set" && p && p->isSetType() ) {
	TQString keys( v.toString() );
	TQStringList lst = TQStringList::split( '|', keys );
	TQStrList l;
	for ( TQStringList::Iterator it = lst.begin(); it != lst.end(); ++it )
	    l.append( *it );
	v = TQVariant( p->keysToValue( l ) );
    }

    if ( prop == "geometry" ) {
	if ( TQT_BASE_OBJECT(obj) == TQT_BASE_OBJECT(toplevel) ) {
	    toplevel->resize( v.toRect().size() );
	    return;
	}
    }

    obj->setProperty( prop, v );
}

void KommanderFactory::createSpacer( const TQDomElement &e, TQLayout *layout )
{
    TQDomElement n = e.firstChild().toElement();
    int row = e.attribute( "row" ).toInt();
    int col = e.attribute( "column" ).toInt();
    int rowspan = e.attribute( "rowspan" ).toInt();
    int colspan = e.attribute( "colspan" ).toInt();

    Qt::Orientation orient = Qt::Horizontal;
    int w = 0, h = 0;
    TQSizePolicy::SizeType sizeType = TQSizePolicy::Preferred;
    while ( !n.isNull() ) {
	if ( n.tagName() == "property" ) {
	    TQString prop = n.attribute( "name" );
	    if ( prop == "orientation" ) {
		if ( n.firstChild().firstChild().toText().data() == "Horizontal" )
		    orient = Qt::Horizontal;
		else
		    orient = Qt::Vertical;
	    } else if ( prop == "sizeType" ) {
		if ( n.firstChild().firstChild().toText().data() == "Fixed" )
		    sizeType = TQSizePolicy::Fixed;
		else if ( n.firstChild().firstChild().toText().data() == "Minimum" )
		    sizeType = TQSizePolicy::Minimum;
		else if ( n.firstChild().firstChild().toText().data() == "Maximum" )
		    sizeType = TQSizePolicy::Maximum;
		else if ( n.firstChild().firstChild().toText().data() == "Preferred" )
		    sizeType = TQSizePolicy::Preferred;
		else if ( n.firstChild().firstChild().toText().data() == "MinimumExpanding" )
		    sizeType = TQSizePolicy::MinimumExpanding;
		else if ( n.firstChild().firstChild().toText().data() == "Expanding" )
		    sizeType = TQSizePolicy::Expanding;
	    } else if ( prop == "sizeHint" ) {
		w = n.firstChild().firstChild().firstChild().toText().data().toInt();
		h = n.firstChild().firstChild().nextSibling().firstChild().toText().data().toInt();
	    }
	}
	n = n.nextSibling().toElement();
    }

    if ( rowspan < 1 )
	rowspan = 1;
    if ( colspan < 1 )
	colspan = 1;
    TQSpacerItem *item = new TQSpacerItem( w, h, orient == Qt::Horizontal ? sizeType : TQSizePolicy::Minimum,
					 orient == Qt::Vertical ? sizeType : TQSizePolicy::Minimum );
    if ( layout ) {
	if ( layout->inherits( TQBOXLAYOUT_OBJECT_NAME_STRING ) )
	    ( (TQBoxLayout*)layout )->addItem( item );
	else
	    ( (TQGridLayout*)layout )->addMultiCell( item, row, row + rowspan - 1, col, col + colspan - 1,
						    orient == Qt::Horizontal ? TQt::AlignVCenter : TQt::AlignHCenter );
    }
}

static TQImage loadImageData( TQDomElement &n2 )
{
    TQImage img;
    TQString data = n2.firstChild().toText().data();
    char *ba = new char[ 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;
    }
    TQString format = n2.attribute( "format", "PNG" );
    if ( format == "XPM.GZ" ) {
	ulong len = n2.attribute( "length" ).toULong();
	if ( len < data.length() * 5 )
	    len = data.length() * 5;
	TQByteArray baunzip( len );
	::uncompress( (uchar*) baunzip.data(), &len, (uchar*) ba, data.length()/2 );
	img.loadFromData( (const uchar*)baunzip.data(), len, "XPM" );
    }  else {
	img.loadFromData( (const uchar*)ba, data.length() / 2, format );
    }
    delete [] ba;

    return img;
}

void KommanderFactory::loadImageCollection( const TQDomElement &e )
{
    TQDomElement n = e.firstChild().toElement();
    while ( !n.isNull() ) {
	if ( n.tagName() == "image" ) {
	    Image img;
	    img.name =  n.attribute( "name" );
	    TQDomElement n2 = n.firstChild().toElement();
	    while ( !n2.isNull() ) {
		if ( n2.tagName() == "data" )
		    img.img = loadImageData( n2 );
		n2 = n2.nextSibling().toElement();
	    }
	    images.append( img );
	    n = n.nextSibling().toElement();
	}
    }
}

TQImage KommanderFactory::loadFromCollection( const TQString &name )
{
    TQValueList<Image>::Iterator it = images.begin();
    for ( ; it != images.end(); ++it ) {
	if ( ( *it ).name == name )
	    return ( *it ).img;
    }
    return TQImage();
}

TQPixmap KommanderFactory::loadPixmap( const TQDomElement &e )
{
    TQString arg = e.firstChild().toText().data();
    if ( usePixmapCollection ) {
	const TQMimeSource *m = TQMimeSourceFactory::defaultFactory()->data( arg );
	if ( !m )
	    return TQPixmap();
	TQPixmap pix;
	TQImageDrag::decode( m, pix );
	return pix;
    }

    TQImage img = loadFromCollection( arg );
    TQPixmap pix;
    pix.convertFromImage( img );
    return pix;
}

TQColorGroup KommanderFactory::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 ) ) );
	} else if ( n.tagName() == "pixmap" ) {
	    TQPixmap pix = loadPixmap( n );
	    cg.setBrush( (TQColorGroup::ColorRole)r, TQBrush( col, pix ) );
	}
	n = n.nextSibling().toElement();
    }
    return cg;
}

struct Connection
{
    TQObject *sender, *receiver;
    TQCString signal, slot;
    bool operator==( const Connection &c ) const {
	return sender == c.sender && receiver == c.receiver &&
	       signal == c.signal && slot == c.slot ;
    }
};

class NormalizeObject : public TQObject
{
public:
    NormalizeObject() : TQObject() {}
    static TQCString normalizeSignalSlot( const char *signalSlot ) { return TQObject::normalizeSignalSlot( signalSlot ); }
};

void KommanderFactory::loadConnections( const TQDomElement &e, TQObject *connector )
{
    TQDomElement n = e.firstChild().toElement();
    while ( !n.isNull() ) {
	if ( n.tagName() == "connection" ) {
	    TQString lang = n.attribute( "language", "C++" );
	    TQDomElement n2 = n.firstChild().toElement();
	    Connection conn;
	    while ( !n2.isNull() ) {
		if ( n2.tagName() == "sender" ) {
		    TQString name = n2.firstChild().toText().data();
		    if ( name == "this" || qstrcmp( toplevel->name(), name ) == 0 ) {
			conn.sender = TQT_TQOBJECT(toplevel);
		    } else {
			if ( name == "this" )
			    name = toplevel->name();
			TQObjectList *l = toplevel->queryList( 0, name, false );
			if ( l ) {
			    if ( l->first() )
				conn.sender = l->first();
			    delete l;
			}
		    }
		    if ( !conn.sender )
			conn.sender = findAction( name );
		} else if ( n2.tagName() == "signal" ) {
		    conn.signal = n2.firstChild().toText().data();
		} else if ( n2.tagName() == "receiver" ) {
		    TQString name = n2.firstChild().toText().data();
		    if ( name == "this" || qstrcmp( toplevel->name(), name ) == 0 ) {
			conn.receiver = TQT_TQOBJECT(toplevel);
		    } else {
			TQObjectList *l = toplevel->queryList( 0, name, false );
			if ( l ) {
			    if ( l->first() )
				conn.receiver = l->first();
			    delete l;
			}
		    }
		} else if ( n2.tagName() == "slot" ) {
		    conn.slot = n2.firstChild().toText().data();
		}
		n2 = n2.nextSibling().toElement();
	    }

	    conn.signal = NormalizeObject::normalizeSignalSlot( conn.signal );
	    conn.slot = NormalizeObject::normalizeSignalSlot( conn.slot );

	    TQObject *sender = 0, *receiver = 0;
	    TQObjectList *l = toplevel->queryList( 0, conn.sender->name(), false );
	    if ( qstrcmp( conn.sender->name(), toplevel->name() ) == 0 ) {
		sender = TQT_TQOBJECT(toplevel);
	    } else {
		if ( !l || !l->first() ) {
		    delete l;
		    n = n.nextSibling().toElement();
		    continue;
		}
		sender = l->first();
		delete l;
	    }
	    if ( !sender )
		sender = findAction( conn.sender->name() );

	    if ( qstrcmp( conn.receiver->name(), toplevel->name() ) == 0 ) {
		receiver = TQT_TQOBJECT(toplevel);
	    } else {
		l = toplevel->queryList( 0, conn.receiver->name(), false );
		if ( !l || !l->first() ) {
		    delete l;
		    n = n.nextSibling().toElement();
		    continue;
		}
		receiver = l->first();
		delete l;
	    }

	    if ( lang == "C++" ) {
		TQString s = "2""%1";
		s = s.arg( conn.signal.data() );
		TQString s2 = "1""%1";
		s2 = s2.arg( conn.slot.data() );

		TQStrList signalList = sender->metaObject()->signalNames( true );
		TQStrList slotList = receiver->metaObject()->slotNames( true );

		// if this is a connection to a custom slot and we have a connector, try this as receiver
		if ( slotList.find( conn.slot ) == -1 && TQT_BASE_OBJECT(receiver) == TQT_BASE_OBJECT(toplevel) && connector ) {
		    slotList = connector->metaObject()->slotNames( true );
		    receiver = connector;
		}

		// avoid warnings
		if ( signalList.find( conn.signal ) == -1 ||
		     slotList.find( conn.slot ) == -1 ) {
		    n = n.nextSibling().toElement();
		    continue;
		}
		TQObject::connect( sender, s, receiver, s2 );
	    } else {
		EventFunction ef = eventMap[ conn.sender ];
		ef.events.append( conn.signal );
		ef.functions.append( TQStringList::split( ',', conn.slot ) );
		eventMap.replace( conn.sender, ef );
	    }
	} else if ( n.tagName() == "slot" ) {
	    TQString s = n.firstChild().toText().data();
	    languageSlots.insert( s.left( s.find( "(" ) ) , n.attribute( "language" ) );
	}
	n = n.nextSibling().toElement();
    }
}

void KommanderFactory::loadTabOrder( const TQDomElement &e )
{
    TQWidget *last = 0;
    TQDomElement n = e.firstChild().toElement();
    while ( !n.isNull() ) {
	if ( n.tagName() == "tabstop" ) {
	    TQString name = n.firstChild().toText().data();
	    TQObjectList *l = toplevel->queryList( 0, name, false );
	    if ( l ) {
		if ( l->first() ) {
		    TQWidget *w = (TQWidget*)l->first();
		    if ( last )
			toplevel->setTabOrder( last, w );
		    last = w;
		}
		delete l;
	    }
	}
	n = n.nextSibling().toElement();
    }
}

void KommanderFactory::createColumn( const TQDomElement &e, TQWidget *widget )
{
    if ( widget->inherits( TQLISTVIEW_OBJECT_NAME_STRING ) && e.tagName() == "column" ) {
	TQListView *lv = (TQListView*)widget;
	TQDomElement n = e.firstChild().toElement();
	TQPixmap pix;
	bool hasPixmap = false;
	TQString txt;
	bool clickable = true, resizeable = true;
	while ( !n.isNull() ) {
	    if ( n.tagName() == "property" ) {
		TQString attrib = n.attribute( "name" );
		TQVariant v = DomTool::elementToVariant( n.firstChild().toElement(), TQVariant() );
		if ( attrib == "text" )
		    txt = translate(v.toString());
		else if ( attrib == "pixmap" ) {
		    pix = loadPixmap( n.firstChild().toElement().toElement() );
		    hasPixmap = !pix.isNull();
		} else if ( attrib == "clickable" )
		    clickable = v.toBool();
		else if ( attrib == "resizeable" )
		    resizeable = v.toBool();
	    }
	    n = n.nextSibling().toElement();
	}
	lv->addColumn( txt );
	int i = lv->header()->count() - 1;
	if ( hasPixmap ) {
	    lv->header()->setLabel( i, pix, txt );
	}
	if ( !clickable )
	    lv->header()->setClickEnabled( clickable, i );
	if ( !resizeable )
	    lv->header()->setResizeEnabled( resizeable, i );
    }
#ifndef TQT_NO_TABLE
    else if ( widget->inherits( TQTABLE_OBJECT_NAME_STRING ) ) {
	TQTable *table = (TQTable*)widget;
#ifndef TQT_NO_SQL
	bool isSql = (widget->inherits( TQDATATABLE_OBJECT_NAME_STRING ));
#endif
	bool isRow;
	if ( ( isRow = e.tagName() == "row" ) )
	    table->setNumRows( table->numRows() + 1 );
	else {
#ifndef TQT_NO_SQL
	    if ( !isSql )
#endif
		table->setNumCols( table->numCols() + 1 );
	}

	TQDomElement n = e.firstChild().toElement();
	TQPixmap pix;
	bool hasPixmap = false;
	TQString txt;
	TQString field;
	TQValueList<Field> fieldMap;
	if ( fieldMaps.find( table ) != fieldMaps.end() ) {
	    fieldMap = *fieldMaps.find( table );
	    fieldMaps.remove( table );
	}
	while ( !n.isNull() ) {
	    if ( n.tagName() == "property" ) {
		TQString attrib = n.attribute( "name" );
		TQVariant v = DomTool::elementToVariant( n.firstChild().toElement(), TQVariant() );
		if ( attrib == "text" )
		    txt = translate(v.toString());
		else if ( attrib == "pixmap" ) {
		    hasPixmap = !n.firstChild().firstChild().toText().data().isEmpty();
		    if ( hasPixmap )
			pix = loadPixmap( n.firstChild().toElement().toElement() );
		} else if ( attrib == "field" )
		    field = v.toString();
	    }
	    n = n.nextSibling().toElement();
	}

	int i = isRow ? table->numRows() - 1 : table->numCols() - 1;
	TQHeader *h = !isRow ? table->horizontalHeader() : table->verticalHeader();
	if ( hasPixmap ) {
#ifndef TQT_NO_SQL
	    if ( isSql )
		((TQDataTable*)table)->addColumn( field, txt, -1, pix );
	    else
#endif
		h->setLabel( i, pix, txt );
	} else {
#ifndef TQT_NO_SQL
	    if ( isSql ) {
		((TQDataTable*)table)->addColumn( field, txt );
	    }
	    else
#endif
		h->setLabel( i, txt );
	}
	if ( !isRow && !field.isEmpty() ) {
	    fieldMap.append( Field( txt, (hasPixmap ? pix : TQPixmap()), field ) );
	    fieldMaps.insert( table, fieldMap );
	}
    }
#endif
}

void KommanderFactory::loadItem( const TQDomElement &e, TQPixmap &pix, TQString &txt, bool &hasPixmap )
{
    TQDomElement n = e;
    hasPixmap = 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 = translate(v.toString());
	    else if ( attrib == "pixmap" ) {
		pix = loadPixmap( n.firstChild().toElement() );
		hasPixmap = !pix.isNull();
	    }
	}
	n = n.nextSibling().toElement();
    }
}

void KommanderFactory::createItem( const TQDomElement &e, TQWidget *widget, TQListViewItem *i )
{
    if ( widget->inherits( TQLISTBOX_OBJECT_NAME_STRING ) || widget->inherits( TQCOMBOBOX_OBJECT_NAME_STRING ) ) {
	TQDomElement n = e.firstChild().toElement();
	TQPixmap pix;
	bool hasPixmap = false;
	TQString txt;
	loadItem( n, pix, txt, hasPixmap );
	TQListBox *lb = 0;
	if ( widget->inherits( TQLISTBOX_OBJECT_NAME_STRING ) )
	    lb = (TQListBox*)widget;
	else
	    lb = ( (TQComboBox*)widget)->listBox();
	if ( hasPixmap ) {
	    new TQListBoxPixmap( lb, pix, txt );
	} else {
	    new TQListBoxText( lb, txt );
	}
#ifndef TQT_NO_ICONVIEW
    } else if ( widget->inherits( TQICONVIEW_OBJECT_NAME_STRING ) ) {
	TQDomElement n = e.firstChild().toElement();
	TQPixmap pix;
	bool hasPixmap = false;
	TQString txt;
	loadItem( n, pix, txt, hasPixmap );

	TQIconView *iv = (TQIconView*)widget;
	new TQIconViewItem( iv, txt, pix );
#endif
    } else if ( widget->inherits( TQLISTVIEW_OBJECT_NAME_STRING ) ) {
	TQDomElement n = e.firstChild().toElement();
	TQPixmap pix;
	TQValueList<TQPixmap> pixmaps;
	TQStringList textes;
	TQListViewItem *item = 0;
	TQListView *lv = (TQListView*)widget;
	if ( i )
	    item = new TQListViewItem( i, lastItem );
	else
	    item = new TQListViewItem( lv, lastItem );
	while ( !n.isNull() ) {
	    if ( n.tagName() == "property" ) {
		TQString attrib = n.attribute( "name" );
		TQVariant v = DomTool::elementToVariant( n.firstChild().toElement(), TQVariant() );
		if ( attrib == "text" )
		    textes << translate(v.toString());
		else if ( attrib == "pixmap" ) {
		    TQString s = v.toString();
		    if ( s.isEmpty() ) {
			pixmaps << TQPixmap();
		    } else {
			pix = loadPixmap( n.firstChild().toElement() );
			pixmaps << pix;
		    }
		}
	    } else if ( n.tagName() == "item" ) {
		item->setOpen( true );
		createItem( n, widget, item );
	    }

	    n = n.nextSibling().toElement();
	}

	for ( int i = 0; i < lv->columns(); ++i ) {
	    item->setText( i, textes[ i ] );
	    item->setPixmap( i, pixmaps[ i ] );
	}
	lastItem = item;
    }
}



void KommanderFactory::loadChildAction( TQObject *parent, const TQDomElement &e )
{
    TQDomElement n = e;
    TQAction *a = 0;
    EventFunction ef;
    if ( n.tagName() == "action" ) {
	a = new TQAction( parent );
	TQDomElement n2 = n.firstChild().toElement();
	while ( !n2.isNull() ) {
	    if ( n2.tagName() == "property" ) {
		setProperty( a, n2.attribute( "name" ), n2.firstChild().toElement() );
	    } else if ( n2.tagName() == "event" ) {
		ef.events.append( n2.attribute( "name" ) );
		ef.functions.append( TQStringList::split( ',', n2.attribute( "functions" ) ) );
	    }
	    n2 = n2.nextSibling().toElement();
	}
	if ( !parent->inherits( TQACTION_OBJECT_NAME_STRING ) )
	    actionList.append( a );
    } else if ( n.tagName() == "actiongroup" ) {
	a = new TQActionGroup( parent );
	TQDomElement n2 = n.firstChild().toElement();
	while ( !n2.isNull() ) {
	    if ( n2.tagName() == "property" ) {
		setProperty( a, n2.attribute( "name" ), n2.firstChild().toElement() );
	    } else if ( n2.tagName() == "action" ||
			n2.tagName() == "actiongroup" ) {
		loadChildAction( a, n2 );
	    } else if ( n2.tagName() == "event" ) {
		ef.events.append( n2.attribute( "name" ) );
		ef.functions.append( TQStringList::split( ',', n2.attribute( "functions" ) ) );
	    }
	    n2 = n2.nextSibling().toElement();
	}
	if ( !parent->inherits( TQACTION_OBJECT_NAME_STRING ) )
	    actionList.append( a );
    }
    if ( a )
	eventMap.insert( a, ef );
}

void KommanderFactory::loadActions( const TQDomElement &e )
{
    TQDomElement n = e.firstChild().toElement();
    while ( !n.isNull() ) {
	if ( n.tagName() == "action" ) {
	    loadChildAction( TQT_TQOBJECT(toplevel), n );
	} else if ( n.tagName() == "actiongroup" ) {
	    loadChildAction( TQT_TQOBJECT(toplevel), n );
	}
	n = n.nextSibling().toElement();
    }
}

void KommanderFactory::loadToolBars( const TQDomElement &e )
{
    TQDomElement n = e.firstChild().toElement();
    TQMainWindow *mw = ( (TQMainWindow*)toplevel );
    TQToolBar *tb = 0;
    while ( !n.isNull() ) {
	if ( n.tagName() == "toolbar" ) {
	    TQt::Dock dock = (TQt::Dock)n.attribute( "dock" ).toInt();
	    tb = new TQToolBar( TQString(), mw, dock );
	    tb->setLabel( n.attribute( "label" ) );
	    tb->setName( n.attribute( "name" ) );
	    TQDomElement n2 = n.firstChild().toElement();
	    while ( !n2.isNull() ) {
		if ( n2.tagName() == "action" ) {
		    TQAction *a = findAction( n2.attribute( "name" ) );
		    if ( a )
			a->addTo( tb );
		} else if ( n2.tagName() == "separator" ) {
		    tb->addSeparator();
		} else if ( n2.tagName() == "widget" ) {
		    (void)createWidgetInternal( n2, tb, 0, n2.attribute( "class", TQWIDGET_OBJECT_NAME_STRING ) );
		} else if ( n2.tagName() == "property" ) {
		    setProperty( TQT_TQOBJECT(tb), n2.attribute( "name" ), n2.firstChild().toElement() );
		}
		n2 = n2.nextSibling().toElement();
	    }
	}
	n = n.nextSibling().toElement();
    }
}

void KommanderFactory::loadMenuBar( const TQDomElement &e )
{
    TQDomElement n = e.firstChild().toElement();
    TQMainWindow *mw = ( (TQMainWindow*)toplevel );
    TQMenuBar *mb = mw->menuBar();
    while ( !n.isNull() ) {
	if ( n.tagName() == "item" ) {
	    TQPopupMenu *popup = new TQPopupMenu( mw );
	    popup->setName( n.attribute( "name" ) );
	    TQDomElement n2 = n.firstChild().toElement();
	    while ( !n2.isNull() ) {
		if ( n2.tagName() == "action" ) {
		    TQAction *a = findAction( n2.attribute( "name" ) );
		    if ( a )
			a->addTo( popup );
		} else if ( n2.tagName() == "separator" ) {
		    popup->insertSeparator();
		}
		n2 = n2.nextSibling().toElement();
	    }
	    mb->insertItem( translate( n.attribute( "text" ) ), popup );
	} else if ( n.tagName() == "property" ) {
	    setProperty( TQT_TQOBJECT(mb), n.attribute( "name" ), n.firstChild().toElement() );
	}
	n = n.nextSibling().toElement();
    }
}


TQAction *KommanderFactory::findAction( const TQString &name )
{
    for ( TQAction *a = actionList.first(); a; a = actionList.next() ) {
	if ( TQString( a->name() ) == name )
	    return a;
	TQAction *ac = (TQAction*)a->child( name.latin1(), TQACTION_OBJECT_NAME_STRING );
	if ( ac )
	    return ac;
    }
    return 0;
}

void KommanderFactory::loadImages( const TQString &dir )
{
  TQDir d(dir);
  TQStringList l = d.entryList(TQDir::Files);
  for (TQStringList::Iterator it = l.begin(); it != l.end(); ++it)
    TQMimeSourceFactory::defaultFactory()->setPixmap(*it, TQPixmap(d.path() + "/" + *it, "PNG"));
}

TQString KommanderFactory::translate( const TQString& sourceText, const TQString& comment )
{
  if (!sourceText.isEmpty() && !comment.isEmpty())
    return KGlobal::locale()->translate(comment.utf8(), sourceText.utf8());
  else if (!sourceText.isEmpty())
    return KGlobal::locale()->translate(sourceText.utf8());
  else
    return sourceText;
}
