aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/utils')
-rw-r--r--src/libs/utils/basevalidatinglineedit.cpp157
-rw-r--r--src/libs/utils/basevalidatinglineedit.h100
-rw-r--r--src/libs/utils/classnamevalidatinglineedit.cpp137
-rw-r--r--src/libs/utils/classnamevalidatinglineedit.h79
-rw-r--r--src/libs/utils/codegeneration.cpp89
-rw-r--r--src/libs/utils/codegeneration.h70
-rw-r--r--src/libs/utils/fancylineedit.cpp317
-rw-r--r--src/libs/utils/fancylineedit.h115
-rw-r--r--src/libs/utils/filenamevalidatinglineedit.cpp97
-rw-r--r--src/libs/utils/filenamevalidatinglineedit.h56
-rw-r--r--src/libs/utils/filesearch.cpp216
-rw-r--r--src/libs/utils/filesearch.h69
-rw-r--r--src/libs/utils/filewizarddialog.cpp73
-rw-r--r--src/libs/utils/filewizarddialog.h69
-rw-r--r--src/libs/utils/filewizardpage.cpp129
-rw-r--r--src/libs/utils/filewizardpage.h86
-rw-r--r--src/libs/utils/filewizardpage.ui83
-rw-r--r--src/libs/utils/linecolumnlabel.cpp69
-rw-r--r--src/libs/utils/linecolumnlabel.h68
-rw-r--r--src/libs/utils/listutils.h54
-rw-r--r--src/libs/utils/newclasswidget.cpp462
-rw-r--r--src/libs/utils/newclasswidget.h150
-rw-r--r--src/libs/utils/newclasswidget.ui150
-rw-r--r--src/libs/utils/pathchooser.cpp185
-rw-r--r--src/libs/utils/pathchooser.h90
-rw-r--r--src/libs/utils/projectintropage.cpp215
-rw-r--r--src/libs/utils/projectintropage.h107
-rw-r--r--src/libs/utils/projectintropage.ui122
-rw-r--r--src/libs/utils/projectnamevalidatinglineedit.cpp66
-rw-r--r--src/libs/utils/projectnamevalidatinglineedit.h56
-rw-r--r--src/libs/utils/qtcolorbutton.cpp290
-rw-r--r--src/libs/utils/qtcolorbutton.h84
-rw-r--r--src/libs/utils/reloadpromptutils.cpp62
-rw-r--r--src/libs/utils/reloadpromptutils.h54
-rw-r--r--src/libs/utils/settingsutils.cpp53
-rw-r--r--src/libs/utils/settingsutils.h48
-rw-r--r--src/libs/utils/submiteditorwidget.cpp305
-rw-r--r--src/libs/utils/submiteditorwidget.h122
-rw-r--r--src/libs/utils/submiteditorwidget.ui59
-rw-r--r--src/libs/utils/synchronousprocess.cpp356
-rw-r--r--src/libs/utils/synchronousprocess.h139
-rw-r--r--src/libs/utils/utils.pri1
-rw-r--r--src/libs/utils/utils.pro53
-rw-r--r--src/libs/utils/utils_global.h57
44 files changed, 5419 insertions, 0 deletions
diff --git a/src/libs/utils/basevalidatinglineedit.cpp b/src/libs/utils/basevalidatinglineedit.cpp
new file mode 100644
index 00000000000..cb936e3c2d2
--- /dev/null
+++ b/src/libs/utils/basevalidatinglineedit.cpp
@@ -0,0 +1,157 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#include "basevalidatinglineedit.h"
+
+#include <QtCore/QDebug>
+
+enum { debug = 0 };
+
+namespace Core {
+namespace Utils {
+
+struct BaseValidatingLineEditPrivate {
+ explicit BaseValidatingLineEditPrivate(const QWidget *w);
+
+ const QColor m_okTextColor;
+ QColor m_errorTextColor;
+
+ BaseValidatingLineEdit::State m_state;
+ QString m_errorMessage;
+ QString m_initialText;
+ bool m_firstChange;
+};
+
+BaseValidatingLineEditPrivate::BaseValidatingLineEditPrivate(const QWidget *w) :
+ m_okTextColor(BaseValidatingLineEdit::textColor(w)),
+ m_errorTextColor(Qt::red),
+ m_state(BaseValidatingLineEdit::Invalid),
+ m_firstChange(true)
+{
+}
+
+BaseValidatingLineEdit::BaseValidatingLineEdit(QWidget *parent) :
+ QLineEdit(parent),
+ m_bd(new BaseValidatingLineEditPrivate(this))
+{
+ // Note that textChanged() is also triggered automagically by
+ // QLineEdit::setText(), no need to trigger manually.
+ connect(this, SIGNAL(textChanged(QString)), this, SLOT(slotChanged(QString)));
+}
+
+BaseValidatingLineEdit::~BaseValidatingLineEdit()
+{
+ delete m_bd;
+}
+
+QString BaseValidatingLineEdit::initialText() const
+{
+ return m_bd->m_initialText;
+}
+
+void BaseValidatingLineEdit::setInitialText(const QString &t)
+{
+ if (m_bd->m_initialText != t) {
+ m_bd->m_initialText = t;
+ m_bd->m_firstChange = true;
+ setText(t);
+ }
+}
+
+QColor BaseValidatingLineEdit::errorColor() const
+{
+ return m_bd->m_errorTextColor;
+}
+
+void BaseValidatingLineEdit::setErrorColor(const QColor &c)
+{
+ m_bd->m_errorTextColor = c;
+}
+
+QColor BaseValidatingLineEdit::textColor(const QWidget *w)
+{
+ return w->palette().color(QPalette::Active, QPalette::Text);
+}
+
+void BaseValidatingLineEdit::setTextColor(QWidget *w, const QColor &c)
+{
+ QPalette palette = w->palette();
+ palette.setColor(QPalette::Active, QPalette::Text, c);
+ w->setPalette(palette);
+}
+
+BaseValidatingLineEdit::State BaseValidatingLineEdit::state() const
+{
+ return m_bd->m_state;
+}
+
+bool BaseValidatingLineEdit::isValid() const
+{
+ return m_bd->m_state == Valid;
+}
+
+QString BaseValidatingLineEdit::errorMessage() const
+{
+ return m_bd->m_errorMessage;
+}
+
+void BaseValidatingLineEdit::slotChanged(const QString &t)
+{
+ m_bd->m_errorMessage.clear();
+ // Are we displaying the initial text?
+ const bool isDisplayingInitialText = !m_bd->m_initialText.isEmpty() && t == m_bd->m_initialText;
+ const State newState = isDisplayingInitialText ?
+ DisplayingInitialText :
+ (validate(t, &m_bd->m_errorMessage) ? Valid : Invalid);
+ setToolTip(m_bd->m_errorMessage);
+ if (debug)
+ qDebug() << Q_FUNC_INFO << t << "State" << m_bd->m_state << "->" << newState << m_bd->m_errorMessage;
+ // Changed..figure out if valid changed. DisplayingInitialText is not valid,
+ // but should not show error color. Also trigger on the first change.
+ if (newState != m_bd->m_state || m_bd->m_firstChange) {
+ const bool validHasChanged = (m_bd->m_state == Valid) != (newState == Valid);
+ m_bd->m_state = newState;
+ m_bd->m_firstChange = false;
+ setTextColor(this, newState == Invalid ? m_bd->m_errorTextColor : m_bd->m_okTextColor);
+ if (validHasChanged)
+ emit validChanged();
+ }
+}
+
+void BaseValidatingLineEdit::slotReturnPressed()
+{
+ if (isValid())
+ emit validReturnPressed();
+}
+
+}
+}
diff --git a/src/libs/utils/basevalidatinglineedit.h b/src/libs/utils/basevalidatinglineedit.h
new file mode 100644
index 00000000000..34826870112
--- /dev/null
+++ b/src/libs/utils/basevalidatinglineedit.h
@@ -0,0 +1,100 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#ifndef BASEVALIDATINGLINEEDIT_H
+#define BASEVALIDATINGLINEEDIT_H
+
+#include "utils_global.h"
+
+#include <QtGui/QLineEdit>
+
+namespace Core {
+namespace Utils {
+
+struct BaseValidatingLineEditPrivate;
+
+/* Base class for validating line edits that performs validation in a virtual
+ * validate() function to be implemented in derived classes.
+ * When invalid, the text color will turn red and a tooltip will
+ * contain the error message. This approach is less intrusive than a
+ * QValidator which will prevent the user from entering certain characters.
+ *
+ * The widget has a concept of an "initialText" which can be something like
+ * "<Enter name here>". This results in state 'DisplayingInitialText', which
+ * is not valid, but is not marked red. */
+
+class QWORKBENCH_UTILS_EXPORT BaseValidatingLineEdit : public QLineEdit {
+ Q_OBJECT
+ Q_DISABLE_COPY(BaseValidatingLineEdit)
+ Q_PROPERTY(QString initialText READ initialText WRITE setInitialText DESIGNABLE true)
+ Q_PROPERTY(QColor errorColor READ errorColor WRITE setErrorColor DESIGNABLE true)
+
+public:
+ enum State { Invalid, DisplayingInitialText, Valid };
+
+ explicit BaseValidatingLineEdit(QWidget *parent = 0);
+ virtual ~BaseValidatingLineEdit();
+
+
+ State state() const;
+ bool isValid() const;
+ QString errorMessage() const;
+
+ QString initialText() const;
+ void setInitialText(const QString &);
+
+ QColor errorColor() const;
+ void setErrorColor(const QColor &);
+
+ static QColor textColor(const QWidget *w);
+ static void setTextColor(QWidget *w, const QColor &c);
+
+signals:
+ void validChanged();
+ void validReturnPressed();
+
+protected:
+ virtual bool validate(const QString &value, QString *errorMessage) const = 0;
+
+protected slots:
+ // Custom behaviour can be added here. The base implementation must
+ // be called.
+ virtual void slotReturnPressed();
+ virtual void slotChanged(const QString &t);
+
+private:
+ BaseValidatingLineEditPrivate *m_bd;
+};
+
+}
+}
+#endif // BASEVALIDATINGLINEEDIT_H
diff --git a/src/libs/utils/classnamevalidatinglineedit.cpp b/src/libs/utils/classnamevalidatinglineedit.cpp
new file mode 100644
index 00000000000..b52758eda5f
--- /dev/null
+++ b/src/libs/utils/classnamevalidatinglineedit.cpp
@@ -0,0 +1,137 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#include "classnamevalidatinglineedit.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QRegExp>
+
+namespace Core {
+namespace Utils {
+
+struct ClassNameValidatingLineEditPrivate {
+ ClassNameValidatingLineEditPrivate();
+
+ const QRegExp m_nameRegexp;
+ const QString m_namespaceDelimiter;
+ bool m_namespacesEnabled;
+};
+
+// Match something like "Namespace1::Namespace2::ClassName".
+ClassNameValidatingLineEditPrivate:: ClassNameValidatingLineEditPrivate() :
+ m_nameRegexp(QLatin1String("[a-zA-Z_][a-zA-Z0-9_]*(::[a-zA-Z_][a-zA-Z0-9_]*)*")),
+ m_namespaceDelimiter(QLatin1String("::")),
+ m_namespacesEnabled(false)
+{
+ Q_ASSERT(m_nameRegexp.isValid());
+}
+
+// --------------------- ClassNameValidatingLineEdit
+ClassNameValidatingLineEdit::ClassNameValidatingLineEdit(QWidget *parent) :
+ Core::Utils::BaseValidatingLineEdit(parent),
+ m_d(new ClassNameValidatingLineEditPrivate)
+{
+}
+
+ClassNameValidatingLineEdit::~ClassNameValidatingLineEdit()
+{
+ delete m_d;
+}
+
+bool ClassNameValidatingLineEdit::namespacesEnabled() const
+{
+ return m_d->m_namespacesEnabled;
+}
+
+void ClassNameValidatingLineEdit::setNamespacesEnabled(bool b)
+{
+ m_d->m_namespacesEnabled = b;
+}
+
+bool ClassNameValidatingLineEdit::validate(const QString &value, QString *errorMessage) const
+{
+ if (!m_d->m_namespacesEnabled && value.contains(QLatin1Char(':'))) {
+ if (errorMessage)
+ *errorMessage = tr("The class name must not contain namespace delimiters.");
+ return false;
+ }
+ if (!m_d->m_nameRegexp.exactMatch(value)) {
+ if (errorMessage)
+ *errorMessage = tr("The class name contains invalid characters.");
+ return false;
+ }
+ return true;
+}
+
+void ClassNameValidatingLineEdit::slotChanged(const QString &t)
+{
+ Core::Utils::BaseValidatingLineEdit::slotChanged(t);
+ if (isValid()) {
+ // Suggest file names, strip namespaces
+ QString fileName = t.toLower();
+ if (m_d->m_namespacesEnabled) {
+ const int namespaceIndex = fileName.lastIndexOf(m_d->m_namespaceDelimiter);
+ if (namespaceIndex != -1)
+ fileName.remove(0, namespaceIndex + m_d->m_namespaceDelimiter.size());
+ }
+ emit updateFileName(fileName);
+ }
+}
+
+QString ClassNameValidatingLineEdit::createClassName(const QString &name)
+{
+ // Remove spaces and convert the adjacent characters to uppercase
+ QString className = name;
+ QRegExp spaceMatcher(QLatin1String(" +(\\w)"), Qt::CaseSensitive, QRegExp::RegExp2);
+ Q_ASSERT(spaceMatcher.isValid());
+ int pos;
+ while ((pos = spaceMatcher.indexIn(className)) != -1) {
+ className.replace(pos, spaceMatcher.matchedLength(),
+ spaceMatcher.cap(1).toUpper());
+ }
+
+ // Filter out any remaining invalid characters
+ className.remove(QRegExp(QLatin1String("[^a-zA-Z0-9_]")));
+
+ // If the first character is numeric, prefix the name with a "_"
+ if (className.at(0).isNumber()) {
+ className.prepend(QLatin1Char('_'));
+ } else {
+ // Convert the first character to uppercase
+ className.replace(0, 1, className.left(1).toUpper());
+ }
+
+ return className;
+}
+
+}
+}
diff --git a/src/libs/utils/classnamevalidatinglineedit.h b/src/libs/utils/classnamevalidatinglineedit.h
new file mode 100644
index 00000000000..c0a209d0d71
--- /dev/null
+++ b/src/libs/utils/classnamevalidatinglineedit.h
@@ -0,0 +1,79 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#ifndef CLASSNAMEVALIDATINGLINEEDIT_H
+#define CLASSNAMEVALIDATINGLINEEDIT_H
+
+#include "utils_global.h"
+#include "basevalidatinglineedit.h"
+
+namespace Core {
+namespace Utils {
+
+struct ClassNameValidatingLineEditPrivate;
+
+/* A Line edit that validates a C++ class name and emits a signal
+ * to derive suggested file names from it. */
+
+class QWORKBENCH_UTILS_EXPORT ClassNameValidatingLineEdit :
+ public Core::Utils::BaseValidatingLineEdit {
+ Q_DISABLE_COPY(ClassNameValidatingLineEdit)
+ Q_PROPERTY(bool namespacesEnabled READ namespacesEnabled WRITE setNamespacesEnabled DESIGNABLE true)
+ Q_OBJECT
+
+public:
+ explicit ClassNameValidatingLineEdit(QWidget *parent = 0);
+ virtual ~ClassNameValidatingLineEdit();
+
+ bool namespacesEnabled() const;
+ void setNamespacesEnabled(bool b);
+
+ // Clean an input string to get a valid class name.
+ static QString createClassName(const QString &name);
+
+signals:
+ // Will be emitted with a suggestion for a base name of the
+ // source/header file of the class.
+ void updateFileName(const QString &t);
+
+protected:
+ virtual bool validate(const QString &value, QString *errorMessage) const;
+ virtual void slotChanged(const QString &t);
+
+private:
+ ClassNameValidatingLineEditPrivate *m_d;
+};
+
+}
+}
+
+#endif // CLASSNAMEVALIDATINGLINEEDIT_H
diff --git a/src/libs/utils/codegeneration.cpp b/src/libs/utils/codegeneration.cpp
new file mode 100644
index 00000000000..3af484935a7
--- /dev/null
+++ b/src/libs/utils/codegeneration.cpp
@@ -0,0 +1,89 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#include "codegeneration.h"
+
+#include <QtCore/QTextStream>
+#include <QtCore/QStringList>
+#include <QtCore/QFileInfo>
+
+namespace Core {
+namespace Utils {
+
+QWORKBENCH_UTILS_EXPORT QString headerGuard(const QString &file)
+{
+ QString rc = QFileInfo(file).baseName().toUpper();
+ rc += QLatin1String("_H");
+ return rc;
+}
+
+QWORKBENCH_UTILS_EXPORT
+void writeIncludeFileDirective(const QString &file, bool globalInclude,
+ QTextStream &str)
+{
+ const QChar opening = globalInclude ? QLatin1Char('<') : QLatin1Char('"');
+ const QChar closing = globalInclude ? QLatin1Char('>') : QLatin1Char('"');
+ str << QLatin1String("#include ") << opening << file << closing << QLatin1Char('\n');
+}
+
+QWORKBENCH_UTILS_EXPORT
+QString writeOpeningNameSpaces(const QStringList &l, const QString &indent,
+ QTextStream &str)
+{
+ const int count = l.size();
+ QString rc;
+ if (count) {
+ str << '\n';
+ for (int i = 0; i < count; i++) {
+ str << rc << "namespace " << l.at(i) << " {\n";
+ rc += indent;
+ }
+ str << '\n';
+ }
+ return rc;
+}
+
+QWORKBENCH_UTILS_EXPORT
+void writeClosingNameSpaces(const QStringList &l, const QString &indent,
+ QTextStream &str)
+{
+ if (!l.empty())
+ str << '\n';
+ for (int i = l.size() - 1; i >= 0; i--) {
+ if (i)
+ str << QString(indent.size() * i, QLatin1Char(' '));
+ str << "} // namespace " << l.at(i) << '\n';
+ }
+}
+
+} // namespace Utils
+} // namespace Core
diff --git a/src/libs/utils/codegeneration.h b/src/libs/utils/codegeneration.h
new file mode 100644
index 00000000000..1a20c76d083
--- /dev/null
+++ b/src/libs/utils/codegeneration.h
@@ -0,0 +1,70 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#ifndef CODEGENERATION_H
+#define CODEGENERATION_H
+
+#include "utils_global.h"
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+class QTextStream;
+class QStringList;
+QT_END_NAMESPACE
+
+namespace Core {
+namespace Utils {
+
+QWORKBENCH_UTILS_EXPORT QString headerGuard(const QString &file);
+
+QWORKBENCH_UTILS_EXPORT
+void writeIncludeFileDirective(const QString &file,
+ bool globalInclude,
+ QTextStream &str);
+
+// Write opening namespaces and return an indentation string to be used
+// in the following code if there are any.
+QWORKBENCH_UTILS_EXPORT
+QString writeOpeningNameSpaces(const QStringList &namespaces,
+ const QString &indent,
+ QTextStream &str);
+
+// Close namespacesnamespaces
+QWORKBENCH_UTILS_EXPORT
+void writeClosingNameSpaces(const QStringList &namespaces,
+ const QString &indent,
+ QTextStream &str);
+
+} // namespace Utils
+} // namespace Core
+
+#endif // CODEGENERATION_H
diff --git a/src/libs/utils/fancylineedit.cpp b/src/libs/utils/fancylineedit.cpp
new file mode 100644
index 00000000000..e7e930c544e
--- /dev/null
+++ b/src/libs/utils/fancylineedit.cpp
@@ -0,0 +1,317 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#include "fancylineedit.h"
+
+#include <QtCore/QEvent>
+#include <QtCore/QDebug>
+#include <QtCore/QString>
+#include <QtGui/QApplication>
+#include <QtGui/QMenu>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QLabel>
+
+enum { margin = 6 };
+
+namespace Core {
+namespace Utils {
+
+static inline QString sideToStyleSheetString(FancyLineEdit::Side side)
+{
+ return side == FancyLineEdit::Left ? QLatin1String("left") : QLatin1String("right");
+}
+
+// Format style sheet for the label containing the pixmap. It has a margin on
+// the outer side of the whole FancyLineEdit.
+static QString labelStyleSheet(FancyLineEdit::Side side)
+{
+ QString rc = QLatin1String("QLabel { margin-");
+ rc += sideToStyleSheetString(side);
+ rc += QLatin1String(": ");
+ rc += QString::number(margin);
+ rc += QLatin1Char('}');
+ return rc;
+}
+
+// --------- FancyLineEditPrivate as QObject with label
+// event filter
+
+class FancyLineEditPrivate : public QObject {
+public:
+ explicit FancyLineEditPrivate(QLineEdit *parent);
+
+ virtual bool eventFilter(QObject *obj, QEvent *event);
+
+ const QString m_leftLabelStyleSheet;
+ const QString m_rightLabelStyleSheet;
+
+ QLineEdit *m_lineEdit;
+ QPixmap m_pixmap;
+ QMenu *m_menu;
+ QLabel *m_menuLabel;
+ FancyLineEdit::Side m_side;
+ bool m_useLayoutDirection;
+ bool m_menuTabFocusTrigger;
+ QString m_hintText;
+ bool m_showingHintText;
+};
+
+
+FancyLineEditPrivate::FancyLineEditPrivate(QLineEdit *parent) :
+ QObject(parent),
+ m_leftLabelStyleSheet(labelStyleSheet(FancyLineEdit::Left)),
+ m_rightLabelStyleSheet(labelStyleSheet(FancyLineEdit::Right)),
+ m_lineEdit(parent),
+ m_menu(0),
+ m_menuLabel(0),
+ m_side(FancyLineEdit::Left),
+ m_useLayoutDirection(false),
+ m_menuTabFocusTrigger(false),
+ m_showingHintText(false)
+{
+}
+
+bool FancyLineEditPrivate::eventFilter(QObject *obj, QEvent *event)
+{
+ if (!m_menu || obj != m_menuLabel)
+ return QObject::eventFilter(obj, event);
+
+ switch (event->type()) {
+ case QEvent::MouseButtonPress: {
+ const QMouseEvent *me = static_cast<QMouseEvent *>(event);
+ m_menu->exec(me->globalPos());
+ return true;
+ }
+ case QEvent::FocusIn:
+ if (m_menuTabFocusTrigger) {
+ m_lineEdit->setFocus();
+ m_menu->exec(m_menuLabel->mapToGlobal(m_menuLabel->rect().center()));
+ return true;
+ }
+ default:
+ break;
+ }
+ return QObject::eventFilter(obj, event);
+}
+
+// --------- FancyLineEdit
+FancyLineEdit::FancyLineEdit(QWidget *parent) :
+ QLineEdit(parent),
+ m_d(new FancyLineEditPrivate(this))
+{
+ m_d->m_menuLabel = new QLabel(this);
+ m_d->m_menuLabel->installEventFilter(m_d);
+ updateMenuLabel();
+ showHintText();
+}
+
+FancyLineEdit::~FancyLineEdit()
+{
+}
+
+// Position the menu label left or right according to size.
+// Called when switching side and from resizeEvent.
+void FancyLineEdit::positionMenuLabel()
+{
+ switch (side()) {
+ case Left:
+ m_d->m_menuLabel->setGeometry(0, 0, m_d->m_pixmap.width()+margin, height());
+ break;
+ case Right:
+ m_d->m_menuLabel->setGeometry(width() - m_d->m_pixmap.width() - margin, 0,
+ m_d->m_pixmap.width()+margin, height());
+ break;
+ }
+}
+
+void FancyLineEdit::updateStyleSheet(Side side)
+{
+ // Udate the LineEdit style sheet. Make room for the label on the
+ // respective side and set color according to whether we are showing the
+ // hint text
+ QString sheet = QLatin1String("QLineEdit{ padding-");
+ sheet += sideToStyleSheetString(side);
+ sheet += QLatin1String(": ");
+ sheet += QString::number(m_d->m_pixmap.width() + margin);
+ sheet += QLatin1Char(';');
+ if (m_d->m_showingHintText)
+ sheet += QLatin1String(" color: #BBBBBB;");
+ sheet += QLatin1Char('}');
+ setStyleSheet(sheet);
+}
+
+void FancyLineEdit::updateMenuLabel()
+{
+ m_d->m_menuLabel->setPixmap(m_d->m_pixmap);
+ const Side s = side();
+ switch (s) {
+ case Left:
+ m_d->m_menuLabel->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
+ m_d->m_menuLabel->setStyleSheet(m_d->m_leftLabelStyleSheet);
+ break;
+ case Right:
+ m_d->m_menuLabel->setAlignment(Qt::AlignVCenter | Qt::AlignRight);
+ m_d->m_menuLabel->setStyleSheet(m_d->m_rightLabelStyleSheet);
+ break;
+ }
+ updateStyleSheet(s);
+ positionMenuLabel();
+}
+
+void FancyLineEdit::setSide(Side side)
+{
+ m_d->m_side = side;
+ updateMenuLabel();
+}
+
+FancyLineEdit::Side FancyLineEdit::side() const
+{
+ if (m_d->m_useLayoutDirection)
+ return qApp->layoutDirection() == Qt::LeftToRight ? Left : Right;
+ return m_d->m_side;
+}
+
+void FancyLineEdit::resizeEvent(QResizeEvent *)
+{
+ positionMenuLabel();
+}
+
+void FancyLineEdit::setPixmap(const QPixmap &pixmap)
+{
+ m_d->m_pixmap = pixmap;
+ updateMenuLabel();
+}
+
+QPixmap FancyLineEdit::pixmap() const
+{
+ return m_d->m_pixmap;
+}
+
+void FancyLineEdit::setMenu(QMenu *menu)
+{
+ m_d->m_menu = menu;
+}
+
+QMenu *FancyLineEdit::menu() const
+{
+ return m_d->m_menu;
+}
+
+bool FancyLineEdit::useLayoutDirection() const
+{
+ return m_d->m_useLayoutDirection;
+}
+
+void FancyLineEdit::setUseLayoutDirection(bool v)
+{
+ m_d->m_useLayoutDirection = v;
+}
+
+bool FancyLineEdit::isSideStored() const
+{
+ return !m_d->m_useLayoutDirection;
+}
+
+bool FancyLineEdit::hasMenuTabFocusTrigger() const
+{
+ return m_d->m_menuTabFocusTrigger;
+}
+
+void FancyLineEdit::setMenuTabFocusTrigger(bool v)
+{
+ if (m_d->m_menuTabFocusTrigger == v)
+ return;
+
+ m_d->m_menuTabFocusTrigger = v;
+ m_d->m_menuLabel->setFocusPolicy(v ? Qt::TabFocus : Qt::NoFocus);
+}
+
+QString FancyLineEdit::hintText() const
+{
+ return m_d->m_hintText;
+}
+
+void FancyLineEdit::setHintText(const QString &ht)
+{
+ // Updating magic to make the property work in Designer.
+ if (ht == m_d->m_hintText)
+ return;
+ hideHintText();
+ m_d->m_hintText = ht;
+ if (!hasFocus() && !ht.isEmpty())
+ showHintText();
+}
+
+void FancyLineEdit::showHintText()
+{
+ if (!m_d->m_showingHintText && text().isEmpty() && !m_d->m_hintText.isEmpty()) {
+ m_d->m_showingHintText = true;
+ setText(m_d->m_hintText);
+ updateStyleSheet(side());
+ }
+}
+
+void FancyLineEdit::hideHintText()
+{
+ if (m_d->m_showingHintText && !m_d->m_hintText.isEmpty()) {
+ m_d->m_showingHintText = false;
+ setText(QString());
+ updateStyleSheet(side());
+ }
+}
+
+void FancyLineEdit::focusInEvent(QFocusEvent *e)
+{
+ hideHintText();
+ QLineEdit::focusInEvent(e);
+}
+
+void FancyLineEdit::focusOutEvent(QFocusEvent *e)
+{
+ // Focus out: Switch to displaying the hint text unless
+ // there is user input
+ showHintText();
+ QLineEdit::focusOutEvent(e);
+}
+
+bool FancyLineEdit::isShowingHintText() const
+{
+ return m_d->m_showingHintText;
+}
+
+QString FancyLineEdit::typedText() const
+{
+ return m_d->m_showingHintText ? QString() : text();
+}
+
+} // namespace Utils
+} // namespace Core
diff --git a/src/libs/utils/fancylineedit.h b/src/libs/utils/fancylineedit.h
new file mode 100644
index 00000000000..24a109eada3
--- /dev/null
+++ b/src/libs/utils/fancylineedit.h
@@ -0,0 +1,115 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#ifndef FANCYLINEEDIT_H
+#define FANCYLINEEDIT_H
+
+#include "utils_global.h"
+
+#include <QtGui/QLineEdit>
+
+namespace Core {
+namespace Utils {
+
+class FancyLineEditPrivate;
+
+/* A line edit with an embedded pixmap on one side that is connected to
+ * a menu. Additionally, it can display a grayed hintText (like "Type Here to")
+ * when not focussed and empty. When connecting to the changed signals and
+ * querying text, one has to be aware that the text is set to that hint
+ * text if isShowingHintText() returns true (that is, does not contain
+ * valid user input).
+ */
+class QWORKBENCH_UTILS_EXPORT FancyLineEdit : public QLineEdit
+{
+ Q_DISABLE_COPY(FancyLineEdit)
+ Q_OBJECT
+ Q_ENUMS(Side)
+ Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap DESIGNABLE true)
+ Q_PROPERTY(Side side READ side WRITE setSide DESIGNABLE isSideStored STORED isSideStored)
+ Q_PROPERTY(bool useLayoutDirection READ useLayoutDirection WRITE setUseLayoutDirection DESIGNABLE true)
+ Q_PROPERTY(bool menuTabFocusTrigger READ hasMenuTabFocusTrigger WRITE setMenuTabFocusTrigger DESIGNABLE true)
+ Q_PROPERTY(QString hintText READ hintText WRITE setHintText DESIGNABLE true)
+
+public:
+ enum Side {Left, Right};
+
+ explicit FancyLineEdit(QWidget *parent = 0);
+ ~FancyLineEdit();
+
+ QPixmap pixmap() const;
+
+ void setMenu(QMenu *menu);
+ QMenu *menu() const;
+
+ void setSide(Side side);
+ Side side() const;
+
+ bool useLayoutDirection() const;
+ void setUseLayoutDirection(bool v);
+
+ /* Set whether tabbing in will trigger the menu. */
+ bool hasMenuTabFocusTrigger() const;
+ void setMenuTabFocusTrigger(bool v);
+
+ /* Hint text that is displayed when no focus is set */
+ QString hintText() const;
+
+ bool isShowingHintText() const;
+
+ // Convenience for accessing the text that returns "" in case of isShowingHintText().
+ QString typedText() const;
+
+public slots:
+ void setPixmap(const QPixmap &pixmap);
+ void setHintText(const QString &ht);
+ void showHintText();
+ void hideHintText();
+
+protected:
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void focusInEvent(QFocusEvent *e);
+ virtual void focusOutEvent(QFocusEvent *e);
+
+private:
+ bool isSideStored() const;
+ void updateMenuLabel();
+ void positionMenuLabel();
+ void updateStyleSheet(Side side);
+
+ FancyLineEditPrivate *m_d;
+};
+
+} // namespace Utils
+} // namespace Core
+
+#endif // FANCYLINEEDIT_H
diff --git a/src/libs/utils/filenamevalidatinglineedit.cpp b/src/libs/utils/filenamevalidatinglineedit.cpp
new file mode 100644
index 00000000000..1beed717efd
--- /dev/null
+++ b/src/libs/utils/filenamevalidatinglineedit.cpp
@@ -0,0 +1,97 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#include "filenamevalidatinglineedit.h"
+
+namespace Core {
+namespace Utils {
+
+FileNameValidatingLineEdit::FileNameValidatingLineEdit(QWidget *parent) :
+ BaseValidatingLineEdit(parent)
+{
+
+}
+
+/* Validate a file base name, check for forbidden characters/strings. */
+
+static const char *notAllowedChars = "/?:&\\*\"|#%<> ";
+static const char *notAllowedSubStrings[] = {".."};
+
+// Naming a file like a device name will break on Windows, even if it is
+// "com1.txt". Since we are cross-platform, we generally disallow such file
+// names.
+static const char *notAllowedStrings[] = {"CON", "AUX", "PRN", "COM1", "COM2", "LPT1", "LPT2" };
+
+bool FileNameValidatingLineEdit::validateFileName(const QString &name, QString *errorMessage /* = 0*/)
+{
+ if (name.isEmpty()) {
+ if (errorMessage)
+ *errorMessage = tr("The name must not be empty");
+ return false;
+ }
+ // Characters
+ for (const char *c = notAllowedChars; *c; c++)
+ if (name.contains(QLatin1Char(*c))) {
+ if (errorMessage)
+ *errorMessage = tr("The name must not contain any of the characters '%1'.").arg(QLatin1String(notAllowedChars));
+ return false;
+ }
+ // Substrings
+ const int notAllowedSubStringCount = sizeof(notAllowedSubStrings)/sizeof(const char *);
+ for (int s = 0; s < notAllowedSubStringCount; s++) {
+ const QLatin1String notAllowedSubString(notAllowedSubStrings[s]);
+ if (name.contains(notAllowedSubString)) {
+ if (errorMessage)
+ *errorMessage = tr("The name must not contain '%1'.").arg(QString(notAllowedSubString));
+ return false;
+ }
+ }
+ // Strings
+ const int notAllowedStringCount = sizeof(notAllowedStrings)/sizeof(const char *);
+ for (int s = 0; s < notAllowedStringCount; s++) {
+ const QLatin1String notAllowedString(notAllowedStrings[s]);
+ if (name == notAllowedString) {
+ if (errorMessage)
+ *errorMessage = tr("The name must not be '%1'.").arg(QString(notAllowedString));
+ return false;
+ }
+ }
+ return true;
+}
+
+bool FileNameValidatingLineEdit::validate(const QString &value, QString *errorMessage) const
+{
+ return validateFileName(value, errorMessage);
+}
+
+}
+}
diff --git a/src/libs/utils/filenamevalidatinglineedit.h b/src/libs/utils/filenamevalidatinglineedit.h
new file mode 100644
index 00000000000..7535fc196de
--- /dev/null
+++ b/src/libs/utils/filenamevalidatinglineedit.h
@@ -0,0 +1,56 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#ifndef FILENAMEVALIDATINGLINEEDIT_H
+#define FILENAMEVALIDATINGLINEEDIT_H
+
+#include "basevalidatinglineedit.h"
+
+namespace Core {
+namespace Utils {
+
+class QWORKBENCH_UTILS_EXPORT FileNameValidatingLineEdit : public BaseValidatingLineEdit {
+ Q_OBJECT
+ Q_DISABLE_COPY(FileNameValidatingLineEdit)
+
+public:
+ explicit FileNameValidatingLineEdit(QWidget *parent = 0);
+
+ static bool validateFileName(const QString &name, QString *errorMessage /* = 0*/);
+
+protected:
+ virtual bool validate(const QString &value, QString *errorMessage) const;
+};
+
+}
+}
+#endif // FILENAMEVALIDATINGLINEEDIT_H
diff --git a/src/libs/utils/filesearch.cpp b/src/libs/utils/filesearch.cpp
new file mode 100644
index 00000000000..9756984b4b0
--- /dev/null
+++ b/src/libs/utils/filesearch.cpp
@@ -0,0 +1,216 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#include "filesearch.h"
+
+#include <QtCore/QFile>
+#include <QtCore/QDir>
+#include <QtCore/QFutureInterface>
+#include <QtCore/QtConcurrentRun>
+#include <QtCore/QRegExp>
+#include <QtGui/QApplication>
+
+#include <qtconcurrent/runextensions.h>
+
+using namespace Core::Utils;
+
+namespace {
+ void runFileSearch(QFutureInterface<FileSearchResult> &future,
+ QString searchTerm,
+ QStringList files,
+ QTextDocument::FindFlags flags)
+ {
+ future.setProgressRange(0, files.size());
+ int numFilesSearched = 0;
+ int numMatches = 0;
+
+ bool caseInsensitive = !(flags & QTextDocument::FindCaseSensitively);
+ bool wholeWord = (flags & QTextDocument::FindWholeWords);
+
+ QByteArray sa = searchTerm.toUtf8();
+ int scMaxIndex = sa.length()-1;
+ const char *sc = sa.constData();
+
+ QByteArray sal = searchTerm.toLower().toUtf8();
+ const char *scl = sal.constData();
+
+ QByteArray sau = searchTerm.toUpper().toUtf8();
+ const char *scu = sau.constData();
+
+ int chunkSize = qMax(100000, sa.length());
+
+ foreach (QString s, files) {
+ if (future.isPaused())
+ future.waitForResume();
+ if (future.isCanceled()) {
+ future.setProgressValueAndText(numFilesSearched,
+ qApp->translate("FileSearch", "%1: canceled. %2 occurrences found in %3 files.").
+ arg(searchTerm).arg(numMatches).arg(numFilesSearched));
+ break;
+ }
+ QFile file(s);
+ if (!file.open(QIODevice::ReadOnly))
+ continue;
+ int lineNr = 1;
+ const char *startOfLastLine = NULL;
+
+ bool firstChunk = true;
+ while (!file.atEnd()) {
+ if (!firstChunk)
+ file.seek(file.pos()-sa.length()+1);
+
+ const QByteArray chunk = file.read(chunkSize);
+ const char *chunkPtr = chunk.constData();
+ startOfLastLine = chunkPtr;
+ for (const char *regionPtr = chunkPtr; regionPtr < chunkPtr + chunk.length()-scMaxIndex; ++regionPtr) {
+ const char *regionEnd = regionPtr + scMaxIndex;
+
+ if (*regionPtr == '\n') {
+ startOfLastLine = regionPtr + 1;
+ ++lineNr;
+ }
+ else if (
+ // case sensitive
+ (!caseInsensitive && *regionPtr == sc[0] && *regionEnd == sc[scMaxIndex])
+ ||
+ // case insensitive
+ (caseInsensitive && (*regionPtr == scl[0] || *regionPtr == scu[0])
+ && (*regionEnd == scl[scMaxIndex] || *regionEnd == scu[scMaxIndex]))
+ ) {
+ const char *afterRegion = regionEnd + 1;
+ const char *beforeRegion = regionPtr - 1;
+ bool equal = true;
+ if (wholeWord &&
+ ( ((*beforeRegion >= '0' && *beforeRegion <= '9') || *beforeRegion >= 'A')
+ || ((*afterRegion >= '0' && *afterRegion <= '9') || *afterRegion >= 'A')))
+ {
+ equal = false;
+ }
+
+ int regionIndex = 1;
+ for (const char *regionCursor = regionPtr + 1; regionCursor < regionEnd; ++regionCursor, ++regionIndex) {
+ if ( // case sensitive
+ (!caseInsensitive && equal && *regionCursor != sc[regionIndex])
+ ||
+ // case insensitive
+ (caseInsensitive && equal && *regionCursor != sc[regionIndex] && *regionCursor != scl[regionIndex] && *regionCursor != scu[regionIndex])
+ ) {
+ equal = false;
+ }
+ }
+ if (equal) {
+ int textLength = chunk.length() - (startOfLastLine - chunkPtr);
+ if (textLength > 0) {
+ QByteArray res;
+ res.reserve(256);
+ int i = 0;
+ int n = 0;
+ while (startOfLastLine[i] != '\n' && startOfLastLine[i] != '\r' && i < textLength && n++ < 256)
+ res.append(startOfLastLine[i++]);
+ future.reportResult(FileSearchResult(QDir::toNativeSeparators(s), lineNr, QString(res),
+ regionPtr - startOfLastLine, sa.length()));
+ ++numMatches;
+ }
+ }
+ }
+ }
+ firstChunk = false;
+ }
+ ++numFilesSearched;
+ future.setProgressValueAndText(numFilesSearched, qApp->translate("FileSearch", "%1: %2 occurrences found in %3 of %4 files.").
+ arg(searchTerm).arg(numMatches).arg(numFilesSearched).arg(files.size()));
+ }
+ if (!future.isCanceled())
+ future.setProgressValueAndText(numFilesSearched, qApp->translate("FileSearch", "%1: %2 occurrences found in %3 files.").
+ arg(searchTerm).arg(numMatches).arg(numFilesSearched));
+ }
+
+ void runFileSearchRegExp(QFutureInterface<FileSearchResult> &future,
+ QString searchTerm,
+ QStringList files,
+ QTextDocument::FindFlags flags)
+ {
+ future.setProgressRange(0, files.size());
+ int numFilesSearched = 0;
+ int numMatches = 0;
+ if (flags & QTextDocument::FindWholeWords)
+ searchTerm = QString("\b%1\b").arg(searchTerm);
+ Qt::CaseSensitivity caseSensitivity = (flags & QTextDocument::FindCaseSensitively) ? Qt::CaseSensitive : Qt::CaseInsensitive;
+ QRegExp expression(searchTerm, caseSensitivity);
+
+ foreach (QString s, files) {
+ if (future.isPaused())
+ future.waitForResume();
+ if (future.isCanceled()) {
+ future.setProgressValueAndText(numFilesSearched,
+ qApp->translate("FileSearch", "%1: canceled. %2 occurrences found in %3 files.").
+ arg(searchTerm).arg(numMatches).arg(numFilesSearched));
+ break;
+ }
+ QFile file(s);
+ if (!file.open(QIODevice::ReadOnly))
+ continue;
+ QTextStream stream(&file);
+ int lineNr = 1;
+ QString line;
+ while (!stream.atEnd()) {
+ line = stream.readLine();
+ int pos = 0;
+ while ((pos = expression.indexIn(line, pos)) != -1) {
+ future.reportResult(FileSearchResult(QDir::toNativeSeparators(s), lineNr, line,
+ pos, expression.matchedLength()));
+ pos += expression.matchedLength();
+ }
+ ++lineNr;
+ }
+ ++numFilesSearched;
+ future.setProgressValueAndText(numFilesSearched, qApp->translate("FileSearch", "%1: %2 occurrences found in %3 of %4 files.").
+ arg(searchTerm).arg(numMatches).arg(numFilesSearched).arg(files.size()));
+ }
+ if (!future.isCanceled())
+ future.setProgressValueAndText(numFilesSearched, qApp->translate("FileSearch", "%1: %2 occurrences found in %3 files.").
+ arg(searchTerm).arg(numMatches).arg(numFilesSearched));
+ }
+} // namespace
+
+
+QFuture<FileSearchResult> Core::Utils::findInFiles(const QString &searchTerm, const QStringList &files,
+ QTextDocument::FindFlags flags)
+{
+ return QtConcurrent::run<FileSearchResult, QString, QStringList, QTextDocument::FindFlags>(runFileSearch, searchTerm, files, flags);
+}
+
+QFuture<FileSearchResult> Core::Utils::findInFilesRegExp(const QString &searchTerm, const QStringList &files,
+ QTextDocument::FindFlags flags)
+{
+ return QtConcurrent::run<FileSearchResult, QString, QStringList, QTextDocument::FindFlags>(runFileSearchRegExp, searchTerm, files, flags);
+}
diff --git a/src/libs/utils/filesearch.h b/src/libs/utils/filesearch.h
new file mode 100644
index 00000000000..3b747fb5489
--- /dev/null
+++ b/src/libs/utils/filesearch.h
@@ -0,0 +1,69 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#ifndef FILESEARCH_H
+#define FILESEARCH_H
+
+#include "utils_global.h"
+
+#include <QtCore/QStringList>
+#include <QtCore/QFuture>
+#include <QtGui/QTextDocument>
+
+namespace Core {
+namespace Utils {
+
+class QWORKBENCH_UTILS_EXPORT FileSearchResult
+{
+public:
+ FileSearchResult() {}
+ FileSearchResult(QString fileName, int lineNumber, QString matchingLine, int matchStart, int matchLength)
+ : fileName(fileName), lineNumber(lineNumber), matchingLine(matchingLine), matchStart(matchStart), matchLength(matchLength)
+ {
+ }
+ QString fileName;
+ int lineNumber;
+ QString matchingLine;
+ int matchStart;
+ int matchLength;
+};
+
+QWORKBENCH_UTILS_EXPORT QFuture<FileSearchResult> findInFiles(const QString &searchTerm, const QStringList &files,
+ QTextDocument::FindFlags flags);
+
+QWORKBENCH_UTILS_EXPORT QFuture<FileSearchResult> findInFilesRegExp(const QString &searchTerm, const QStringList &files,
+ QTextDocument::FindFlags flags);
+
+} //Utils
+} //Core
+
+#endif
diff --git a/src/libs/utils/filewizarddialog.cpp b/src/libs/utils/filewizarddialog.cpp
new file mode 100644
index 00000000000..2843a304e5b
--- /dev/null
+++ b/src/libs/utils/filewizarddialog.cpp
@@ -0,0 +1,73 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#include "filewizarddialog.h"
+#include "filewizardpage.h"
+
+#include <QtGui/QAbstractButton>
+
+namespace Core {
+namespace Utils {
+
+FileWizardDialog::FileWizardDialog(QWidget *parent) :
+ QWizard(parent),
+ m_filePage(new FileWizardPage)
+{
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ setPixmap(QWizard::WatermarkPixmap, QPixmap(QLatin1String(":/qworkbench/images/qtwatermark.png")));
+ addPage(m_filePage);
+ connect(m_filePage, SIGNAL(activated()), button(QWizard::FinishButton), SLOT(animateClick()));
+}
+
+QString FileWizardDialog::name() const
+{
+ return m_filePage->name();
+}
+
+QString FileWizardDialog::path() const
+{
+ return m_filePage->path();
+}
+
+void FileWizardDialog::setPath(const QString &path)
+{
+ m_filePage->setPath(path);
+
+}
+
+void FileWizardDialog::setName(const QString &name)
+{
+ m_filePage->setName(name);
+}
+
+} // namespace Utils
+} // namespace Core
diff --git a/src/libs/utils/filewizarddialog.h b/src/libs/utils/filewizarddialog.h
new file mode 100644
index 00000000000..6a4a7d9ba6f
--- /dev/null
+++ b/src/libs/utils/filewizarddialog.h
@@ -0,0 +1,69 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#ifndef FILEWIZARDDIALOG_H
+#define FILEWIZARDDIALOG_H
+
+#include "utils_global.h"
+
+#include <QtGui/QWizard>
+
+namespace Core {
+namespace Utils {
+
+class FileWizardPage;
+
+/*
+ Standard wizard for a single file letting the user choose name
+ and path. Custom pages can be added via Core::IWizardExtension.
+*/
+
+class QWORKBENCH_UTILS_EXPORT FileWizardDialog : public QWizard {
+ Q_OBJECT
+ Q_DISABLE_COPY(FileWizardDialog)
+public:
+ explicit FileWizardDialog(QWidget *parent = 0);
+
+ QString name() const;
+ QString path() const;
+
+public slots:
+ void setPath(const QString &path);
+ void setName(const QString &name);
+
+private:
+ FileWizardPage *m_filePage;
+};
+
+}
+}
+#endif // FILEWIZARDDIALOG_H
diff --git a/src/libs/utils/filewizardpage.cpp b/src/libs/utils/filewizardpage.cpp
new file mode 100644
index 00000000000..a448ebe7395
--- /dev/null
+++ b/src/libs/utils/filewizardpage.cpp
@@ -0,0 +1,129 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#include "filewizardpage.h"
+#include "ui_filewizardpage.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
+#include <QtGui/QMessageBox>
+
+namespace Core {
+namespace Utils {
+
+struct FileWizardPagePrivate
+{
+ FileWizardPagePrivate();
+ Ui::WizardPage m_ui;
+ bool m_complete;
+};
+
+FileWizardPagePrivate::FileWizardPagePrivate() :
+ m_complete(false)
+{
+}
+
+FileWizardPage::FileWizardPage(QWidget *parent) :
+ QWizardPage(parent),
+ m_d(new FileWizardPagePrivate)
+{
+ m_d->m_ui.setupUi(this);
+ connect(m_d->m_ui.pathChooser, SIGNAL(validChanged()), this, SLOT(slotValidChanged()));
+ connect(m_d->m_ui.nameLineEdit, SIGNAL(validChanged()), this, SLOT(slotValidChanged()));
+
+ connect(m_d->m_ui.pathChooser, SIGNAL(returnPressed()), this, SLOT(slotActivated()));
+ connect(m_d->m_ui.nameLineEdit, SIGNAL(validReturnPressed()), this, SLOT(slotActivated()));
+}
+
+FileWizardPage::~FileWizardPage()
+{
+ delete m_d;
+}
+
+QString FileWizardPage::name() const
+{
+ return m_d->m_ui.nameLineEdit->text();
+}
+
+QString FileWizardPage::path() const
+{
+ return m_d->m_ui.pathChooser->path();
+}
+
+void FileWizardPage::setPath(const QString &path)
+{
+ m_d->m_ui.pathChooser->setPath(path);
+}
+
+void FileWizardPage::setName(const QString &name)
+{
+ m_d->m_ui.nameLineEdit->setText(name);
+}
+
+void FileWizardPage::changeEvent(QEvent *e)
+{
+ switch(e->type()) {
+ case QEvent::LanguageChange:
+ m_d->m_ui.retranslateUi(this);
+ break;
+ default:
+ break;
+ }
+}
+
+bool FileWizardPage::isComplete() const
+{
+ return m_d->m_complete;
+}
+
+void FileWizardPage::slotValidChanged()
+{
+ const bool newComplete = m_d->m_ui.pathChooser->isValid() && m_d->m_ui.nameLineEdit->isValid();
+ if (newComplete != m_d->m_complete) {
+ m_d->m_complete = newComplete;
+ emit completeChanged();
+ }
+}
+
+void FileWizardPage::slotActivated()
+{
+ if (m_d->m_complete)
+ emit activated();
+}
+
+bool FileWizardPage::validateBaseName(const QString &name, QString *errorMessage /* = 0*/)
+{
+ return FileNameValidatingLineEdit::validateFileName(name, errorMessage);
+}
+
+} // namespace Utils
+} // namespace Core
diff --git a/src/libs/utils/filewizardpage.h b/src/libs/utils/filewizardpage.h
new file mode 100644
index 00000000000..b2ae28a9d0d
--- /dev/null
+++ b/src/libs/utils/filewizardpage.h
@@ -0,0 +1,86 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#ifndef FILEWIZARDPAGE_H
+#define FILEWIZARDPAGE_H
+
+#include "utils_global.h"
+
+#include <QtGui/QWizardPage>
+
+namespace Core {
+namespace Utils {
+
+struct FileWizardPagePrivate;
+
+/* Standard wizard page for a single file letting the user choose name
+ * and path. Sets the "FileNames" QWizard field. */
+
+class QWORKBENCH_UTILS_EXPORT FileWizardPage : public QWizardPage {
+ Q_OBJECT
+ Q_DISABLE_COPY(FileWizardPage)
+ Q_PROPERTY(QString path READ path WRITE setPath DESIGNABLE true)
+ Q_PROPERTY(QString name READ name WRITE setName DESIGNABLE true)
+public:
+ explicit FileWizardPage(QWidget *parent = 0);
+ virtual ~FileWizardPage();
+
+ QString name() const;
+ QString path() const;
+
+ virtual bool isComplete() const;
+
+ // Validate a base name entry field (potentially containing extension)
+ static bool validateBaseName(const QString &name, QString *errorMessage = 0);
+
+signals:
+ void activated();
+ void pathChanged();
+
+public slots:
+ void setPath(const QString &path);
+ void setName(const QString &name);
+
+private slots:
+ void slotValidChanged();
+ void slotActivated();
+
+protected:
+ virtual void changeEvent(QEvent *e);
+
+private:
+ FileWizardPagePrivate *m_d;
+};
+
+}
+}
+#endif // FILEWIZARDPAGE_H
diff --git a/src/libs/utils/filewizardpage.ui b/src/libs/utils/filewizardpage.ui
new file mode 100644
index 00000000000..2e614c6f552
--- /dev/null
+++ b/src/libs/utils/filewizardpage.ui
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Core::Utils::WizardPage</class>
+ <widget class="QWizardPage" name="Core::Utils::WizardPage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>WizardPage</string>
+ </property>
+ <property name="title">
+ <string>Choose the location</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QWidget" name="widget" native="true">
+ <layout class="QFormLayout" name="formLayout">
+ <property name="fieldGrowthPolicy">
+ <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="nameLabel">
+ <property name="text">
+ <string>Name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="Core::Utils::FileNameValidatingLineEdit" name="nameLineEdit"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="pathLabel">
+ <property name="text">
+ <string>Path:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="Core::Utils::PathChooser" name="pathChooser" native="true"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>201</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>Core::Utils::PathChooser</class>
+ <extends>QWidget</extends>
+ <header>pathchooser.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>Core::Utils::FileNameValidatingLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>filenamevalidatinglineedit.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/libs/utils/linecolumnlabel.cpp b/src/libs/utils/linecolumnlabel.cpp
new file mode 100644
index 00000000000..c6028ab13ff
--- /dev/null
+++ b/src/libs/utils/linecolumnlabel.cpp
@@ -0,0 +1,69 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#include "linecolumnlabel.h"
+
+namespace Core {
+namespace Utils {
+
+LineColumnLabel::LineColumnLabel(QWidget *parent) :
+ QLabel(parent),
+ m_unused(0)
+{
+}
+
+LineColumnLabel::~LineColumnLabel()
+{
+}
+
+void LineColumnLabel::setText(const QString &text, const QString &maxText)
+{
+ QLabel::setText(text);
+ m_maxText = maxText;
+}
+QSize LineColumnLabel::sizeHint() const
+{
+ return fontMetrics().boundingRect(m_maxText).size();
+}
+
+QString LineColumnLabel::maxText() const
+{
+ return m_maxText;
+}
+
+void LineColumnLabel::setMaxText(const QString &maxText)
+{
+ m_maxText = maxText;
+}
+
+}
+}
diff --git a/src/libs/utils/linecolumnlabel.h b/src/libs/utils/linecolumnlabel.h
new file mode 100644
index 00000000000..d5dea084cc2
--- /dev/null
+++ b/src/libs/utils/linecolumnlabel.h
@@ -0,0 +1,68 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#ifndef LINECOLUMNLABEL_H
+#define LINECOLUMNLABEL_H
+
+#include "utils_global.h"
+#include <QtGui/QLabel>
+
+namespace Core {
+namespace Utils {
+
+/* A label suitable for displaying cursor positions, etc. with a fixed
+ * with derived from a sample text. */
+
+class QWORKBENCH_UTILS_EXPORT LineColumnLabel : public QLabel {
+ Q_DISABLE_COPY(LineColumnLabel)
+ Q_OBJECT
+ Q_PROPERTY(QString maxText READ maxText WRITE setMaxText DESIGNABLE true)
+
+public:
+ explicit LineColumnLabel(QWidget *parent = 0);
+ virtual ~LineColumnLabel();
+
+ void setText(const QString &text, const QString &maxText);
+ QSize sizeHint() const;
+
+ QString maxText() const;
+ void setMaxText(const QString &maxText);
+
+private:
+ QString m_maxText;
+ void *m_unused;
+};
+
+}
+}
+
+#endif // LINECOLUMNLABEL_H
diff --git a/src/libs/utils/listutils.h b/src/libs/utils/listutils.h
new file mode 100644
index 00000000000..3b688f336df
--- /dev/null
+++ b/src/libs/utils/listutils.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#ifndef LISTUTILS_H
+#define LISTUTILS_H
+
+#include <QtCore/QList>
+
+namespace Core {
+namespace Utils {
+
+template <class T1, class T2>
+QList<T1> qwConvertList(const QList<T2> &list)
+{
+ QList<T1> convertedList;
+ foreach (T2 listEntry, list) {
+ convertedList << qobject_cast<T1>(listEntry);
+ }
+ return convertedList;
+}
+
+} // Utils
+} // Core
+
+#endif // LISTUTILS_H
diff --git a/src/libs/utils/newclasswidget.cpp b/src/libs/utils/newclasswidget.cpp
new file mode 100644
index 00000000000..67cd1f8691d
--- /dev/null
+++ b/src/libs/utils/newclasswidget.cpp
@@ -0,0 +1,462 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#include "newclasswidget.h"
+#include "ui_newclasswidget.h"
+
+#include <utils/filewizardpage.h>
+
+#include <QtGui/QFileDialog>
+#include <QtCore/QFileInfo>
+#include <QtCore/QStringList>
+#include <QtCore/QDir>
+#include <QtCore/QDebug>
+#include <QtCore/QRegExp>
+
+enum { debugNewClassWidget = 0 };
+
+namespace Core {
+namespace Utils {
+
+struct NewClassWidgetPrivate {
+ NewClassWidgetPrivate();
+
+ Ui::NewClassWidget m_ui;
+ QString m_headerExtension;
+ QString m_sourceExtension;
+ QString m_formExtension;
+ bool m_valid;
+ bool m_classEdited;
+ // Store the "visible" values to prevent the READ accessors from being
+ // fooled by a temporarily hidden widget
+ bool m_baseClassInputVisible;
+ bool m_formInputVisible;
+ bool m_pathInputVisible;
+ bool m_formInputCheckable;
+};
+
+NewClassWidgetPrivate:: NewClassWidgetPrivate() :
+ m_headerExtension(QLatin1String("h")),
+ m_sourceExtension(QLatin1String("cpp")),
+ m_formExtension(QLatin1String("ui")),
+ m_valid(false),
+ m_classEdited(false),
+ m_baseClassInputVisible(true),
+ m_formInputVisible(true),
+ m_pathInputVisible(true),
+ m_formInputCheckable(false)
+{
+}
+
+// --------------------- NewClassWidget
+NewClassWidget::NewClassWidget(QWidget *parent) :
+ QWidget(parent),
+ m_d(new NewClassWidgetPrivate)
+{
+ m_d->m_ui.setupUi(this);
+
+ m_d->m_ui.baseClassComboBox->setEditable(false);
+
+ connect(m_d->m_ui.classLineEdit, SIGNAL(updateFileName(QString)),
+ this, SLOT(updateFileNames(QString)));
+ connect(m_d->m_ui.classLineEdit, SIGNAL(textEdited(QString)),
+ this, SLOT(classNameEdited()));
+ connect(m_d->m_ui.baseClassComboBox, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(suggestClassNameFromBase()));
+ connect(m_d->m_ui.baseClassComboBox, SIGNAL(editTextChanged(QString)),
+ this, SLOT(slotValidChanged()));
+ connect(m_d->m_ui.classLineEdit, SIGNAL(validChanged()),
+ this, SLOT(slotValidChanged()));
+ connect(m_d->m_ui.headerFileLineEdit, SIGNAL(validChanged()),
+ this, SLOT(slotValidChanged()));
+ connect(m_d->m_ui.sourceFileLineEdit, SIGNAL(validChanged()),
+ this, SLOT(slotValidChanged()));
+ connect(m_d->m_ui.formFileLineEdit, SIGNAL(validChanged()),
+ this, SLOT(slotValidChanged()));
+ connect(m_d->m_ui.pathChooser, SIGNAL(validChanged()),
+ this, SLOT(slotValidChanged()));
+
+ connect(m_d->m_ui.classLineEdit, SIGNAL(validReturnPressed()),
+ this, SLOT(slotActivated()));
+ connect(m_d->m_ui.headerFileLineEdit, SIGNAL(validReturnPressed()),
+ this, SLOT(slotActivated()));
+ connect(m_d->m_ui.sourceFileLineEdit, SIGNAL(validReturnPressed()),
+ this, SLOT(slotActivated()));
+ connect(m_d->m_ui.formFileLineEdit, SIGNAL(validReturnPressed()),
+ this, SLOT(slotActivated()));
+ connect(m_d->m_ui.formFileLineEdit, SIGNAL(validReturnPressed()),
+ this, SLOT(slotActivated()));
+ connect(m_d->m_ui.pathChooser, SIGNAL(returnPressed()),
+ this, SLOT(slotActivated()));
+
+ connect(m_d->m_ui.generateFormCheckBox, SIGNAL(stateChanged(int)),
+ this, SLOT(slotFormInputChecked()));
+
+ m_d->m_ui.generateFormCheckBox->setChecked(true);
+ setFormInputCheckable(false, true);
+}
+
+NewClassWidget::~NewClassWidget()
+{
+ delete m_d;
+}
+
+void NewClassWidget::classNameEdited()
+{
+ if (debugNewClassWidget)
+ qDebug() << Q_FUNC_INFO << m_d->m_headerExtension << m_d->m_sourceExtension;
+ m_d->m_classEdited = true;
+}
+
+void NewClassWidget::suggestClassNameFromBase()
+{
+ if (debugNewClassWidget)
+ qDebug() << Q_FUNC_INFO << m_d->m_headerExtension << m_d->m_sourceExtension;
+ if (m_d->m_classEdited)
+ return;
+ // Suggest a class unless edited ("QMainWindow"->"MainWindow")
+ QString base = baseClassName();
+ if (base.startsWith(QLatin1Char('Q'))) {
+ base.remove(0, 1);
+ setClassName(base);
+ }
+}
+
+QStringList NewClassWidget::baseClassChoices() const
+{
+ QStringList rc;
+ const int count = m_d->m_ui.baseClassComboBox->count();
+ for (int i = 0; i < count; i++)
+ rc.push_back(m_d->m_ui.baseClassComboBox->itemText(i));
+ return rc;
+}
+
+void NewClassWidget::setBaseClassChoices(const QStringList &choices)
+{
+ m_d->m_ui.baseClassComboBox->clear();
+ m_d->m_ui.baseClassComboBox->addItems(choices);
+}
+
+void NewClassWidget::setBaseClassInputVisible(bool visible)
+{
+ m_d->m_baseClassInputVisible = visible;
+ m_d->m_ui.baseClassLabel->setVisible(visible);
+ m_d->m_ui.baseClassComboBox->setVisible(visible);
+}
+
+void NewClassWidget::setBaseClassEditable(bool editable)
+{
+ m_d->m_ui.baseClassComboBox->setEditable(editable);
+}
+
+bool NewClassWidget::isBaseClassInputVisible() const
+{
+ return m_d->m_baseClassInputVisible;
+}
+
+bool NewClassWidget::isBaseClassEditable() const
+{
+ return m_d->m_ui.baseClassComboBox->isEditable();
+}
+
+void NewClassWidget::setFormInputVisible(bool visible)
+{
+ m_d->m_formInputVisible = visible;
+ m_d->m_ui.formLabel->setVisible(visible);
+ m_d->m_ui.formFileLineEdit->setVisible(visible);
+}
+
+bool NewClassWidget::isFormInputVisible() const
+{
+ return m_d->m_formInputVisible;
+}
+
+void NewClassWidget::setFormInputCheckable(bool checkable)
+{
+ setFormInputCheckable(checkable, false);
+}
+
+void NewClassWidget::setFormInputCheckable(bool checkable, bool force)
+{
+ if (!force && checkable == m_d->m_formInputCheckable)
+ return;
+ m_d->m_formInputCheckable = checkable;
+ m_d->m_ui.generateFormLabel->setVisible(checkable);
+ m_d->m_ui.generateFormCheckBox->setVisible(checkable);
+}
+
+void NewClassWidget::setFormInputChecked(bool v)
+{
+ m_d->m_ui.generateFormCheckBox->setChecked(v);
+}
+
+bool NewClassWidget::formInputCheckable() const
+{
+ return m_d->m_formInputCheckable;
+}
+
+bool NewClassWidget::formInputChecked() const
+{
+ return m_d->m_ui.generateFormCheckBox->isChecked();
+}
+
+void NewClassWidget::slotFormInputChecked()
+{
+ const bool checked = formInputChecked();
+ m_d->m_ui.formLabel->setEnabled(checked);
+ m_d->m_ui.formFileLineEdit->setEnabled(checked);
+}
+
+void NewClassWidget::setPathInputVisible(bool visible)
+{
+ m_d->m_pathInputVisible = visible;
+ m_d->m_ui.pathLabel->setVisible(visible);
+ m_d->m_ui.pathChooser->setVisible(visible);
+}
+
+bool NewClassWidget::isPathInputVisible() const
+{
+ return m_d->m_pathInputVisible;
+}
+
+void NewClassWidget::setClassName(const QString &suggestedName)
+{
+ if (debugNewClassWidget)
+ qDebug() << Q_FUNC_INFO << suggestedName << m_d->m_headerExtension << m_d->m_sourceExtension;
+ m_d->m_ui.classLineEdit->setText(ClassNameValidatingLineEdit::createClassName(suggestedName));
+}
+
+QString NewClassWidget::className() const
+{
+ return m_d->m_ui.classLineEdit->text();
+}
+
+QString NewClassWidget::baseClassName() const
+{
+ return m_d->m_ui.baseClassComboBox->currentText();
+}
+
+void NewClassWidget::setBaseClassName(const QString &c)
+{
+ const int index = m_d->m_ui.baseClassComboBox->findText(c);
+ if (index != -1) {
+ m_d->m_ui.baseClassComboBox->setCurrentIndex(index);
+ suggestClassNameFromBase();
+ }
+}
+
+QString NewClassWidget::sourceFileName() const
+{
+ return m_d->m_ui.sourceFileLineEdit->text();
+}
+
+QString NewClassWidget::headerFileName() const
+{
+ return m_d->m_ui.headerFileLineEdit->text();
+}
+
+QString NewClassWidget::formFileName() const
+{
+ return m_d->m_ui.formFileLineEdit->text();
+}
+
+QString NewClassWidget::path() const
+{
+ return m_d->m_ui.pathChooser->path();
+}
+
+void NewClassWidget::setPath(const QString &path)
+{
+ m_d->m_ui.pathChooser->setPath(path);
+}
+
+bool NewClassWidget::namespacesEnabled() const
+{
+ return m_d->m_ui.classLineEdit->namespacesEnabled();
+}
+
+void NewClassWidget::setNamespacesEnabled(bool b)
+{
+ m_d->m_ui.classLineEdit->setNamespacesEnabled(b);
+}
+
+QString NewClassWidget::sourceExtension() const
+{
+ return m_d->m_sourceExtension;
+}
+
+void NewClassWidget::setSourceExtension(const QString &e)
+{
+ if (debugNewClassWidget)
+ qDebug() << Q_FUNC_INFO << e;
+ m_d->m_sourceExtension = fixSuffix(e);
+}
+
+QString NewClassWidget::headerExtension() const
+{
+ return m_d->m_headerExtension;
+}
+
+void NewClassWidget::setHeaderExtension(const QString &e)
+{
+ if (debugNewClassWidget)
+ qDebug() << Q_FUNC_INFO << e;
+ m_d->m_headerExtension = fixSuffix(e);
+}
+
+QString NewClassWidget::formExtension() const
+{
+ return m_d->m_formExtension;
+}
+
+void NewClassWidget::setFormExtension(const QString &e)
+{
+ if (debugNewClassWidget)
+ qDebug() << Q_FUNC_INFO << e;
+ m_d->m_formExtension = fixSuffix(e);
+}
+
+void NewClassWidget::slotValidChanged()
+{
+ const bool newValid = isValid();
+ if (newValid != m_d->m_valid) {
+ m_d->m_valid = newValid;
+ emit validChanged();
+ }
+}
+
+bool NewClassWidget::isValid(QString *error) const
+{
+ if (!m_d->m_ui.classLineEdit->isValid()) {
+ if (error)
+ *error = m_d->m_ui.classLineEdit->errorMessage();
+ return false;
+ }
+
+ if (isBaseClassInputVisible() && isBaseClassEditable()) {
+ // TODO: Should this be a ClassNameValidatingComboBox?
+ QRegExp classNameValidator(QLatin1String("[a-zA-Z_][a-zA-Z0-9_]*(::[a-zA-Z_][a-zA-Z0-9_]*)*"));
+ const QString baseClass = m_d->m_ui.baseClassComboBox->currentText().trimmed();
+ if (!baseClass.isEmpty() && !classNameValidator.exactMatch(baseClass)) {
+ if (error)
+ *error = tr("Invalid base class name");
+ return false;
+ }
+ }
+
+ if (!m_d->m_ui.headerFileLineEdit->isValid()) {
+ if (error)
+ *error = tr("Invalid header file name: %1").arg(m_d->m_ui.headerFileLineEdit->errorMessage());
+ return false;
+ }
+
+ if (!m_d->m_ui.sourceFileLineEdit->isValid()) {
+ if (error)
+ *error = tr("Invalid source file name: %1").arg(m_d->m_ui.sourceFileLineEdit->errorMessage());
+ return false;
+ }
+
+ if (isFormInputVisible()) {
+ if (!m_d->m_ui.formFileLineEdit->isValid()) {
+ if (error)
+ *error = tr("Invalid form file name: %1").arg(m_d->m_ui.formFileLineEdit->errorMessage());
+ return false;
+ }
+ }
+
+ if (isPathInputVisible()) {
+ if (!m_d->m_ui.pathChooser->isValid()) {
+ if (error)
+ *error = m_d->m_ui.pathChooser->errorMessage();
+ return false;
+ }
+ }
+ return true;
+}
+
+void NewClassWidget::updateFileNames(const QString &baseName)
+{
+ if (debugNewClassWidget)
+ qDebug() << Q_FUNC_INFO << baseName << m_d->m_headerExtension << m_d->m_sourceExtension;
+ const QChar dot = QLatin1Char('.');
+ m_d->m_ui.sourceFileLineEdit->setText(baseName + dot + m_d->m_sourceExtension);
+ m_d->m_ui.headerFileLineEdit->setText(baseName + dot + m_d->m_headerExtension);
+ m_d->m_ui.formFileLineEdit->setText(baseName + dot + m_d->m_formExtension);
+}
+
+void NewClassWidget::slotActivated()
+{
+ if (m_d->m_valid)
+ emit activated();
+}
+
+QString NewClassWidget::fixSuffix(const QString &suffix)
+{
+ QString s = suffix;
+ if (s.startsWith(QLatin1Char('.')))
+ s.remove(0, 1);
+ return s;
+}
+
+// Utility to add a suffix to a file unless the user specified one
+static QString ensureSuffix(QString f, const QString &extension)
+{
+ const QChar dot = QLatin1Char('.');
+ if (f.contains(dot))
+ return f;
+ f += dot;
+ f += extension;
+ return f;
+}
+
+// If a non-empty name was passed, expand to directory and suffix
+static QString expandFileName(const QDir &dir, const QString name, const QString &extension)
+{
+ if (name.isEmpty())
+ return QString();
+ return dir.absoluteFilePath(ensureSuffix(name, extension));
+}
+
+QStringList NewClassWidget::files() const
+{
+ QStringList rc;
+ const QDir dir = QDir(path());
+ rc.push_back(expandFileName(dir, headerFileName(), headerExtension()));
+ rc.push_back(expandFileName(dir, sourceFileName(), sourceExtension()));
+ if (isFormInputVisible())
+ rc.push_back(expandFileName(dir, formFileName(), formExtension()));
+ return rc;
+}
+
+
+} // namespace Utils
+} // namespace Core
diff --git a/src/libs/utils/newclasswidget.h b/src/libs/utils/newclasswidget.h
new file mode 100644
index 00000000000..e534189d775
--- /dev/null
+++ b/src/libs/utils/newclasswidget.h
@@ -0,0 +1,150 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#ifndef NEWCLASSWIDGET_H
+#define NEWCLASSWIDGET_H
+
+#include "utils_global.h"
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+class QStringList;
+QT_END_NAMESPACE
+
+namespace Core {
+namespace Utils {
+
+struct NewClassWidgetPrivate;
+
+/* NewClassWidget: Utility widget for 'New Class' wizards. Prompts the user
+ * to enter a class name (optionally derived from some base class) and file
+ * names for header, source and form files. Has some smart logic to derive
+ * the file names from the class name. */
+
+class QWORKBENCH_UTILS_EXPORT NewClassWidget : public QWidget
+{
+ Q_DISABLE_COPY(NewClassWidget)
+ Q_OBJECT
+ Q_PROPERTY(bool namespacesEnabled READ namespacesEnabled WRITE setNamespacesEnabled DESIGNABLE true)
+ Q_PROPERTY(bool baseClassInputVisible READ isBaseClassInputVisible WRITE setBaseClassInputVisible DESIGNABLE true)
+ Q_PROPERTY(bool baseClassEditable READ isBaseClassEditable WRITE setBaseClassEditable DESIGNABLE false)
+ Q_PROPERTY(bool formInputVisible READ isFormInputVisible WRITE setFormInputVisible DESIGNABLE true)
+ Q_PROPERTY(bool pathInputVisible READ isPathInputVisible WRITE setPathInputVisible DESIGNABLE true)
+ Q_PROPERTY(QString className READ className WRITE setClassName DESIGNABLE true)
+ Q_PROPERTY(QString baseClassName READ baseClassName WRITE setBaseClassName DESIGNABLE true)
+ Q_PROPERTY(QString sourceFileName READ sourceFileName DESIGNABLE false)
+ Q_PROPERTY(QString headerFileName READ headerFileName DESIGNABLE false)
+ Q_PROPERTY(QString formFileName READ formFileName DESIGNABLE false)
+ Q_PROPERTY(QString path READ path WRITE setPath DESIGNABLE true)
+ Q_PROPERTY(QStringList baseClassChoices READ baseClassChoices WRITE setBaseClassChoices DESIGNABLE true)
+ Q_PROPERTY(QString sourceExtension READ sourceExtension WRITE setSourceExtension DESIGNABLE true)
+ Q_PROPERTY(QString headerExtension READ headerExtension WRITE setHeaderExtension DESIGNABLE true)
+ Q_PROPERTY(QString formExtension READ formExtension WRITE setFormExtension DESIGNABLE true)
+ Q_PROPERTY(bool formInputCheckable READ formInputCheckable WRITE setFormInputCheckable DESIGNABLE true)
+ Q_PROPERTY(bool formInputChecked READ formInputChecked WRITE setFormInputChecked DESIGNABLE true)
+ // Utility "USER" property for wizards containing file names.
+ Q_PROPERTY(QStringList files READ files DESIGNABLE false USER true)
+public:
+ explicit NewClassWidget(QWidget *parent = 0);
+ ~NewClassWidget();
+
+ bool namespacesEnabled() const;
+ bool isBaseClassInputVisible() const;
+ bool isBaseClassEditable() const;
+ bool isFormInputVisible() const;
+ bool isPathInputVisible() const;
+ bool formInputCheckable() const;
+ bool formInputChecked() const;
+
+ QString className() const;
+ QString baseClassName() const;
+ QString sourceFileName() const;
+ QString headerFileName() const;
+ QString formFileName() const;
+ QString path() const;
+ QStringList baseClassChoices() const;
+ QString sourceExtension() const;
+ QString headerExtension() const;
+ QString formExtension() const;
+
+
+ bool isValid(QString *error = 0) const;
+
+ QStringList files() const;
+
+signals:
+ void validChanged();
+ void activated();
+
+public slots:
+ void setNamespacesEnabled(bool b);
+ void setBaseClassInputVisible(bool visible);
+ void setBaseClassEditable(bool editable);
+ void setFormInputVisible(bool visible);
+ void setPathInputVisible(bool visible);
+ void setFormInputCheckable(bool v);
+ void setFormInputChecked(bool v);
+
+ /* The name passed into the new class widget will be reformatted to be a
+ * valid class name. */
+ void setClassName(const QString &suggestedName);
+ void setBaseClassName(const QString &);
+ void setPath(const QString &path);
+ void setBaseClassChoices(const QStringList &choices);
+ void setSourceExtension(const QString &e);
+ void setHeaderExtension(const QString &e);
+ void setFormExtension(const QString &e);
+
+ /* Suggest a class name from the base class by stripping the leading 'Q'
+ * character. This will happen automagically if the base class combo
+ * changes until the class line edited is manually edited. */
+ void suggestClassNameFromBase();
+
+private slots:
+ void updateFileNames(const QString &t);
+ void slotValidChanged();
+ void slotActivated();
+ void classNameEdited();
+ void slotFormInputChecked();
+
+private:
+ void setFormInputCheckable(bool checkable, bool force);
+
+ QString fixSuffix(const QString &suffix);
+ NewClassWidgetPrivate *m_d;
+};
+
+} // namespace Utils
+} // namespace Core
+
+#endif // NEWCLASSWIDGET_H
diff --git a/src/libs/utils/newclasswidget.ui b/src/libs/utils/newclasswidget.ui
new file mode 100644
index 00000000000..14e0a6574b8
--- /dev/null
+++ b/src/libs/utils/newclasswidget.ui
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Core::Utils::NewClassWidget</class>
+ <widget class="QWidget" name="Core::Utils::NewClassWidget">
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QFormLayout" name="formLayout">
+ <property name="fieldGrowthPolicy">
+ <enum>QFormLayout::ExpandingFieldsGrow</enum>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="classNameLabel">
+ <property name="text">
+ <string>Class name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="Core::Utils::ClassNameValidatingLineEdit" name="classLineEdit"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="baseClassLabel">
+ <property name="text">
+ <string>Base class:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="baseClassComboBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="1">
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="headerLabel">
+ <property name="text">
+ <string>Header file:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="Core::Utils::FileNameValidatingLineEdit" name="headerFileLineEdit"/>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="sourceLabel">
+ <property name="text">
+ <string>Source file:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="Core::Utils::FileNameValidatingLineEdit" name="sourceFileLineEdit"/>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="generateFormLabel">
+ <property name="text">
+ <string>Generate form:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="formLabel">
+ <property name="text">
+ <string>Form file:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="Core::Utils::FileNameValidatingLineEdit" name="formFileLineEdit"/>
+ </item>
+ <item row="7" column="0">
+ <widget class="QLabel" name="pathLabel">
+ <property name="text">
+ <string>Path:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="1">
+ <widget class="Core::Utils::PathChooser" name="pathChooser" native="true"/>
+ </item>
+ <item row="5" column="1">
+ <widget class="QCheckBox" name="generateFormCheckBox">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>Core::Utils::PathChooser</class>
+ <extends>QWidget</extends>
+ <header location="global">pathchooser.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>Core::Utils::ClassNameValidatingLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>classnamevalidatinglineedit.h</header>
+ </customwidget>
+ <customwidget>
+ <class>Core::Utils::FileNameValidatingLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header location="global">utils/filenamevalidatinglineedit.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/libs/utils/pathchooser.cpp b/src/libs/utils/pathchooser.cpp
new file mode 100644
index 00000000000..188aa3b126b
--- /dev/null
+++ b/src/libs/utils/pathchooser.cpp
@@ -0,0 +1,185 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#include "pathchooser.h"
+#include "basevalidatinglineedit.h"
+
+#include <QtGui/QLineEdit>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QToolButton>
+#include <QtGui/QFileDialog>
+#include <QtGui/QDesktopServices>
+
+#include <QtCore/QFileInfo>
+#include <QtCore/QDir>
+#include <QtCore/QSettings>
+#include <QtCore/QDebug>
+
+namespace Core {
+namespace Utils {
+
+// ------------------ PathValidatingLineEdit
+class PathValidatingLineEdit : public BaseValidatingLineEdit {
+public:
+ explicit PathValidatingLineEdit(QWidget *parent = 0);
+
+protected:
+ virtual bool validate(const QString &value, QString *errorMessage) const;
+};
+
+PathValidatingLineEdit::PathValidatingLineEdit(QWidget *parent) :
+ BaseValidatingLineEdit(parent)
+{
+}
+
+bool PathValidatingLineEdit::validate(const QString &value, QString *errorMessage) const
+{
+ return PathChooser::validatePath(value, errorMessage);
+}
+
+// ------------------ PathChooserPrivate
+struct PathChooserPrivate {
+ PathChooserPrivate();
+
+ PathValidatingLineEdit *m_lineEdit;
+};
+
+PathChooserPrivate::PathChooserPrivate() :
+ m_lineEdit(new PathValidatingLineEdit)
+{
+}
+
+PathChooser::PathChooser(QWidget *parent) :
+ QWidget(parent),
+ m_d(new PathChooserPrivate)
+{
+ QHBoxLayout *hLayout = new QHBoxLayout;
+ hLayout->setContentsMargins(0, 0, 0, 0);
+
+ connect(m_d->m_lineEdit, SIGNAL(validReturnPressed()), this, SIGNAL(returnPressed()));
+ connect(m_d->m_lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(changed()));
+ connect(m_d->m_lineEdit, SIGNAL(validChanged()), this, SIGNAL(validChanged()));
+
+ m_d->m_lineEdit->setMinimumWidth(300);
+ hLayout->addWidget(m_d->m_lineEdit);
+
+ QToolButton *browseButton = new QToolButton;
+ browseButton->setText(tr("..."));
+ connect(browseButton, SIGNAL(clicked()), this, SLOT(slotBrowse()));
+
+ hLayout->addWidget(browseButton);
+ setLayout(hLayout);
+ setFocusProxy(m_d->m_lineEdit);
+}
+
+PathChooser::~PathChooser()
+{
+ delete m_d;
+}
+
+QString PathChooser::path() const
+{
+ return m_d->m_lineEdit->text();
+}
+
+void PathChooser::setPath(const QString &path)
+{
+ const QString defaultPath = path.isEmpty() ? homePath() : path;
+ m_d->m_lineEdit->setText(QDir::toNativeSeparators(defaultPath));
+}
+
+void PathChooser::slotBrowse()
+{
+ QString predefined = path();
+ if (!predefined.isEmpty() && !QFileInfo(predefined).isDir())
+ predefined.clear();
+ // Prompt for a directory, delete trailing slashes unless it is "/", only
+ QString newPath = QFileDialog::getExistingDirectory(this, tr("Choose a path"), predefined);
+ if (!newPath .isEmpty()) {
+ if (newPath .size() > 1 && newPath .endsWith(QDir::separator()))
+ newPath .truncate(newPath .size() - 1);
+ setPath(newPath);
+ }
+}
+
+bool PathChooser::isValid() const
+{
+ return m_d->m_lineEdit->isValid();
+}
+
+QString PathChooser::errorMessage() const
+{
+ return m_d->m_lineEdit->errorMessage();
+}
+
+bool PathChooser::validatePath(const QString &path, QString *errorMessage)
+{
+ if (path.isEmpty()) {
+ if (errorMessage)
+ *errorMessage = tr("The path must not be empty.");
+ return false;
+ }
+ // Must be a directory?
+ const QFileInfo fi(path);
+ if (fi.isDir())
+ return true; // Happy!
+
+ if (!fi.exists()) {
+ if (errorMessage)
+ *errorMessage = tr("The path '%1' does not exist.").arg(path);
+ return false;
+ }
+ // Must be something weird
+ if (errorMessage)
+ *errorMessage = tr("The path '%1' is not a directory.").arg(path);
+ return false;
+}
+
+QString PathChooser::label()
+{
+ return tr("Path:");
+}
+
+QString PathChooser::homePath()
+{
+#ifdef Q_OS_WIN
+ // Return 'users/<name>/Documents' on Windows, since Windows explorer
+ // does not let people actually display the contents of their home
+ // directory. Alternatively, create a QtCreator-specific directory?
+ return QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation);
+#else
+ return QDir::homePath();
+#endif
+}
+
+}
+}
diff --git a/src/libs/utils/pathchooser.h b/src/libs/utils/pathchooser.h
new file mode 100644
index 00000000000..e09040c4c06
--- /dev/null
+++ b/src/libs/utils/pathchooser.h
@@ -0,0 +1,90 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#ifndef PATHCHOOSER_H
+#define PATHCHOOSER_H
+
+#include "utils_global.h"
+
+#include <QtGui/QWidget>
+
+namespace Core {
+namespace Utils {
+
+struct PathChooserPrivate;
+
+/* A Control that let's the user choose a path, consisting of a QLineEdit and
+ * a "Browse" button. Has some validation logic for embedding into
+ * QWizardPage. */
+
+class QWORKBENCH_UTILS_EXPORT PathChooser : public QWidget
+{
+ Q_DISABLE_COPY(PathChooser)
+ Q_OBJECT
+ Q_PROPERTY(QString path READ path WRITE setPath DESIGNABLE true)
+
+public:
+ explicit PathChooser(QWidget *parent = 0);
+ virtual ~PathChooser();
+
+ bool isValid() const;
+ QString errorMessage() const;
+
+ QString path() const;
+
+ // Returns the suggested label title when used in a form layout
+ static QString label();
+
+ static bool validatePath(const QString &path, QString *errorMessage = 0);
+
+ // Return the home directory, which needs some fixing under Windows.
+ static QString homePath();
+
+signals:
+ void validChanged();
+ void changed();
+ void returnPressed();
+
+public slots:
+ void setPath(const QString &);
+
+private slots:
+ void slotBrowse();
+
+private:
+ PathChooserPrivate *m_d;
+};
+
+}
+}
+
+#endif // PATHCHOOSER_H
diff --git a/src/libs/utils/projectintropage.cpp b/src/libs/utils/projectintropage.cpp
new file mode 100644
index 00000000000..bc17333fb97
--- /dev/null
+++ b/src/libs/utils/projectintropage.cpp
@@ -0,0 +1,215 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#include "projectintropage.h"
+#include "filewizardpage.h"
+#include "ui_projectintropage.h"
+
+#include <QtGui/QMessageBox>
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+
+namespace Core {
+namespace Utils {
+
+struct ProjectIntroPagePrivate
+{
+ ProjectIntroPagePrivate();
+ Ui::ProjectIntroPage m_ui;
+ bool m_complete;
+ // Status label style sheets
+ const QString m_errorStyleSheet;
+ const QString m_warningStyleSheet;
+ const QString m_hintStyleSheet;
+};
+
+ProjectIntroPagePrivate:: ProjectIntroPagePrivate() :
+ m_complete(false),
+ m_errorStyleSheet(QLatin1String("background : red;")),
+ m_warningStyleSheet(QLatin1String("background : yellow;")),
+ m_hintStyleSheet()
+{
+}
+
+ProjectIntroPage::ProjectIntroPage(QWidget *parent) :
+ QWizardPage(parent),
+ m_d(new ProjectIntroPagePrivate)
+{
+ m_d->m_ui.setupUi(this);
+ hideStatusLabel();
+ m_d->m_ui.nameLineEdit->setInitialText(tr("<Enter_Name>"));
+ m_d->m_ui.nameLineEdit->setFocus(Qt::TabFocusReason);
+ connect(m_d->m_ui.pathChooser, SIGNAL(changed()), this, SLOT(slotChanged()));
+ connect(m_d->m_ui.nameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotChanged()));
+ connect(m_d->m_ui.pathChooser, SIGNAL(returnPressed()), this, SLOT(slotActivated()));
+ connect(m_d->m_ui.nameLineEdit, SIGNAL(validReturnPressed()), this, SLOT(slotActivated()));
+}
+
+void ProjectIntroPage::insertControl(int row, QWidget *label, QWidget *control)
+{
+ m_d->m_ui.formLayout->insertRow(row, label, control);
+}
+
+ProjectIntroPage::~ProjectIntroPage()
+{
+ delete m_d;
+}
+
+QString ProjectIntroPage::name() const
+{
+ return m_d->m_ui.nameLineEdit->text();
+}
+
+QString ProjectIntroPage::path() const
+{
+ return m_d->m_ui.pathChooser->path();
+}
+
+void ProjectIntroPage::setPath(const QString &path)
+{
+ m_d->m_ui.pathChooser->setPath(path);
+}
+
+void ProjectIntroPage::setName(const QString &name)
+{
+ m_d->m_ui.nameLineEdit->setText(name);
+}
+
+QString ProjectIntroPage::description() const
+{
+ return m_d->m_ui.descriptionLabel->text();
+}
+
+void ProjectIntroPage::setDescription(const QString &description)
+{
+ m_d->m_ui.descriptionLabel->setText(description);
+}
+
+void ProjectIntroPage::changeEvent(QEvent *e)
+{
+ switch(e->type()) {
+ case QEvent::LanguageChange:
+ m_d->m_ui.retranslateUi(this);
+ break;
+ default:
+ break;
+ }
+}
+
+bool ProjectIntroPage::isComplete() const
+{
+ return m_d->m_complete;
+}
+
+bool ProjectIntroPage::validate()
+{
+ // Validate and display status
+ if (!m_d->m_ui.pathChooser->isValid()) {
+ displayStatusMessage(Error, m_d->m_ui.pathChooser->errorMessage());
+ return false;
+ }
+
+ // Name valid? Ignore 'DisplayingInitialText' state.
+ bool nameValid = false;
+ switch (m_d->m_ui.nameLineEdit->state()) {
+ case BaseValidatingLineEdit::Invalid:
+ displayStatusMessage(Error, m_d->m_ui.nameLineEdit->errorMessage());
+ return false;
+ case BaseValidatingLineEdit::DisplayingInitialText:
+ break;
+ case BaseValidatingLineEdit::Valid:
+ nameValid = true;
+ break;
+ }
+
+ // Check existence of the directory
+ QString projectDir = path();
+ projectDir += QDir::separator();
+ projectDir += m_d->m_ui.nameLineEdit->text();
+ const QFileInfo projectDirFile(projectDir);
+ if (!projectDirFile.exists()) { // All happy
+ hideStatusLabel();
+ return nameValid;
+ }
+
+ if (projectDirFile.isDir()) {
+ displayStatusMessage(Warning, tr("The project already exists."));
+ return nameValid;;
+ }
+ // 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();
+ if (newComplete != m_d->m_complete) {
+ m_d->m_complete = newComplete;
+ emit completeChanged();
+ }
+}
+
+void ProjectIntroPage::slotActivated()
+{
+ if (m_d->m_complete)
+ emit activated();
+}
+
+bool ProjectIntroPage::validateProjectDirectory(const QString &name, QString *errorMessage)
+{
+ return ProjectNameValidatingLineEdit::validateProjectName(name, errorMessage);
+}
+
+void ProjectIntroPage::displayStatusMessage(StatusLabelMode m, const QString &s)
+{
+ switch (m) {
+ case Error:
+ m_d->m_ui.stateLabel->setStyleSheet(m_d->m_errorStyleSheet);
+ break;
+ case Warning:
+ m_d->m_ui.stateLabel->setStyleSheet(m_d->m_warningStyleSheet);
+ break;
+ case Hint:
+ m_d->m_ui.stateLabel->setStyleSheet(m_d->m_hintStyleSheet);
+ break;
+ }
+ m_d->m_ui.stateLabel->setText(s);
+}
+
+void ProjectIntroPage::hideStatusLabel()
+{
+ displayStatusMessage(Hint, QString());
+}
+
+}
+}
diff --git a/src/libs/utils/projectintropage.h b/src/libs/utils/projectintropage.h
new file mode 100644
index 00000000000..56dcc253272
--- /dev/null
+++ b/src/libs/utils/projectintropage.h
@@ -0,0 +1,107 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#ifndef PROJECTINTROPAGE_H
+#define PROJECTINTROPAGE_H
+
+#include "utils_global.h"
+
+#include <QtGui/QWizardPage>
+
+namespace Core {
+namespace Utils {
+
+struct ProjectIntroPagePrivate;
+
+/* Standard wizard page for a single file letting the user choose name
+ * and path. Looks similar to FileWizardPage, but provides additional
+ * functionality:
+ * - Description label at the top for displaying introductory text
+ * - It does on the fly validation (connected to changed()) and displays
+ * warnings/errors in a status label at the bottom (the page is complete
+ * when fully validated, validatePage() is thus not implemented).
+ *
+ * Note: Careful when changing projectintropage.ui. It must have main
+ * geometry cleared and QLayout::SetMinimumSize constraint on the main
+ * layout, otherwise, QWizard will squeeze it due to its strange expanding
+ * hacks. */
+
+class QWORKBENCH_UTILS_EXPORT ProjectIntroPage : public QWizardPage {
+ Q_OBJECT
+ Q_DISABLE_COPY(ProjectIntroPage)
+ Q_PROPERTY(QString description READ description WRITE setPath DESIGNABLE true)
+ Q_PROPERTY(QString path READ path WRITE setPath DESIGNABLE true)
+ Q_PROPERTY(QString name READ name WRITE setName DESIGNABLE true)
+public:
+ explicit ProjectIntroPage(QWidget *parent = 0);
+ virtual ~ProjectIntroPage();
+
+ QString name() const;
+ QString path() const;
+ QString description() const;
+
+ // Insert an additional control into the form layout for the target.
+ void insertControl(int row, QWidget *label, QWidget *control);
+
+ virtual bool isComplete() const;
+
+ // Validate a project directory name entry field
+ static bool validateProjectDirectory(const QString &name, QString *errorMessage);
+
+signals:
+ void activated();
+
+public slots:
+ void setPath(const QString &path);
+ void setName(const QString &name);
+ void setDescription(const QString &description);
+
+private slots:
+ void slotChanged();
+ void slotActivated();
+
+protected:
+ virtual void changeEvent(QEvent *e);
+
+private:
+ enum StatusLabelMode { Error, Warning, Hint };
+
+ bool validate();
+ void displayStatusMessage(StatusLabelMode m, const QString &);
+ void hideStatusLabel();
+
+ ProjectIntroPagePrivate *m_d;
+};
+
+}
+}
+#endif // PROJECTINTROPAGE_H
diff --git a/src/libs/utils/projectintropage.ui b/src/libs/utils/projectintropage.ui
new file mode 100644
index 00000000000..f530b78044e
--- /dev/null
+++ b/src/libs/utils/projectintropage.ui
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Core::Utils::ProjectIntroPage</class>
+ <widget class="QWizardPage" name="Core::Utils::ProjectIntroPage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>208</width>
+ <height>143</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>WizardPage</string>
+ </property>
+ <property name="title">
+ <string>Introduction and project location</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetMinimumSize</enum>
+ </property>
+ <item>
+ <widget class="QLabel" name="descriptionLabel">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QFrame" name="frame">
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QFormLayout" name="formLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="nameLabel">
+ <property name="text">
+ <string>Name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="Core::Utils::ProjectNameValidatingLineEdit" name="nameLineEdit"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="pathLabel">
+ <property name="text">
+ <string>Path:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="Core::Utils::PathChooser" name="pathChooser" native="true"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="stateLabel">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>Core::Utils::PathChooser</class>
+ <extends>QWidget</extends>
+ <header>pathchooser.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>Core::Utils::ProjectNameValidatingLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>projectnamevalidatinglineedit.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/libs/utils/projectnamevalidatinglineedit.cpp b/src/libs/utils/projectnamevalidatinglineedit.cpp
new file mode 100644
index 00000000000..fb979d39345
--- /dev/null
+++ b/src/libs/utils/projectnamevalidatinglineedit.cpp
@@ -0,0 +1,66 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#include "projectnamevalidatinglineedit.h"
+#include "filenamevalidatinglineedit.h"
+
+namespace Core {
+namespace Utils {
+
+ProjectNameValidatingLineEdit::ProjectNameValidatingLineEdit(QWidget *parent) :
+ BaseValidatingLineEdit(parent)
+{
+}
+
+bool ProjectNameValidatingLineEdit::validateProjectName(const QString &name, QString *errorMessage /* = 0*/)
+{
+ // Validation is file name + checking for dots
+ if (!FileNameValidatingLineEdit::validateFileName(name, errorMessage))
+ return false;
+
+ // We don't want dots in the directory name for some legacy Windows
+ // reason. Since we are cross-platform, we generally disallow it.
+ if (name.contains(QLatin1Char('.'))) {
+ if (errorMessage)
+ *errorMessage = tr("The name must not contain the '.'-character.");
+ return false;
+ }
+ return true;
+}
+
+bool ProjectNameValidatingLineEdit::validate(const QString &value, QString *errorMessage) const
+{
+ return validateProjectName(value, errorMessage);
+}
+
+}
+}
diff --git a/src/libs/utils/projectnamevalidatinglineedit.h b/src/libs/utils/projectnamevalidatinglineedit.h
new file mode 100644
index 00000000000..c677cea1414
--- /dev/null
+++ b/src/libs/utils/projectnamevalidatinglineedit.h
@@ -0,0 +1,56 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#ifndef PROJECTNAMEVALIDATINGLINEEDIT_H
+#define PROJECTNAMEVALIDATINGLINEEDIT_H
+
+#include "basevalidatinglineedit.h"
+
+namespace Core {
+namespace Utils {
+
+class QWORKBENCH_UTILS_EXPORT ProjectNameValidatingLineEdit : public BaseValidatingLineEdit {
+ Q_OBJECT
+ Q_DISABLE_COPY(ProjectNameValidatingLineEdit)
+
+public:
+ explicit ProjectNameValidatingLineEdit(QWidget *parent = 0);
+
+ static bool validateProjectName(const QString &name, QString *errorMessage /* = 0*/);
+
+protected:
+ virtual bool validate(const QString &value, QString *errorMessage) const;
+};
+
+}
+}
+#endif // PROJECTNAMEVALIDATINGLINEEDIT_H
diff --git a/src/libs/utils/qtcolorbutton.cpp b/src/libs/utils/qtcolorbutton.cpp
new file mode 100644
index 00000000000..8b54bdda1d4
--- /dev/null
+++ b/src/libs/utils/qtcolorbutton.cpp
@@ -0,0 +1,290 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#include "qtcolorbutton.h"
+#include <QtGui/QColorDialog>
+#include <QtGui/QPainter>
+#include <QtCore/QMimeData>
+#include <QtGui/QDragEnterEvent>
+#include <QtGui/QApplication>
+
+namespace Core {
+namespace Utils {
+
+class QtColorButtonPrivate
+{
+ QtColorButton *q_ptr;
+ Q_DECLARE_PUBLIC(QtColorButton)
+public:
+ QColor m_color;
+#ifndef QT_NO_DRAGANDDROP
+ QColor m_dragColor;
+ QPoint m_dragStart;
+ bool m_dragging;
+#endif
+ bool m_backgroundCheckered;
+ bool m_alphaAllowed;
+
+ void slotEditColor();
+ QColor shownColor() const;
+ QPixmap generatePixmap() const;
+};
+
+void QtColorButtonPrivate::slotEditColor()
+{
+ QColor newColor;
+ if (m_alphaAllowed) {
+ bool ok;
+ const QRgb rgba = QColorDialog::getRgba(m_color.rgba(), &ok, q_ptr);
+ if (!ok)
+ return;
+ newColor = QColor::fromRgba(rgba);
+ } else {
+ newColor = QColorDialog::getColor(m_color, q_ptr);
+ if (!newColor.isValid())
+ return;
+ }
+ if (newColor == q_ptr->color())
+ return;
+ q_ptr->setColor(newColor);
+ emit q_ptr->colorChanged(m_color);
+}
+
+QColor QtColorButtonPrivate::shownColor() const
+{
+#ifndef QT_NO_DRAGANDDROP
+ if (m_dragging)
+ return m_dragColor;
+#endif
+ return m_color;
+}
+
+QPixmap QtColorButtonPrivate::generatePixmap() const
+{
+ QPixmap pix(24, 24);
+
+ int pixSize = 20;
+ QBrush br(shownColor());
+
+ QPixmap pm(2 * pixSize, 2 * pixSize);
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, pixSize, pixSize, Qt::lightGray);
+ pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::lightGray);
+ pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::darkGray);
+ pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::darkGray);
+ pmp.fillRect(0, 0, 2 * pixSize, 2 * pixSize, shownColor());
+ br = QBrush(pm);
+
+ QPainter p(&pix);
+ int corr = 1;
+ QRect r = pix.rect().adjusted(corr, corr, -corr, -corr);
+ p.setBrushOrigin((r.width() % pixSize + pixSize) / 2 + corr, (r.height() % pixSize + pixSize) / 2 + corr);
+ p.fillRect(r, br);
+
+ p.fillRect(r.width() / 4 + corr, r.height() / 4 + corr,
+ r.width() / 2, r.height() / 2,
+ QColor(shownColor().rgb()));
+ p.drawRect(pix.rect().adjusted(0, 0, -1, -1));
+
+ return pix;
+}
+
+///////////////
+
+QtColorButton::QtColorButton(QWidget *parent)
+ : QToolButton(parent)
+{
+ d_ptr = new QtColorButtonPrivate;
+ d_ptr->q_ptr = this;
+ d_ptr->m_dragging = false;
+ d_ptr->m_backgroundCheckered = true;
+ d_ptr->m_alphaAllowed = true;
+
+ setAcceptDrops(true);
+
+ connect(this, SIGNAL(clicked()), this, SLOT(slotEditColor()));
+ setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
+}
+
+QtColorButton::~QtColorButton()
+{
+ delete d_ptr;
+}
+
+void QtColorButton::setColor(const QColor &color)
+{
+ if (d_ptr->m_color == color)
+ return;
+ d_ptr->m_color = color;
+ update();
+}
+
+QColor QtColorButton::color() const
+{
+ return d_ptr->m_color;
+}
+
+void QtColorButton::setBackgroundCheckered(bool checkered)
+{
+ if (d_ptr->m_backgroundCheckered == checkered)
+ return;
+ d_ptr->m_backgroundCheckered = checkered;
+ update();
+}
+
+bool QtColorButton::isBackgroundCheckered() const
+{
+ return d_ptr->m_backgroundCheckered;
+}
+
+void QtColorButton::setAlphaAllowed(bool allowed)
+{
+ d_ptr->m_alphaAllowed = allowed;
+}
+
+bool QtColorButton::isAlphaAllowed() const
+{
+ return d_ptr->m_alphaAllowed;
+}
+
+void QtColorButton::paintEvent(QPaintEvent *event)
+{
+ QToolButton::paintEvent(event);
+ if (!isEnabled())
+ return;
+
+ const int pixSize = 10;
+ QBrush br(d_ptr->shownColor());
+ if (d_ptr->m_backgroundCheckered) {
+ QPixmap pm(2 * pixSize, 2 * pixSize);
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, pixSize, pixSize, Qt::white);
+ pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::white);
+ pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::black);
+ pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::black);
+ pmp.fillRect(0, 0, 2 * pixSize, 2 * pixSize, d_ptr->shownColor());
+ br = QBrush(pm);
+ }
+
+ QPainter p(this);
+ const int corr = 5;
+ QRect r = rect().adjusted(corr, corr, -corr, -corr);
+ p.setBrushOrigin((r.width() % pixSize + pixSize) / 2 + corr, (r.height() % pixSize + pixSize) / 2 + corr);
+ p.fillRect(r, br);
+
+ //const int adjX = qRound(r.width() / 4.0);
+ //const int adjY = qRound(r.height() / 4.0);
+ //p.fillRect(r.adjusted(adjX, adjY, -adjX, -adjY),
+ // QColor(d_ptr->shownColor().rgb()));
+ /*
+ p.fillRect(r.adjusted(0, r.height() * 3 / 4, 0, 0),
+ QColor(d_ptr->shownColor().rgb()));
+ p.fillRect(r.adjusted(0, 0, 0, -r.height() * 3 / 4),
+ QColor(d_ptr->shownColor().rgb()));
+ */
+ /*
+ const QColor frameColor0(0, 0, 0, qRound(0.2 * (0xFF - d_ptr->shownColor().alpha())));
+ p.setPen(frameColor0);
+ p.drawRect(r.adjusted(adjX, adjY, -adjX - 1, -adjY - 1));
+ */
+
+ const QColor frameColor1(0, 0, 0, 26);
+ p.setPen(frameColor1);
+ p.drawRect(r.adjusted(1, 1, -2, -2));
+ const QColor frameColor2(0, 0, 0, 51);
+ p.setPen(frameColor2);
+ p.drawRect(r.adjusted(0, 0, -1, -1));
+}
+
+void QtColorButton::mousePressEvent(QMouseEvent *event)
+{
+#ifndef QT_NO_DRAGANDDROP
+ if (event->button() == Qt::LeftButton)
+ d_ptr->m_dragStart = event->pos();
+#endif
+ QToolButton::mousePressEvent(event);
+}
+
+void QtColorButton::mouseMoveEvent(QMouseEvent *event)
+{
+#ifndef QT_NO_DRAGANDDROP
+ if (event->buttons() & Qt::LeftButton &&
+ (d_ptr->m_dragStart - event->pos()).manhattanLength() > QApplication::startDragDistance()) {
+ QMimeData *mime = new QMimeData;
+ mime->setColorData(color());
+ QDrag *drg = new QDrag(this);
+ drg->setMimeData(mime);
+ drg->setPixmap(d_ptr->generatePixmap());
+ setDown(false);
+ event->accept();
+ drg->start();
+ return;
+ }
+#endif
+ QToolButton::mouseMoveEvent(event);
+}
+
+#ifndef QT_NO_DRAGANDDROP
+void QtColorButton::dragEnterEvent(QDragEnterEvent *event)
+{
+ const QMimeData *mime = event->mimeData();
+ if (!mime->hasColor())
+ return;
+
+ event->accept();
+ d_ptr->m_dragColor = qvariant_cast<QColor>(mime->colorData());
+ d_ptr->m_dragging = true;
+ update();
+}
+
+void QtColorButton::dragLeaveEvent(QDragLeaveEvent *event)
+{
+ event->accept();
+ d_ptr->m_dragging = false;
+ update();
+}
+
+void QtColorButton::dropEvent(QDropEvent *event)
+{
+ event->accept();
+ d_ptr->m_dragging = false;
+ if (d_ptr->m_dragColor == color())
+ return;
+ setColor(d_ptr->m_dragColor);
+ emit colorChanged(color());
+}
+#endif
+
+} // namespace Utils
+} // namespace Core
+
+#include "moc_qtcolorbutton.cpp"
diff --git a/src/libs/utils/qtcolorbutton.h b/src/libs/utils/qtcolorbutton.h
new file mode 100644
index 00000000000..07355c883ec
--- /dev/null
+++ b/src/libs/utils/qtcolorbutton.h
@@ -0,0 +1,84 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#ifndef QTCOLORBUTTON_H
+#define QTCOLORBUTTON_H
+
+#include "utils_global.h"
+
+#include <QtGui/QToolButton>
+
+namespace Core {
+namespace Utils {
+
+class QWORKBENCH_UTILS_EXPORT QtColorButton : public QToolButton
+{
+ Q_OBJECT
+ Q_PROPERTY(bool backgroundCheckered READ isBackgroundCheckered WRITE setBackgroundCheckered)
+ Q_PROPERTY(bool alphaAllowed READ isAlphaAllowed WRITE setAlphaAllowed)
+public:
+ QtColorButton(QWidget *parent = 0);
+ ~QtColorButton();
+
+ bool isBackgroundCheckered() const;
+ void setBackgroundCheckered(bool checkered);
+
+ bool isAlphaAllowed() const;
+ void setAlphaAllowed(bool allowed);
+
+ QColor color() const;
+
+public slots:
+ void setColor(const QColor &color);
+
+signals:
+ void colorChanged(const QColor &color);
+protected:
+ void paintEvent(QPaintEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+#ifndef QT_NO_DRAGANDDROP
+ void dragEnterEvent(QDragEnterEvent *event);
+ void dragLeaveEvent(QDragLeaveEvent *event);
+ void dropEvent(QDropEvent *event);
+#endif
+private:
+ class QtColorButtonPrivate *d_ptr;
+ friend class QtColorButtonPrivate;
+ Q_DISABLE_COPY(QtColorButton)
+ Q_PRIVATE_SLOT(d_ptr, void slotEditColor())
+};
+
+} // namespace Utils
+} // namespace Core
+
+#endif // QTCOLORBUTTON_H
diff --git a/src/libs/utils/reloadpromptutils.cpp b/src/libs/utils/reloadpromptutils.cpp
new file mode 100644
index 00000000000..ca1d9e23ded
--- /dev/null
+++ b/src/libs/utils/reloadpromptutils.cpp
@@ -0,0 +1,62 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#include "reloadpromptutils.h"
+#include <QtGui/QMessageBox>
+
+using namespace Core;
+using namespace Core::Utils;
+
+QWORKBENCH_UTILS_EXPORT Core::Utils::ReloadPromptAnswer
+ Core::Utils::reloadPrompt(const QString &fileName, QWidget *parent)
+{
+ return reloadPrompt(QObject::tr("File Changed"),
+ QObject::tr("The file %1 has changed outside Qt Creator. Do you want to reload it?").arg(fileName),
+ parent);
+}
+
+QWORKBENCH_UTILS_EXPORT Core::Utils::ReloadPromptAnswer
+ Core::Utils::reloadPrompt(const QString &title, const QString &prompt, QWidget *parent)
+{
+ switch (QMessageBox::question(parent, title, prompt, QMessageBox::Yes|QMessageBox::YesToAll|QMessageBox::No|QMessageBox::NoToAll,
+ QMessageBox::YesToAll)) {
+ case QMessageBox::Yes:
+ return ReloadCurrent;
+ case QMessageBox::YesToAll:
+ return ReloadAll;
+ case QMessageBox::No:
+ return ReloadSkipCurrent;
+ default:
+ break;
+ }
+ return ReloadNone;
+}
diff --git a/src/libs/utils/reloadpromptutils.h b/src/libs/utils/reloadpromptutils.h
new file mode 100644
index 00000000000..deaf4b920a6
--- /dev/null
+++ b/src/libs/utils/reloadpromptutils.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#ifndef RELOADPROMPTUTILS_H
+#define RELOADPROMPTUTILS_H
+
+#include "utils_global.h"
+
+QT_BEGIN_NAMESPACE
+class QString;
+class QWidget;
+QT_END_NAMESPACE
+
+namespace Core {
+namespace Utils {
+
+enum ReloadPromptAnswer { ReloadCurrent, ReloadAll, ReloadSkipCurrent, ReloadNone };
+
+QWORKBENCH_UTILS_EXPORT ReloadPromptAnswer reloadPrompt(const QString &fileName, QWidget *parent);
+QWORKBENCH_UTILS_EXPORT ReloadPromptAnswer reloadPrompt(const QString &title, const QString &prompt, QWidget *parent);
+
+} // namespace Utils
+} // namespace Core
+
+#endif // RELOADPROMPTUTILS_H
diff --git a/src/libs/utils/settingsutils.cpp b/src/libs/utils/settingsutils.cpp
new file mode 100644
index 00000000000..ca8de01828e
--- /dev/null
+++ b/src/libs/utils/settingsutils.cpp
@@ -0,0 +1,53 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#include "settingsutils.h"
+#include <QtCore/QString>
+
+namespace Core {
+namespace Utils {
+
+QWORKBENCH_UTILS_EXPORT QString settingsKey(const QString &category)
+{
+ QString rc(category);
+ const QChar underscore = QLatin1Char('_');
+ const int size = rc.size();
+ for (int i = 0; i < size;i++) {
+ const QChar c = rc.at(i);
+ if (!c.isLetterOrNumber() && c != underscore)
+ rc[i] = underscore;
+ }
+ return rc;
+}
+
+}
+}
diff --git a/src/libs/utils/settingsutils.h b/src/libs/utils/settingsutils.h
new file mode 100644
index 00000000000..734a2f02f9d
--- /dev/null
+++ b/src/libs/utils/settingsutils.h
@@ -0,0 +1,48 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#ifndef SETTINGSTUTILS_H
+#define SETTINGSTUTILS_H
+
+#include "utils_global.h"
+
+namespace Core {
+namespace Utils {
+
+// Create a usable settings key from a category,
+// for example Editor|C++ -> Editor_C__
+QWORKBENCH_UTILS_EXPORT QString settingsKey(const QString &category);
+
+} // namespace Utils
+} // namespace Core
+
+#endif // SETTINGSTUTILS_H
diff --git a/src/libs/utils/submiteditorwidget.cpp b/src/libs/utils/submiteditorwidget.cpp
new file mode 100644
index 00000000000..aeafcd828d5
--- /dev/null
+++ b/src/libs/utils/submiteditorwidget.cpp
@@ -0,0 +1,305 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#include "submiteditorwidget.h"
+#include "ui_submiteditorwidget.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QPointer>
+
+enum { debug= 0 };
+
+namespace Core {
+namespace Utils {
+
+struct SubmitEditorWidgetPrivate {
+ SubmitEditorWidgetPrivate();
+
+ Ui::SubmitEditorWidget m_ui;
+ bool m_filesSelected;
+ bool m_filesChecked;
+};
+
+SubmitEditorWidgetPrivate::SubmitEditorWidgetPrivate() :
+ m_filesSelected(false),
+ m_filesChecked(false)
+{
+}
+
+SubmitEditorWidget::SubmitEditorWidget(QWidget *parent) :
+ QWidget(parent),
+ m_d(new SubmitEditorWidgetPrivate)
+{
+ m_d->m_ui.setupUi(this);
+ // File List
+ m_d->m_ui.fileList->setSelectionMode(QAbstractItemView::ExtendedSelection);
+ connect(m_d->m_ui.fileList, SIGNAL(itemActivated(QListWidgetItem*)), this, SLOT(triggerDiffSelected()));
+ connect(m_d->m_ui.fileList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(fileItemChanged(QListWidgetItem*)));
+ connect(m_d->m_ui.fileList, SIGNAL(itemSelectionChanged()), this, SLOT(fileSelectionChanged()));
+
+ // Text
+ m_d->m_ui.description->setFont(QFont(QLatin1String("Courier")));
+
+ setFocusPolicy(Qt::StrongFocus);
+ setFocusProxy(m_d->m_ui.description);
+}
+
+SubmitEditorWidget::~SubmitEditorWidget()
+{
+ delete m_d;
+}
+
+void SubmitEditorWidget::registerActions(QAction *editorUndoAction, QAction *editorRedoAction,
+ QAction *submitAction, QAction *diffAction)
+{
+ if (editorUndoAction) {
+ editorUndoAction->setEnabled(m_d->m_ui.description->document()->isUndoAvailable());
+ connect(m_d->m_ui.description, SIGNAL(undoAvailable(bool)), editorUndoAction, SLOT(setEnabled(bool)));
+ connect(editorUndoAction, SIGNAL(triggered()), m_d->m_ui.description, SLOT(undo()));
+ }
+ if (editorRedoAction) {
+ editorRedoAction->setEnabled(m_d->m_ui.description->document()->isRedoAvailable());
+ connect(m_d->m_ui.description, SIGNAL(redoAvailable(bool)), editorRedoAction, SLOT(setEnabled(bool)));
+ connect(editorRedoAction, SIGNAL(triggered()), m_d->m_ui.description, SLOT(redo()));
+ }
+
+ if (submitAction) {
+ if (debug)
+ qDebug() << submitAction << m_d->m_ui.fileList->count() << "items" << m_d->m_filesChecked;
+ submitAction->setEnabled(m_d->m_filesChecked);
+ connect(this, SIGNAL(fileCheckStateChanged(bool)), submitAction, SLOT(setEnabled(bool)));
+ }
+ if (diffAction) {
+ if (debug)
+ qDebug() << diffAction << m_d->m_filesSelected;
+ diffAction->setEnabled(m_d->m_filesSelected);
+ connect(this, SIGNAL(fileSelectionChanged(bool)), diffAction, SLOT(setEnabled(bool)));
+ connect(diffAction, SIGNAL(triggered()), this, SLOT(triggerDiffSelected()));
+ }
+}
+
+void SubmitEditorWidget::unregisterActions(QAction *editorUndoAction, QAction *editorRedoAction,
+ QAction *submitAction, QAction *diffAction)
+{
+ if (editorUndoAction) {
+ disconnect(m_d->m_ui.description, SIGNAL(undoAvailableChanged(bool)), editorUndoAction, SLOT(setEnabled(bool)));
+ disconnect(editorUndoAction, SIGNAL(triggered()), m_d->m_ui.description, SLOT(undo()));
+ }
+ if (editorRedoAction) {
+ disconnect(m_d->m_ui.description, SIGNAL(redoAvailableChanged(bool)), editorRedoAction, SLOT(setEnabled(bool)));
+ disconnect(editorRedoAction, SIGNAL(triggered()), m_d->m_ui.description, SLOT(redo()));
+ }
+
+ if (submitAction)
+ disconnect(this, SIGNAL(fileCheckStateChanged(bool)), submitAction, SLOT(setEnabled(bool)));
+
+ if (diffAction) {
+ disconnect(this, SIGNAL(fileSelectionChanged(bool)), diffAction, SLOT(setEnabled(bool)));
+ disconnect(diffAction, SIGNAL(triggered()), this, SLOT(triggerDiffSelected()));
+ }
+}
+
+
+QString SubmitEditorWidget::trimmedDescriptionText() const
+{
+ // Make sure we have one terminating NL
+ QString text = descriptionText().trimmed();
+ text += QLatin1Char('\n');
+ return text;
+}
+
+QString SubmitEditorWidget::descriptionText() const
+{
+ return m_d->m_ui.description->toPlainText();
+}
+
+void SubmitEditorWidget::setDescriptionText(const QString &text)
+{
+ m_d->m_ui.description->setPlainText(text);
+}
+
+QStringList SubmitEditorWidget::fileList() const
+{
+ QStringList rc;
+ const int count = m_d->m_ui.fileList->count();
+ for (int i = 0; i < count; i++)
+ rc.push_back(m_d->m_ui.fileList->item(i)->text());
+ return rc;
+}
+
+void SubmitEditorWidget::addFilesUnblocked(const QStringList &list, bool checked, bool userCheckable)
+{
+ if (debug)
+ qDebug() << Q_FUNC_INFO << list << checked << userCheckable;
+ foreach (const QString &f, list) {
+ QListWidgetItem *item = new QListWidgetItem(f);
+ item->setCheckState(checked ? Qt::Checked : Qt::Unchecked);
+ if (!userCheckable)
+ item->setFlags(item->flags() & ~Qt::ItemIsUserCheckable);
+ m_d->m_ui.fileList->addItem(item);
+ }
+}
+
+void SubmitEditorWidget::addFiles(const QStringList &list, bool checked, bool userCheckable)
+{
+ if (list.empty())
+ return;
+
+ const bool blocked = m_d->m_ui.fileList->blockSignals(true);
+ addFilesUnblocked(list, checked, userCheckable);
+ m_d->m_ui.fileList->blockSignals(blocked);
+ // Did we gain any checked files..update action accordingly
+ if (!m_d->m_filesChecked && checked) {
+ m_d->m_filesChecked = true;
+ emit fileCheckStateChanged(m_d->m_filesChecked);
+ }
+}
+
+void SubmitEditorWidget::setFileList(const QStringList &list)
+{
+ // Trigger enabling of menu action
+ m_d->m_ui.fileList->clearSelection();
+
+ const bool blocked = m_d->m_ui.fileList->blockSignals(true);
+ m_d->m_ui.fileList->clear();
+ if (!list.empty()) {
+ addFilesUnblocked(list, true, true);
+ // Checked files added?
+ if (!m_d->m_filesChecked) {
+ m_d->m_filesChecked = true;
+ emit fileCheckStateChanged(m_d->m_filesChecked);
+ }
+ }
+ m_d->m_ui.fileList->blockSignals(blocked);
+}
+
+static bool containsCheckState(const QListWidget *lw, Qt::CheckState cs)
+{
+ const int count = lw->count();
+ for (int i = 0; i < count; i++)
+ if (lw->item(i)->checkState() == cs)
+ return true;
+ return false;
+}
+
+QStringList SubmitEditorWidget::selectedFiles() const
+{
+ QStringList rc;
+ const int count = m_d->m_ui.fileList->count();
+ for (int i = 0; i < count; i++) {
+ const QListWidgetItem *item = m_d->m_ui.fileList->item(i);
+ if (item->isSelected())
+ rc.push_back(item->text());
+ }
+ return rc;
+}
+
+QStringList SubmitEditorWidget::checkedFiles() const
+{
+ QStringList rc;
+ const int count = m_d->m_ui.fileList->count();
+ for (int i = 0; i < count; i++) {
+ const QListWidgetItem *item = m_d->m_ui.fileList->item(i);
+ if (item->checkState() == Qt::Checked)
+ rc.push_back(item->text());
+ }
+ return rc;
+}
+
+QPlainTextEdit *SubmitEditorWidget::descriptionEdit() const
+{
+ return m_d->m_ui.description;
+}
+
+void SubmitEditorWidget::triggerDiffSelected()
+{
+ const QStringList sel = selectedFiles();
+ if (!sel.empty())
+ emit diffSelected(sel);
+}
+
+void SubmitEditorWidget::fileItemChanged(QListWidgetItem *item)
+{
+ const Qt::CheckState st = item->checkState();
+ if (debug)
+ qDebug() << Q_FUNC_INFO << st << item->text() << m_d->m_filesChecked;
+ // Enable the actions according to check state
+ switch (st) {
+ case Qt::Unchecked: // Item was unchecked: Any checked items left?
+ if (m_d->m_filesChecked && !containsCheckState(m_d->m_ui.fileList, Qt::Checked)) {
+ m_d->m_filesChecked = false;
+ emit fileCheckStateChanged(m_d->m_filesChecked);
+ }
+ break;
+ case Qt::Checked:
+ // Item was Checked. First one?
+ if (!m_d->m_filesChecked) {
+ m_d->m_filesChecked = true;
+ emit fileCheckStateChanged(m_d->m_filesChecked);
+ }
+ break;
+ case Qt::PartiallyChecked: // Errm?
+ break;
+ }
+}
+
+void SubmitEditorWidget::fileSelectionChanged()
+{
+ const bool newFilesSelected = !m_d->m_ui.fileList->selectedItems().empty();
+ if (debug)
+ qDebug() << Q_FUNC_INFO << newFilesSelected;
+ if (m_d->m_filesSelected != newFilesSelected) {
+ m_d->m_filesSelected = newFilesSelected;
+ emit fileSelectionChanged(m_d->m_filesSelected);
+ if (debug)
+ qDebug() << Q_FUNC_INFO << m_d->m_filesSelected;
+ }
+}
+
+void SubmitEditorWidget::changeEvent(QEvent *e)
+{
+ switch(e->type()) {
+ case QEvent::LanguageChange:
+ m_d->m_ui.retranslateUi(this);
+ break;
+ default:
+ break;
+ }
+}
+
+void SubmitEditorWidget::insertTopWidget(QWidget *w)
+{
+ m_d->m_ui.vboxLayout->insertWidget(0, w);
+}
+
+} // namespace Utils
+} // namespace Core
diff --git a/src/libs/utils/submiteditorwidget.h b/src/libs/utils/submiteditorwidget.h
new file mode 100644
index 00000000000..3c40ccecba7
--- /dev/null
+++ b/src/libs/utils/submiteditorwidget.h
@@ -0,0 +1,122 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#ifndef SUBMITEDITORWIDGET_H
+#define SUBMITEDITORWIDGET_H
+
+#include "utils_global.h"
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+class QPlainTextEdit;
+class QListWidgetItem;
+class QAction;
+QT_END_NAMESPACE
+
+namespace Core {
+namespace Utils {
+
+struct SubmitEditorWidgetPrivate;
+
+/* The submit editor presents the commit message in a text editor and an
+ * checkable list of modified files in a list window. The user can delete
+ * files from the list by pressing unchecking them or diff the selection
+ * by doubleclicking.
+ *
+ * Additionally, standard creator actions can be registered:
+ * Undo/redo will be set up to work with the description editor.
+ * Submit will be set up to be enabled according to checkstate.
+ * Diff will be set up to trigger diffSelected().
+ *
+ * Note that the actions are connected by signals; in the rare event that there
+ * are several instances of the SubmitEditorWidget belonging to the same
+ * context active, the actions must be registered/unregistered in the editor
+ * change event.
+ * Care should be taken to ensure the widget is deleted properly when the
+ * editor closes. */
+
+class QWORKBENCH_UTILS_EXPORT SubmitEditorWidget : public QWidget {
+ Q_OBJECT
+ Q_DISABLE_COPY(SubmitEditorWidget)
+ Q_PROPERTY(QString descriptionText READ descriptionText WRITE setDescriptionText DESIGNABLE true)
+ Q_PROPERTY(QStringList fileList READ fileList WRITE setFileList DESIGNABLE true)
+public:
+ explicit SubmitEditorWidget(QWidget *parent = 0);
+ virtual ~SubmitEditorWidget();
+
+ void registerActions(QAction *editorUndoAction, QAction *editorRedoAction,
+ QAction *submitAction = 0, QAction *diffAction = 0);
+ void unregisterActions(QAction *editorUndoAction, QAction *editorRedoAction,
+ QAction *submitAction = 0, QAction *diffAction = 0);
+
+ QString descriptionText() const;
+ void setDescriptionText(const QString &text);
+ // Should be used to normalize newlines.
+ QString trimmedDescriptionText() const;
+
+ // The raw file list
+ QStringList fileList() const;
+ void addFiles(const QStringList&, bool checked = true, bool userCheckable = true);
+ void setFileList(const QStringList&);
+
+ // Files to be included in submit
+ QStringList checkedFiles() const;
+
+ // Selected files for diff
+ QStringList selectedFiles() const;
+
+ QPlainTextEdit *descriptionEdit() const;
+
+signals:
+ void diffSelected(const QStringList &);
+ void fileSelectionChanged(bool someFileSelected);
+ void fileCheckStateChanged(bool someFileChecked);
+
+protected:
+ virtual void changeEvent(QEvent *e);
+ void insertTopWidget(QWidget *w);
+
+private slots:
+ void triggerDiffSelected();
+ void fileItemChanged(QListWidgetItem *);
+ void fileSelectionChanged();
+
+private:
+ void addFilesUnblocked(const QStringList &list, bool checked, bool userCheckable);
+
+ SubmitEditorWidgetPrivate *m_d;
+};
+
+}
+}
+#endif // SUBMITEDITORWIDGET_H
diff --git a/src/libs/utils/submiteditorwidget.ui b/src/libs/utils/submiteditorwidget.ui
new file mode 100644
index 00000000000..1a30e8b7919
--- /dev/null
+++ b/src/libs/utils/submiteditorwidget.ui
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Core::Utils::SubmitEditorWidget</class>
+ <widget class="QWidget" name="Core::Utils::SubmitEditorWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>582</width>
+ <height>502</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Subversion Submit</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QGroupBox" name="descriptionBox">
+ <property name="title">
+ <string>Des&amp;cription</string>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <widget class="QPlainTextEdit" name="description">
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>F&amp;iles</string>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <widget class="QListWidget" name="fileList">
+ <property name="font">
+ <font/>
+ </property>
+ <property name="textElideMode">
+ <enum>Qt::ElideNone</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/libs/utils/synchronousprocess.cpp b/src/libs/utils/synchronousprocess.cpp
new file mode 100644
index 00000000000..71bcdffb6cc
--- /dev/null
+++ b/src/libs/utils/synchronousprocess.cpp
@@ -0,0 +1,356 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+
+#include "synchronousprocess.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QTimer>
+#include <QtCore/QEventLoop>
+#include <QtCore/QTextCodec>
+
+#include <QtGui/QApplication>
+
+enum { debug = 0 };
+
+enum { defaultMaxHangTimerCount = 10 };
+
+namespace Core {
+namespace Utils {
+
+// ----------- SynchronousProcessResponse
+SynchronousProcessResponse::SynchronousProcessResponse() :
+ result(StartFailed),
+ exitCode(-1)
+{
+}
+
+void SynchronousProcessResponse::clear()
+{
+ result = StartFailed;
+ exitCode = -1;
+ stdOut.clear();
+ stdErr.clear();
+}
+
+QWORKBENCH_UTILS_EXPORT QDebug operator<<(QDebug str, const SynchronousProcessResponse& r)
+{
+ QDebug nsp = str.nospace();
+ nsp << "SynchronousProcessResponse: result=" << r.result << " ex=" << r.exitCode << '\n'
+ << r.stdOut.size() << " bytes stdout, stderr=" << r.stdErr << '\n';
+ return str;
+}
+
+// Data for one channel buffer (stderr/stdout)
+struct ChannelBuffer {
+ ChannelBuffer();
+ void clearForRun();
+ QByteArray linesRead();
+
+ QByteArray data;
+ bool firstData;
+ bool bufferedSignalsEnabled;
+ bool firstBuffer;
+ int bufferPos;
+};
+
+ChannelBuffer::ChannelBuffer() :
+ firstData(true),
+ bufferedSignalsEnabled(false),
+ firstBuffer(true),
+ bufferPos(0)
+{
+}
+
+void ChannelBuffer::clearForRun()
+{
+ firstData = true;
+ firstBuffer = true;
+ bufferPos = 0;
+}
+
+/* Check for complete lines read from the device and return them, moving the
+ * buffer position. This is based on the assumption that '\n' is the new line
+ * marker in any sane codec. */
+QByteArray ChannelBuffer::linesRead()
+{
+ // Any new lines?
+ const int lastLineIndex = data.lastIndexOf('\n');
+ if (lastLineIndex == -1 || lastLineIndex <= bufferPos)
+ return QByteArray();
+ const int nextBufferPos = lastLineIndex + 1;
+ const QByteArray lines = data.mid(bufferPos, nextBufferPos - bufferPos);
+ bufferPos = nextBufferPos;
+ return lines;
+}
+
+// ----------- SynchronousProcessPrivate
+struct SynchronousProcessPrivate {
+ SynchronousProcessPrivate();
+ void clearForRun();
+
+ QTextCodec *m_stdOutCodec;
+ QProcess m_process;
+ QTimer m_timer;
+ QEventLoop m_eventLoop;
+ SynchronousProcessResponse m_result;
+ int m_hangTimerCount;
+ int m_maxHangTimerCount;
+
+ ChannelBuffer m_stdOut;
+ ChannelBuffer m_stdErr;
+};
+
+SynchronousProcessPrivate::SynchronousProcessPrivate() :
+ m_stdOutCodec(0),
+ m_hangTimerCount(0),
+ m_maxHangTimerCount(defaultMaxHangTimerCount)
+{
+}
+
+void SynchronousProcessPrivate::clearForRun()
+{
+ m_hangTimerCount = 0;
+ m_stdOut.clearForRun();
+ m_stdErr.clearForRun();
+ m_result.clear();
+}
+
+// ----------- SynchronousProcess
+SynchronousProcess::SynchronousProcess() :
+ m_d(new SynchronousProcessPrivate)
+{
+ m_d->m_timer.setInterval(1000);
+ connect(&m_d->m_timer, SIGNAL(timeout()), this, SLOT(slotTimeout()));
+ connect(&m_d->m_process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(finished(int,QProcess::ExitStatus)));
+ connect(&m_d->m_process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(error(QProcess::ProcessError)));
+ connect(&m_d->m_process, SIGNAL(readyReadStandardOutput()),
+ this, SLOT(stdOutReady()));
+ connect(&m_d->m_process, SIGNAL(readyReadStandardError()),
+ this, SLOT(stdErrReady()));
+}
+
+SynchronousProcess::~SynchronousProcess()
+{
+ delete m_d;
+}
+
+void SynchronousProcess::setTimeout(int timeoutMS)
+{
+ m_d->m_maxHangTimerCount = qMax(2, timeoutMS / 1000);
+}
+
+int SynchronousProcess::timeout() const
+{
+ return 1000 * m_d->m_maxHangTimerCount;
+}
+
+void SynchronousProcess::setStdOutCodec(QTextCodec *c)
+{
+ m_d->m_stdOutCodec = c;
+}
+
+QTextCodec *SynchronousProcess::stdOutCodec() const
+{
+ return m_d->m_stdOutCodec;
+}
+
+bool SynchronousProcess::stdOutBufferedSignalsEnabled() const
+{
+ return m_d->m_stdOut.bufferedSignalsEnabled;
+}
+
+void SynchronousProcess::setStdOutBufferedSignalsEnabled(bool v)
+{
+ m_d->m_stdOut.bufferedSignalsEnabled = v;
+}
+
+bool SynchronousProcess::stdErrBufferedSignalsEnabled() const
+{
+ return m_d->m_stdErr.bufferedSignalsEnabled;
+}
+
+void SynchronousProcess::setStdErrBufferedSignalsEnabled(bool v)
+{
+ m_d->m_stdErr.bufferedSignalsEnabled = v;
+}
+
+QStringList SynchronousProcess::environment() const
+{
+ return m_d->m_process.environment();
+}
+
+void SynchronousProcess::setEnvironment(const QStringList &e)
+{
+ m_d->m_process.setEnvironment(e);
+}
+
+SynchronousProcessResponse SynchronousProcess::run(const QString &binary,
+ const QStringList &args)
+{
+ if (debug)
+ qDebug() << '>' << Q_FUNC_INFO << binary << args;
+
+ m_d->clearForRun();
+ m_d->m_timer.start();
+
+ QApplication::setOverrideCursor(Qt::WaitCursor);
+
+ m_d->m_process.start(binary, args, QIODevice::ReadOnly);
+ m_d->m_eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
+ if (m_d->m_result.result == SynchronousProcessResponse::Finished || m_d->m_result.result == SynchronousProcessResponse::FinishedError) {
+ processStdOut(false);
+ processStdErr(false);
+ }
+
+ m_d->m_result.stdOut = convertStdOut(m_d->m_stdOut.data);
+ m_d->m_result.stdErr = convertStdErr(m_d->m_stdErr.data);
+
+ m_d->m_timer.stop();
+ QApplication::restoreOverrideCursor();
+
+ if (debug)
+ qDebug() << '<' << Q_FUNC_INFO << binary << m_d->m_result;
+ return m_d->m_result;
+}
+
+void SynchronousProcess::slotTimeout()
+{
+ if (++m_d->m_hangTimerCount > m_d->m_maxHangTimerCount) {
+ m_d->m_process.kill();
+ m_d->m_result.result = SynchronousProcessResponse::Hang;
+ }
+
+ if (debug)
+ qDebug() << Q_FUNC_INFO << m_d->m_hangTimerCount;
+}
+
+void SynchronousProcess::finished(int exitCode, QProcess::ExitStatus e)
+{
+ if (debug)
+ qDebug() << Q_FUNC_INFO << exitCode << e;
+ m_d->m_hangTimerCount = 0;
+ switch (e) {
+ case QProcess::NormalExit:
+ m_d->m_result.result = exitCode ? SynchronousProcessResponse::FinishedError : SynchronousProcessResponse::Finished;
+ m_d->m_result.exitCode = exitCode;
+ break;
+ case QProcess::CrashExit:
+ m_d->m_result.result = SynchronousProcessResponse::TerminatedAbnormally;
+ m_d->m_result.exitCode = -1;
+ break;
+ }
+ m_d->m_eventLoop.quit();
+}
+
+void SynchronousProcess::error(QProcess::ProcessError e)
+{
+ m_d->m_hangTimerCount = 0;
+ if (debug)
+ qDebug() << Q_FUNC_INFO << e;
+ m_d->m_result.result = SynchronousProcessResponse::StartFailed;
+ m_d->m_eventLoop.quit();
+}
+
+void SynchronousProcess::stdOutReady()
+{
+ m_d->m_hangTimerCount = 0;
+ processStdOut(true);
+}
+
+void SynchronousProcess::stdErrReady()
+{
+ m_d->m_hangTimerCount = 0;
+ processStdErr(true);
+}
+
+QString SynchronousProcess::convertStdErr(const QByteArray &ba)
+{
+ return QString::fromLocal8Bit(ba).remove(QLatin1Char('\r'));
+}
+
+QString SynchronousProcess::convertStdOut(const QByteArray &ba) const
+{
+ QString stdOut = m_d->m_stdOutCodec ? m_d->m_stdOutCodec->toUnicode(ba) : QString::fromLocal8Bit(ba);
+ return stdOut.remove(QLatin1Char('\r'));
+}
+
+void SynchronousProcess::processStdOut(bool emitSignals)
+{
+ // Handle binary data
+ const QByteArray ba = m_d->m_process.readAllStandardOutput();
+ if (debug > 1)
+ qDebug() << Q_FUNC_INFO << emitSignals << ba;
+ if (!ba.isEmpty()) {
+ m_d->m_stdOut.data += ba;
+ if (emitSignals) {
+ // Emit binary signals
+ emit stdOut(ba, m_d->m_stdOut.firstData);
+ m_d->m_stdOut.firstData = false;
+ // Buffered. Emit complete lines?
+ if (m_d->m_stdOut.bufferedSignalsEnabled) {
+ const QByteArray lines = m_d->m_stdOut.linesRead();
+ if (!lines.isEmpty()) {
+ emit stdOutBuffered(convertStdOut(lines), m_d->m_stdOut.firstBuffer);
+ m_d->m_stdOut.firstBuffer = false;
+ }
+ }
+ }
+ }
+}
+
+void SynchronousProcess::processStdErr(bool emitSignals)
+{
+ // Handle binary data
+ const QByteArray ba = m_d->m_process.readAllStandardError();
+ if (debug > 1)
+ qDebug() << Q_FUNC_INFO << emitSignals << ba;
+ if (!ba.isEmpty()) {
+ m_d->m_stdErr.data += ba;
+ if (emitSignals) {
+ // Emit binary signals
+ emit stdErr(ba, m_d->m_stdErr.firstData);
+ m_d->m_stdErr.firstData = false;
+ if (m_d->m_stdErr.bufferedSignalsEnabled) {
+ // Buffered. Emit complete lines?
+ const QByteArray lines = m_d->m_stdErr.linesRead();
+ if (!lines.isEmpty()) {
+ emit stdErrBuffered(convertStdErr(lines), m_d->m_stdErr.firstBuffer);
+ m_d->m_stdErr.firstBuffer = false;
+ }
+ }
+ }
+ }
+}
+
+}
+}
diff --git a/src/libs/utils/synchronousprocess.h b/src/libs/utils/synchronousprocess.h
new file mode 100644
index 00000000000..9458655d6bf
--- /dev/null
+++ b/src/libs/utils/synchronousprocess.h
@@ -0,0 +1,139 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#ifndef SYNCHRONOUSPROCESS_H
+#define SYNCHRONOUSPROCESS_H
+
+#include <QtCore/QObject>
+#include <QtCore/QProcess>
+#include <QtCore/QStringList>
+
+#include "utils_global.h"
+
+QT_BEGIN_NAMESPACE
+class QTextCodec;
+class QDebug;
+class QByteArray;
+QT_END_NAMESPACE
+
+namespace Core {
+namespace Utils {
+
+struct SynchronousProcessPrivate;
+
+/* Result of SynchronousProcess execution */
+struct QWORKBENCH_UTILS_EXPORT SynchronousProcessResponse {
+ enum Result {
+ // Finished with return code 0
+ Finished,
+ // Finished with return code != 0
+ FinishedError,
+ // Process terminated abnormally (kill)
+ TerminatedAbnormally,
+ // Executable could not be started
+ StartFailed,
+ // Hang, no output after time out
+ Hang };
+
+ SynchronousProcessResponse();
+ void clear();
+
+ Result result;
+ int exitCode;
+ QString stdOut;
+ QString stdErr;
+};
+
+QWORKBENCH_UTILS_EXPORT QDebug operator<<(QDebug str, const SynchronousProcessResponse &);
+
+/* SynchronousProcess: Runs a synchronous process in its own event loop
+ * that blocks only user input events. Thus, it allows for the gui to
+ * repaint and append output to log windows.
+ *
+ * The stdOut(), stdErr() signals are emitted unbuffered as the process
+ * writes them.
+ *
+ * The stdOutBuffered(), stdErrBuffered() signals are emitted with complete
+ * lines based on the '\n' marker if they are enabled using
+ * stdOutBufferedSignalsEnabled()/setStdErrBufferedSignalsEnabled().
+ * They would typically be used for log windows. */
+
+class QWORKBENCH_UTILS_EXPORT SynchronousProcess : public QObject {
+ Q_OBJECT
+public:
+ SynchronousProcess();
+ virtual ~SynchronousProcess();
+
+ /* Timeout for hanging processes (no reaction on stderr/stdout)*/
+ void setTimeout(int timeoutMS);
+ int timeout() const;
+
+ void setStdOutCodec(QTextCodec *c);
+ QTextCodec *stdOutCodec() const;
+
+ bool stdOutBufferedSignalsEnabled() const;
+ void setStdOutBufferedSignalsEnabled(bool);
+
+ bool stdErrBufferedSignalsEnabled() const;
+ void setStdErrBufferedSignalsEnabled(bool);
+
+ QStringList environment() const;
+ void setEnvironment(const QStringList &);
+
+ SynchronousProcessResponse run(const QString &binary, const QStringList &args);
+
+signals:
+ void stdOut(const QByteArray &data, bool firstTime);
+ void stdErr(const QByteArray &data, bool firstTime);
+
+ void stdOutBuffered(const QString &data, bool firstTime);
+ void stdErrBuffered(const QString &data, bool firstTime);
+
+private slots:
+ void slotTimeout();
+ void finished(int exitCode, QProcess::ExitStatus e);
+ void error(QProcess::ProcessError);
+ void stdOutReady();
+ void stdErrReady();
+
+private:
+ void processStdOut(bool emitSignals);
+ void processStdErr(bool emitSignals);
+ static QString convertStdErr(const QByteArray &);
+ QString convertStdOut(const QByteArray &) const;
+
+ SynchronousProcessPrivate *m_d;
+};
+
+}
+}
+#endif
diff --git a/src/libs/utils/utils.pri b/src/libs/utils/utils.pri
new file mode 100644
index 00000000000..4e173f2cad1
--- /dev/null
+++ b/src/libs/utils/utils.pri
@@ -0,0 +1 @@
+LIBS *= -l$$qtLibraryTarget(Utils)
diff --git a/src/libs/utils/utils.pro b/src/libs/utils/utils.pro
new file mode 100644
index 00000000000..d98ca1d889b
--- /dev/null
+++ b/src/libs/utils/utils.pro
@@ -0,0 +1,53 @@
+TEMPLATE = lib
+TARGET = Utils
+
+DEFINES += QWORKBENCH_UTILS_LIBRARY
+
+include(../../qworkbenchlibrary.pri)
+
+SOURCES += \
+ reloadpromptutils.cpp \
+ settingsutils.cpp \
+ filesearch.cpp \
+ pathchooser.cpp \
+ filewizardpage.cpp \
+ filewizarddialog.cpp \
+ projectintropage.cpp \
+ basevalidatinglineedit.cpp \
+ filenamevalidatinglineedit.cpp \
+ projectnamevalidatinglineedit.cpp \
+ codegeneration.cpp \
+ newclasswidget.cpp \
+ classnamevalidatinglineedit.cpp \
+ linecolumnlabel.cpp \
+ fancylineedit.cpp \
+ qtcolorbutton.cpp \
+ submiteditorwidget.cpp \
+ synchronousprocess.cpp
+
+HEADERS += \
+ utils_global.h \
+ reloadpromptutils.h \
+ settingsutils.h \
+ filesearch.h \
+ listutils.h \
+ pathchooser.h \
+ filewizardpage.h \
+ filewizarddialog.h \
+ projectintropage.h \
+ basevalidatinglineedit.h \
+ filenamevalidatinglineedit.h \
+ projectnamevalidatinglineedit.h \
+ codegeneration.h \
+ newclasswidget.h \
+ classnamevalidatinglineedit.h \
+ linecolumnlabel.h \
+ fancylineedit.h \
+ qtcolorbutton.h \
+ submiteditorwidget.h \
+ synchronousprocess.h
+
+FORMS += filewizardpage.ui \
+ projectintropage.ui \
+ newclasswidget.ui \
+ submiteditorwidget.ui
diff --git a/src/libs/utils/utils_global.h b/src/libs/utils/utils_global.h
new file mode 100644
index 00000000000..3a91f77a2b9
--- /dev/null
+++ b/src/libs/utils/utils_global.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** 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
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** 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
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+/****************************************************************************
+**
+** Copyright (C) 1992-$THISYEAR$ Trolltech AS. All rights reserved.
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $LICENSE$
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#ifndef UTILS_GLOBAL_H
+#define UTILS_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+#if defined(QWORKBENCH_UTILS_LIBRARY)
+# define QWORKBENCH_UTILS_EXPORT Q_DECL_EXPORT
+#else
+# define QWORKBENCH_UTILS_EXPORT Q_DECL_IMPORT
+#endif
+
+#endif // UTILS_GLOBAL_H