2010-03-12 11:20:32 +01:00
/**************************************************************************
* *
* * This file is part of Qt Creator
* *
2012-01-26 18:33:46 +01:00
* * Copyright ( c ) 2012 Nokia Corporation and / or its subsidiary ( - ies ) .
2010-03-12 11:20:32 +01:00
* *
2011-11-02 15:59:12 +01:00
* * Contact : Nokia Corporation ( qt - info @ nokia . com )
2010-03-12 11:20:32 +01:00
* *
* *
* * GNU Lesser General Public License Usage
* *
2011-04-13 08:42:33 +02:00
* * This file may be used under the terms of the GNU Lesser General Public
* * License version 2.1 as published by the Free Software Foundation and
* * appearing in the file LICENSE . LGPL included in the packaging of this file .
* * Please review the following information to ensure the GNU Lesser General
* * Public License version 2.1 requirements will be met :
* * http : //www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
2010-03-12 11:20:32 +01:00
* *
2010-12-17 16:01:08 +01:00
* * In addition , as a special exception , Nokia gives you certain additional
2011-04-13 08:42:33 +02:00
* * rights . These rights are described in the Nokia Qt LGPL Exception
2010-12-17 16:01:08 +01:00
* * version 1.1 , included in the file LGPL_EXCEPTION . txt in this package .
* *
2011-04-13 08:42:33 +02:00
* * Other Usage
* *
* * Alternatively , this file may be used in accordance with the terms and
* * conditions contained in a signed written agreement between you and Nokia .
* *
2010-12-17 16:01:08 +01:00
* * If you have questions regarding the use of this file , please contact
2011-11-02 15:59:12 +01:00
* * Nokia at qt - info @ nokia . com .
2010-03-12 11:20:32 +01:00
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "customwizard.h"
# include "customwizardparameters.h"
# include "customwizardpage.h"
# include "projectexplorer.h"
# include "baseprojectwizarddialog.h"
2010-09-01 13:27:24 +02:00
# include "customwizardscriptgenerator.h"
2010-03-12 11:20:32 +01:00
# include <coreplugin/icore.h>
2010-03-19 11:26:56 +01:00
# include <coreplugin/messagemanager.h>
# include <extensionsystem/pluginmanager.h>
2011-03-30 15:15:15 +02:00
# include <utils/fileutils.h>
2010-03-12 11:20:32 +01:00
# include <utils/qtcassert.h>
# include <QtCore/QDebug>
# include <QtCore/QFile>
# include <QtCore/QMap>
# include <QtCore/QDir>
2010-08-31 14:34:09 +02:00
# include <QtCore/QTextStream>
2010-03-12 11:20:32 +01:00
# include <QtCore/QFileInfo>
2010-03-31 14:48:08 +02:00
# include <QtCore/QCoreApplication>
2010-03-12 11:20:32 +01:00
static const char templatePathC [ ] = " templates/wizards " ;
static const char configFileC [ ] = " wizard.xml " ;
namespace ProjectExplorer {
2011-04-14 12:58:14 +02:00
/*!
\ class ProjectExplorer : : ICustomWizardFactory
\ brief Factory for creating custom wizards extending the base class
( CustomWizard or CustomProjectWizard )
The factory can be registered under a name in CustomWizard . The name can
be specified in the \ c < wizard class = ' ' . . . > attribute in the \ c wizard . xml file
and thus allows for specifying a C + + derived wizard class .
For example , this is currently used in Qt4ProjectManager to get Qt - specific
aspects into the custom wizard .
\ sa ProjectExplorer : : CustomWizard , ProjectExplorer : : CustomProjectWizard
*/
2010-03-12 11:20:32 +01:00
struct CustomWizardPrivate {
2010-03-22 15:33:33 +01:00
CustomWizardPrivate ( ) : m_context ( new Internal : : CustomWizardContext ) { }
2010-03-12 11:20:32 +01:00
QSharedPointer < Internal : : CustomWizardParameters > m_parameters ;
2010-03-22 15:33:33 +01:00
QSharedPointer < Internal : : CustomWizardContext > m_context ;
2010-03-17 15:17:03 +01:00
static int verbose ;
2010-03-12 11:20:32 +01:00
} ;
2010-03-17 15:17:03 +01:00
int CustomWizardPrivate : : verbose = 0 ;
2011-04-14 12:58:14 +02:00
/*!
\ class ProjectExplorer : : CustomWizard
\ brief Base classes for custom wizards based on file templates and a XML
configuration file ( \ c share / qtcreator / templates / wizards ) .
Presents CustomWizardDialog ( fields page containing path control ) for wizards
of type " class " or " file " . Serves as base class for project wizards .
*/
2010-03-12 11:20:32 +01:00
CustomWizard : : CustomWizard ( const Core : : BaseFileWizardParameters & baseFileParameters ,
QObject * parent ) :
Core : : BaseFileWizard ( baseFileParameters , parent ) ,
d ( new CustomWizardPrivate )
{
}
CustomWizard : : ~ CustomWizard ( )
{
delete d ;
}
2010-03-17 15:17:03 +01:00
void CustomWizard : : setVerbose ( int v )
{
CustomWizardPrivate : : verbose = v ;
}
int CustomWizard : : verbose ( )
{
return CustomWizardPrivate : : verbose ;
}
2010-03-12 11:20:32 +01:00
void CustomWizard : : setParameters ( const CustomWizardParametersPtr & p )
{
d - > m_parameters = p ;
}
// Add a wizard page with an id, visibly warn if something goes wrong.
2010-03-31 14:48:08 +02:00
static inline void addWizardPage ( Utils : : Wizard * w , QWizardPage * p , int id )
2010-03-12 11:20:32 +01:00
{
2010-03-31 14:48:08 +02:00
int addedPageId = 0 ;
2010-03-12 11:20:32 +01:00
if ( id = = - 1 ) {
2010-03-31 14:48:08 +02:00
addedPageId = w - > addPage ( p ) ;
2010-03-12 11:20:32 +01:00
} else {
if ( w - > pageIds ( ) . contains ( id ) ) {
qWarning ( " Page %d already present in custom wizard dialog, defaulting to add. " , id ) ;
2010-03-31 14:48:08 +02:00
addedPageId = w - > addPage ( p ) ;
2010-03-12 11:20:32 +01:00
} else {
w - > setPage ( id , p ) ;
2010-03-31 14:48:08 +02:00
addedPageId = id ;
2010-03-12 11:20:32 +01:00
}
}
2010-03-31 14:48:08 +02:00
w - > wizardProgress ( ) - > item ( addedPageId ) - > setTitle ( QCoreApplication : : translate ( " ProjectExplorer::CustomWizard " , " Details " , " Default short title for custom wizard page to be shown in the progress pane of the wizard. " ) ) ;
2010-03-12 11:20:32 +01:00
}
// Initialize a wizard with a custom file page.
2010-03-31 14:48:08 +02:00
void CustomWizard : : initWizardDialog ( Utils : : Wizard * wizard , const QString & defaultPath ,
2010-03-12 11:20:32 +01:00
const WizardPageList & extensionPages ) const
{
QTC_ASSERT ( ! parameters ( ) . isNull ( ) , return ) ;
2010-03-22 15:33:33 +01:00
d - > m_context - > reset ( ) ;
2010-09-27 13:52:34 +02:00
Internal : : CustomWizardPage * customPage = new Internal : : CustomWizardPage ( d - > m_context , parameters ( ) ) ;
2010-03-12 11:20:32 +01:00
customPage - > setPath ( defaultPath ) ;
addWizardPage ( wizard , customPage , parameters ( ) - > firstPageId ) ;
if ( ! parameters ( ) - > fieldPageTitle . isEmpty ( ) )
customPage - > setTitle ( parameters ( ) - > fieldPageTitle ) ;
foreach ( QWizardPage * ep , extensionPages )
2010-03-31 14:48:08 +02:00
BaseFileWizard : : applyExtensionPageShortTitle ( wizard , wizard - > addPage ( ep ) ) ;
2010-03-12 11:20:32 +01:00
Core : : BaseFileWizard : : setupWizard ( wizard ) ;
2010-03-17 15:17:03 +01:00
if ( CustomWizardPrivate : : verbose )
2010-03-12 11:20:32 +01:00
qDebug ( ) < < " initWizardDialog " < < wizard < < wizard - > pageIds ( ) ;
}
QWizard * CustomWizard : : createWizardDialog ( QWidget * parent ,
2012-02-03 18:00:08 +01:00
const Core : : WizardDialogParameters & wizardDialogParameters ) const
2010-03-12 11:20:32 +01:00
{
QTC_ASSERT ( ! d - > m_parameters . isNull ( ) , return 0 ) ;
2010-03-31 14:48:08 +02:00
Utils : : Wizard * wizard = new Utils : : Wizard ( parent ) ;
2012-02-03 18:00:08 +01:00
initWizardDialog ( wizard , wizardDialogParameters . defaultPath ( ) , wizardDialogParameters . extensionPages ( ) ) ;
2010-03-12 11:20:32 +01:00
return wizard ;
}
// Read out files and store contents with field contents replaced.
static inline bool createFile ( Internal : : CustomWizardFile cwFile ,
const QString & sourceDirectory ,
const QString & targetDirectory ,
const CustomProjectWizard : : FieldReplacementMap & fm ,
Core : : GeneratedFiles * files ,
QString * errorMessage )
{
const QChar slash = QLatin1Char ( ' / ' ) ;
const QString sourcePath = sourceDirectory + slash + cwFile . source ;
2010-03-22 15:33:33 +01:00
// Field replacement on target path
Internal : : CustomWizardContext : : replaceFields ( fm , & cwFile . target ) ;
2010-09-30 16:50:59 +02:00
const QString targetPath = targetDirectory + slash + cwFile . target ;
2010-03-17 15:17:03 +01:00
if ( CustomWizardPrivate : : verbose )
2010-03-12 11:20:32 +01:00
qDebug ( ) < < " generating " < < targetPath < < sourcePath < < fm ;
2010-09-14 17:03:08 +02:00
// Read contents of source file
const QFile : : OpenMode openMode
= cwFile . binary ? QIODevice : : ReadOnly : ( QIODevice : : ReadOnly | QIODevice : : Text ) ;
2011-03-30 15:15:15 +02:00
Utils : : FileReader reader ;
if ( ! reader . fetch ( sourcePath , openMode , errorMessage ) )
2010-03-12 11:20:32 +01:00
return false ;
2010-07-09 08:31:46 +02:00
2010-03-12 11:20:32 +01:00
Core : : GeneratedFile generatedFile ;
generatedFile . setPath ( targetPath ) ;
2010-09-14 17:03:08 +02:00
if ( cwFile . binary ) {
// Binary file: Set data.
generatedFile . setBinary ( true ) ;
2011-03-30 15:15:15 +02:00
generatedFile . setBinaryContents ( reader . data ( ) ) ;
2010-09-14 17:03:08 +02:00
} else {
// Template file: Preprocess.
2011-03-30 15:15:15 +02:00
const QString contentsIn = QString : : fromLocal8Bit ( reader . data ( ) ) ;
2010-09-14 17:03:08 +02:00
generatedFile . setContents ( Internal : : CustomWizardContext : : processFile ( fm , contentsIn ) ) ;
}
2010-04-16 15:55:32 +02:00
Core : : GeneratedFile : : Attributes attributes = 0 ;
if ( cwFile . openEditor )
attributes | = Core : : GeneratedFile : : OpenEditorAttribute ;
if ( cwFile . openProject )
attributes | = Core : : GeneratedFile : : OpenProjectAttribute ;
generatedFile . setAttributes ( attributes ) ;
2010-03-12 11:20:32 +01:00
files - > push_back ( generatedFile ) ;
return true ;
}
// Helper to find a specific wizard page of a wizard by type.
template < class WizardPage >
WizardPage * findWizardPage ( const QWizard * w )
{
foreach ( int pageId , w - > pageIds ( ) )
if ( WizardPage * wp = qobject_cast < WizardPage * > ( w - > page ( pageId ) ) )
return wp ;
return 0 ;
}
2010-09-07 11:28:00 +02:00
// Determine where to run the generator script. The user may specify
// an expression subject to field replacement, default is the target path.
static inline QString scriptWorkingDirectory ( const QSharedPointer < Internal : : CustomWizardContext > & ctx ,
const QSharedPointer < Internal : : CustomWizardParameters > & p )
{
if ( p - > filesGeneratorScriptWorkingDirectory . isEmpty ( ) )
return ctx - > targetPath ;
QString path = p - > filesGeneratorScriptWorkingDirectory ;
Internal : : CustomWizardContext : : replaceFields ( ctx - > replacements , & path ) ;
return path ;
}
2010-03-12 11:20:32 +01:00
Core : : GeneratedFiles CustomWizard : : generateFiles ( const QWizard * dialog , QString * errorMessage ) const
{
// Look for the Custom field page to find the path
const Internal : : CustomWizardPage * cwp = findWizardPage < Internal : : CustomWizardPage > ( dialog ) ;
QTC_ASSERT ( cwp , return Core : : GeneratedFiles ( ) )
2010-09-01 13:27:24 +02:00
CustomWizardContextPtr ctx = context ( ) ;
2010-09-06 16:33:44 +02:00
ctx - > path = ctx - > targetPath = cwp - > path ( ) ;
2010-09-01 13:27:24 +02:00
ctx - > replacements = replacementMap ( dialog ) ;
2010-03-22 15:33:33 +01:00
if ( CustomWizardPrivate : : verbose ) {
QString logText ;
QTextStream str ( & logText ) ;
2010-09-01 13:27:24 +02:00
str < < " CustomWizard::generateFiles: " < < ctx - > targetPath < < ' \n ' ;
const FieldReplacementMap : : const_iterator cend = context ( ) - > replacements . constEnd ( ) ;
for ( FieldReplacementMap : : const_iterator it = context ( ) - > replacements . constBegin ( ) ; it ! = cend ; + + it )
2010-03-22 15:33:33 +01:00
str < < " ' " < < it . key ( ) < < " ' -> ' " < < it . value ( ) < < " ' \n " ;
qWarning ( " %s " , qPrintable ( logText ) ) ;
}
2010-09-01 13:27:24 +02:00
return generateWizardFiles ( errorMessage ) ;
2010-03-12 11:20:32 +01:00
}
2012-01-18 13:50:14 +01:00
Core : : FeatureSet CustomWizard : : requiredFeatures ( ) const
{
return baseFileWizardParameters ( ) . requiredFeatures ( ) ;
}
2010-09-01 13:27:24 +02:00
bool CustomWizard : : writeFiles ( const Core : : GeneratedFiles & files , QString * errorMessage )
{
if ( ! Core : : BaseFileWizard : : writeFiles ( files , errorMessage ) )
return false ;
if ( d - > m_parameters - > filesGeneratorScript . isEmpty ( ) )
return true ;
// Prepare run of the custom script to generate. In the case of a
// project wizard that is entirely created by a script,
// the target project directory might not exist.
2011-04-15 11:27:15 +02:00
// Known issue: By nature, the script does not honor
// Core::GeneratedFile::KeepExistingFileAttribute.
2010-09-01 13:27:24 +02:00
const CustomWizardContextPtr ctx = context ( ) ;
2010-09-07 11:28:00 +02:00
const QString scriptWorkingDir = scriptWorkingDirectory ( ctx , d - > m_parameters ) ;
const QDir scriptWorkingDirDir ( scriptWorkingDir ) ;
if ( ! scriptWorkingDirDir . exists ( ) ) {
2010-09-01 13:27:24 +02:00
if ( CustomWizardPrivate : : verbose )
2010-09-07 11:28:00 +02:00
qDebug ( " Creating directory %s " , qPrintable ( scriptWorkingDir ) ) ;
if ( ! scriptWorkingDirDir . mkpath ( scriptWorkingDir ) ) {
* errorMessage = QString : : fromLatin1 ( " Unable to create the target directory '%1' " ) . arg ( scriptWorkingDir ) ;
2010-09-01 13:27:24 +02:00
return false ;
}
}
// Run the custom script to actually generate the files.
2010-09-07 11:28:00 +02:00
if ( ! Internal : : runCustomWizardGeneratorScript ( scriptWorkingDir ,
2010-09-03 14:27:13 +02:00
d - > m_parameters - > filesGeneratorScript ,
d - > m_parameters - > filesGeneratorScriptArguments ,
2010-09-01 13:27:24 +02:00
ctx - > replacements , errorMessage ) )
return false ;
// Paranoia: Check on the files generated by the script:
foreach ( const Core : : GeneratedFile & generatedFile , files )
if ( generatedFile . attributes ( ) & Core : : GeneratedFile : : CustomGeneratorAttribute )
if ( ! QFileInfo ( generatedFile . path ( ) ) . isFile ( ) ) {
* errorMessage = QString : : fromLatin1 ( " %1 failed to generate %2 " ) .
2010-09-03 14:27:13 +02:00
arg ( d - > m_parameters - > filesGeneratorScript . back ( ) , generatedFile . path ( ) ) ;
2010-09-01 13:27:24 +02:00
return false ;
}
return true ;
}
Core : : GeneratedFiles CustomWizard : : generateWizardFiles ( QString * errorMessage ) const
2010-03-12 11:20:32 +01:00
{
Core : : GeneratedFiles rc ;
2010-09-01 13:27:24 +02:00
const CustomWizardContextPtr ctx = context ( ) ;
QTC_ASSERT ( ! ctx - > targetPath . isEmpty ( ) , return rc )
if ( CustomWizardPrivate : : verbose )
qDebug ( ) < < " CustomWizard::generateWizardFiles: in "
< < ctx - > targetPath < < " , using: " < < ctx - > replacements ;
// If generator script is non-empty, do a dry run to get it's files.
if ( ! d - > m_parameters - > filesGeneratorScript . isEmpty ( ) ) {
2010-09-07 11:28:00 +02:00
rc + = Internal : : dryRunCustomWizardGeneratorScript ( scriptWorkingDirectory ( ctx , d - > m_parameters ) ,
2010-09-03 14:27:13 +02:00
d - > m_parameters - > filesGeneratorScript ,
d - > m_parameters - > filesGeneratorScriptArguments ,
2010-09-07 11:28:00 +02:00
ctx - > replacements ,
errorMessage ) ;
2010-09-01 13:27:24 +02:00
if ( rc . isEmpty ( ) )
return rc ;
}
// Add the template files specified by the <file> elements.
2010-03-12 11:20:32 +01:00
foreach ( const Internal : : CustomWizardFile & file , d - > m_parameters - > files )
2010-09-01 13:27:24 +02:00
if ( ! createFile ( file , d - > m_parameters - > directory , ctx - > targetPath , context ( ) - > replacements , & rc , errorMessage ) )
2010-03-12 11:20:32 +01:00
return Core : : GeneratedFiles ( ) ;
return rc ;
}
2010-03-22 15:33:33 +01:00
// Create a replacement map of static base fields + wizard dialog fields
CustomWizard : : FieldReplacementMap CustomWizard : : replacementMap ( const QWizard * w ) const
2010-03-12 11:20:32 +01:00
{
2010-09-27 13:52:34 +02:00
return Internal : : CustomWizardFieldPage : : replacementMap ( w , context ( ) , d - > m_parameters - > fields ) ;
2010-03-12 11:20:32 +01:00
}
CustomWizard : : CustomWizardParametersPtr CustomWizard : : parameters ( ) const
{
return d - > m_parameters ;
}
2010-03-22 15:33:33 +01:00
CustomWizard : : CustomWizardContextPtr CustomWizard : : context ( ) const
{
return d - > m_context ;
}
2010-03-12 11:20:32 +01:00
// Static factory map
typedef QMap < QString , QSharedPointer < ICustomWizardFactory > > CustomWizardFactoryMap ;
Q_GLOBAL_STATIC ( CustomWizardFactoryMap , customWizardFactoryMap )
void CustomWizard : : registerFactory ( const QString & name , const ICustomWizardFactoryPtr & f )
{
customWizardFactoryMap ( ) - > insert ( name , f ) ;
}
CustomWizard * CustomWizard : : createWizard ( const CustomWizardParametersPtr & p , const Core : : BaseFileWizardParameters & b )
{
CustomWizard * rc = 0 ;
if ( p - > klass . isEmpty ( ) ) {
// Use defaults for empty class names
switch ( b . kind ( ) ) {
case Core : : IWizard : : ProjectWizard :
rc = new CustomProjectWizard ( b ) ;
break ;
case Core : : IWizard : : FileWizard :
case Core : : IWizard : : ClassWizard :
rc = new CustomWizard ( b ) ;
break ;
}
} else {
// Look up class name in map
const CustomWizardFactoryMap : : const_iterator it = customWizardFactoryMap ( ) - > constFind ( p - > klass ) ;
if ( it ! = customWizardFactoryMap ( ) - > constEnd ( ) )
rc = it . value ( ) - > create ( b ) ;
}
if ( ! rc ) {
qWarning ( " Unable to create custom wizard for class %s. " , qPrintable ( p - > klass ) ) ;
return 0 ;
}
rc - > setParameters ( p ) ;
return rc ;
}
2010-03-19 11:26:56 +01:00
// Format all wizards for display
static QString listWizards ( )
{
typedef QMultiMap < QString , const Core : : IWizard * > CategoryWizardMap ;
// Sort by category via multimap
QString rc ;
QTextStream str ( & rc ) ;
CategoryWizardMap categoryWizardMap ;
2011-05-10 15:19:38 +02:00
foreach ( const Core : : IWizard * w , Core : : IWizard : : allWizards ( ) )
2010-03-19 11:26:56 +01:00
categoryWizardMap . insert ( w - > category ( ) , w ) ;
str < < " ### Registered wizards ( " < < categoryWizardMap . size ( ) < < " ) \n " ;
// Format
QString lastCategory ;
const CategoryWizardMap : : const_iterator cend = categoryWizardMap . constEnd ( ) ;
for ( CategoryWizardMap : : const_iterator it = categoryWizardMap . constBegin ( ) ; it ! = cend ; + + it ) {
const Core : : IWizard * wizard = it . value ( ) ;
if ( it . key ( ) ! = lastCategory ) {
lastCategory = it . key ( ) ;
str < < " \n Category: ' " < < lastCategory < < " ' / ' " < < wizard - > displayCategory ( ) < < " ' \n " ;
}
str < < " Id: ' " < < wizard - > id ( ) < < " ' / ' " < < wizard - > displayName ( ) < < " ' Kind: "
< < wizard - > kind ( ) < < " \n Class: " < < wizard - > metaObject ( ) - > className ( )
< < " Description: ' " < < wizard - > description ( ) < < " ' \n " ;
}
return rc ;
}
2011-04-14 12:58:14 +02:00
/*!
\ brief Reads \ c share / qtcreator / templates / wizards and creates all custom wizards .
As other plugins might register factories for derived
classes , call it in extensionsInitialized ( ) .
Scans the subdirectories of the template directory for directories
containing valid configuration files and parse them into wizards .
*/
2010-03-12 11:20:32 +01:00
QList < CustomWizard * > CustomWizard : : createWizards ( )
{
QList < CustomWizard * > rc ;
QString errorMessage ;
2010-03-19 11:26:56 +01:00
QString verboseLog ;
2012-01-24 15:36:40 +01:00
const QString templateDirName = Core : : ICore : : resourcePath ( ) +
2010-03-12 11:20:32 +01:00
QLatin1Char ( ' / ' ) + QLatin1String ( templatePathC ) ;
2010-03-19 11:26:56 +01:00
2010-08-25 19:11:44 +02:00
2012-01-24 15:36:40 +01:00
const QString userTemplateDirName = Core : : ICore : : userResourcePath ( ) +
2010-08-25 19:11:44 +02:00
QLatin1Char ( ' / ' ) + QLatin1String ( templatePathC ) ;
2010-03-12 11:20:32 +01:00
const QDir templateDir ( templateDirName ) ;
2010-03-19 11:26:56 +01:00
if ( CustomWizardPrivate : : verbose )
verboseLog = QString : : fromLatin1 ( " ### CustomWizard: Checking '%1' \n " ) . arg ( templateDirName ) ;
2010-03-12 11:20:32 +01:00
if ( ! templateDir . exists ( ) ) {
2010-03-17 15:17:03 +01:00
if ( CustomWizardPrivate : : verbose )
2010-03-12 11:20:32 +01:00
qWarning ( " Custom project template path %s does not exist. " , qPrintable ( templateDir . absolutePath ( ) ) ) ;
return rc ;
}
2010-08-25 19:11:44 +02:00
const QDir userTemplateDir ( userTemplateDirName ) ;
if ( CustomWizardPrivate : : verbose )
verboseLog = QString : : fromLatin1 ( " ### CustomWizard: Checking '%1' \n " ) . arg ( userTemplateDirName ) ;
2010-08-27 09:50:34 +02:00
const QDir : : Filters filters = QDir : : Dirs | QDir : : Readable | QDir : : NoDotAndDotDot ;
const QDir : : SortFlags sortflags = QDir : : Name | QDir : : IgnoreCase ;
QList < QFileInfo > dirs = templateDir . entryInfoList ( filters , sortflags ) ;
2010-08-25 19:11:44 +02:00
if ( userTemplateDir . exists ( ) ) {
if ( CustomWizardPrivate : : verbose )
verboseLog = QString : : fromLatin1 ( " ### CustomWizard: userTemplateDir '%1' found, adding \n " ) . arg ( userTemplateDirName ) ;
2010-08-27 09:50:34 +02:00
dirs + = userTemplateDir . entryInfoList ( filters , sortflags ) ;
2010-08-25 19:11:44 +02:00
}
2010-03-12 11:20:32 +01:00
const QString configFile = QLatin1String ( configFileC ) ;
// Check and parse config file in each directory.
foreach ( const QFileInfo & dirFi , dirs ) {
const QDir dir ( dirFi . absoluteFilePath ( ) ) ;
2010-03-17 15:17:03 +01:00
if ( CustomWizardPrivate : : verbose )
2010-03-19 11:26:56 +01:00
verboseLog + = QString : : fromLatin1 ( " CustomWizard: Scanning %1 \n " ) . arg ( dirFi . absoluteFilePath ( ) ) ;
2010-03-12 11:20:32 +01:00
if ( dir . exists ( configFile ) ) {
CustomWizardParametersPtr parameters ( new Internal : : CustomWizardParameters ) ;
Core : : BaseFileWizardParameters baseFileParameters ;
2010-08-13 11:10:11 +02:00
switch ( parameters - > parse ( dir . absoluteFilePath ( configFile ) , & baseFileParameters , & errorMessage ) ) {
case Internal : : CustomWizardParameters : : ParseOk :
2010-03-12 11:20:32 +01:00
parameters - > directory = dir . absolutePath ( ) ;
2010-03-17 15:17:03 +01:00
if ( CustomWizardPrivate : : verbose )
2010-08-31 14:34:09 +02:00
QTextStream ( & verboseLog )
< < " \n ### Adding: " < < baseFileParameters . id ( ) < < " / " < < baseFileParameters . displayName ( ) < < ' \n '
< < baseFileParameters . category ( ) < < " / " < < baseFileParameters . displayCategory ( ) < < ' \n '
< < " ( " < < baseFileParameters . description ( ) < < " ) \n "
< < parameters - > toString ( ) ;
if ( CustomWizard * w = createWizard ( parameters , baseFileParameters ) ) {
2010-03-12 11:20:32 +01:00
rc . push_back ( w ) ;
2010-08-31 14:34:09 +02:00
} else {
qWarning ( " Custom wizard factory function failed for %s " , qPrintable ( baseFileParameters . id ( ) ) ) ;
}
break ;
2010-08-13 11:10:11 +02:00
case Internal : : CustomWizardParameters : : ParseDisabled :
if ( CustomWizardPrivate : : verbose )
qWarning ( " Ignoring disabled wizard %s... " , qPrintable ( dir . absolutePath ( ) ) ) ;
break ;
case Internal : : CustomWizardParameters : : ParseFailed :
2010-03-12 11:20:32 +01:00
qWarning ( " Failed to initialize custom project wizard in %s: %s " ,
qPrintable ( dir . absolutePath ( ) ) , qPrintable ( errorMessage ) ) ;
2010-08-31 14:34:09 +02:00
break ;
2010-03-12 11:20:32 +01:00
}
2010-03-17 15:17:03 +01:00
} else {
if ( CustomWizardPrivate : : verbose )
2010-03-19 11:26:56 +01:00
if ( CustomWizardPrivate : : verbose )
2012-01-09 16:30:33 +01:00
verboseLog + = QString : : fromLatin1 ( " CustomWizard: '%1' not found \n " ) . arg ( configFile ) ;
2010-03-12 11:20:32 +01:00
}
}
2010-03-19 11:26:56 +01:00
if ( CustomWizardPrivate : : verbose ) { // Print to output pane for Windows.
verboseLog + = listWizards ( ) ;
qWarning ( " %s " , qPrintable ( verboseLog ) ) ;
2012-01-24 15:36:40 +01:00
Core : : ICore : : messageManager ( ) - > printToOutputPanePopup ( verboseLog ) ;
2010-03-19 11:26:56 +01:00
}
2010-03-12 11:20:32 +01:00
return rc ;
}
2011-04-14 12:58:14 +02:00
/*!
\ class ProjectExplorer : : CustomProjectWizard
\ brief A custom project wizard .
Presents a CustomProjectWizardDialog ( Project intro page and fields page )
for wizards of type " project " .
Overwrites postGenerateFiles ( ) to open the project files according to the
file attributes . Also inserts \ c ' % ProjectName % ' into the base
replacement map once the intro page is left to have it available
for QLineEdit - type fields ' default text .
*/
2010-03-12 11:20:32 +01:00
CustomProjectWizard : : CustomProjectWizard ( const Core : : BaseFileWizardParameters & baseFileParameters ,
QObject * parent ) :
CustomWizard ( baseFileParameters , parent )
{
}
2011-04-14 12:58:14 +02:00
/*!
\ brief Can be reimplemented to create custom project wizards .
initProjectWizardDialog ( ) needs to be called .
*/
2012-02-03 18:00:08 +01:00
QWizard * CustomProjectWizard : : createWizardDialog ( QWidget * parent ,
const Core : : WizardDialogParameters & wizardDialogParameters ) const
2010-03-12 11:20:32 +01:00
{
QTC_ASSERT ( ! parameters ( ) . isNull ( ) , return 0 ) ;
2012-02-03 18:00:08 +01:00
BaseProjectWizardDialog * projectDialog = new BaseProjectWizardDialog ( parent , wizardDialogParameters ) ;
initProjectWizardDialog ( projectDialog ,
wizardDialogParameters . defaultPath ( ) ,
wizardDialogParameters . extensionPages ( ) ) ;
2010-03-12 11:20:32 +01:00
return projectDialog ;
}
void CustomProjectWizard : : initProjectWizardDialog ( BaseProjectWizardDialog * w ,
const QString & defaultPath ,
const WizardPageList & extensionPages ) const
{
2010-03-22 15:33:33 +01:00
const CustomWizardParametersPtr pa = parameters ( ) ;
QTC_ASSERT ( ! pa . isNull ( ) , return ) ;
const CustomWizardContextPtr ctx = context ( ) ;
ctx - > reset ( ) ;
2010-03-31 14:48:08 +02:00
if ( ! displayName ( ) . isEmpty ( ) )
w - > setWindowTitle ( displayName ( ) ) ;
2010-03-22 15:33:33 +01:00
if ( ! pa - > fields . isEmpty ( ) ) {
2010-09-27 13:52:34 +02:00
Internal : : CustomWizardFieldPage * cp = new Internal : : CustomWizardFieldPage ( ctx , pa ) ;
2010-03-12 11:20:32 +01:00
addWizardPage ( w , cp , parameters ( ) - > firstPageId ) ;
2010-03-22 15:33:33 +01:00
if ( ! pa - > fieldPageTitle . isEmpty ( ) )
cp - > setTitle ( pa - > fieldPageTitle ) ;
2010-03-12 11:20:32 +01:00
}
foreach ( QWizardPage * ep , extensionPages )
2010-03-31 14:48:08 +02:00
BaseFileWizard : : applyExtensionPageShortTitle ( w , w - > addPage ( ep ) ) ;
2010-03-12 11:20:32 +01:00
w - > setPath ( defaultPath ) ;
w - > setProjectName ( BaseProjectWizardDialog : : uniqueProjectName ( defaultPath ) ) ;
2010-03-22 15:33:33 +01:00
2010-10-27 12:51:33 +02:00
connect ( w , SIGNAL ( projectParametersChanged ( QString , QString ) ) , this , SLOT ( projectParametersChanged ( QString , QString ) ) ) ;
2010-03-22 15:33:33 +01:00
2010-03-17 15:17:03 +01:00
if ( CustomWizardPrivate : : verbose )
2010-03-12 11:20:32 +01:00
qDebug ( ) < < " initProjectWizardDialog " < < w < < w - > pageIds ( ) ;
}
Core : : GeneratedFiles CustomProjectWizard : : generateFiles ( const QWizard * w , QString * errorMessage ) const
{
const BaseProjectWizardDialog * dialog = qobject_cast < const BaseProjectWizardDialog * > ( w ) ;
QTC_ASSERT ( dialog , return Core : : GeneratedFiles ( ) )
2010-09-01 13:27:24 +02:00
// Add project name as macro. Path is here under project directory
CustomWizardContextPtr ctx = context ( ) ;
2010-09-06 16:33:44 +02:00
ctx - > path = dialog - > path ( ) ;
ctx - > targetPath = ctx - > path + QLatin1Char ( ' / ' ) + dialog - > projectName ( ) ;
2010-03-22 15:33:33 +01:00
FieldReplacementMap fieldReplacementMap = replacementMap ( dialog ) ;
2010-03-12 11:20:32 +01:00
fieldReplacementMap . insert ( QLatin1String ( " ProjectName " ) , dialog - > projectName ( ) ) ;
2010-09-01 13:27:24 +02:00
ctx - > replacements = fieldReplacementMap ;
2010-03-17 15:17:03 +01:00
if ( CustomWizardPrivate : : verbose )
2010-09-01 13:27:24 +02:00
qDebug ( ) < < " CustomProjectWizard::generateFiles " < < dialog < < ctx - > targetPath < < ctx - > replacements ;
const Core : : GeneratedFiles generatedFiles = generateWizardFiles ( errorMessage ) ;
return generatedFiles ;
2010-03-12 11:20:32 +01:00
}
2011-04-14 12:58:14 +02:00
/*!
\ brief Utility to open the projects and editors for the files that have
the respective attributes set .
*/
2010-04-16 15:55:32 +02:00
bool CustomProjectWizard : : postGenerateOpen ( const Core : : GeneratedFiles & l , QString * errorMessage )
{
// Post-Generate: Open the project and the editors as desired
foreach ( const Core : : GeneratedFile & file , l ) {
if ( file . attributes ( ) & Core : : GeneratedFile : : OpenProjectAttribute ) {
2011-09-05 13:47:29 +02:00
if ( ! ProjectExplorer : : ProjectExplorerPlugin : : instance ( ) - > openProject ( file . path ( ) , errorMessage ) ) {
2010-04-16 15:55:32 +02:00
return false ;
}
}
}
return BaseFileWizard : : postGenerateOpenEditors ( l , errorMessage ) ;
}
2010-03-12 11:20:32 +01:00
bool CustomProjectWizard : : postGenerateFiles ( const QWizard * , const Core : : GeneratedFiles & l , QString * errorMessage )
{
2010-03-17 15:17:03 +01:00
if ( CustomWizardPrivate : : verbose )
2010-04-16 15:55:32 +02:00
qDebug ( ) < < " CustomProjectWizard::postGenerateFiles() " ;
return CustomProjectWizard : : postGenerateOpen ( l , errorMessage ) ;
2010-03-12 11:20:32 +01:00
}
2010-10-27 12:51:33 +02:00
void CustomProjectWizard : : projectParametersChanged ( const QString & project , const QString & path )
2010-03-22 15:33:33 +01:00
{
// Make '%ProjectName%' available in base replacements.
context ( ) - > baseReplacements . insert ( QLatin1String ( " ProjectName " ) , project ) ;
2010-04-20 12:56:21 +02:00
2012-01-09 16:30:33 +01:00
emit projectLocationChanged ( path + QLatin1Char ( ' / ' ) + project ) ;
2010-03-22 15:33:33 +01:00
}
2010-03-12 11:20:32 +01:00
} // namespace ProjectExplorer