2008-12-02 12:01:29 +01:00
/***************************************************************************
* *
* * This file is part of Qt Creator
* *
* * Copyright ( c ) 2008 Nokia Corporation and / or its subsidiary ( - ies ) .
* *
* * Contact : Qt Software Information ( qt - info @ nokia . com )
* *
2008-12-02 14:17:16 +01:00
* *
* * Non - Open Source Usage
* *
2008-12-02 12:01:29 +01:00
* * Licensees may use this file in accordance with the Qt Beta Version
* * License Agreement , Agreement version 2.2 provided with the Software or ,
* * alternatively , in accordance with the terms contained in a written
2008-12-02 14:17:16 +01:00
* * agreement between you and Nokia .
* *
* * GNU General Public License Usage
* *
2008-12-02 12:01:29 +01:00
* * Alternatively , this file may be used under the terms of the GNU General
* * Public License versions 2.0 or 3.0 as published by the Free Software
* * Foundation and appearing in the file LICENSE . GPL included in the packaging
* * of this file . Please review the following information to ensure GNU
* * General Public Licensing requirements will be met :
* *
* * http : //www.fsf.org/licensing/licenses/info/GPLv2.html and
* * http : //www.gnu.org/copyleft/gpl.html.
* *
* * In addition , as a special exception , Nokia gives you certain additional
2008-12-02 14:17:16 +01:00
* * rights . These rights are described in the Nokia Qt GPL Exception
2008-12-16 17:20:00 +01:00
* * version 1.3 , included in the file GPL_EXCEPTION . txt in this package .
2008-12-02 14:17:16 +01:00
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-12-02 16:19:05 +01:00
2008-12-02 12:01:29 +01:00
# include "qt4runconfiguration.h"
2008-12-02 16:19:05 +01:00
2008-12-09 15:25:01 +01:00
# include "makestep.h"
2008-12-02 12:01:29 +01:00
# include "profilereader.h"
# include "qt4nodes.h"
2008-12-09 15:25:01 +01:00
# include "qt4project.h"
2008-12-02 12:01:29 +01:00
# include <coreplugin/icore.h>
# include <coreplugin/messagemanager.h>
# include <coreplugin/variablemanager.h>
# include <projectexplorer/buildstep.h>
2008-12-09 15:25:01 +01:00
# include <utils/qtcassert.h>
2008-12-02 12:01:29 +01:00
# include <QtGui/QFormLayout>
# include <QtGui/QInputDialog>
using namespace Qt4ProjectManager : : Internal ;
using namespace Qt4ProjectManager ;
using ProjectExplorer : : ApplicationRunConfiguration ;
using ProjectExplorer : : PersistentSettingsReader ;
using ProjectExplorer : : PersistentSettingsWriter ;
Qt4RunConfiguration : : Qt4RunConfiguration ( Qt4Project * pro , QString proFilePath )
: ApplicationRunConfiguration ( pro ) , m_proFilePath ( proFilePath ) , m_userSetName ( false )
{
setName ( tr ( " Qt4RunConfiguration " ) ) ;
if ( ! m_proFilePath . isEmpty ( ) ) {
updateCachedValues ( ) ;
setName ( QFileInfo ( m_proFilePath ) . baseName ( ) ) ;
}
}
Qt4RunConfiguration : : ~ Qt4RunConfiguration ( )
{
}
QString Qt4RunConfiguration : : type ( ) const
{
return " Qt4ProjectManager.Qt4RunConfiguration " ;
}
QWidget * Qt4RunConfiguration : : configurationWidget ( )
{
QWidget * configWidget = new QWidget ;
QFormLayout * toplayout = new QFormLayout ( configWidget ) ;
toplayout - > setMargin ( 0 ) ;
QLabel * nameLabel = new QLabel ( tr ( " Name: " ) ) ;
QLineEdit * nameLineEdit = new QLineEdit ( name ( ) ) ;
nameLabel - > setBuddy ( nameLineEdit ) ;
toplayout - > addRow ( nameLabel , nameLineEdit ) ;
QLabel * executableLabel = new QLabel ( tr ( " Executable: " ) ) ;
QLabel * executableLabel2 = new QLabel ( executable ( ) ) ;
toplayout - > addRow ( executableLabel , executableLabel2 ) ;
QLabel * workingDirectoryLabel = new QLabel ( tr ( " Working Directory: " ) ) ;
QLabel * workingDirectoryLabel2 = new QLabel ( workingDirectory ( ) ) ;
toplayout - > addRow ( workingDirectoryLabel , workingDirectoryLabel2 ) ;
QLabel * argumentsLabel = new QLabel ( tr ( " &Arguments: " ) ) ;
QLineEdit * argumentsLineEdit = new QLineEdit ( ProjectExplorer : : Environment : : joinArgumentList ( commandLineArguments ( ) ) ) ;
argumentsLabel - > setBuddy ( argumentsLineEdit ) ;
toplayout - > addRow ( argumentsLabel , argumentsLineEdit ) ;
connect ( argumentsLineEdit , SIGNAL ( textEdited ( const QString & ) ) ,
this , SLOT ( setCommandLineArguments ( const QString & ) ) ) ;
connect ( nameLineEdit , SIGNAL ( textEdited ( const QString & ) ) ,
this , SLOT ( nameEdited ( const QString & ) ) ) ;
return configWidget ;
}
void Qt4RunConfiguration : : save ( PersistentSettingsWriter & writer ) const
{
writer . saveValue ( " CommandLineArguments " , m_commandLineArguments ) ;
writer . saveValue ( " ProFile " , m_proFilePath ) ;
writer . saveValue ( " UserSetName " , m_userSetName ) ;
ApplicationRunConfiguration : : save ( writer ) ;
}
void Qt4RunConfiguration : : restore ( const PersistentSettingsReader & reader )
{
ApplicationRunConfiguration : : restore ( reader ) ;
m_commandLineArguments = reader . restoreValue ( " CommandLineArguments " ) . toStringList ( ) ;
m_proFilePath = reader . restoreValue ( " ProFile " ) . toString ( ) ;
m_userSetName = reader . restoreValue ( " UserSetName " ) . toBool ( ) ;
if ( ! m_proFilePath . isEmpty ( ) ) {
updateCachedValues ( ) ;
if ( ! m_userSetName )
setName ( QFileInfo ( m_proFilePath ) . baseName ( ) ) ;
}
}
QString Qt4RunConfiguration : : executable ( ) const
{
return resolveVariables ( project ( ) - > activeBuildConfiguration ( ) , m_executable ) ;
}
ApplicationRunConfiguration : : RunMode Qt4RunConfiguration : : runMode ( ) const
{
return m_runMode ;
}
QString Qt4RunConfiguration : : workingDirectory ( ) const
{
return resolveVariables ( project ( ) - > activeBuildConfiguration ( ) , m_workingDir ) ;
}
QStringList Qt4RunConfiguration : : commandLineArguments ( ) const
{
return m_commandLineArguments ;
}
ProjectExplorer : : Environment Qt4RunConfiguration : : environment ( ) const
{
Qt4Project * pro = qobject_cast < Qt4Project * > ( project ( ) ) ;
2008-12-09 15:25:01 +01:00
QTC_ASSERT ( pro , return ProjectExplorer : : Environment ( ) ) ;
2008-12-02 12:01:29 +01:00
return pro - > environment ( pro - > activeBuildConfiguration ( ) ) ;
}
void Qt4RunConfiguration : : setCommandLineArguments ( const QString & argumentsString )
{
m_commandLineArguments = ProjectExplorer : : Environment : : parseCombinedArgString ( argumentsString ) ;
}
void Qt4RunConfiguration : : nameEdited ( const QString & name )
{
if ( name = = " " ) {
setName ( tr ( " Qt4RunConfiguration " ) ) ;
m_userSetName = false ;
} else {
setName ( name ) ;
m_userSetName = true ;
}
}
QString Qt4RunConfiguration : : proFilePath ( ) const
{
return m_proFilePath ;
}
// and needs to be reloaded.
// Check wheter it is
void Qt4RunConfiguration : : updateCachedValues ( )
{
ProFileReader * reader = static_cast < Qt4Project * > ( project ( ) ) - > createProFileReader ( ) ;
if ( ! reader - > readProFile ( m_proFilePath ) ) {
delete reader ;
Core : : ICore * core = ExtensionSystem : : PluginManager : : instance ( ) - > getObject < Core : : ICore > ( ) ;
core - > messageManager ( ) - > printToOutputPane ( QString ( " Could not parse %1. The Qt4 run configuration %2 can not be started. " ) . arg ( m_proFilePath ) . arg ( name ( ) ) ) ;
return ;
}
QString destDir ;
if ( reader - > contains ( " DESTDIR " ) ) {
// TODO Can return different destdirs for different scopes!
destDir = reader - > value ( " DESTDIR " ) ;
if ( QDir : : isRelativePath ( destDir ) ) {
destDir = " ${BASEDIR} " + QLatin1Char ( ' / ' ) + destDir ;
}
} else {
destDir = " ${BASEDIR} " ;
# if defined(Q_OS_WIN)
if ( ! reader - > contains ( " DESTDIR " ) )
destDir + = QLatin1Char ( ' / ' ) + " ${QMAKE_BUILDCONFIG} " ;
# endif
}
# if defined (Q_OS_MAC)
if ( ! reader - > values ( " -CONFIG " ) . contains ( " app_bundle " ) ) {
destDir + = QLatin1Char ( ' / ' )
+ " ${QMAKE_TARGET} "
+ QLatin1String ( " .app/Contents/MacOS " ) ;
}
# endif
m_workingDir = destDir ;
m_executable = destDir + QLatin1Char ( ' / ' ) + " ${QMAKE_TARGET} " ;
# if defined (Q_OS_WIN)
m_executable + = QLatin1String ( " .exe " ) ;
# endif
m_targets = reader - > values ( QLatin1String ( " TARGET " ) ) ;
m_srcDir = QFileInfo ( m_proFilePath ) . path ( ) ;
const QStringList config = reader - > values ( QLatin1String ( " CONFIG " ) ) ;
m_runMode = ProjectExplorer : : ApplicationRunConfiguration : : Gui ;
delete reader ;
}
QString Qt4RunConfiguration : : resolveVariables ( const QString & buildConfiguration , const QString & in ) const
{
detectQtShadowBuild ( buildConfiguration ) ;
QString relSubDir = QFileInfo ( project ( ) - > file ( ) - > fileName ( ) ) . absoluteDir ( ) . relativeFilePath ( m_srcDir ) ;
QString baseDir = QDir ( project ( ) - > buildDirectory ( buildConfiguration ) ) . absoluteFilePath ( relSubDir ) ;
Core : : VariableManager * vm = ExtensionSystem : : PluginManager : : instance ( ) - > getObject < Core : : ICore > ( ) - > variableManager ( ) ;
if ( ! vm )
return QString ( ) ;
QString dest ;
bool found = false ;
vm - > insert ( " QMAKE_BUILDCONFIG " , qmakeBuildConfigFromBuildConfiguration ( buildConfiguration ) ) ;
vm - > insert ( " BASEDIR " , baseDir ) ;
/*
TODO This is a hack to detect correct target ( there might be different targets in
different scopes )
*/
// This code also works for workingDirectory,
// since directories are executable.
foreach ( const QString & target , m_targets ) {
dest = in ;
vm - > insert ( " QMAKE_TARGET " , target ) ;
dest = QDir : : cleanPath ( vm - > resolve ( dest ) ) ;
vm - > remove ( " QMAKE_TARGET " ) ;
QFileInfo fi ( dest ) ;
if ( fi . exists ( ) & & ( fi . isExecutable ( ) | | dest . endsWith ( " .js " ) ) ) {
found = true ;
break ;
}
}
vm - > remove ( " BASEDIR " ) ;
vm - > remove ( " QMAKE_BUILDCONFIG " ) ;
if ( found )
return dest ;
else
return QString ( ) ;
}
/* This function tries to find out wheter qmake/make will put the binary in "/debug/" or in "/release/"
That is this function is strictly only for windows .
We look wheter make gets an explicit parameter " debug " or " release "
That works because if we have either debug or release there then it is surely a
debug_and_release buildconfiguration and thus we are put in a subdirectory .
Now if there is no explicit debug or release parameter , then we need to look at what qmake ' s CONFIG
value is , if it is not debug_and_release , we don ' t care and return " "
otherwise we look at wheter the default is debug or not
Note : When fixing this function consider those cases
qmake CONFIG + = debug_and_release CONFIG + = debug
make release
= > we should return release
qmake CONFIG + = debug_and_release CONFIG + = debug
make
= > we should return debug
qmake CONFIG - = debug_and_release CONFIG + = debug
make
= > we should return " " , since the executable is not put in a subdirectory
Not a function to be proud of
*/
QString Qt4RunConfiguration : : qmakeBuildConfigFromBuildConfiguration ( const QString & buildConfigurationName ) const
{
MakeStep * ms = qobject_cast < Qt4Project * > ( project ( ) ) - > makeStep ( ) ;
QStringList makeargs = ms - > value ( buildConfigurationName , " makeargs " ) . toStringList ( ) ;
if ( makeargs . contains ( " debug " ) )
return " debug " ;
2008-12-09 11:07:24 +01:00
else if ( makeargs . contains ( " release " ) )
2008-12-02 12:01:29 +01:00
return " release " ;
// Oh we don't have an explicit make argument
QMakeStep * qs = qobject_cast < Qt4Project * > ( project ( ) ) - > qmakeStep ( ) ;
QVariant qmakeBuildConfiguration = qs - > value ( buildConfigurationName , " buildConfiguration " ) ;
if ( qmakeBuildConfiguration . isValid ( ) ) {
QtVersion : : QmakeBuildConfig projectBuildConfiguration = QtVersion : : QmakeBuildConfig ( qmakeBuildConfiguration . toInt ( ) ) ;
if ( projectBuildConfiguration & QtVersion : : BuildAll ) {
if ( projectBuildConfiguration & QtVersion : : DebugBuild )
return " debug " ;
else
return " release " ;
} else {
return " " ;
}
} else {
// Old sytle always CONFIG+=debug_and_release
if ( qobject_cast < Qt4Project * > ( project ( ) ) - > qtVersion ( buildConfigurationName ) - > defaultBuildConfig ( ) & QtVersion : : DebugBuild )
return " debug " ;
else
return " release " ;
}
// enable us to infer the right string
return " " ;
}
/*!
Handle special case were a subproject of the qt directory is opened , and
qt was configured to be built as a shadow build - > also build in the sub -
project in the correct shadow build directory .
*/
void Qt4RunConfiguration : : detectQtShadowBuild ( const QString & buildConfiguration ) const
{
if ( project ( ) - > activeBuildConfiguration ( ) = = buildConfiguration )
return ;
const QString currentQtDir = static_cast < Qt4Project * > ( project ( ) ) - > qtDir ( buildConfiguration ) ;
const QString qtSourceDir = static_cast < Qt4Project * > ( project ( ) ) - > qtVersion ( buildConfiguration ) - > sourcePath ( ) ;
// if the project is a sub-project of Qt and Qt was shadow-built then automatically
// adjust the build directory of the sub-project.
if ( project ( ) - > file ( ) - > fileName ( ) . startsWith ( qtSourceDir ) & & qtSourceDir ! = currentQtDir ) {
project ( ) - > setValue ( buildConfiguration , " useShadowBuild " , true ) ;
QString buildDir = QFileInfo ( project ( ) - > file ( ) - > fileName ( ) ) . absolutePath ( ) ;
buildDir . replace ( qtSourceDir , currentQtDir ) ;
project ( ) - > setValue ( buildConfiguration , " buildDirectory " , buildDir ) ;
project ( ) - > setValue ( buildConfiguration , " autoShadowBuild " , true ) ;
}
}
///
/// Qt4RunConfigurationFactory
/// This class is used to restore run settings (saved in .user files)
///
Qt4RunConfigurationFactory : : Qt4RunConfigurationFactory ( )
{
}
Qt4RunConfigurationFactory : : ~ Qt4RunConfigurationFactory ( )
{
}
// used to recreate the runConfigurations when restoring settings
bool Qt4RunConfigurationFactory : : canCreate ( const QString & type ) const
{
return type = = " Qt4ProjectManager.Qt4RunConfiguration " ;
}
2008-12-09 15:25:01 +01:00
QSharedPointer < ProjectExplorer : : RunConfiguration > Qt4RunConfigurationFactory : : create
( ProjectExplorer : : Project * project , const QString & type )
2008-12-02 12:01:29 +01:00
{
Qt4Project * p = qobject_cast < Qt4Project * > ( project ) ;
2008-12-09 15:25:01 +01:00
QTC_ASSERT ( p , /**/ ) ;
QTC_ASSERT ( type = = " Qt4ProjectManager.Qt4RunConfiguration " , /**/ ) ;
2008-12-02 12:01:29 +01:00
// The right path is set in restoreSettings
QSharedPointer < ProjectExplorer : : RunConfiguration > rc ( new Qt4RunConfiguration ( p , QString : : null ) ) ;
return rc ;
}
QStringList Qt4RunConfigurationFactory : : canCreate ( ProjectExplorer : : Project * pro ) const
{
Qt4Project * qt4project = qobject_cast < Qt4Project * > ( pro ) ;
if ( qt4project )
return QStringList ( ) ;
else
return QStringList ( ) ;
}
QString Qt4RunConfigurationFactory : : nameForType ( const QString & type ) const
{
Q_UNUSED ( type ) ;
return " Run Qt4 application " ;
}
///
/// Qt4RunConfigurationFactoryUser
/// This class is used to create new RunConfiguration from the runsettings page
///
Qt4RunConfigurationFactoryUser : : Qt4RunConfigurationFactoryUser ( )
{
}
Qt4RunConfigurationFactoryUser : : ~ Qt4RunConfigurationFactoryUser ( )
{
}
bool Qt4RunConfigurationFactoryUser : : canCreate ( const QString & type ) const
{
Q_UNUSED ( type ) ;
return false ;
}
QSharedPointer < ProjectExplorer : : RunConfiguration > Qt4RunConfigurationFactoryUser : : create ( ProjectExplorer : : Project * project , const QString & type )
{
Qt4Project * p = qobject_cast < Qt4Project * > ( project ) ;
2008-12-09 15:25:01 +01:00
QTC_ASSERT ( p , /**/ ) ;
2008-12-02 12:01:29 +01:00
QString fileName = type . mid ( QString ( " Qt4RunConfiguration. " ) . size ( ) ) ;
return QSharedPointer < ProjectExplorer : : RunConfiguration > ( new Qt4RunConfiguration ( p , fileName ) ) ;
}
QStringList Qt4RunConfigurationFactoryUser : : canCreate ( ProjectExplorer : : Project * pro ) const
{
Qt4Project * qt4project = qobject_cast < Qt4Project * > ( pro ) ;
if ( qt4project ) {
QStringList applicationProFiles ;
QList < Qt4ProFileNode * > list = qt4project - > applicationProFiles ( ) ;
2008-12-09 11:07:24 +01:00
foreach ( Qt4ProFileNode * node , list ) {
2008-12-02 12:01:29 +01:00
applicationProFiles . append ( " Qt4RunConfiguration. " + node - > path ( ) ) ;
}
return applicationProFiles ;
} else {
return QStringList ( ) ;
}
}
QString Qt4RunConfigurationFactoryUser : : nameForType ( const QString & type ) const
{
QString fileName = type . mid ( QString ( " Qt4RunConfiguration. " ) . size ( ) ) ;
return QFileInfo ( fileName ) . baseName ( ) ;
}