/********************************************************************** ** Copyright (C) 2000 Trolltech AS. All rights reserved. ** **1 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. ** ** Licensees holding valid TQt Enterprise Edition or TQt Professional Edition ** licenses may use this file in accordance with the TQt Commercial License ** Agreement provided with the Software. ** ** 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. ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ** information about TQt Commercial License Agreements. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #include "project.h" #include "formwindow.h" #include "designerappiface.h" #include "../interfaces/languageinterface.h" #include "pixmapcollection.h" #ifndef TQT_NO_SQL #include "dbconnectionimpl.h" #endif #include "resource.h" #include #include "outputwindow.h" #include #include #include #include #include #include #include #include #include #include "mainwindow.h" #include #ifndef TQT_NO_SQL #include #include #include #endif #include #ifdef Q_OS_UNIX # include #endif #include #ifndef TQT_NO_SQL DatabaseConnection::~DatabaseConnection() { delete iface; } bool DatabaseConnection::refreshCatalog() { #ifndef TQT_NO_SQL if ( loaded ) return TRUE; if ( !open() ) return FALSE; tbls = conn->tables( TQSql::TableType( TQSql::Tables | TQSql::Views ) ); flds.clear(); for ( TQStringList::Iterator it = tbls.begin(); it != tbls.end(); ++it ) { TQSqlRecord fil = conn->record( *it ); TQStringList lst; for ( uint j = 0; j < fil.count(); ++j ) lst << fil.field( j )->name(); flds.insert( *it, lst ); } loaded = TRUE; conn->close(); return loaded; #else return FALSE; #endif } #ifndef TQT_NO_SQL void DatabaseConnection::remove() { if ( nm == "(default)" ) TQSqlDatabase::removeDatabase( TQSqlDatabase::defaultConnection ); else TQSqlDatabase::removeDatabase( nm ); // the above will effectively delete the current connection conn = 0; } #endif bool DatabaseConnection::open( bool suppressDialog ) { #ifndef TQT_NO_SQL // register our name, if nec if ( nm == "(default)" ) { if ( !TQSqlDatabase::contains() ) // default doesn't exists? conn = TQSqlDatabase::addDatabase( drv ); else conn = TQSqlDatabase::database(); } else { if ( !TQSqlDatabase::contains( nm ) ) conn = TQSqlDatabase::addDatabase( drv, nm ); else conn = TQSqlDatabase::database( nm ); } conn->setDatabaseName( dbName ); conn->setUserName( uname ); conn->setPassword( pword ); conn->setHostName( hname ); conn->setPort( prt ); bool success = conn->open(); for( ; suppressDialog == FALSE ; ) { bool done = FALSE; if ( !success ) { DatabaseConnectionEditor dia( this, 0 , 0 , TRUE ); switch( dia.exec() ) { case TQDialog::Accepted: done = FALSE; break; case TQDialog::Rejected: done = TRUE; break; } } if ( done ) break; conn->setUserName( uname ); conn->setPassword( pword ); conn->setHostName( hname ); conn->setPort( prt ); success = conn->open(); if ( !success ) { switch( TQMessageBox::warning( project->messageBoxParent(), i18n( "Connection" ), i18n( "Could not connect to the database.\n" "Press 'OK' to continue or 'Cancel' to " "specify different\nconnection information.\n" ) + TQString( "[" + conn->lastError().driverText() + "\n" + conn->lastError().databaseText() + "]\n" ), i18n( "&OK" ), i18n( "&Cancel" ), TQString(), 0, 1 ) ) { case 0: // OK or Enter continue; case 1: // Cancel or Escape done = TRUE; break; } } else break; if ( done ) break; } if ( !success ) { dbErr = conn->lastError().driverText() + "\n" + conn->lastError().databaseText(); remove(); } return success; #else return FALSE; #endif } void DatabaseConnection::close() { if ( !loaded ) return; #ifndef TQT_NO_SQL if ( conn ) { conn->close(); } #endif } DesignerDatabase *DatabaseConnection::iFace() { if ( !iface ) iface = new DesignerDatabaseImpl( this ); return iface; } #endif //////// bool Project::isDummy() const { return isDummyProject; } Project::Project( const TQString &fn, const TQString &pName, TQPluginManager *pm, bool isDummy, const TQString &l ) : proName( pName ), projectSettingsPluginManager( pm ), isDummyProject( isDummy ) { modified = TRUE; pixCollection = new PixmapCollection( this ); iface = 0; lang = l; is_cpp = lang == "C++"; cfg.insert( "(all)", "qt warn_on release" ); templ = "app"; setFileName( fn ); if ( !pName.isEmpty() ) proName = pName; sourcefiles.setAutoDelete( TRUE ); modified = FALSE; objs.setAutoDelete( FALSE ); fakeFormFiles.setAutoDelete( FALSE ); } Project::~Project() { if ( singleProjectMode() ) removeTempProject(); delete iface; delete pixCollection; } void Project::setModified( bool b ) { modified = b; emit projectModified(); } #ifndef TQT_NO_SQL DatabaseConnection *Project::databaseConnection( const TQString &name ) { for ( DatabaseConnection *conn = dbConnections.first(); conn; conn = dbConnections.next() ) { if ( conn->name() == name ) return conn; } return 0; } #endif void Project::setFileName( const TQString &fn, bool doClear ) { if ( fn == filename ) return; if ( singleProjectMode() ) { TQString qsa = TQString( getenv( "HOME" ) ) + TQString( "/.qsa" ); if ( !TQFile::exists( qsa ) ) { TQDir d; d.mkdir( qsa ); } if ( fn == singleProFileName ) return; singleProFileName = fn; static int counter = 0; TQString str_counter = TQString::number( counter++ ); str_counter = "/.qsa/" + str_counter; LanguageInterface *iface = MetaDataBase::languageInterface( language() ); filename = TQString( getenv( "HOME" ) + str_counter + TQString( "tmp_" ) + TQFileInfo( fn ).baseName() + "/" + TQFileInfo( fn ).baseName() + ".pro" ); removeTempProject(); if ( iface && iface->supports( LanguageInterface::CompressProject ) ) { filename = iface->uncompressProject( makeAbsolute( singleProFileName ), TQString( getenv( "HOME" ) + str_counter + TQString( "tmp_" ) + TQFileInfo( fn ).baseName() ) ); proName = makeAbsolute( singleProFileName ); } } else { filename = fn; if ( !filename.endsWith( ".pro" ) ) filename += ".pro"; proName = filename; } if ( proName.contains( '.' ) ) proName = proName.left( proName.find( '.' ) ); if ( !doClear ) return; clear(); if ( TQFile::exists( filename ) ) parse(); } TQString Project::fileName( bool singlePro ) const { if ( singlePro ) return singleProFileName; return filename; } TQString Project::databaseDescription() const { return dbFile; } TQString Project::projectName() const { return proName; } static TQString parse_part( const TQString &part ) { TQString res; bool inName = FALSE; TQString currName; for ( int i = 0; i < (int)part.length(); ++i ) { TQChar c = part[ i ]; if ( !inName ) { if ( c != ' ' && c != '\t' && c != '\n' && c != '=' && c != '\\' && c != '+' ) inName = TRUE; else continue; } if ( inName ) { if ( c == '\n' ) break; res += c; } } return res; } TQStringList parse_multiline_part( const TQString &contents, const TQString &key, int *start = 0 ) { if ( start ) *start = -1; TQString lastWord; // Account for things like win32: SOURCES int extraWhiteSpaceCount = 0; int braceCount = 0; for ( int i = 0; i < (int)contents.length(); ++i ) { TQChar c( contents[ i ] ); switch ( c ) { case '{': braceCount++; lastWord = ""; break; case '}': braceCount--; lastWord = ""; break; case ' ': case '\t': if (!key.startsWith(lastWord)) { lastWord = ""; extraWhiteSpaceCount = 0; } else { extraWhiteSpaceCount++; } break; case '\\': case '\n': lastWord = ""; break; default: lastWord += c; } // ### we should read the 'bla { SOURCES= ... }' stuff as well (braceCount > 0) if ( lastWord == key && braceCount == 0 ) { if ( start ) *start = i - lastWord.length() - extraWhiteSpaceCount + 1; TQStringList lst; bool inName = FALSE; TQString currName; bool hadEqual = FALSE; for ( ; i < (int)contents.length(); ++i ) { c = contents[ i ]; if ( !hadEqual && c != '=' ) continue; if ( !hadEqual ) { hadEqual = TRUE; continue; } if ( ( c.isLetter() || c.isDigit() || c == '.' || c == '/' || c == '_' || c == '\\' || c == '\"' || c == '\'' || c == '=' || c == '$' || c == '-' || c == '(' || c == ')' || c == ':' || c == '+' || c == ',' || c == '~' ) && c != ' ' && c != '\t' && c != '\n' ) { if ( !inName ) currName = TQString(); if ( c != '\\' || contents[i+1] != '\n' ) { currName += c; inName = TRUE; } } else { if ( inName ) { inName = FALSE; if ( currName.simplifyWhiteSpace() != "\\" ) lst.append( currName ); } if ( c == '\n' && i > 0 && contents[ (int)i - 1 ] != '\\' ) break; } } return lst; } } return TQStringList(); } void Project::parse() { TQFile f( filename ); if ( !f.exists() || !f.open( IO_ReadOnly ) ) return; TQTextStream ts( &f ); TQString contents = ts.read(); f.close(); proName = TQFileInfo( filename ).baseName(); TQStringList::ConstIterator it; int i = contents.find( "LANGUAGE" ); if ( i != -1 ) { lang = ""; is_cpp = FALSE; TQString part = contents.mid( i + TQString( "LANGUAGE" ).length() ); lang = parse_part( part ); is_cpp = lang == "C++"; } i = contents.find( "DBFILE" ); if ( i != -1 ) { dbFile = ""; TQString part = contents.mid( i + TQString( "DBFILE" ).length() ); dbFile = parse_part( part ); } TQStringList uifiles = parse_multiline_part( contents, "FORMS" ); uifiles += parse_multiline_part( contents, "INTERFACES" ); // compatibility for ( it = uifiles.begin(); it != uifiles.end(); ++it ) { if ( (*it).startsWith( "__APPOBJ" ) ) continue; (void) new FormFile( *it, FALSE, this ); } i = contents.find( "TEMPLATE" ); if ( i != -1 ) { templ = ""; TQString part = contents.mid( i + TQString( "TEMPLATE" ).length() ); templ = parse_part( part ); } readPlatformSettings( contents, "CONFIG", cfg ); readPlatformSettings( contents, "LIBS", lbs ); readPlatformSettings( contents, "INCLUDEPATH", inclPath ); readPlatformSettings( contents, "DEFINES", defs ); readPlatformSettings( contents, "SOURCES", sources ); readPlatformSettings( contents, "HEADERS", headers ); LanguageInterface *iface = MetaDataBase::languageInterface( lang ); if ( iface ) { TQStringList sourceKeys; iface->sourceProjectKeys( sourceKeys ); for ( TQStringList::Iterator it = sourceKeys.begin(); it != sourceKeys.end(); ++it ) { TQStringList lst = parse_multiline_part( contents, *it ); for ( TQStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) (void) new SourceFile( *it, FALSE, this ); } } updateCustomSettings(); for ( it = csList.begin(); it != csList.end(); ++it ) { i = contents.find( *it ); if ( i != -1 ) { TQString val = ""; TQString part = contents.mid( i + TQString( *it ).length() ); val = parse_part( part ); customSettings.replace( *it, val ); } } loadConnections(); TQStringList images = parse_multiline_part( contents, "IMAGES" ); // ### remove that for the final - this is beta-compatibility if ( images.isEmpty() && TQDir( TQFileInfo( filename ).dirPath( TRUE ) + "/images" ).exists() ) { images = TQDir( TQFileInfo( filename ).dirPath( TRUE ) + "/images" ).entryList(); for ( int i = 0; i < (int)images.count(); ++i ) images[ i ].prepend( "images/" ); modified = TRUE; } for ( TQStringList::ConstIterator pit = images.begin(); pit != images.end(); ++pit ) pixCollection->load( *pit ); } void Project::clear() { dbFile = ""; proName = "unnamed"; desc = ""; } bool Project::removeSourceFile( SourceFile *sf ) { if ( !sourcefiles.containsRef( sf ) ) return FALSE; if ( !sf->close() ) return FALSE; sourcefiles.removeRef( sf ); modified = TRUE; emit sourceFileRemoved( sf ); return TRUE; } void Project::setDatabaseDescription( const TQString &db ) { dbFile = db; } void Project::setDescription( const TQString &s ) { desc = s; } TQString Project::description() const { return desc; } bool Project::isValid() const { // #### do more checking here? if ( filename.isEmpty() || proName.isEmpty() ) return FALSE; return TRUE; } TQString Project::makeAbsolute( const TQString &f ) { if ( isDummy() ) return f; TQString encodedUrl = TQFileInfo( filename ).dirPath( TRUE ); TQUrl::encode( encodedUrl ); TQUrl u( encodedUrl, f ); return u.path(); } TQString Project::makeRelative( const TQString &f ) { if ( isDummy() ) return f; TQString p = TQFileInfo( filename ).dirPath( TRUE ); TQString f2 = f; if ( f2.left( p.length() ) == p ) f2.remove( 0, p.length() + 1 ); return f2; } static void remove_contents( TQString &contents, const TQString &s ) { int i = contents.find( s ); if ( i != -1 ) { int start = i; int end = contents.find( '\n', i ); if ( end == -1 ) end = contents.length() - 1; contents.remove( start, end - start + 1 ); } } static void remove_multiline_contents( TQString &contents, const TQString &s, int *strt = 0 ) { int i = contents.find( s ); if ( strt ) *strt = i; int start = i; bool lastWasBackspash = FALSE; if ( i != -1 && ( i == 0 || contents[ i - 1 ] != '{' || contents[ i - 1 ] != ':' ) ) { for ( ; i < (int)contents.length(); ++i ) { if ( contents[ i ] == '\n' && !lastWasBackspash ) break; lastWasBackspash = ( contents[ i ] == '\\' || lastWasBackspash && ( contents[ i ] == ' ' || contents[ i ] == '\t' ) ); } contents.remove( start, i - start + 1 ); } } void Project::save( bool onlyProjectFile ) { bool anythingModified = FALSE; // save sources and forms if ( !onlyProjectFile ) { saveConnections(); for ( SourceFile *sf = sourcefiles.first(); sf; sf = sourcefiles.next() ) { anythingModified = anythingModified || sf->isModified(); if ( !sf->save() ) return; } for ( FormFile *ff = formfiles.first(); ff; ff = formfiles.next() ) { anythingModified = anythingModified || ff->isModified(); if ( !ff->save() ) return; } } if ( isDummy() || filename.isEmpty() ) return; if ( !modified ) { if ( singleProjectMode() ) { LanguageInterface *iface = MetaDataBase::languageInterface( language() ); if ( iface && iface->supports( LanguageInterface::CompressProject ) ) iface->compressProject( makeAbsolute( filename ), singleProFileName, anythingModified ); } return; } TQFile f( filename ); TQString original = ""; // read the existing file bool hasPreviousContents = FALSE; if ( f.open( IO_ReadOnly ) ) { TQTextStream ts( &f ); original = ts.read(); f.close(); hasPreviousContents = TRUE; remove_contents( original, "{SOURCES+=" ); // ### compatibility with early 3.0 betas remove_contents( original, "DBFILE" ); remove_contents( original, "LANGUAGE" ); remove_contents( original, "TEMPLATE" ); removePlatformSettings( original, "CONFIG" ); removePlatformSettings( original, "DEFINES" ); removePlatformSettings( original, "LIBS" ); removePlatformSettings( original, "INCLUDEPATH" ); removePlatformSettings( original, "SOURCES" ); removePlatformSettings( original, "HEADERS" ); remove_multiline_contents( original, "FORMS" ); remove_multiline_contents( original, "INTERFACES" ); // compatibility remove_multiline_contents( original, "IMAGES" ); for ( TQStringList::Iterator it = csList.begin(); it != csList.end(); ++it ) remove_contents( original, *it ); } // the contents of the saved file TQString contents; // template contents += "TEMPLATE\t= " + templ + "\n"; // language contents += "LANGUAGE\t= " + lang + "\n"; contents += "\n"; // config writePlatformSettings( contents, "CONFIG", cfg ); LanguageInterface *iface = MetaDataBase::languageInterface( lang ); if ( iface ) { TQStringList sourceKeys; iface->sourceProjectKeys( sourceKeys ); for ( TQStringList::Iterator spit = sourceKeys.begin(); spit != sourceKeys.end(); ++spit ) remove_multiline_contents( contents, *spit ); } contents += "\n"; // libs, defines, includes writePlatformSettings( contents, "LIBS", lbs ); writePlatformSettings( contents, "DEFINES", defs ); writePlatformSettings( contents, "INCLUDEPATH", inclPath ); writePlatformSettings( contents, "SOURCES", sources ); writePlatformSettings( contents, "HEADERS", headers ); // unix if ( !hasPreviousContents ) { contents += "unix {\n" " UI_DIR = .ui\n" " MOC_DIR = .moc\n" " OBJECTS_DIR = .obj\n" "}\n"; } contents += "\n"; // sources if ( !sourcefiles.isEmpty() && iface ) { TQMap sourceToKey; for ( SourceFile *f = sourcefiles.first(); f; f = sourcefiles.next() ) { TQString key = iface->projectKeyForExtension( TQFileInfo( f->fileName() ).extension() ); TQStringList lst = sourceToKey[ key ]; lst << makeRelative( f->fileName() ); sourceToKey.replace( key, lst ); } for ( TQMap::Iterator skit = sourceToKey.begin(); skit != sourceToKey.end(); ++skit ) { TQString part = skit.key() + "\t+= "; TQStringList lst = *skit; for ( TQStringList::Iterator sit = lst.begin(); sit != lst.end(); ++sit ) { part += *sit; part += ++sit != lst.end() ? " \\\n\t" : ""; --sit; } part += "\n"; contents += part; } } // forms and interfaces if ( !formfiles.isEmpty() ) { contents += "FORMS\t= "; for ( TQPtrListIterator fit = formfiles; fit.current(); ++fit ) { contents += fit.current()->fileName() + (fit != formfiles.last() ? " \\\n\t" : ""); } contents += "\n"; } // images if ( !pixCollection->isEmpty() ) { contents += "IMAGES\t= "; TQValueList pixmaps = pixCollection->pixmaps(); for ( TQValueList::Iterator it = pixmaps.begin(); it != pixmaps.end(); ++it ) { contents += makeRelative( (*it).absname ); contents += ++it != pixmaps.end() ? " \\\n\t" : ""; --it; } contents += "\n"; } // database if ( !dbFile.isEmpty() ) contents += "DBFILE\t= " + dbFile + "\n"; contents += "\n"; // custom settings for ( TQStringList::Iterator it = csList.begin(); it != csList.end(); ++it ) { TQString val = *customSettings.find( *it ); if ( !val.isEmpty() ) contents += *it + "\t= " + val + "\n"; } if ( !f.open( IO_WriteOnly | IO_Translate ) ) { TQMessageBox::warning( messageBoxParent(), "Save Project Failed", "Couldn't write project file " + filename ); return; } TQTextStream os( &f ); os << contents; if (hasPreviousContents) os << original; f.close(); setModified( FALSE ); if ( singleProjectMode() ) { LanguageInterface *iface = MetaDataBase::languageInterface( language() ); if ( iface && iface->supports( LanguageInterface::CompressProject ) ) iface->compressProject( makeAbsolute( filename ), singleProFileName, TRUE ); } } #ifndef TQT_NO_SQL TQPtrList Project::databaseConnections() const { return dbConnections; } #endif #ifndef TQT_NO_SQL void Project::setDatabaseConnections( const TQPtrList &lst ) { dbConnections = lst; } #endif #ifndef TQT_NO_SQL void Project::addDatabaseConnection( DatabaseConnection *conn ) { dbConnections.append( conn ); modified = TRUE; } #endif #ifndef TQT_NO_SQL void Project::removeDatabaseConnection( const TQString &c ) { for ( DatabaseConnection *conn = dbConnections.first(); conn; conn = dbConnections.next() ) { if ( conn->name() == c ) { conn->remove(); dbConnections.removeRef( conn ); delete conn; return; } } } #endif #ifndef TQT_NO_SQL TQStringList Project::databaseConnectionList() { TQStringList lst; for ( DatabaseConnection *conn = dbConnections.first(); conn; conn = dbConnections.next() ) lst << conn->name(); return lst; } #endif #ifndef TQT_NO_SQL TQStringList Project::databaseTableList( const TQString &connection ) { DatabaseConnection *conn = databaseConnection( connection ); if ( !conn ) { return TQStringList(); } return conn->tables(); } #endif #ifndef TQT_NO_SQL TQStringList Project::databaseFieldList( const TQString &connection, const TQString &table ) { DatabaseConnection *conn = databaseConnection( connection ); if ( !conn ) return TQStringList(); return conn->fields( table ); } #endif #ifndef TQT_NO_SQL static TQString makeIndent( int indent ) { TQString s; s.fill( ' ', indent * 4 ); return s; } #endif #ifndef TQT_NO_SQL static void saveSingleProperty( TQTextStream &ts, const TQString& name, const TQString& value, int indent ) { ts << makeIndent( indent ) << "" << endl; ++indent; ts << makeIndent( indent ) << "" << value << "" << endl; --indent; ts << makeIndent( indent ) << "" << endl; } #endif void Project::saveConnections() { #ifndef TQT_NO_SQL if ( dbFile.isEmpty() ) { TQFileInfo fi( fileName() ); setDatabaseDescription( fi.baseName() + ".db" ); } TQFile f( makeAbsolute( dbFile ) ); if ( dbConnections.isEmpty() ) { if ( f.exists() ) f.remove(); setDatabaseDescription( "" ); modified = TRUE; return; } /* .db xml */ if ( f.open( IO_WriteOnly | IO_Translate ) ) { TQTextStream ts( &f ); ts.setCodec( TQTextCodec::codecForName( "UTF-8" ) ); ts << "" << endl; /* db connections */ int indent = 0; for ( DatabaseConnection *conn = dbConnections.first(); conn; conn = dbConnections.next() ) { ts << makeIndent( indent ) << "" << 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", TQString::number( conn->port() ), indent ); /* connection tables */ TQStringList tables = conn->tables(); for ( TQStringList::Iterator it = tables.begin(); it != tables.end(); ++it ) { ts << makeIndent( indent ) << "" << endl; ++indent; saveSingleProperty( ts, "name", (*it), indent ); /* tables fields */ TQStringList fields = conn->fields( *it ); for ( TQStringList::Iterator it2 = fields.begin(); it2 != fields.end(); ++it2 ) { ts << makeIndent( indent ) << "" << endl; ++indent; saveSingleProperty( ts, "name", (*it2), indent ); --indent; ts << makeIndent( indent ) << "" << endl; } --indent; ts << makeIndent( indent ) << "
" << endl; } --indent; ts << makeIndent( indent ) << "
" << endl; } ts << "
" << endl; f.close(); } #endif } #ifndef TQT_NO_SQL static TQDomElement loadSingleProperty( TQDomElement e, const TQString& name ) { TQDomElement 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; } #endif void Project::loadConnections() { #ifndef TQT_NO_SQL if ( dbFile.isEmpty() || !TQFile::exists( makeAbsolute( dbFile ) ) ) return; TQFile f( makeAbsolute( dbFile ) ); if ( f.open( IO_ReadOnly ) ) { TQDomDocument doc; TQString errMsg; int errLine; if ( doc.setContent( &f, &errMsg, &errLine ) ) { TQDomElement e; e = doc.firstChild().toElement(); /* connections */ TQDomNodeList connections = e.toElement().elementsByTagName( "connection" ); for ( uint i = 0; i < connections.length(); i++ ) { TQDomElement connection = connections.item(i).toElement(); TQDomElement connectionName = loadSingleProperty( connection, "name" ); TQDomElement connectionDriver = loadSingleProperty( connection, "driver" ); TQDomElement connectionDatabase = loadSingleProperty( connection, "database" ); TQDomElement connectionUsername = loadSingleProperty( connection, "username" ); TQDomElement connectionHostname = loadSingleProperty( connection, "hostname" ); TQDomElement connectionPort = loadSingleProperty( connection, "port" ); DatabaseConnection *conn = new DatabaseConnection( this ); conn->setName( connectionName.firstChild().firstChild().toText().data() ); conn->setDriver( connectionDriver.firstChild().firstChild().toText().data() ); conn->setDatabase( connectionDatabase.firstChild().firstChild().toText().data() ); conn->setUsername( connectionUsername.firstChild().firstChild().toText().data() ); conn->setHostname( connectionHostname.firstChild().firstChild().toText().data() ); conn->setPort( TQString( connectionPort.firstChild().firstChild().toText().data() ).toInt() ); /* connection tables */ TQDomNodeList tables = connection.toElement().elementsByTagName( "table" ); for ( uint j = 0; j < tables.length(); j++ ) { TQDomElement table = tables.item(j).toElement(); TQDomElement tableName = loadSingleProperty( table, "name" ); conn->addTable( tableName.firstChild().firstChild().toText().data() ); /* table fields */ TQStringList fieldList; TQDomNodeList fields = table.toElement().elementsByTagName( "field" ); for ( uint k = 0; k < fields.length(); k++ ) { TQDomElement field = fields.item(k).toElement(); TQDomElement fieldName = loadSingleProperty( field, "name" ); fieldList.append( fieldName.firstChild().firstChild().toText().data() ); } conn->setFields( tableName.firstChild().firstChild().toText().data(), fieldList ); } dbConnections.append( conn ); } } else { tqDebug( TQString("Parse error: ") + errMsg + TQString(" in line %d"), errLine ); } f.close(); } #endif } /*! Opens the database \a connection. The connection remains open and can be closed again with closeDatabase(). */ bool Project::openDatabase( const TQString &connection, bool suppressDialog ) { #ifndef TQT_NO_SQL DatabaseConnection *conn = databaseConnection( connection ); if ( connection.isEmpty() && !conn ) conn = databaseConnection( "(default)" ); if ( !conn ) return FALSE; bool b = conn->open( suppressDialog ); return b; #else Q_UNUSED( connection ); Q_UNUSED( suppressDialog ); return FALSE; #endif } /*! Closes the database \a connection. */ void Project::closeDatabase( const TQString &connection ) { #ifndef TQT_NO_SQL DatabaseConnection *conn = databaseConnection( connection ); if ( connection.isEmpty() && !conn ) conn = databaseConnection( "(default)" ); if ( !conn ) return; conn->close(); #else Q_UNUSED( connection ); #endif } // void Project::formClosed( FormWindow *fw ) // { // formWindows.remove( fw ); // } TQObjectList *Project::formList( bool resolveFakeObjects ) const { TQObjectList *l = new TQObjectList; for ( TQPtrListIterator forms(formfiles); forms.current(); ++forms ) { FormFile* f = forms.current(); if ( f->formWindow() ) { if ( resolveFakeObjects && f->formWindow()->isFake() ) l->append( objectForFakeForm( f->formWindow() ) ); else l->append( f->formWindow()->child( 0, TQWIDGET_OBJECT_NAME_STRING ) ); } else if ( f->isFake() ) { l->append( objectForFakeFormFile( f ) ); } } return l; } DesignerProject *Project::iFace() { if ( !iface ) iface = new DesignerProjectImpl( this ); return iface; } void Project::setLanguage( const TQString &l ) { if ( l == lang ) return; lang = l; is_cpp = lang == "C++"; updateCustomSettings(); modified = TRUE; } TQString Project::language() const { return lang; } void Project::setCustomSetting( const TQString &key, const TQString &value ) { customSettings.remove( key ); customSettings.insert( key, value ); modified = TRUE; } TQString Project::customSetting( const TQString &key ) const { return *customSettings.find( key ); } void Project::updateCustomSettings() { if ( !projectSettingsPluginManager ) return; /* ProjectSettingsInterface *iface = 0; projectSettingsPluginManager->queryInterface( lang, (TQUnknownInterface**)&iface ); if ( !iface ) return; csList = iface->projectSettings(); iface->release(); */ TQInterfacePtr iface; projectSettingsPluginManager->queryInterface( lang, &iface ); if ( !iface ) return; csList = iface->projectSettings(); customSettings.clear(); } void Project::setActive( bool b ) { pixCollection->setActive( b ); } void Project::addSourceFile( SourceFile *sf ) { sourcefiles.append( sf ); modified = TRUE; emit sourceFileAdded( sf ); } SourceFile* Project::findSourceFile( const TQString& filename, SourceFile *ignore ) const { TQPtrListIterator it(sourcefiles); while ( it.current() ) { if ( it.current() != ignore && it.current()->fileName() == filename ) return it.current(); ++it; } return 0; } FormFile* Project::findFormFile( const TQString& filename, FormFile *ignore ) const { TQPtrListIterator it(formfiles); while ( it.current() ) { if ( it.current() != ignore && it.current()->fileName() == filename ) return it.current(); ++it; } return 0; } void Project::setIncludePath( const TQString &platform, const TQString &path ) { if ( inclPath[platform] == path ) return; inclPath.replace( platform, path ); modified = TRUE; } void Project::setLibs( const TQString &platform, const TQString &path ) { lbs.replace( platform, path ); } void Project::setDefines( const TQString &platform, const TQString &path ) { defs.replace( platform, path ); } void Project::setConfig( const TQString &platform, const TQString &config ) { cfg.replace( platform, config ); } TQString Project::config( const TQString &platform ) const { return cfg[ platform ]; } TQString Project::libs( const TQString &platform ) const { return lbs[ platform ]; } TQString Project::defines( const TQString &platform ) const { return defs[ platform ]; } TQString Project::includePath( const TQString &platform ) const { return inclPath[ platform ]; } TQString Project::templte() const { return templ; } void Project::setTemplate( const TQString &t ) { templ = t; } void Project::readPlatformSettings( const TQString &contents, const TQString &setting, TQMap &res ) { const TQString platforms[] = { "", "win32", "unix", "mac", TQString() }; for ( int i = 0; platforms[ i ] != TQString(); ++i ) { TQString p = platforms[ i ]; if ( !p.isEmpty() ) p += ":"; TQStringList lst = parse_multiline_part( contents, p + setting ); TQString s = lst.join( " " ); TQString key = platforms[ i ]; if ( key.isEmpty() ) key = "(all)"; res.replace( key, s ); } } void Project::removePlatformSettings( TQString &contents, const TQString &setting ) { const TQString platforms[] = { "win32", "unix", "mac", "", TQString() }; for ( int i = 0; platforms[ i ] != TQString(); ++i ) { TQString p = platforms[ i ]; if ( !p.isEmpty() ) p += ":"; remove_multiline_contents( contents, p + setting ); } } void Project::writePlatformSettings( TQString &contents, const TQString &setting, const TQMap &input ) { const TQString platforms[] = { "", "win32", "unix", "mac", TQString() }; int i; LanguageInterface *iface = MetaDataBase::languageInterface( lang ); if (iface && (setting == "SOURCES" || setting == "HEADERS")) // The (all) part will be saved later on i = 1; else i = 0; for (; platforms[ i ] != TQString(); ++i ) { TQString p = platforms[ i ]; if ( !p.isEmpty() ) p += ":"; TQString key = platforms[ i ]; if ( key.isEmpty() ) key = "(all)"; TQMap::ConstIterator it = input.find( key ); if ( it == input.end() || (*it).isEmpty() ) continue; contents += p + setting + "\t+= " + *it + "\n"; } } void Project::addFormFile( FormFile *ff ) { formfiles.append( ff ); modified = TRUE; emit formFileAdded( ff ); } bool Project::removeFormFile( FormFile *ff ) { if ( !formfiles.containsRef( ff ) ) return FALSE; if ( !ff->close() ) return FALSE; formfiles.removeRef( ff ); modified = TRUE; emit formFileRemoved( ff ); return TRUE; } void Project::addObject( TQObject *o ) { bool wasModified = modified; objs.append( o ); FormFile *ff = new FormFile( "", FALSE, this, "qt_fakewindow" ); ff->setFileName( "__APPOBJ" + TQString( o->name() ) + ".ui" ); fakeFormFiles.insert( (void*)o, ff ); MetaDataBase::addEntry( o ); if ( hasGUI() ) { TQWidget *parent = MainWindow::self ? MainWindow::self->qWorkspace() : 0; FormWindow *fw = new FormWindow( ff, MainWindow::self, parent, "qt_fakewindow" ); fw->setProject( this ); if ( TQFile::exists( ff->absFileName() ) ) Resource::loadExtraSource( ff, ff->absFileName(), MetaDataBase::languageInterface( language() ), FALSE ); if ( MainWindow::self ) fw->setMainWindow( MainWindow::self ); if ( MainWindow::self ) { TQApplication::sendPostedEvents( MainWindow::self->qWorkspace(), TQEvent::ChildInserted ); connect( fw, TQT_SIGNAL( undoRedoChanged( bool, bool, const TQString &, const TQString & ) ), MainWindow::self, TQT_SLOT( updateUndoRedo( bool, bool, const TQString &, const TQString & ) ) ); } if ( fw->parentWidget() ) { fw->parentWidget()->setFixedSize( 1, 1 ); fw->show(); } } else { if ( TQFile::exists( ff->absFileName() ) ) Resource::loadExtraSource( ff, ff->absFileName(), MetaDataBase::languageInterface( language() ), FALSE ); } emit objectAdded( o ); modified = wasModified; } void Project::setObjects( const TQObjectList &ol ) { for ( TQObjectListIt it( ol ); it.current(); ++it ) addObject( it.current() ); } void Project::removeObject( TQObject *o ) { bool wasModified = modified; objs.removeRef( o ); MetaDataBase::removeEntry( o ); fakeFormFiles.remove( (void*)o ); emit objectRemoved( o ); modified = wasModified; } TQObjectList Project::objects() const { return objs; } FormFile *Project::fakeFormFileFor( TQObject *o ) const { return fakeFormFiles.find( (void*)o ); } TQObject *Project::objectForFakeForm( FormWindow *fw ) const { for ( TQPtrDictIterator it( fakeFormFiles ); it.current(); ++it ) { if ( it.current()->formWindow() == fw || it.current() == fw->formFile() ) return (TQObject*)it.currentKey(); } return 0; } TQObject *Project::objectForFakeFormFile( FormFile *ff ) const { for ( TQPtrDictIterator it( fakeFormFiles ); it.current(); ++it ) { if ( it.current() == ff ) return (TQObject*)it.currentKey(); } return 0; } void Project::removeTempProject() { if ( !singleProjectMode() ) return; TQDir d( TQFileInfo( filename ).dirPath() ); if ( !d.exists( TQFileInfo( filename ).dirPath() ) ) return; TQStringList files = d.entryList( TQDir::Files ); TQStringList::Iterator it; for ( it = files.begin(); it != files.end(); ++it ) { d.remove( *it ); } if ( d.exists( TQFileInfo( filename ).dirPath() + "/images" ) ) { d = TQDir( TQFileInfo( filename ).dirPath() + "/images" ); files = d.entryList( TQDir::Files ); for ( it = files.begin(); it != files.end(); ++it ) d.remove( *it ); d = TQDir( TQFileInfo( filename ).dirPath() ); d.remove( "images" ); } d.remove( TQFileInfo( filename ).dirPath() ); #if defined(Q_OS_UNIX) // ##### implement for all platforms, ideally should be in TQt ::rmdir( TQFile::encodeName( d.absPath() ) ); #endif } void Project::addAndEditFunction( const TQString &function, const TQString &functionBody, bool openDeveloper ) { for ( SourceFile *f = sourcefiles.first(); f; f = sourcefiles.next() ) { if ( TQFileInfo( f->fileName() ).baseName() == "main" ) { TQValueList funcs; LanguageInterface *iface = MetaDataBase::languageInterface( language() ); if ( !iface ) return; iface->functions( f->text(), &funcs ); TQString func = function; int i = func.find( '(' ); if ( i != -1 ) func = func.left( i ); bool found = FALSE; for ( TQValueList::Iterator it = funcs.begin(); it != funcs.end(); ++it ) { if ( (*it).name.left( (*it).name.find( '(' ) ) == func ) { found = TRUE; break; } } if ( !found ) { TQString code = f->text(); if ( functionBody.isEmpty() ) code += "\n\n" + iface->createFunctionStart( "", func, "", "" ) + "()\n{\n\n}\n"; else code += "\n\n" + iface->createFunctionStart( "", func, "", "" ) + "()\n" + functionBody + "\n"; f->setText( code ); if ( f->editor() ) f->editor()->refresh( FALSE ); } if ( openDeveloper ) { if ( MainWindow::self ) MainWindow::self->editSource( f ); f->editor()->setFunction( func, "" ); } break; } } } bool Project::hasParentObject( TQObject *o ) { for ( TQObject *p = objs.first(); p; p = objs.next() ) { TQObject *c = p->child( o->name(), o->className() ); if ( c ) return TRUE; } return FALSE; } TQString Project::qualifiedName( TQObject *o ) { TQString name = o->name(); TQObject *p = o->parent(); while ( p ) { name.prepend( TQString( p->name() ) + "." ); if ( objs.findRef( p ) != -1 ) break; p = p->parent(); } return name; } bool Project::singleProjectMode() const { return !MainWindow::self || MainWindow::self->singleProjectMode(); } TQWidget *Project::messageBoxParent() const { return MainWindow::self; } void Project::designerCreated() { for ( FormFile *ff = formfiles.first(); ff; ff = formfiles.next() ) { FormWindow *fw = ff->formWindow(); if ( !fw || fw->mainWindow() ) continue; fw->setMainWindow( MainWindow::self ); connect( fw, TQT_SIGNAL( undoRedoChanged( bool, bool, const TQString &, const TQString & ) ), MainWindow::self, TQT_SLOT( updateUndoRedo( bool, bool, const TQString &, const TQString & ) ) ); fw->reparent( MainWindow::self->qWorkspace(), TQPoint( 0, 0 ), FALSE ); TQApplication::sendPostedEvents( MainWindow::self->qWorkspace(), TQEvent::ChildInserted ); fw->parentWidget()->setFixedSize( 1, 1 ); fw->show(); } } void Project::formOpened( FormWindow *fw ) { if ( fw->isFake() ) return; emit newFormOpened( fw ); } TQString Project::locationOfObject( TQObject *o ) { if ( !o ) return TQString(); if ( MainWindow::self ) { TQWidgetList windows = MainWindow::self->qWorkspace()->windowList(); for ( TQWidget *w = windows.first(); w; w = windows.next() ) { FormWindow *fw = ::tqqt_cast(w); SourceEditor *se = ::tqqt_cast(w); if ( fw ) { if ( fw->isFake() ) return objectForFakeForm( fw )->name() + TQString( " [Source]" ); else return fw->name() + TQString( " [Source]" ); } else if ( se ) { if ( !se->object() ) continue; if ( se->formWindow() ) return se->formWindow()->name() + TQString( " [Source]" ); else return makeRelative( se->sourceFile()->fileName() ); } } } if ( ::tqqt_cast(o) ) { for ( TQPtrListIterator sources = sourceFiles(); sources.current(); ++sources ) { SourceFile* f = sources.current(); if ( f == o ) return makeRelative( f->fileName() ); } } extern TQMap *qwf_forms; if ( !qwf_forms ) { tqWarning( "Project::locationOfObject: qwf_forms is NULL!" ); return TQString(); } TQString s = makeRelative( *qwf_forms->find( (TQWidget*)o ) ); s += " [Source]"; return s; } bool Project::hasGUI() const { return tqApp->type() != TQApplication::Tty; }