2012-10-02 09:12:39 +02:00
|
|
|
/****************************************************************************
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2016-01-15 14:58:39 +01:00
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
|
|
|
** Contact: https://www.qt.io/licensing/
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** This file is part of Qt Creator.
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** Commercial License Usage
|
|
|
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
|
|
|
** accordance with the commercial license agreement provided with the
|
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
2016-01-15 14:58:39 +01:00
|
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
|
|
|
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
|
|
|
** information use the contact form at https://www.qt.io/contact-us.
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2016-01-15 14:58:39 +01:00
|
|
|
** GNU General Public License Usage
|
|
|
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
|
|
|
** General Public License version 3 as published by the Free Software
|
|
|
|
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
|
|
|
** included in the packaging of this file. Please review the following
|
|
|
|
|
** information to ensure the GNU General Public License requirements will
|
|
|
|
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
2010-12-17 16:01:08 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
****************************************************************************/
|
2008-12-02 14:09:21 +01:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
#include "projectintropage.h"
|
|
|
|
|
#include "ui_projectintropage.h"
|
|
|
|
|
|
2015-04-28 14:49:56 +02:00
|
|
|
#include "filenamevalidatinglineedit.h"
|
2014-05-30 11:38:08 +02:00
|
|
|
#include "wizard.h"
|
|
|
|
|
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QDir>
|
2011-03-02 17:13:33 +01:00
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\class Utils::ProjectIntroPage
|
|
|
|
|
|
2013-06-05 14:29:24 +02:00
|
|
|
\brief The ProjectIntroPage class is the standard wizard page for a project,
|
|
|
|
|
letting the user choose its name
|
2011-03-02 17:13:33 +01:00
|
|
|
and path.
|
|
|
|
|
|
|
|
|
|
Looks similar to FileWizardPage, but provides additional
|
|
|
|
|
functionality:
|
|
|
|
|
\list
|
2013-09-06 13:23:11 +02:00
|
|
|
\li Contains a description label at the top for displaying introductory text.
|
|
|
|
|
\li Does on the fly validation (connected to changed()) and displays
|
|
|
|
|
warnings and errors in a status label at the bottom (the page is complete
|
2011-03-02 17:13:33 +01:00
|
|
|
when fully validated, validatePage() is thus not implemented).
|
|
|
|
|
\endlist
|
|
|
|
|
|
2013-09-06 13:23:11 +02:00
|
|
|
\note Careful when changing projectintropage.ui. It must have main
|
2011-03-02 17:13:33 +01:00
|
|
|
geometry cleared and QLayout::SetMinimumSize constraint on the main
|
|
|
|
|
layout, otherwise, QWizard will squeeze it due to its strange expanding
|
|
|
|
|
hacks.
|
|
|
|
|
*/
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
namespace Utils {
|
|
|
|
|
|
2015-10-22 15:32:42 +02:00
|
|
|
class ProjectIntroPagePrivate
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2015-10-22 15:32:42 +02:00
|
|
|
public:
|
2008-12-02 12:01:29 +01:00
|
|
|
ProjectIntroPagePrivate();
|
|
|
|
|
Ui::ProjectIntroPage m_ui;
|
2018-09-21 01:15:38 +03:00
|
|
|
bool m_complete = false;
|
2015-10-22 15:32:42 +02:00
|
|
|
QRegularExpressionValidator m_projectNameValidator;
|
2008-12-02 12:01:29 +01:00
|
|
|
// Status label style sheets
|
|
|
|
|
const QString m_errorStyleSheet;
|
|
|
|
|
const QString m_warningStyleSheet;
|
|
|
|
|
const QString m_hintStyleSheet;
|
2018-09-21 01:15:38 +03:00
|
|
|
bool m_forceSubProject = false;
|
2012-04-13 16:37:48 +02:00
|
|
|
QStringList m_projectDirectories;
|
2008-12-02 12:01:29 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ProjectIntroPagePrivate:: ProjectIntroPagePrivate() :
|
|
|
|
|
m_errorStyleSheet(QLatin1String("background : red;")),
|
2018-09-21 01:15:38 +03:00
|
|
|
m_warningStyleSheet(QLatin1String("background : yellow;"))
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ProjectIntroPage::ProjectIntroPage(QWidget *parent) :
|
2014-08-25 17:21:49 +02:00
|
|
|
WizardPage(parent),
|
2011-09-07 14:26:11 +02:00
|
|
|
d(new ProjectIntroPagePrivate)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2011-09-07 14:26:11 +02:00
|
|
|
d->m_ui.setupUi(this);
|
2008-12-02 12:01:29 +01:00
|
|
|
hideStatusLabel();
|
2017-10-21 21:04:51 +02:00
|
|
|
d->m_ui.nameLineEdit->setPlaceholderText(tr("Enter project name"));
|
2011-09-07 14:26:11 +02:00
|
|
|
d->m_ui.nameLineEdit->setFocus();
|
2015-04-28 14:49:56 +02:00
|
|
|
d->m_ui.nameLineEdit->setValidationFunction([this](FancyLineEdit *edit, QString *errorString) {
|
2015-10-22 15:32:42 +02:00
|
|
|
return validateProjectName(edit->text(), errorString);
|
2015-04-28 14:49:56 +02:00
|
|
|
});
|
2012-04-13 16:37:48 +02:00
|
|
|
d->m_ui.projectLabel->setVisible(d->m_forceSubProject);
|
|
|
|
|
d->m_ui.projectComboBox->setVisible(d->m_forceSubProject);
|
|
|
|
|
d->m_ui.pathChooser->setDisabled(d->m_forceSubProject);
|
|
|
|
|
d->m_ui.projectsDirectoryCheckBox->setDisabled(d->m_forceSubProject);
|
2015-08-20 15:37:56 +02:00
|
|
|
connect(d->m_ui.pathChooser, &PathChooser::pathChanged, this, &ProjectIntroPage::slotChanged);
|
2015-03-05 22:00:05 +02:00
|
|
|
connect(d->m_ui.nameLineEdit, &QLineEdit::textChanged,
|
|
|
|
|
this, &ProjectIntroPage::slotChanged);
|
|
|
|
|
connect(d->m_ui.pathChooser, &PathChooser::validChanged,
|
|
|
|
|
this, &ProjectIntroPage::slotChanged);
|
|
|
|
|
connect(d->m_ui.pathChooser, &PathChooser::returnPressed,
|
|
|
|
|
this, &ProjectIntroPage::slotActivated);
|
|
|
|
|
connect(d->m_ui.nameLineEdit, &FancyLineEdit::validReturnPressed,
|
|
|
|
|
this, &ProjectIntroPage::slotActivated);
|
|
|
|
|
connect(d->m_ui.projectComboBox,
|
2019-02-26 09:40:49 +01:00
|
|
|
QOverload<int>::of(&QComboBox::currentIndexChanged),
|
2015-03-05 22:00:05 +02:00
|
|
|
this, &ProjectIntroPage::slotChanged);
|
2014-05-30 11:38:08 +02:00
|
|
|
|
|
|
|
|
setProperty(SHORT_TITLE_PROPERTY, tr("Location"));
|
2014-08-25 17:21:49 +02:00
|
|
|
registerFieldWithName(QLatin1String("Path"), d->m_ui.pathChooser, "path", SIGNAL(pathChanged(QString)));
|
|
|
|
|
registerFieldWithName(QLatin1String("ProjectName"), d->m_ui.nameLineEdit);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ProjectIntroPage::insertControl(int row, QWidget *label, QWidget *control)
|
|
|
|
|
{
|
2011-09-07 14:26:11 +02:00
|
|
|
d->m_ui.formLayout->insertRow(row, label, control);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ProjectIntroPage::~ProjectIntroPage()
|
|
|
|
|
{
|
2011-09-07 14:26:11 +02:00
|
|
|
delete d;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2010-01-07 18:17:24 +01:00
|
|
|
QString ProjectIntroPage::projectName() const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2011-09-07 14:26:11 +02:00
|
|
|
return d->m_ui.nameLineEdit->text();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString ProjectIntroPage::path() const
|
|
|
|
|
{
|
2011-09-07 14:26:11 +02:00
|
|
|
return d->m_ui.pathChooser->path();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ProjectIntroPage::setPath(const QString &path)
|
|
|
|
|
{
|
2011-09-07 14:26:11 +02:00
|
|
|
d->m_ui.pathChooser->setPath(path);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2015-10-22 15:32:42 +02:00
|
|
|
void ProjectIntroPage::setProjectNameRegularExpression(const QRegularExpression ®Ex)
|
|
|
|
|
{
|
|
|
|
|
Q_ASSERT_X(regEx.isValid(), Q_FUNC_INFO, qPrintable(regEx.errorString()));
|
|
|
|
|
d->m_projectNameValidator.setRegularExpression(regEx);
|
|
|
|
|
}
|
|
|
|
|
|
2010-01-07 18:17:24 +01:00
|
|
|
void ProjectIntroPage::setProjectName(const QString &name)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2011-09-07 14:26:11 +02:00
|
|
|
d->m_ui.nameLineEdit->setText(name);
|
|
|
|
|
d->m_ui.nameLineEdit->selectAll();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString ProjectIntroPage::description() const
|
|
|
|
|
{
|
2011-09-07 14:26:11 +02:00
|
|
|
return d->m_ui.descriptionLabel->text();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ProjectIntroPage::setDescription(const QString &description)
|
|
|
|
|
{
|
2011-09-07 14:26:11 +02:00
|
|
|
d->m_ui.descriptionLabel->setText(description);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ProjectIntroPage::isComplete() const
|
|
|
|
|
{
|
2011-09-07 14:26:11 +02:00
|
|
|
return d->m_complete;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ProjectIntroPage::validate()
|
|
|
|
|
{
|
2012-04-13 16:37:48 +02:00
|
|
|
if (d->m_forceSubProject) {
|
|
|
|
|
int index = d->m_ui.projectComboBox->currentIndex();
|
|
|
|
|
if (index == 0)
|
|
|
|
|
return false;
|
|
|
|
|
d->m_ui.pathChooser->setPath(d->m_projectDirectories.at(index));
|
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
// Validate and display status
|
2011-09-07 14:26:11 +02:00
|
|
|
if (!d->m_ui.pathChooser->isValid()) {
|
|
|
|
|
displayStatusMessage(Error, d->m_ui.pathChooser->errorMessage());
|
2008-12-02 12:01:29 +01:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-21 21:04:51 +02:00
|
|
|
// Name valid? Ignore 'DisplayingPlaceholderText' state.
|
2008-12-02 12:01:29 +01:00
|
|
|
bool nameValid = false;
|
2011-09-07 14:26:11 +02:00
|
|
|
switch (d->m_ui.nameLineEdit->state()) {
|
2014-02-13 16:13:54 +01:00
|
|
|
case FancyLineEdit::Invalid:
|
2011-09-07 14:26:11 +02:00
|
|
|
displayStatusMessage(Error, d->m_ui.nameLineEdit->errorMessage());
|
2008-12-02 12:01:29 +01:00
|
|
|
return false;
|
2017-10-21 21:04:51 +02:00
|
|
|
case FancyLineEdit::DisplayingPlaceholderText:
|
2008-12-02 12:01:29 +01:00
|
|
|
break;
|
2014-02-13 16:13:54 +01:00
|
|
|
case FancyLineEdit::Valid:
|
2008-12-02 12:01:29 +01:00
|
|
|
nameValid = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check existence of the directory
|
2015-01-31 22:11:11 +02:00
|
|
|
const QFileInfo projectDirFile(path() + QLatin1Char('/')
|
|
|
|
|
+ QDir::fromNativeSeparators(d->m_ui.nameLineEdit->text()));
|
2008-12-02 12:01:29 +01:00
|
|
|
if (!projectDirFile.exists()) { // All happy
|
|
|
|
|
hideStatusLabel();
|
|
|
|
|
return nameValid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (projectDirFile.isDir()) {
|
|
|
|
|
displayStatusMessage(Warning, tr("The project already exists."));
|
2013-09-03 18:48:02 +02:00
|
|
|
return nameValid;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
// Not a directory, but something else, likely causing directory creation to fail
|
|
|
|
|
displayStatusMessage(Error, tr("A file with that name already exists."));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ProjectIntroPage::slotChanged()
|
|
|
|
|
{
|
|
|
|
|
const bool newComplete = validate();
|
2011-09-07 14:26:11 +02:00
|
|
|
if (newComplete != d->m_complete) {
|
|
|
|
|
d->m_complete = newComplete;
|
2008-12-02 12:01:29 +01:00
|
|
|
emit completeChanged();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ProjectIntroPage::slotActivated()
|
|
|
|
|
{
|
2011-09-07 14:26:11 +02:00
|
|
|
if (d->m_complete)
|
2008-12-02 12:01:29 +01:00
|
|
|
emit activated();
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-13 16:37:48 +02:00
|
|
|
bool ProjectIntroPage::forceSubProject() const
|
|
|
|
|
{
|
|
|
|
|
return d->m_forceSubProject;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ProjectIntroPage::setForceSubProject(bool force)
|
|
|
|
|
{
|
|
|
|
|
d->m_forceSubProject = force;
|
|
|
|
|
d->m_ui.projectLabel->setVisible(d->m_forceSubProject);
|
|
|
|
|
d->m_ui.projectComboBox->setVisible(d->m_forceSubProject);
|
|
|
|
|
d->m_ui.pathChooser->setDisabled(d->m_forceSubProject);
|
|
|
|
|
d->m_ui.projectsDirectoryCheckBox->setDisabled(d->m_forceSubProject);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ProjectIntroPage::setProjectList(const QStringList &projectList)
|
|
|
|
|
{
|
|
|
|
|
d->m_ui.projectComboBox->clear();
|
|
|
|
|
d->m_ui.projectComboBox->addItems(projectList);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ProjectIntroPage::setProjectDirectories(const QStringList &directoryList)
|
|
|
|
|
{
|
|
|
|
|
d->m_projectDirectories = directoryList;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ProjectIntroPage::projectIndex() const
|
|
|
|
|
{
|
|
|
|
|
return d->m_ui.projectComboBox->currentIndex();
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-22 15:32:42 +02:00
|
|
|
bool ProjectIntroPage::validateProjectName(const QString &name, QString *errorMessage)
|
2015-04-28 14:49:56 +02:00
|
|
|
{
|
2015-10-22 15:32:42 +02:00
|
|
|
int pos = -1;
|
|
|
|
|
// if we have a pattern it was set
|
|
|
|
|
if (!d->m_projectNameValidator.regularExpression().pattern().isEmpty()) {
|
|
|
|
|
if (name.isEmpty()) {
|
|
|
|
|
if (errorMessage)
|
|
|
|
|
*errorMessage = tr("Name is empty.");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
// pos is set by reference
|
|
|
|
|
QString tmp = name;
|
|
|
|
|
QValidator::State validatorState = d->m_projectNameValidator.validate(tmp, pos);
|
|
|
|
|
|
|
|
|
|
// if pos is set by validate it is cought at the bottom where it shows
|
|
|
|
|
// a more detailed error message
|
|
|
|
|
if (validatorState != QValidator::Acceptable && (pos == -1 || pos >= name.count())) {
|
|
|
|
|
if (errorMessage) {
|
|
|
|
|
*errorMessage = tr("Name does not match \"%1\".").arg(
|
|
|
|
|
d->m_projectNameValidator.regularExpression().pattern());
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
} else { // no validator means usually a qmake project
|
|
|
|
|
// Validation is file name + checking for dots
|
|
|
|
|
if (!FileNameValidatingLineEdit::validateFileName(name, false, errorMessage))
|
|
|
|
|
return false;
|
|
|
|
|
if (name.contains(QLatin1Char('.'))) {
|
|
|
|
|
if (errorMessage)
|
|
|
|
|
*errorMessage = tr("Invalid character \".\".");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
pos = FileUtils::indexOfQmakeUnfriendly(name);
|
|
|
|
|
}
|
2015-04-28 14:49:56 +02:00
|
|
|
if (pos >= 0) {
|
|
|
|
|
if (errorMessage)
|
|
|
|
|
*errorMessage = tr("Invalid character \"%1\" found.").arg(name.at(pos));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
void ProjectIntroPage::displayStatusMessage(StatusLabelMode m, const QString &s)
|
|
|
|
|
{
|
|
|
|
|
switch (m) {
|
|
|
|
|
case Error:
|
2011-09-07 14:26:11 +02:00
|
|
|
d->m_ui.stateLabel->setStyleSheet(d->m_errorStyleSheet);
|
2008-12-02 12:01:29 +01:00
|
|
|
break;
|
|
|
|
|
case Warning:
|
2011-09-07 14:26:11 +02:00
|
|
|
d->m_ui.stateLabel->setStyleSheet(d->m_warningStyleSheet);
|
2008-12-02 12:01:29 +01:00
|
|
|
break;
|
|
|
|
|
case Hint:
|
2011-09-07 14:26:11 +02:00
|
|
|
d->m_ui.stateLabel->setStyleSheet(d->m_hintStyleSheet);
|
2008-12-02 12:01:29 +01:00
|
|
|
break;
|
|
|
|
|
}
|
2011-09-07 14:26:11 +02:00
|
|
|
d->m_ui.stateLabel->setText(s);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ProjectIntroPage::hideStatusLabel()
|
|
|
|
|
{
|
|
|
|
|
displayStatusMessage(Hint, QString());
|
|
|
|
|
}
|
|
|
|
|
|
2009-11-26 18:03:16 +01:00
|
|
|
bool ProjectIntroPage::useAsDefaultPath() const
|
|
|
|
|
{
|
2011-09-07 14:26:11 +02:00
|
|
|
return d->m_ui.projectsDirectoryCheckBox->isChecked();
|
2009-11-26 18:03:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ProjectIntroPage::setUseAsDefaultPath(bool u)
|
|
|
|
|
{
|
2011-09-07 14:26:11 +02:00
|
|
|
d->m_ui.projectsDirectoryCheckBox->setChecked(u);
|
2009-11-26 18:03:16 +01:00
|
|
|
}
|
|
|
|
|
|
2008-12-02 14:09:21 +01:00
|
|
|
} // namespace Utils
|