Logo Search packages:      
Sourcecode: datakiosk version File versions  Download package

project.cpp

/***************************************************************************
*   Copyright (C) 2005 by Adam Treat                                      *
*   treat@kde.org                                                         *
*                                                                         *
*   Copyright (C) 2004 by Scott Wheeler                                   *
*   wheeler@kde.org                                                       *
*                                                                         *
*   Copyright (C) 2000 Trolltech AS.  All rights reserved.                *
*   info@trolltech.com                                                    *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
***************************************************************************/

#include "project.h"
#include "datatable.h"
#include "datareport.h"
#include "datatablesearch.h"
#include "databaseconnection.h"
#include "actioncollection.h"
#include "advancedsearchdialog.h"
#include "sqlformwizardimpl.h"
#include "reportwizardbaseimpl.h"

#include <qfile.h>
#include <qfileinfo.h>
#include <qtextstream.h>
#include <qurl.h>
#include <qobjectlist.h>
#include <qfeatures.h>
#include <qtextcodec.h>
#include <qdom.h>
#include <qmessagebox.h>
#include <qapplication.h>
#include <qworkspace.h>
#include <qwidgetfactory.h>
#include <qwidgetstack.h>
#include <qsqldatabase.h>
#include <qsqlrecord.h>
#include <qdatatable.h>

#include <kdebug.h>
#include <kglobal.h>
#include <kconfig.h>
#include <config.h>
#include <kiconloader.h>
#include <kicondialog.h>
#include <kactionclasses.h>
#include <kapplication.h>
#include <kcmdlineargs.h>
#include <kinputdialog.h>
#include <kmessagebox.h>
#include <kfiledialog.h>

#define widget (kapp->mainWidget())

using namespace ActionCollection;

Project::Project( QWidgetStack *dataTableStack, const QString &fn )
        : m_modified( false ),
        m_projectIcon( "table" ),
        m_fileName( fn ),
        m_dataTableStack( dataTableStack )
{
    KCmdLineArgs * args = KCmdLineArgs::parsedArgs();
    QCString filename = args->getOption( "project" );

    if ( !filename.isEmpty() )
        m_fileName = filename;

    m_actionHandler = new ActionHandler( this );
}

Project::~Project()
{
    closeProject();
    delete m_actionHandler;
    removeAllDatabaseConnections();
}

static QString makeIndent( int indent )
{
    QString s;
    s.fill( ' ', indent * 4 );
    return s;
}

static void saveSingleProperty( QTextStream &ts, const QString& name, const QString& value, int indent )
{
    ts << makeIndent( indent ) << "<property name=\"" << name << "\">" << endl;
    ++indent;
    ts << makeIndent( indent ) << "<string>" << value << "</string>" << endl;
    --indent;
    ts << makeIndent( indent ) << "</property>" << endl;
}

static void saveDataFieldList( QTextStream &ts, int indent, DataFieldList list, bool rlist = false )
{
    for ( DataFieldList::Iterator it = list.begin(); it != list.end(); ++it )
    {
        ts << makeIndent( indent ) << "<datafield>" << endl;
        ++indent;
        saveSingleProperty( ts, "name", ( *it ) ->name().latin1(), indent );
        saveSingleProperty( ts, "type", QString::number( ( *it ) ->type() ), indent );
        if ( !rlist ) saveSingleProperty( ts, "required", QString::number( ( *it ) ->isRequired() ), indent );
        if ( !rlist ) saveSingleProperty( ts, "calculated", ( *it ) ->calculated() ? "true" : "false" , indent );
        if ( !rlist ) saveSingleProperty( ts, "virtual", ( *it ) ->isVirtual() ? "true" : "false" , indent );
        if ( !rlist ) saveSingleProperty( ts, "equation", ( *it ) ->equation().latin1(), indent );
        if ( !rlist ) saveSingleProperty( ts, "label", ( *it ) ->label().latin1(), indent );
        saveSingleProperty( ts, "number", QString::number( ( *it ) ->number() ), indent );
        if ( !rlist ) saveSingleProperty( ts, "width", QString::number( ( *it ) ->width() ), indent );
        if ( rlist ) saveSingleProperty( ts, "editorwidth", QString::number( ( *it ) ->editorWidth() ), indent );
        saveSingleProperty( ts, "foreign", ( *it ) ->foreign() ? "true" : "false" , indent );
        saveSingleProperty( ts, "primary", ( *it ) ->primary() ? "true" : "false" , indent );
        if ( rlist ) saveSingleProperty( ts, "reporter", ( *it ) ->reporter() ? "true" : "false" , indent );
        saveSingleProperty( ts, "hidden", ( *it ) ->hidden() ? "true" : "false" , indent );
        if ( !rlist ) saveSingleProperty( ts, "resizable", ( *it ) ->resizable() ? "true" : "false" , indent );
        if ( !rlist ) saveSingleProperty( ts, "sortable", ( *it ) ->sortable() ? "true" : "false" , indent );

        if ( ( *it ) ->relation() )
        {
            ts << makeIndent( indent ) << "<datarelation>" << endl;
            ++indent;
            saveSingleProperty( ts, "table", ( *it ) ->relation() ->table().latin1(), indent );
            saveSingleProperty( ts, "key", ( *it ) ->relation() ->key().latin1(), indent );
            saveSingleProperty( ts, "field", ( *it ) ->relation() ->field().latin1(), indent );
            if ( ( *it ) ->relation() ->constraint() != QString::null )
                saveSingleProperty( ts, "constraint", ( *it ) ->relation() ->constraint().latin1(), indent );
            saveSingleProperty( ts, "type", QString::number( ( *it ) ->relation() ->type() ), indent );
            saveSingleProperty( ts, "number", QString::number( ( *it ) ->relation() ->number() ), indent );
            saveSingleProperty( ts, "editorwidth", QString::number( ( *it ) ->relation() ->editorWidth() ), indent );

            saveDataFieldList( ts, indent, ( *it ) ->relation()->fieldList(), true );

            --indent;
            ts << makeIndent( indent ) << "</datarelation>" << endl;
        }

        --indent;
        ts << makeIndent( indent ) << "</datafield>" << endl;
    }
}

static QDomElement loadSingleProperty( QDomElement e, const QString& name )
{
    QDomElement n;
    for ( n = e.firstChild().toElement();
            !n.isNull();
            n = n.nextSibling().toElement() )
    {
        if ( n.tagName() == "property" && n.toElement().attribute( "name" ) == name )
            return n;
    }
    return n;
}

static QString readSingleProperty( QDomElement e, const QString& name )
{
    QDomElement n;
    for ( n = e.firstChild().toElement();
            !n.isNull();
            n = n.nextSibling().toElement() )
    {
        if ( n.tagName() == "property" && n.toElement().attribute( "name" ) == name )
            return n.firstChild().firstChild().toText().data();
    }
    return QString::null;
}

static void loadDataFieldList( QDomNodeList fields, DataTable *table, DataRelation *relation = 0 )
{
    for ( uint i = 0; i < fields.length(); i++ )
    {
        QDomElement datafield = fields.item( i ).toElement();
        if ( datafield.tagName() != "datafield" )
            continue;

        QString fieldName = readSingleProperty( datafield, "name" );
        QString fieldType = readSingleProperty( datafield, "type" );
        QString fieldNumber = readSingleProperty( datafield, "number" );
        bool fieldForeign = readSingleProperty( datafield, "foreign" ) == "true";
        bool fieldPrimary = readSingleProperty( datafield, "primary" ) == "true";
        bool fieldHidden = readSingleProperty( datafield, "hidden" ) == "true";

        if ( table )
        {
            QString fieldRequired = readSingleProperty( datafield, "required" );
            bool fieldCalculated = readSingleProperty( datafield, "calculated" ) == "true";
            bool fieldVirtual = readSingleProperty( datafield, "virtual" ) == "true";
            QString fieldEquation = readSingleProperty( datafield, "equation" );
            QString fieldLabel = readSingleProperty( datafield, "label" );
            QString fieldWidth = readSingleProperty( datafield, "width" );
            bool fieldResizable = readSingleProperty( datafield, "resizable" ) == "true";
            bool fieldSortable = readSingleProperty( datafield, "sortable" ) == "true";
            table ->addDataField( fieldName, QVariant::Type( fieldType.toInt() ),
                                  fieldRequired.toInt(), fieldCalculated, fieldVirtual,
                                  fieldEquation, fieldLabel,
                                  fieldNumber.toInt(), fieldWidth.toInt(),
                                  fieldForeign, fieldPrimary, fieldHidden,
                                  fieldResizable, fieldSortable );
        }
        else if ( relation && !fieldPrimary )
        {
            QString editorWidth = readSingleProperty( datafield, "editorwidth" );
            bool fieldReporter = readSingleProperty( datafield, "reporter" ) == "true";
            relation ->addDataField( fieldName, QVariant::Type( fieldType.toInt() ),
                                     fieldNumber.toInt(), editorWidth.toInt(),
                                     fieldForeign, fieldPrimary, fieldReporter, fieldHidden );
        }

        QDomNodeList relations = datafield.toElement().childNodes();
        for ( uint i = 0; i < relations.length(); i++ )
        {
            QDomElement datarelation = relations.item( i ).toElement();
            if ( datarelation.tagName() != "datarelation" )
                continue;
            QString relationTable = readSingleProperty( datarelation, "table" );
            QString relationKey = readSingleProperty( datarelation, "key" );
            QString relationField = readSingleProperty( datarelation, "field" );
            QString relationConstraint = readSingleProperty( datarelation, "constraint" );
            QString relationType = readSingleProperty( datarelation, "type" );
            QString relationNumber = readSingleProperty( datarelation, "number" );
            QString relationEditorWidth = readSingleProperty( datarelation, "editorwidth" );

            if ( table )
                table ->addDataRelation( fieldName, relationTable, relationKey,
                                         relationField, relationConstraint,
                                         QVariant::Type( relationType.toInt() ),
                                         relationNumber.toInt(), relationEditorWidth.toInt() );
            else
                relation ->addDataRelation( fieldName, relationTable, relationKey,
                                            relationField, relationConstraint,
                                            QVariant::Type( relationType.toInt() ),
                                            relationNumber.toInt(), relationEditorWidth.toInt() );

            QDomNodeList relationfields = datarelation.toElement().childNodes();
            if ( table )
                loadDataFieldList( relationfields, 0, table->dataRelation( fieldName ) );
        }
    }
}

void Project::initialize()
{
    // implemented in subclass
}

//UGLY HACK
void Project::uglyInitialize()
{
    // implemented in subclass
}

QString Project::fileName() const
{
    return m_fileName;
}

void Project::newProject()
{
    // implemented in subclass
}

void Project::openProject()
{
    if ( m_modified )
        closeProject();

    QString filename = KFileDialog::getOpenFileName (
                           QString::null,
                           "*.pro",
                           widget,
                           i18n("Open Project File")
                       );
    m_fileName = filename;

    kdDebug() << "loading project file:" << filename << endl;

    uglyInitialize();
}

void Project::saveProject()
{
    if ( m_fileName.isEmpty() )
        saveAsProject();

    QFile f( makeAbsolute( m_fileName ) );

    if ( m_dbConnections.isEmpty() && m_dataTables.isEmpty() )
    {
        if ( f.exists() )
            f.remove();
        m_fileName = QString::null;
        m_modified = true;
        return ;
    }

    widget->setCaption( QFileInfo( f ).baseName() );

    if ( f.open( IO_WriteOnly | IO_Translate ) )
    {
        QTextStream ts( &f );
        ts.setCodec( QTextCodec::codecForName( "UTF-8" ) );
        ts << "<!DOCTYPE DataKiosk><DataKiosk version=\"1.0\">" << endl;

        int indent = 0;
        saveSingleProperty( ts, "icon", m_projectIcon, indent );

        /* db connections */
        for ( DatabaseConnection * conn = m_dbConnections.first(); conn; conn = m_dbConnections.next() )
        {
            ts << makeIndent( indent ) << "<connection>" << endl;
            ++indent;
            saveSingleProperty( ts, "name", conn->name(), indent );
            saveSingleProperty( ts, "driver", conn->driver(), indent );
            saveSingleProperty( ts, "database", conn->database(), indent );
            saveSingleProperty( ts, "username", conn->username(), indent );
            saveSingleProperty( ts, "hostname", conn->hostname(), indent );
            saveSingleProperty( ts, "port", QString::number( conn->port() ), indent );

            /* connection tables */
            QStringList tables = conn->tables();
            for ( QStringList::Iterator it = tables.begin();
                    it != tables.end(); ++it )
            {
                ts << makeIndent( indent ) << "<table>" << endl;
                ++indent;
                saveSingleProperty( ts, "name", ( *it ), indent );

                /* tables fields */
                QStringList fields = conn->fields( *it );
                for ( QStringList::Iterator it2 = fields.begin();
                        it2 != fields.end(); ++it2 )
                {
                    ts << makeIndent( indent ) << "<field>" << endl;
                    ++indent;
                    saveSingleProperty( ts, "name", ( *it2 ), indent );
                    --indent;
                    ts << makeIndent( indent ) << "</field>" << endl;
                }

                --indent;
                ts << makeIndent( indent ) << "</table>" << endl;
            }

            --indent;
            ts << makeIndent( indent ) << "</connection>" << endl;
        }

        for ( DataTable * table = m_dataTables.first(); table; table = m_dataTables.next() )
        {
            ts << makeIndent( indent ) << "<datatable>" << endl;
            ++indent;
            saveSingleProperty( ts, "connection", table->connection(), indent );
            saveSingleProperty( ts, "tablename", table->tableName(), indent );
            saveSingleProperty( ts, "number", QString::number( table->number() ), indent );
            saveSingleProperty( ts, "parentname", table->parentName(), indent );
            saveSingleProperty( ts, "relationtoparent", QString::number( table->relationToParent() ), indent );
            saveSingleProperty( ts, "parentkey", table->parentKey(), indent );
            saveSingleProperty( ts, "foreignkey", table->foreignKey(), indent );
            saveSingleProperty( ts, "name", table->name(), indent );
            saveSingleProperty( ts, "icon", table->iconName(), indent );
            saveSingleProperty( ts, "readonly",
                                table ->dataTableEdit()->isReadOnly() ? "true" : "false" , indent );
            saveSingleProperty( ts, "confirminsert",
                                table ->dataTableEdit()->confirmInsert() ? "true" : "false", indent );
            saveSingleProperty( ts, "confirmupdate",
                                table ->dataTableEdit()->confirmUpdate() ? "true" : "false", indent );
            saveSingleProperty( ts, "confirmdelete",
                                table ->dataTableEdit()->confirmDelete() ? "true" : "false", indent );
            saveSingleProperty( ts, "confirmcancel",
                                table ->dataTableEdit()->confirmCancels() ? "true" : "false", indent );
            saveSingleProperty( ts, "sorting",
                                table ->dataTableView()->sorting() ? "true" : "false", indent );

            QStringList sort = table->sort();
            QStringList::Iterator str = sort.begin();
            for ( ; str != sort.end(); ++str )
            {
                ts << makeIndent( indent ) << "<sort>" << endl;
                ++indent;
                saveSingleProperty( ts, "orderby", ( *str ), indent );
                --indent;
                ts << makeIndent( indent ) << "</sort>" << endl;
            }

            DataFieldList fields = table->fieldList();
            saveDataFieldList( ts, indent, fields );
            --indent;
            ts << makeIndent( indent ) << "</datatable>" << endl;
        }

        DataSearchList searches = m_searchList;
        for ( DataSearchList::Iterator it3 = searches.begin(); it3 != searches.end(); ++it3 )
        {
            ts << makeIndent( indent ) << "<datasearch>" << endl;
            ++indent;
            saveSingleProperty( ts, "name", ( *it3 ).name().latin1(), indent );
            saveSingleProperty( ts, "searchmode", QString::number( ( *it3 ).searchMode() ), indent );
            saveSingleProperty( ts, "searchlevel", QString::number( ( *it3 ).searchLevel() ), indent );
            saveSingleProperty( ts, "parentname", ( *it3 ).parentName().latin1(), indent );

            DataTableSearch::ComponentList components = ( *it3 ).components();
            for ( DataTableSearch::ComponentList::Iterator it4 = components.begin(); it4 != components.end(); ++it4 )
            {
                DataTable *dt = ( *it4 ).dataTable();
                DataField *df = ( *it4 ).dataField();
                if ( !dt )
                    continue;
                ts << makeIndent( indent ) << "<component>" << endl;
                ++indent;
                saveSingleProperty( ts, "query", sanitize( ( *it4 ).query() ).latin1(), indent );
                saveSingleProperty( ts, "datatable", dt ->name().latin1(), indent );
                if ( df )
                    saveSingleProperty( ts, "datafield", df ->name().latin1(), indent );
                saveSingleProperty( ts, "prompt", ( *it4 ).isPrompt() ? "true" : "false", indent );
                saveSingleProperty( ts, "matchmode", QString::number( ( *it4 ).matchMode() ), indent );
                --indent;
                ts << makeIndent( indent ) << "</component>" << endl;
            }

            --indent;
            ts << makeIndent( indent ) << "</datasearch>" << endl;
        }

        for ( DataReport * report = m_dataReports.first(); report; report = m_dataReports.next() )
        {
            ts << makeIndent( indent ) << "<datareport>" << endl;
            ++indent;
            saveSingleProperty( ts, "name", report->name(), indent );
            saveSingleProperty( ts, "icon", report->iconName(), indent );
            saveSingleProperty( ts, "templateurl", report->templateURL(), indent );
            saveSingleProperty( ts, "parentname", report->parent() ->name(), indent );
            if ( !report->dataSearch().isEmpty() )
                saveSingleProperty( ts, "datasearch", report->dataSearch(), indent );

            QStringList tables = report->tables();
            QStringList::Iterator str = tables.begin();
            for ( ; str != tables.end(); ++str )
            {
                ts << makeIndent( indent ) << "<table>" << endl;
                ++indent;
                saveSingleProperty( ts, "name", ( *str ), indent );
                --indent;
                ts << makeIndent( indent ) << "</table>" << endl;
            }

            QStringList sort = report->sort();
            QStringList::Iterator str2 = sort.begin();
            for ( ; str2 != sort.end(); ++str2 )
            {
                ts << makeIndent( indent ) << "<sort>" << endl;
                ++indent;
                saveSingleProperty( ts, "orderby", ( *str2 ), indent );
                --indent;
                ts << makeIndent( indent ) << "</sort>" << endl;
            }

            --indent;
            ts << makeIndent( indent ) << "</datareport>" << endl;
        }

        ts << "</DataKiosk>" << endl;
        f.close();
    }
}

void Project::saveAsProject()
{
    QString filename = KFileDialog::getSaveFileName (
                           QString::null,
                           "*.pro",
                           widget,
                           i18n("Save Project File As")
                       );

    if ( filename.isEmpty() )
        return;

    if ( filename.endsWith( ".pro", true ) )
        m_fileName = filename;
    else
        m_fileName = filename += ".pro";

    kdDebug() << "saving project file:" << filename << endl;
    saveProject();
}

void Project::closeProject()
{
    if ( !m_modified )
        return ;

    if ( !m_fileName.isEmpty() )
        saveProject();

    m_fileName = "";
    m_projectIcon = "table";
    widget->setIcon( SmallIcon( "table", 32 ) );
    widget->setCaption( "" );
    m_modified = false;

    action( "edit_project" ) ->setEnabled( false );
    action( "create_datatable" ) ->setEnabled( false );
    action( "save_project" ) ->setEnabled( false );
    action( "save_project_as" ) ->setEnabled( false );
    action( "close_project" ) ->setEnabled( false );

    removeAllDatabaseConnections();
}

void Project::editProject()
{
    QString iconName = KIconDialog::getIcon( KIcon::NoGroup, KIcon::Any, false, 32, true, widget, i18n("Select Icon for This Project") );
    m_projectIcon = iconName;
    widget->setIcon( SmallIcon( iconName, 32 ) );
}

void Project::clipboard()
{
    //reimp
}

QString Project::makeAbsolute( const QString &f )
{
    QString encodedUrl = QFileInfo( m_fileName ).dirPath( true );
    QUrl::encode( encodedUrl );
    QUrl u( encodedUrl, f );
    return u.path();
}

QString Project::makeRelative( const QString &f )
{
    QString p = QFileInfo( m_fileName ).dirPath( true );
    QString f2 = f;
    if ( f2.left( p.length() ) == p )
        f2.remove( 0, p.length() + 1 );
    return f2;
}

bool Project::openDatabase( const QString &connection, bool suppressDialog )
{
    DatabaseConnection * conn = databaseConnection( connection );
    if ( connection.isEmpty() && !conn )
        conn = databaseConnection( "(default)" );
    if ( !conn )
        return false;
    bool b = conn->open( suppressDialog );
    return b;

    Q_UNUSED( connection );
    Q_UNUSED( suppressDialog );
    return false;
}

void Project::closeDatabase( const QString &connection )
{
    DatabaseConnection * conn = databaseConnection( connection );
    if ( connection.isEmpty() && !conn )
        conn = databaseConnection( "(default)" );
    if ( !conn )
        return ;
    conn->close();
}

QPtrList<DataTable> Project::dataTablesByPtr() const
{
    return m_dataTables;
}

QPtrList<DatabaseConnection> Project::databaseConnections() const
{
    return m_dbConnections;
}

void Project::setDatabaseConnections( const QPtrList<DatabaseConnection> &lst )
{
    m_dbConnections = lst;
}

void Project::addDatabaseConnection( DatabaseConnection *conn )
{
    m_dbConnections.append( conn );
    m_modified = true;
}

void Project::removeDatabaseConnection( const QString &c )
{
    for ( DatabaseConnection * conn = m_dbConnections.first(); conn; conn = m_dbConnections.next() )
    {
        if ( conn->name() == c )
        {
            conn->remove
            ();
            m_dbConnections.removeRef( conn );
            delete conn;
            return ;
        }
    }
}

void Project::removeAllDatabaseConnections()
{
    QStringList list = databaseConnectionList();
    QStringList::iterator it = list.begin();
    for ( ; it != list.end(); ++it )
        removeDatabaseConnection( ( *it ) );
}

DatabaseConnection *Project::databaseConnection( const QString &name )
{
    for ( DatabaseConnection * conn = m_dbConnections.first();
            conn;
            conn = m_dbConnections.next() )
    {
        if ( conn->name() == name )
            return conn;
    }
    return 0;
}

QStringList Project::databaseConnectionList()
{
    QStringList lst;
    for ( DatabaseConnection * conn = m_dbConnections.first(); conn; conn = m_dbConnections.next() )
        lst << conn->name();
    return lst;
}

QStringList Project::databaseTableList( const QString &connection )
{
    DatabaseConnection * conn = databaseConnection( connection );
    if ( !conn )
    {
        return QStringList();
    }
    return conn->tables();
}

QStringList Project::databaseFieldList( const QString &connection, const QString &table )
{
    DatabaseConnection * conn = databaseConnection( connection );
    if ( !conn )
        return QStringList();
    return conn->fields( table );
}

bool Project::loadConnections()
{
    bool isPopulated = false;

    if ( m_fileName.isEmpty() || !QFile::exists( makeAbsolute( m_fileName ) ) )
        return isPopulated;

    QFile f( makeAbsolute( m_fileName ) );
    if ( f.open( IO_ReadOnly ) )
    {
        QDomDocument doc;
        QString errMsg;
        int errLine;
        if ( doc.setContent( &f, &errMsg, &errLine ) )
        {
            QDomElement e;
            e = doc.firstChild().toElement();

            /* connections */
            QDomNodeList connections = e.toElement().elementsByTagName( "connection" );
            for ( uint i = 0; i < connections.length(); i++ )
            {
                QDomElement connection = connections.item( i ).toElement();
                QString connectionName = readSingleProperty( connection, "name" );
                QString connectionDriver = readSingleProperty( connection, "driver" );
                QString connectionDatabase = readSingleProperty( connection, "database" );
                QString connectionUsername = readSingleProperty( connection, "username" );
                QString connectionHostname = readSingleProperty( connection, "hostname" );
                QString connectionPort = readSingleProperty( connection, "port" );

                DatabaseConnection *conn = new DatabaseConnection();
                conn->setName( connectionName );
                conn->setDriver( connectionDriver );
                conn->setDatabase( connectionDatabase );
                conn->setUsername( connectionUsername );
                conn->setHostname( connectionHostname );
                conn->setPort( connectionPort.toInt() );

                /* connection tables */
                QDomNodeList tables = connection.toElement().elementsByTagName( "table" );
                for ( uint j = 0; j < tables.length(); j++ )
                {
                    QDomElement table = tables.item( j ).toElement();
                    QString tableName = readSingleProperty( table, "name" );
                    conn->addTable( tableName );

                    /* table fields */
                    QStringList fieldList;
                    QDomNodeList fields = table.toElement().elementsByTagName( "field" );
                    for ( uint k = 0; k < fields.length(); k++ )
                    {
                        QDomElement field = fields.item( k ).toElement();
                        QString fieldName = readSingleProperty( field, "name" );
                        fieldList.append( fieldName );
                    }
                    conn->setFields( tableName, fieldList );
                }

                m_dbConnections.append( conn );

                isPopulated = true;
            }
        }
        else
        {
            kdDebug() << "Parse error: " << errMsg << endl;
        }
        f.close();
    }

    return isPopulated;
}

void Project::setDataTables( const QPtrList<DataTable> &lst )
{
    m_dataTables = lst;
}

void Project::addDataTable( DataTable *table )
{
    m_dataTables.append( table );
    m_modified = true;
}

void Project::addDataReport( DataReport *report )
{
    m_dataReports.append( report );
    m_modified = true;
}

void Project::removeDataTable( const QString &l )
{
    for ( DataTable * table = m_dataTables.first(); table; table = m_dataTables.next() )
    {
        if ( table->name() == l )
        {
            m_dataTables.removeRef( table );
            //delete table;
            return ;
        }
    }
}

void Project::removeDataReport( const QString &r )
{
    for ( DataReport * report = m_dataReports.first(); report; report = m_dataReports.next() )
    {
        if ( report->name() == r )
        {
            m_dataReports.removeRef( report );
            //delete table;
            return ;
        }
    }
}

DataTable *Project::dataTable( const QString &name )
{
    for ( DataTable * table = m_dataTables.first();
            table;
            table = m_dataTables.next() )
    {
        if ( table->name() == name )
            return table;
    }
    return 0;
}

QStringList Project::dataTableList()
{
    QStringList lst;
    for ( DataTable * table = m_dataTables.first(); table; table = m_dataTables.next() )
        lst << table->name();
    return lst;
}

bool Project::loadDataTables()
{
    bool isPopulated = false;

    if ( m_fileName.isEmpty() || !QFile::exists( makeAbsolute( m_fileName ) ) )
        return isPopulated;

    QFile f( makeAbsolute( m_fileName ) );
    if ( f.open( IO_ReadOnly ) )
    {
        QDomDocument doc;
        QString errMsg;
        int errLine;
        if ( doc.setContent( &f, &errMsg, &errLine ) )
        {
            QDomElement e;
            e = doc.firstChild().toElement();

            QString projectIcon = readSingleProperty( e, "icon" );
            if ( !projectIcon.isEmpty() )
            {
                m_projectIcon = projectIcon;
                widget->setIcon( SmallIcon( projectIcon, 32 ) );
                widget->setCaption( QFileInfo( f ).baseName() );
            }

            /* dataTables */
            QDomNodeList dataTables = e.toElement().elementsByTagName( "datatable" );
            for ( uint i = 0; i < dataTables.length(); i++ )
            {
                QDomElement dataTable = dataTables.item( i ).toElement();
                QString dataTableConnection = readSingleProperty( dataTable, "connection" );
                QString dataTableTableName = readSingleProperty( dataTable, "tablename" );
                QString dataTableNumber = readSingleProperty( dataTable, "number" );
                QString dataTableParentName = readSingleProperty( dataTable, "parentname" );
                QString dataTableRelationToParent = readSingleProperty( dataTable, "relationtoparent" );
                QString dataTableParentKey = readSingleProperty( dataTable, "parentkey" );
                QString dataTableForeignKey = readSingleProperty( dataTable, "foreignkey" );
                QString dataTableName = readSingleProperty( dataTable, "name" );
                QString dataTableIcon = readSingleProperty( dataTable, "icon" );
                bool readOnly = readSingleProperty( dataTable, "readonly" ) == "true";
                bool confirmInsert = readSingleProperty( dataTable, "confirminsert" ) == "true";
                bool confirmUpdate = readSingleProperty( dataTable, "confirmupdate" ) == "true";
                bool confirmDelete = readSingleProperty( dataTable, "confirmdelete" ) == "true";
                bool confirmCancel = readSingleProperty( dataTable, "confirmcancel" ) == "true";
                bool sorting = readSingleProperty( dataTable, "sorting" ) == "true";

                if ( dataTableParentName != QString::null )
                    createChildDataTable( dataTableParentName );
                else
                    createDataTable();

                if ( !currentDataTable() )
                {
                    kdDebug() << "Could not create DataTable: " << dataTableName << endl;
                    continue;
                }

                currentDataTable() ->setConnection( dataTableConnection );
                currentDataTable() ->setTableName( dataTableTableName );
                currentDataTable() ->setNumber( dataTableNumber.toInt() );
                currentDataTable() ->setParentName( dataTableParentName );
                currentDataTable() ->setRelationToParent( DataTable::RelationToParent( dataTableRelationToParent.toInt() ) );
                currentDataTable() ->setParentKey( dataTableParentKey );
                currentDataTable() ->setForeignKey( dataTableForeignKey );
                currentDataTable() ->setName( dataTableName );
                currentDataTable() ->setIconName( dataTableIcon );
                currentDataTable() ->dataTableEdit()->setReadOnly( readOnly );
                currentDataTable() ->dataTableEdit()->setConfirmInsert( confirmInsert );
                currentDataTable() ->dataTableEdit()->setConfirmUpdate( confirmUpdate );
                currentDataTable() ->dataTableEdit()->setConfirmDelete( confirmDelete );
                currentDataTable() ->dataTableEdit()->setConfirmCancels( confirmCancel );
                currentDataTable() ->dataTableView()->setSorting( sorting );

                QStringList strList;
                QDomNodeList sort = dataTable.toElement().elementsByTagName( "sort" );
                for ( uint i = 0; i < sort.length(); i++ )
                {
                    QDomElement orderby = sort.item( i ).toElement();
                    strList.append( readSingleProperty( orderby, "orderby" ) );;
                }
                currentDataTable() ->setSort( strList );

                QDomNodeList fields = dataTable.toElement().childNodes();
                loadDataFieldList( fields, currentDataTable() );

                setSplashMessage( i18n( "Loading table: " ) + dataTableName );

                currentDataTable() ->initialize();
                addDataTable( currentDataTable() );

                isPopulated = true;
            }

            QDomNodeList searches = e.toElement().elementsByTagName( "datasearch" );
            for ( uint i = 0; i < searches.length(); i++ )
            {
                QDomElement datasearch = searches.item( i ).toElement();
                QString searchName = readSingleProperty( datasearch, "name" );
                QString searchSearchMode = readSingleProperty( datasearch, "searchmode" );
                QString searchSearchLevel = readSingleProperty( datasearch, "searchlevel" );
                QString searchParentName = readSingleProperty( datasearch, "parentname" );

                DataTableSearch s( DataTableSearch::MatchAny, DataTableSearch::Advanced );
                s.clearComponents();
                s.setName( searchName );
                s.setDataTables( dataTablesInDataTableTree( dataTableByName( searchParentName ) ) );
                s.setSearchMode( DataTableSearch::SearchMode( searchSearchMode.toInt() ) );
                s.setSearchLevel( DataTableSearch::SearchLevel( searchSearchLevel.toInt() ) );

                QDomNodeList components = datasearch.toElement().elementsByTagName( "component" );
                for ( uint i = 0; i < components.length(); i++ )
                {
                    QDomElement component = components.item( i ).toElement();
                    QString componentQuery = deSanitize( readSingleProperty( component, "query" ) );
                    QString componentDataTable = readSingleProperty( component, "datatable" );
                    QString componentDataField = readSingleProperty( component, "datafield" );
                    bool componentPrompt = readSingleProperty( component, "prompt" ) == "true";
                    QString componentMatchMode = readSingleProperty( component, "matchmode" );

                    DataTable *table = dataTableByName( componentDataTable );
                    if ( !table )
                        continue;
                    DataField *field = table ->dataField( componentDataField );

                    s.addComponent( DataTableSearch::Component( componentQuery, table, field, componentPrompt,
                                    DataTableSearch::MatchMode( componentMatchMode.toInt() ) )
                                  );
                }

                appendSearch( s );
            }

            QDomNodeList dataReports = e.toElement().elementsByTagName( "datareport" );
            for ( uint i = 0; i < dataReports.length(); i++ )
            {
                QDomElement dataReport = dataReports.item( i ).toElement();
                QString dataReportName = readSingleProperty( dataReport, "name" );
                QString dataReportIcon = readSingleProperty( dataReport, "icon" );
                QString dataReportTemplateURL = readSingleProperty( dataReport, "templateurl" );
                QString dataReportParentName = readSingleProperty( dataReport, "parentname" );
                QString dataReportDataSearch = readSingleProperty( dataReport, "datasearch" );

                createKugarReport( dataReportParentName );

                if ( !currentDataReport() )
                {
                    kdDebug() << "Could not create DataReport: " << dataReportName << endl;
                    continue;
                }

                currentDataReport() ->setName( dataReportName );
                currentDataReport() ->setIconName( dataReportIcon );
                currentDataReport() ->setTemplateURL( dataReportTemplateURL );
                currentDataReport() ->setDataSearch( dataReportDataSearch );

                QDomNodeList tables = dataReport.toElement().elementsByTagName( "table" );
                for ( uint i = 0; i < tables.length(); i++ )
                {
                    QDomElement table = tables.item( i ).toElement();
                    QString tableName = readSingleProperty( table, "name" );

                    currentDataReport() ->addTable( tableName );
                }

                QStringList strList;
                QDomNodeList sort = dataReport.toElement().elementsByTagName( "sort" );
                for ( uint i = 0; i < sort.length(); i++ )
                {
                    QDomElement orderby = sort.item( i ).toElement();
                    strList.append( readSingleProperty( orderby, "orderby" ) );;
                }
                currentDataReport() ->setSort( strList );

                //I don't want to initialize on load... too big.
                /*currentDataReport()->initialize();*/
                currentDataReport() ->queueRefresh(); //do something on load ;
                addDataReport( currentDataReport() );
            }
        }
        else
        {
            kdDebug() << "Parse error: " << errMsg << endl;
        }
        f.close();
    }

    return isPopulated;
}

//    ******************** DataTableCollection ********************
QString Project::name() const
{
    return currentDataTable() ->name();
}

QStringList Project::dataTables() const
{
    QStringList l;

    QObjectList *childList = m_dataTableStack->queryList( "DataTable" );
    QObject *obj;
    for ( obj = childList->first(); obj; obj = childList->next() )
    {
        DataTable * p = static_cast<DataTable*>( obj );
        l.append( p->name() );
    }

    delete childList;
    return l;
}

QString Project::dataTable() const
{
    if ( currentDataTable() )
        return currentDataTable() ->name();
    return QString::null;
}

void Project::setDataTable( const QString &dataTable )
{
    DataTable * p = dataTableByName( dataTable );
    if ( p )
        raise( p );
}

void Project::configureTable()
{
    DataTable * parent = dataTableByName( currentDataTable() ->parentName() );

    SqlFormWizard wizard( this, currentDataTable(), parent, true );
    wizard.exec();
}

void Project::addVirtualField()
{
    if ( currentDataTable() )
        currentDataTable()->addVirtualField();
}

void Project::removeTable()
{
    // implemented in subclass
}

void Project::moveTableUp()
{
    DataTableList dataTables = dataTablesInCurrentPeerTree();
    int currentNumber = currentDataTable()->number();
    if ( currentNumber == 0 )
        return;

    DataTableList::Iterator it = dataTables.begin();
    for ( ; it != dataTables.end(); ++it )
    {
        if ( ( *it ) == currentDataTable() )
            ( *it )->setNumber( currentNumber - 1 );
        else if ( ( *it )->number() == currentNumber - 1 )
            ( *it )->setNumber( currentNumber );
    }
    sortTables();
}

void Project::moveTableDown()
{
    DataTableList dataTables = dataTablesInCurrentPeerTree();
    int currentNumber = currentDataTable()->number();
    if ( currentNumber == (int)dataTables.count() - 1 )
        return;

    DataTableList::Iterator it = dataTables.begin();
    for ( ; it != dataTables.end(); ++it )
    {
        if ( ( *it ) == currentDataTable() )
            ( *it )->setNumber( currentNumber + 1 );
        else if ( ( *it )->number() == currentNumber + 1 )
            ( *it )->setNumber( currentNumber );
    }
    sortTables();
}

void Project::sortTables()
{
    // implemented in subclass
}

void Project::configureReport()
{
    ReportWizard wizard( this, currentDataReport(), currentDataReport() ->parent(), true );
    wizard.exec();
}

void Project::removeReport()
{
    // implemented in subclass
}

void Project::refreshReport()
{
    currentDataReport() ->refreshReport();
}

void Project::editSearch()
{
    // implemented in subclass
}

void Project::removeSearch()
{
    removeSearch( currentDataTable() ->search() );
}

DataSearchList Project::searchList()
{
    if ( !rootOfCurrentDataTable() )
        return DataSearchList();

    DataSearchList searchList;
    DataSearchList::Iterator it = m_searchList.begin();
    for ( ; it != m_searchList.end(); ++it )
    {
        if ( ( *it ).parentName() == rootOfCurrentDataTable()->name() )
            searchList.append( ( *it ) );
    }
    return searchList;
}

void Project::appendSearch( const DataTableSearch &search )
{
    //UGLY HACK TODO Remove the search if it's of the same name...before appending.
    removeSearch( search );
    m_searchList.append( search );
}

void Project::removeSearch( const DataTableSearch &search )
{
    DataSearchList copy = m_searchList;
    m_searchList.clear();
    for ( DataSearchList::Iterator it = copy.begin(); it != copy.end(); ++it )
    {
        if ( ( *it ).name() != search.name() )
            m_searchList.append( ( *it ) );
    }
}

void Project::invokeSearch( const QString &/*search*/ )
{
    // implemented in subclass
}

void Project::advancedSearchRequested()
{
    // implemented in subclass
}

void Project::createKugarReport()
{
    DataTable * parent = currentDataTable();

    if ( !parent )
        return ;

    raise( new DataReport( this, parent ) );
    currentDataReport() ->setName( uniqueDataTableName( i18n( "Data Report" ) ) );

    ReportWizard wizard( this, currentDataReport(), parent );
    wizard.exec();
}

void Project::createKugarReport( const QString &parentTable )
{
    DataTable * parent = dataTableByName( parentTable );

    if ( !parent )
        return ;

    raise( new DataReport( this, parent ) );
    currentDataReport() ->setName( uniqueDataTableName( i18n( "Data Report" ) ) );
}

void Project::createDataTable()
{
    raise( new DataTable( this ) );
}

void Project::createChildDataTable( const QString &name )
{
    DataTable * parent = dataTableByName( name );

    if ( !parent )
        return ;

    raise( new DataTable( this, parent ) );

    QObject::connect( parent, SIGNAL( myCurrentChanged( QSqlRecord* ) ),
                      currentDataTable(), SLOT( slotDetailFromMaster( QSqlRecord* ) ) );

    QObject::connect( parent, SIGNAL( signalNameChanged( const QString & ) ),
                      currentDataTable(), SLOT( setParentName( const QString & ) ) );

    QObject::connect( currentDataTable(), SIGNAL( requestParentSelect() ),
                      parent, SLOT( slotSelectFirstRow() ) );

    QObject::connect( currentDataTable(), SIGNAL( childValueChanged( const QString &, const QVariant & ) ),
                      parent, SLOT( slotValueFromChild( const QString &, const QVariant & ) ) );

}

void Project::createSearchDataTable()
{
    //     QString name = uniqueDataTableName( i18n( "Search DataTable" ) );
    //
    //     AdvancedSearchDialog::Result r =
    //         AdvancedSearchDialog( name, dataTablesInCurrentTree(), DataTableSearch(), widget ).exec();

    //     if ( r.result == AdvancedSearchDialog::Accepted )
    //         raise( new SearchDataTable( this, r.search, r.dataTableName ) );
}

void Project::createForeignDataTable()
{
    DataTable * parent = currentDataTable();

    if ( !parent )
        return ;

    raise( new DataTable( this, parent ) );

    QObject::connect( parent->dataTableView(), SIGNAL( selectionChanged() ),
                      parent, SLOT( slotUpdate() ) );

    QObject::connect( parent, SIGNAL( myCurrentChanged( QSqlRecord* ) ),
                      currentDataTable(), SLOT( slotDetailFromMaster( QSqlRecord* ) ) );

    QObject::connect( currentDataTable(), SIGNAL( requestParentSelect() ),
                      parent, SLOT( slotSelectFirstRow() ) );

    QObject::connect( currentDataTable(), SIGNAL( childValueChanged( const QString &, const QVariant & ) ),
                      parent, SLOT( slotValueFromChild( const QString &, const QVariant & ) ) );

    currentDataTable() ->setParentName( parent->name() );
    currentDataTable() ->setName( uniqueDataTableName( i18n( "Parent Relation Table" ) ) );
    currentDataTable() ->setNumber( dataTablesInCurrentPeerTree().count() );

    SqlFormWizard wizard( this, currentDataTable(), parent );
    wizard.exec();
}

void Project::createDatabaseDataTable()
{
    createDataTable();
    currentDataTable() ->setName( uniqueDataTableName( i18n( "Data Table" ) ) );
    currentDataTable() ->setNumber( dataTablesInCurrentPeerTree().count() );

    SqlFormWizard wizard( this, currentDataTable() );
    wizard.exec();
}

QObject *Project::object() const
{
    return m_actionHandler;
}

DataTable *Project::currentDataTable() const
{
    return dynamic_cast<DataTable *>( m_dataTableStack->visibleWidget() );
}

DataReport *Project::currentDataReport() const
{
    return dynamic_cast<DataReport *>( m_dataTableStack->visibleWidget() );
}

QWidgetStack *Project::dataTableStack() const
{
    return m_dataTableStack;
}

void Project::raise( DataTable *dataTable )
{
    m_dataTableStack->raiseWidget( dataTable );
}

void Project::raise( DataReport *dataReport )
{
    m_dataTableStack->raiseWidget( dataReport );
}

void Project::setSplashMessage( const QString & )
{
    // implemented in subclass
}

void Project::setupDataTable( DataTable *dataTable, const QString & )
{
    if ( !dataTable->name().isNull() )
        m_dataTableNames.append( dataTable->name() );

    //     QObject::connect( dataTable->dataTableView(), SIGNAL( selectionChanged() ),
    //                       object(), SIGNAL( signalSelectedItemsChanged() ) );
}

void Project::setupDataTable( DataTable *dataTable, const QString &, DataTable* )
{
    if ( !dataTable->name().isNull() )
        m_dataTableNames.append( dataTable->name() );

    //     QObject::connect( dataTable->dataTableView(), SIGNAL( selectionChanged() ),
    //                       object(), SIGNAL( signalSelectedItemsChanged() ) );
}

void Project::setIconName( DataTable *, const QString & )
{
    //impl in derived class
}

void Project::setupDataReport( DataReport *dataReport, const QString & )
{
    if ( !dataReport->name().isNull() )
        m_dataTableNames.append( dataReport->name() );

    //     QObject::connect( dataReport, SIGNAL( selectionChanged() ),
    //                       object(), SIGNAL( signalSelectedItemsChanged() ) );
}

void Project::setupDataReport( DataReport *dataReport, const QString &, DataTable* )
{
    if ( !dataReport->name().isNull() )
        m_dataTableNames.append( dataReport->name() );

    //     QObject::connect( dataReport, SIGNAL( selectionChanged() ),
    //                       object(), SIGNAL( signalSelectedItemsChanged() ) );
}

void Project::setIconName( DataReport *, const QString & )
{
    //impl in derived class
}

QString Project::dataTableNameDialog( const QString &caption,
                                      const QString &suggest,
                                      bool forceUnique ) const
{
    bool ok;

    QString name = KInputDialog::getText(
                       caption,
                       i18n( "Please enter a name for this dataTable:" ),
                       forceUnique ? uniqueDataTableName( suggest ) : suggest,
                       &ok );

    return ok ? uniqueDataTableName( name ) : QString::null;
}

QString Project::uniqueDataTableName( const QString &suggest ) const
{
    if ( suggest.isEmpty() )
        return uniqueDataTableName();

    bool contains = false;
    QStringList::ConstIterator it = m_dataTableNames.begin();
    for ( ; it != m_dataTableNames.end(); ++it )
        contains = DataTable::sanitize( (*it) ) ==
                    DataTable::sanitize( suggest ) ?
                    true : contains;

    if ( !contains )
        return suggest;

    QString base = suggest;
    base.remove( QRegExp( "\\s\\([0-9]+\\)$" ) );

    int count = 1;
    QString s = QString( "%1 (%2)" ).arg( base ).arg( count );

    while ( m_dataTableNames.contains( s ) )
    {
        count++;
        s = QString( "%1 (%2)" ).arg( base ).arg( count );
    }

    return s;
}

DataTable* Project::rootOfCurrentDataTable()
{
    //reimp
    return 0;
}

DataTableList Project::dataTablesInCurrentTree()
{
    //reimp
    return DataTableList();
}

DataTableList Project::dataTablesInDataTableTree( DataTable * )
{
    //reimp
    return DataTableList();
}

DataTableList Project::childrenOfDataTable( DataTable * )
{
    //reimp
    return DataTableList();
}

DataTableList Project::dataTablesInCurrentPeerTree()
{
    return dataTablesInDataTablePeerTree( currentDataTable() );
}

DataTableList Project::dataTablesInDataTablePeerTree( DataTable *dataTable )
{
    DataTableList dataTables;
    for ( DataTable * table = m_dataTables.first(); table; table = m_dataTables.next() )
        if ( table->parentName() == dataTable->parentName() )
            dataTables.append( table );
    return dataTables;
}

void Project::scrollTableUp()
{
    //reimp
}

void Project::scrollTableDown()
{
    //reimp
}

void Project::scrollTabLeft()
{
    //Scroll _all_ the datatables so they are in sync
    //it's just to distracting not too.
    int i = -1;
    if ( currentDataTable() )
        i = currentDataTable() ->scrollTabLeft( i );

    for ( DataTable * table = m_dataTables.first(); table; table = m_dataTables.next() )
    {
        if ( table != currentDataTable() )
            table ->scrollTabLeft( i );
    }
}

void Project::scrollTabRight()
{
    //Scroll _all_ the datatables so they are in sync
    //it's just to distracting not too.
    int i = -1;
    if ( currentDataTable() )
        i = currentDataTable() ->scrollTabRight( i );

    for ( DataTable * table = m_dataTables.first(); table; table = m_dataTables.next() )
    {
        if ( table != currentDataTable() )
            table ->scrollTabRight( i );
    }
}

void Project::firstRecord()
{
    if ( currentDataTable() )
        currentDataTable()->firstRecord();
}

void Project::previousRecord()
{
    if ( currentDataTable() )
        currentDataTable()->previousRecord();
}

void Project::nextRecord()
{
    if ( currentDataTable() )
        currentDataTable()->nextRecord();
}

void Project::lastRecord()
{
    if ( currentDataTable() )
        currentDataTable()->lastRecord();
}

void Project::commit()
{
    if ( currentDataTable() )
        currentDataTable()->commit();
}

void Project::insertRecord()
{
    if ( currentDataTable() )
        currentDataTable()->insertRecord();
}

void Project::changeRecord()
{
    if ( currentDataTable() )
        currentDataTable()->changeRecord();
}

void Project::deleteRecord()
{
    if ( currentDataTable() )
        currentDataTable()->deleteRecord();
}

void Project::addName( const QString &name )
{
    m_dataTableNames.append( name );
}

void Project::removeName( const QString &name )
{
    m_dataTableNames.remove( name );
}

DataTable *Project::dataTableByName( const QString &name ) const
{
    QObjectList * l = m_dataTableStack->queryList( "DataTable" );
    DataTable *table = 0;
    QObject *obj;

    for ( obj = l->first(); obj; obj = l->next() )
    {
        DataTable * p = static_cast<DataTable*>( obj );
        if ( p->name() == name )
        {
            table = p;
            break;
        }
    }

    delete l;
    return table;
}

Project::ActionHandler::ActionHandler( Project *collection ) :
        QObject( 0, "ActionHandler" ),
        m_project( collection )
{
    createAction( i18n( "New Project..." ), SLOT( slotNewProject() ),
                  "new_project", "filenew");
    createAction( i18n( "Open Project..." ), SLOT( slotOpenProject() ),
                  "open_project", "fileopen" );
    createAction( i18n( "Save Project" ), SLOT( slotSaveProject() ),
                  "save_project", "filesave" );
    createAction( i18n( "Save Project As..." ), SLOT( slotSaveAsProject() ),
                  "save_project_as", "filesaveas" );
    createAction( i18n( "Close Project" ), SLOT( slotCloseProject() ),
                  "close_project", "fileclose" );
    createAction( i18n( "Edit Project..." ), SLOT( slotEditProject() ),
                  "edit_project", "edit" );

    KToggleAction *clip = new KToggleAction( i18n( "Clipboard" ),
                                             "CRTL+B",
                                             this,
                                             SLOT( slotClipboard() ),
                                             actions(),
                                             "clipboard_manager" );
    clip->setChecked( false );

    createAction( i18n( "Create Table..." ), SLOT( slotCreateDatabaseDataTable() ),
                  "create_datatable", "table");
    createAction( i18n( "Create Child..." ), SLOT( slotCreateForeignDataTable() ),
                  "create_childtable", "child");

    createAction( i18n( "Create Search..." ), SLOT( slotAdvancedSearchClicked() ),
                  "create_search", "wizard");
    createAction( i18n( "Create Report..." ), SLOT( slotCreateKugarReport() ),
                  "create_report", "kugar");
    createAction( i18n( "&Edit Table..." ), SLOT( slotConfigureTable() ), "edit_table", "edit" );
    createAction( i18n( "&Add Virtual Field..." ), SLOT( slotAddVirtualField() ), "add_virtual", "filenew" );
    createAction( i18n( "&Remove Table" ), SLOT( slotRemoveTable() ), "remove_table", "remove" );

    createAction( i18n( "Move Table Up"), SLOT( slotMoveTableUp() ), "table_up", "up" );
    createAction( i18n( "Move Table Down"), SLOT( slotMoveTableDown() ), "table_down", "down" );

    createAction( i18n( "&Edit Search..." ), SLOT( slotEditSearch() ), "edit_search", "edit" );
    createAction( i18n( "&Remove Search" ), SLOT( slotRemoveSearch() ), "remove_search", "remove" );

    createAction( i18n( "Print Report" ), 0, "print", "fileprint" );
    createAction( i18n( "&Refresh Report" ), SLOT( slotRefreshReport() ), "refresh_report", "reload" );
    createAction( i18n( "&Edit Report..." ), SLOT( slotConfigureReport() ), "edit_report", "edit" );
    createAction( i18n( "&Remove Report" ), SLOT( slotRemoveReport() ), "remove_report", "remove" );

    createAction( i18n( "Scroll Table Up" ), SLOT( slotScrollTableUp() ), "move_up", "", "ALT+Up" );
    createAction( i18n( "Scroll Table Down" ), SLOT( slotScrollTableDown() ), "move_down", "", "ALT+Down" );
    createAction( i18n( "Scroll Tab Left" ), SLOT( slotScrollTabLeft() ), "tab_left", "", "ALT+Left" );
    createAction( i18n( "Scroll Tab Right" ), SLOT( slotScrollTabRight() ), "tab_right", "", "ALT+Right" );

    createAction( i18n( "First Record" ), SLOT( slotFirstRecord() ), "first_record", "", "Home" );
    createAction( i18n( "Previous Record" ), SLOT( slotPreviousRecord() ), "previous_record", "", "PageUp" );
    createAction( i18n( "Next Record" ), SLOT( slotNextRecord() ), "next_record", "", "PageDown" );
    createAction( i18n( "Last Record" ), SLOT( slotLastRecord() ), "last_record", "", "End" );

    createAction( i18n( "Commit Changes" ), SLOT( slotCommit() ), "commit", "", "CTRL+s" );

    createAction( i18n( "Insert New Record" ), SLOT( slotInsertRecord() ), "insert", "insert_row", "CTRL+i" );
    createAction( i18n( "Change Child Record" ), SLOT( slotChangeRecord() ), "change", "change_row", "" );
    createAction( i18n( "Delete Current Record" ), SLOT( slotDeleteRecord() ), "delete", "delete_row", "CTRL+d" );
}

KAction *Project::ActionHandler::createAction( const QString &text,
        const char *slot,
        const char *name,
        const QString &icon,
        const KShortcut &shortcut )
{
    if ( icon.isNull() )
        return new KAction( text, shortcut, this, slot, actions(), name );
    else
        return new KAction( text, icon, shortcut, this, slot, actions(), name );
}

//    ******************** DataTableCollection ********************

#ifdef widget
#undef widget
#endif

#include "project.moc"

Generated by  Doxygen 1.6.0   Back to index