project.cpp
来自「qt-x11-free-3.0.3.tar.gz minigui图形界面工具」· C++ 代码 · 共 1,160 行 · 第 1/2 页
CPP
1,160 行
/************************************************************************ Copyright (C) 2000 Trolltech AS. All rights reserved.**** This file is part of Qt Designer.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "project.h"#include "formwindow.h"#include "config.h"#include "designerappiface.h"#include "../interfaces/languageinterface.h"#include "pixmapcollection.h"#ifndef QT_NO_SQL#include "dbconnectionimpl.h"#endif#include <qfile.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 "mainwindow.h"#ifndef QT_NO_SQL#include <qsqldatabase.h>#include <qsqlrecord.h>#include <qdatatable.h>#endif#ifndef QT_NO_SQLDatabaseConnection::~DatabaseConnection(){ delete iface;}bool DatabaseConnection::refreshCatalog(){#ifndef QT_NO_SQL if ( loaded ) return TRUE; if ( !open() ) return FALSE; tbls = conn->tables(); flds.clear(); for ( QStringList::Iterator it = tbls.begin(); it != tbls.end(); ++it ) { QSqlRecord fil = conn->record( *it ); QStringList 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 QT_NO_SQLvoid DatabaseConnection::remove(){ if ( nm == "(default)" ) QSqlDatabase::removeDatabase( QSqlDatabase::defaultConnection ); else QSqlDatabase::removeDatabase( nm ); // the above will effectively delete the current connection conn = 0;}#endifbool DatabaseConnection::open( bool suppressDialog ){#ifndef QT_NO_SQL // register our name, if nec if ( nm == "(default)" ) { if ( !QSqlDatabase::contains() ) // default doesn't exists? conn = QSqlDatabase::addDatabase( drv ); else conn = QSqlDatabase::database(); } else { if ( !QSqlDatabase::contains( nm ) ) conn = QSqlDatabase::addDatabase( drv, nm ); else conn = QSqlDatabase::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 QDialog::Accepted: done = FALSE; break; case QDialog::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( QMessageBox::warning( MainWindow::self, QApplication::tr( "Connection" ), QApplication::tr( "Could not connect to the database.\n" "Press 'OK' to continue or 'Cancel' to " "specify different\nconnection information.\n" ) + QString( "[" + conn->lastError().driverText() + "\n" + conn->lastError().databaseText() + "]\n" ), QApplication::tr( "&OK" ), QApplication::tr( "&Cancel" ), 0, 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 QT_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 QString &fn, const QString &pName, QPluginManager<ProjectSettingsInterface> *pm, bool isDummy ) : proName( pName ), projectSettingsPluginManager( pm ), isDummyProject( isDummy ){ modified = TRUE; pixCollection = new PixmapCollection( this ); iface = 0; lang = "C++"; cfg.insert( "(all)", "qt warn_on release" ); templ = "app"; setFileName( fn ); if ( !pName.isEmpty() ) proName = pName; sourcefiles.setAutoDelete( TRUE ); modified = FALSE;}Project::~Project(){ delete iface; delete pixCollection;}void Project::setModified( bool b ){ modified = b; emit projectModified();}#ifndef QT_NO_SQLDatabaseConnection *Project::databaseConnection( const QString &name ){ for ( DatabaseConnection *conn = dbConnections.first(); conn; conn = dbConnections.next() ) { if ( conn->name() == name ) return conn; } return 0;}#endifvoid Project::setFileName( const QString &fn, bool doClear ){ if ( fn == filename ) return; filename = fn; if ( !filename.endsWith( ".pro" ) ) filename += ".pro"; proName = filename; if ( proName.contains( '.' ) ) proName = proName.left( proName.find( '.' ) ); if ( !doClear ) return; clear(); if ( QFile::exists( fn ) ) parse();}QString Project::fileName() const{ return filename;}QString Project::databaseDescription() const{ return dbFile;}QString Project::projectName() const{ return proName;}static QString parse_part( const QString &part ){ QString res; bool inName = FALSE; QString currName; for ( int i = 0; i < (int)part.length(); ++i ) { QChar 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;}QStringList parse_multiline_part( const QString &contents, const QString &key, int *start = 0 ){ if ( start ) *start = -1; QString lastWord; int braceCount = 0; for ( int i = 0; i < (int)contents.length(); ++i ) { QChar c( contents[ i ] ); switch ( c ) { case '{': braceCount++; lastWord = ""; break; case '}': braceCount--; lastWord = ""; break; case ' ': case '\t': 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() + 1; QStringList lst; bool inName = FALSE; QString currName; bool hadEqual = 0; for ( ; i < (int)contents.length(); ++i ) { c = contents[ i ]; if ( !hadEqual && c != '=' ) continue; hadEqual = TRUE; if ( ( c.isLetter() || c.isDigit() || c == '.' || c == '/' || c == '_' || c == '\\' || c == '$' || c == '-' || c == '(' || c == ')' || c == ':' || c == '+' || c == ',' ) && c != ' ' && c != '\t' && c != '\n' && c != '=' ) { if ( !inName ) currName = QString::null; 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 QStringList();}void Project::parse(){ QFile f( filename ); if ( !f.exists() || !f.open( IO_ReadOnly ) ) return; QTextStream ts( &f ); QString contents = ts.read(); f.close(); proName = QFileInfo( filename ).baseName(); QStringList::ConstIterator it; int i = contents.find( "LANGUAGE" ); if ( i != -1 ) { lang = ""; QString part = contents.mid( i + QString( "LANGUAGE" ).length() ); lang = parse_part( part ); } i = contents.find( "DBFILE" ); if ( i != -1 ) { dbFile = ""; QString part = contents.mid( i + QString( "DBFILE" ).length() ); dbFile = parse_part( part ); } QStringList uifiles = parse_multiline_part( contents, "FORMS" ); uifiles += parse_multiline_part( contents, "INTERFACES" ); // compatibility for ( it = uifiles.begin(); it != uifiles.end(); ++it ) (void) new FormFile( *it, FALSE, this ); i = contents.find( "TEMPLATE" ); if ( i != -1 ) { templ = ""; QString part = contents.mid( i + QString( "TEMPLATE" ).length() ); templ = parse_part( part ); } readPlatformSettings( contents, "CONFIG", cfg ); readPlatformSettings( contents, "LIBS", lbs ); readPlatformSettings( contents, "INCLUDEPATH", inclPath ); readPlatformSettings( contents, "DEFINES", defs ); LanguageInterface *iface = MetaDataBase::languageInterface( lang ); if ( iface ) { QStringList sourceKeys; iface->sourceProjectKeys( sourceKeys ); for ( QStringList::Iterator it = sourceKeys.begin(); it != sourceKeys.end(); ++it ) { QStringList lst = parse_multiline_part( contents, *it ); for ( QStringList::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 ) { QString val = ""; QString part = contents.mid( i + QString( *it ).length() ); val = parse_part( part ); customSettings.replace( *it, val ); } } loadConnections(); QStringList images = parse_multiline_part( contents, "IMAGES" ); // ### remove that for the final - this is beta-compatibility if ( images.isEmpty() && QDir( QFileInfo( filename ).dirPath( TRUE ) + "/images" ).exists() ) { images = QDir( QFileInfo( filename ).dirPath( TRUE ) + "/images" ).entryList(); for ( int i = 0; i < (int)images.count(); ++i ) images[ i ].prepend( "images/" ); modified = TRUE; } for ( QStringList::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 QString &db ){ dbFile = db;}void Project::setDescription( const QString &s ){ desc = s;}QString Project::description() const{ return desc;}bool Project::isValid() const{ // #### do more checking here? if ( filename.isEmpty() || proName.isEmpty() ) return FALSE; return TRUE;}QString Project::makeAbsolute( const QString &f ){ if ( isDummy() ) return f; QUrl u( QFileInfo( filename ).dirPath( TRUE ), f ); return u.path();}QString Project::makeRelative( const QString &f ){ if ( isDummy() ) return f; QString p = QFileInfo( filename ).dirPath( TRUE ); QString f2 = f; if ( f2.left( p.length() ) == p ) f2.remove( 0, p.length() + 1 ); return f2;}static void remove_contents( QString &contents, const QString &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( QString &contents, const QString &s, int *strt = 0 ){ int i; parse_multiline_part( contents, s, &i ); 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 ){ if ( !onlyProjectFile ) { for ( SourceFile *sf = sourcefiles.first(); sf; sf = sourcefiles.next() ) { if ( !sf->save() ) return; } for ( FormFile *ff = formfiles.first(); ff; ff = formfiles.next() ) { if ( !ff->save() ) return; } } if ( isDummy() || filename.isEmpty() ) return; if ( !modified ) return; QFile f( filename ); QString contents; if ( f.open( IO_ReadOnly ) ) { QTextStream ts( &f ); contents = ts.read(); f.close(); } else { // initial contents contents = "unix {\n" " UI_DIR = .ui\n" " MOC_DIR = .moc\n" " OBJECTS_DIR = .obj\n" "}\n"; } remove_multiline_contents( contents, "FORMS" ); remove_multiline_contents( contents, "INTERFACES" ); // compatibility if ( !formfiles.isEmpty() ) { contents += "FORMS\t= "; for ( QPtrListIterator<FormFile> fit = formfiles; fit.current(); ++fit ) contents += fit.current()->fileName() + " "; contents += "\n"; } remove_multiline_contents( contents, "IMAGES" ); if ( !pixCollection->isEmpty() ) { contents += "IMAGES\t= "; QValueList<PixmapCollection::Pixmap> pixmaps = pixCollection->pixmaps(); for ( QValueList<PixmapCollection::Pixmap>::Iterator it = pixmaps.begin(); it != pixmaps.end(); ++it ) contents += makeRelative( (*it).absname ) + " "; contents += "\n"; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?