summaryrefslogtreecommitdiffstats
path: root/kdevdesigner/designer/project.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kdevdesigner/designer/project.cpp')
-rw-r--r--kdevdesigner/designer/project.cpp1558
1 files changed, 1558 insertions, 0 deletions
diff --git a/kdevdesigner/designer/project.cpp b/kdevdesigner/designer/project.cpp
new file mode 100644
index 00000000..0ab26894
--- /dev/null
+++ b/kdevdesigner/designer/project.cpp
@@ -0,0 +1,1558 @@
+/**********************************************************************
+** 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 <tqwidgetfactory.h>
+#include "outputwindow.h"
+
+#include <tqfile.h>
+#include <tqtextstream.h>
+#include <tqurl.h>
+#include <tqobjectlist.h>
+#include <tqfeatures.h>
+#include <tqtextcodec.h>
+#include <tqdom.h>
+#include <tqmessagebox.h>
+#include <tqapplication.h>
+#include "mainwindow.h"
+#include <tqworkspace.h>
+
+#ifndef TQT_NO_SQL
+#include <tqsqldatabase.h>
+#include <tqsqlrecord.h>
+#include <tqdatatable.h>
+#endif
+
+#include <stdlib.h>
+#ifdef Q_OS_UNIX
+# include <unistd.h>
+#endif
+
+#include <tdelocale.h>
+
+#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<ProjectSettingsInterface> *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<TQString, TQStringList> 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<TQString, TQStringList>::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<FormFile> fit = formfiles; fit.current(); ++fit ) {
+ contents += fit.current()->fileName() +
+ (fit != formfiles.last() ? " \\\n\t" : "");
+ }
+ contents += "\n";
+ }
+
+ // images
+ if ( !pixCollection->isEmpty() ) {
+ contents += "IMAGES\t= ";
+ TQValueList<PixmapCollection::Pixmap> pixmaps = pixCollection->pixmaps();
+ for ( TQValueList<PixmapCollection::Pixmap>::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<DatabaseConnection> Project::databaseConnections() const
+{
+ return dbConnections;
+}
+#endif
+
+#ifndef TQT_NO_SQL
+void Project::setDatabaseConnections( const TQPtrList<DatabaseConnection> &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 ) << "<property name=\"" << name << "\">" << endl;
+ ++indent;
+ ts << makeIndent( indent ) << "<string>" << value << "</string>" << endl;
+ --indent;
+ ts << makeIndent( indent ) << "</property>" << 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 << "<!DOCTYPE DB><DB version=\"1.0\">" << endl;
+
+ /* db connections */
+ int indent = 0;
+ for ( DatabaseConnection *conn = dbConnections.first(); conn; conn = 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", TQString::number( conn->port() ), indent );
+
+ /* connection tables */
+ TQStringList tables = conn->tables();
+ for ( TQStringList::Iterator it = tables.begin();
+ it != tables.end(); ++it ) {
+ ts << makeIndent( indent ) << "<table>" << 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 ) << "<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;
+ }
+
+ ts << "</DB>" << 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<FormFile> 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<ProjectSettingsInterface> 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<SourceFile> 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<FormFile> 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<TQString, TQString> &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<TQString, TQString> &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<TQString, TQString>::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<FormFile> 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<FormFile> 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<LanguageInterface::Function> 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<LanguageInterface::Function>::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<FormWindow*>(w);
+ SourceEditor *se = ::tqqt_cast<SourceEditor*>(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<SourceFile*>(o) ) {
+ for ( TQPtrListIterator<SourceFile> sources = sourceFiles();
+ sources.current(); ++sources ) {
+ SourceFile* f = sources.current();
+ if ( f == o )
+ return makeRelative( f->fileName() );
+ }
+ }
+
+ extern TQMap<TQWidget*, TQString> *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;
+}