forked from qt-creator/qt-creator
Fixes: Add common configuration to the VCSA base plugin; submit message check script and user name configuration. Details: Extend submit editor widget by configureable fields. Use them in the VCS base submit editor to specify users, provide completion and selection dialog for them.
This commit is contained in:
251
src/plugins/vcsbase/nicknamedialog.cpp
Normal file
251
src/plugins/vcsbase/nicknamedialog.cpp
Normal file
@@ -0,0 +1,251 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at qt-sales@nokia.com.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "nicknamedialog.h"
|
||||
#include "ui_nicknamedialog.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtGui/QPushButton>
|
||||
#include <QtGui/QStandardItemModel>
|
||||
#include <QtGui/QSortFilterProxyModel>
|
||||
|
||||
namespace VCSBase {
|
||||
namespace Internal {
|
||||
|
||||
struct NickEntry {
|
||||
void clear();
|
||||
bool parse(const QString &);
|
||||
QString nickName() const;
|
||||
|
||||
QString name;
|
||||
QString email;
|
||||
QString aliasName;
|
||||
QString aliasEmail;
|
||||
};
|
||||
|
||||
void NickEntry::clear()
|
||||
{
|
||||
name.clear();
|
||||
email.clear();
|
||||
aliasName.clear();
|
||||
aliasEmail.clear();
|
||||
}
|
||||
|
||||
// Parse "Hans Mustermann <HM@acme.de> [Alias [<alias@acme.de>]]"
|
||||
|
||||
bool NickEntry::parse(const QString &l)
|
||||
{
|
||||
clear();
|
||||
const QChar lessThan = QLatin1Char('<');
|
||||
const QChar greaterThan = QLatin1Char('>');
|
||||
// Get first name/mail pair
|
||||
int mailPos = l.indexOf(lessThan);
|
||||
if (mailPos == -1)
|
||||
return false;
|
||||
name = l.mid(0, mailPos).trimmed();
|
||||
mailPos++;
|
||||
const int mailEndPos = l.indexOf(greaterThan, mailPos);
|
||||
if (mailEndPos == -1)
|
||||
return false;
|
||||
email = l.mid(mailPos, mailEndPos - mailPos);
|
||||
// get optional 2nd name/mail pair
|
||||
const int aliasNameStart = mailEndPos + 1;
|
||||
if (aliasNameStart >= l.size())
|
||||
return true;
|
||||
int aliasMailPos = l.indexOf(lessThan, aliasNameStart);
|
||||
if (aliasMailPos == -1) {
|
||||
aliasName =l.mid(aliasNameStart, l.size() - aliasNameStart).trimmed();
|
||||
return true;
|
||||
}
|
||||
aliasName = l.mid(aliasNameStart, aliasMailPos - aliasNameStart).trimmed();
|
||||
aliasMailPos++;
|
||||
const int aliasMailEndPos = l.indexOf(greaterThan, aliasMailPos);
|
||||
if (aliasMailEndPos == -1)
|
||||
return true;
|
||||
aliasEmail = l.mid(aliasMailPos, aliasMailEndPos - aliasMailPos);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Format "Hans Mustermann <HM@acme.de>"
|
||||
static inline QString formatNick(const QString &name, const QString &email)
|
||||
{
|
||||
QString rc = name;
|
||||
if (!email.isEmpty()) {
|
||||
rc += QLatin1String(" <");
|
||||
rc += email;
|
||||
rc += QLatin1Char('>');
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
QString NickEntry::nickName() const
|
||||
{
|
||||
return aliasName.isEmpty() ? formatNick(name, email) : formatNick(aliasName, aliasEmail);
|
||||
}
|
||||
|
||||
// Sort by name
|
||||
bool operator<(const NickEntry &n1, const NickEntry &n2)
|
||||
{
|
||||
return n1.name < n2.name;
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug d, const NickEntry &e)
|
||||
{
|
||||
d.nospace() << "Name='" << e.name << "' Mail='" << e.email
|
||||
<< " Alias='" << e.aliasName << " AliasEmail='" << e.aliasEmail << "'\n";
|
||||
return d;
|
||||
}
|
||||
|
||||
// Globally cached list
|
||||
static QList<NickEntry> &nickList()
|
||||
{
|
||||
static QList<NickEntry> rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Create a model populated with the names
|
||||
static QStandardItemModel *createModel(QObject *parent)
|
||||
{
|
||||
QStandardItemModel *rc = new QStandardItemModel(parent);
|
||||
QStringList headers;
|
||||
headers << NickNameDialog::tr("Name")
|
||||
<< NickNameDialog::tr("E-mail")
|
||||
<< NickNameDialog::tr("Alias")
|
||||
<< NickNameDialog::tr("Alias e-mail");
|
||||
rc->setHorizontalHeaderLabels(headers);
|
||||
foreach(const NickEntry &ne, nickList()) {
|
||||
QList<QStandardItem *> row;
|
||||
row.push_back(new QStandardItem(ne.name));
|
||||
row.push_back(new QStandardItem(ne.email));
|
||||
row.push_back(new QStandardItem(ne.aliasName));
|
||||
row.push_back(new QStandardItem(ne.aliasEmail));
|
||||
rc->appendRow(row);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
NickNameDialog::NickNameDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
m_ui(new Ui::NickNameDialog),
|
||||
m_filterModel(new QSortFilterProxyModel(this))
|
||||
{
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
m_ui->setupUi(this);
|
||||
okButton()->setEnabled(false);
|
||||
|
||||
// Populate model and grow tree to accommodate it
|
||||
m_filterModel->setSourceModel(createModel(this));
|
||||
m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||
m_ui->filterTreeView->setModel(m_filterModel);
|
||||
const int columnCount = m_filterModel->columnCount();
|
||||
int treeWidth = 0;
|
||||
for (int c = 0; c < columnCount; c++) {
|
||||
m_ui->filterTreeView->resizeColumnToContents(c);
|
||||
treeWidth += m_ui->filterTreeView->columnWidth(c);
|
||||
}
|
||||
m_ui->filterTreeView->setMinimumWidth(treeWidth + 20);
|
||||
connect(m_ui->filterTreeView, SIGNAL(doubleClicked(QModelIndex)), this,
|
||||
SLOT(slotDoubleClicked(QModelIndex)));
|
||||
connect(m_ui->filterTreeView->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
|
||||
this, SLOT(slotCurrentItemChanged(QModelIndex)));
|
||||
connect(m_ui->filterLineEdit, SIGNAL(textChanged(QString)),
|
||||
m_filterModel, SLOT(setFilterFixedString(QString)));
|
||||
}
|
||||
|
||||
NickNameDialog::~NickNameDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
QPushButton *NickNameDialog::okButton() const
|
||||
{
|
||||
return m_ui->buttonBox->button(QDialogButtonBox::Ok);
|
||||
}
|
||||
|
||||
void NickNameDialog::slotCurrentItemChanged(const QModelIndex &index)
|
||||
{
|
||||
okButton()->setEnabled(index.isValid());
|
||||
}
|
||||
|
||||
void NickNameDialog::slotDoubleClicked(const QModelIndex &)
|
||||
{
|
||||
if (okButton()->isEnabled())
|
||||
okButton()->animateClick();
|
||||
}
|
||||
|
||||
QString NickNameDialog::nickName() const
|
||||
{
|
||||
const QModelIndex index = m_ui->filterTreeView->selectionModel()->currentIndex();
|
||||
if (index.isValid()) {
|
||||
const QModelIndex sourceIndex = m_filterModel->mapToSource(index);
|
||||
return nickList().at(sourceIndex.row()).nickName();
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
void NickNameDialog::clearNickNames()
|
||||
{
|
||||
nickList().clear();
|
||||
}
|
||||
|
||||
bool NickNameDialog::readNickNamesFromMailCapFile(const QString &fileName, QString *errorMessage)
|
||||
{
|
||||
QFile file(fileName);
|
||||
if (!file.open(QIODevice::ReadOnly|QIODevice::Text)) {
|
||||
*errorMessage = tr("Cannot open '%1': %2").arg(fileName, file.errorString());
|
||||
return false;
|
||||
}
|
||||
// Split into lines and read
|
||||
QList<NickEntry> &nl = nickList();
|
||||
nl.clear();
|
||||
NickEntry entry;
|
||||
const QStringList lines = QString::fromUtf8(file.readAll()).trimmed().split(QLatin1Char('\n'));
|
||||
const int count = lines.size();
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (entry.parse(lines.at(i))) {
|
||||
nl.push_back(entry);
|
||||
} else {
|
||||
qWarning("%s: Invalid mail cap entry at line %d: '%s'\n", qPrintable(fileName), i + 1, qPrintable(lines.at(i)));
|
||||
}
|
||||
}
|
||||
qStableSort(nl);
|
||||
return true;
|
||||
}
|
||||
|
||||
QStringList NickNameDialog::nickNameList()
|
||||
{
|
||||
QStringList rc;
|
||||
foreach(const NickEntry &ne, nickList())
|
||||
rc.push_back(ne.nickName());
|
||||
return rc;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
81
src/plugins/vcsbase/nicknamedialog.h
Normal file
81
src/plugins/vcsbase/nicknamedialog.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at qt-sales@nokia.com.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef NICKNAMEDIALOG_H
|
||||
#define NICKNAMEDIALOG_H
|
||||
|
||||
#include <QtGui/QDialog>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui {
|
||||
class NickNameDialog;
|
||||
}
|
||||
class QSortFilterProxyModel;
|
||||
class QModelIndex;
|
||||
class QPushButton;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace VCSBase {
|
||||
namespace Internal {
|
||||
|
||||
/* Nick name dialog: Manages a list of users read from an extended
|
||||
* mail cap file, consisting of 4 columns:
|
||||
* "Name Mail [AliasName [AliasMail]]".
|
||||
* The names can be used for insertion into "RevBy:" fields; aliases will
|
||||
* be preferred. */
|
||||
|
||||
class NickNameDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit NickNameDialog(QWidget *parent = 0);
|
||||
virtual ~NickNameDialog();
|
||||
|
||||
QString nickName() const;
|
||||
|
||||
// Fill/clear the global nick name cache
|
||||
static bool readNickNamesFromMailCapFile(const QString &file, QString *errorMessage);
|
||||
static void clearNickNames();
|
||||
// Return a list for a completer on the field line edits
|
||||
static QStringList nickNameList();
|
||||
|
||||
private slots:
|
||||
void slotCurrentItemChanged(const QModelIndex &);
|
||||
void slotDoubleClicked(const QModelIndex &);
|
||||
|
||||
private:
|
||||
QPushButton *okButton() const;
|
||||
|
||||
Ui::NickNameDialog *m_ui;
|
||||
QSortFilterProxyModel *m_filterModel;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace VCSBase
|
||||
|
||||
#endif // NICKNAMEDIALOG_H
|
||||
117
src/plugins/vcsbase/nicknamedialog.ui
Normal file
117
src/plugins/vcsbase/nicknamedialog.ui
Normal file
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>NickNameDialog</class>
|
||||
<widget class="QDialog" name="NickNameDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>618</width>
|
||||
<height>414</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Nick Names</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="filterLabel">
|
||||
<property name="text">
|
||||
<string>Filter:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="filterLineEdit"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="filterClearToolButton">
|
||||
<property name="text">
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeView" name="filterTreeView"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>NickNameDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>252</x>
|
||||
<y>405</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>NickNameDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>293</x>
|
||||
<y>405</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>filterClearToolButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>filterLineEdit</receiver>
|
||||
<slot>clear()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>263</x>
|
||||
<y>14</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>198</x>
|
||||
<y>19</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -14,7 +14,11 @@ HEADERS += vcsbase_global.h \
|
||||
basevcseditorfactory.h \
|
||||
submiteditorfile.h \
|
||||
basevcssubmiteditorfactory.h \
|
||||
submitfilemodel.h
|
||||
submitfilemodel.h \
|
||||
vcsbasesettings.h \
|
||||
vcsbasesettingspage.h \
|
||||
nicknamedialog.h
|
||||
|
||||
SOURCES += vcsbaseplugin.cpp \
|
||||
baseannotationhighlighter.cpp \
|
||||
diffhighlighter.cpp \
|
||||
@@ -24,5 +28,12 @@ SOURCES += vcsbaseplugin.cpp \
|
||||
basevcseditorfactory.cpp \
|
||||
submiteditorfile.cpp \
|
||||
basevcssubmiteditorfactory.cpp \
|
||||
submitfilemodel.cpp
|
||||
RESOURCES = vcsbase.qrc
|
||||
submitfilemodel.cpp \
|
||||
vcsbasesettings.cpp \
|
||||
vcsbasesettingspage.cpp \
|
||||
nicknamedialog.cpp
|
||||
|
||||
RESOURCES += vcsbase.qrc
|
||||
|
||||
FORMS += vcsbasesettingspage.ui \
|
||||
nicknamedialog.ui
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace VCSBase {
|
||||
namespace Constants {
|
||||
|
||||
const char * const VCS_SETTINGS_CATEGORY = QT_TRANSLATE_NOOP("VCSBase", "Version Control System");
|
||||
const char * const VCS_COMMON_SETTINGS_ID = QT_TRANSLATE_NOOP("VCSBase", "Common");
|
||||
|
||||
namespace Internal {
|
||||
enum { debug = 0 };
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#include "vcsbaseplugin.h"
|
||||
#include "diffhighlighter.h"
|
||||
#include "vcsbasesettingspage.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/coreconstants.h>
|
||||
@@ -42,7 +43,8 @@ namespace Internal {
|
||||
|
||||
VCSBasePlugin *VCSBasePlugin::m_instance = 0;
|
||||
|
||||
VCSBasePlugin::VCSBasePlugin()
|
||||
VCSBasePlugin::VCSBasePlugin() :
|
||||
m_settingsPage(0)
|
||||
{
|
||||
m_instance = this;
|
||||
}
|
||||
@@ -61,6 +63,8 @@ bool VCSBasePlugin::initialize(const QStringList &arguments, QString *errorMessa
|
||||
if (!core->mimeDatabase()->addMimeTypes(QLatin1String(":/vcsbase/VCSBase.mimetypes.xml"), errorMessage))
|
||||
return false;
|
||||
|
||||
m_settingsPage = new VCSBaseSettingsPage;
|
||||
addAutoReleasedObject(m_settingsPage);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -73,6 +77,11 @@ VCSBasePlugin *VCSBasePlugin::instance()
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
VCSBaseSettings VCSBasePlugin::settings() const
|
||||
{
|
||||
return m_settingsPage->settings();
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace VCSBase
|
||||
|
||||
|
||||
@@ -37,6 +37,9 @@
|
||||
namespace VCSBase {
|
||||
namespace Internal {
|
||||
|
||||
struct VCSBaseSettings;
|
||||
class VCSBaseSettingsPage;
|
||||
|
||||
class VCSBasePlugin : public ExtensionSystem::IPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -51,8 +54,11 @@ public:
|
||||
|
||||
static VCSBasePlugin *instance();
|
||||
|
||||
VCSBaseSettings settings() const;
|
||||
|
||||
private:
|
||||
static VCSBasePlugin *m_instance;
|
||||
VCSBaseSettingsPage *m_settingsPage;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
78
src/plugins/vcsbase/vcsbasesettings.cpp
Normal file
78
src/plugins/vcsbase/vcsbasesettings.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at qt-sales@nokia.com.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "vcsbasesettings.h"
|
||||
|
||||
#include <QtCore/QSettings>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
static const char *settingsGroupC = "VCS";
|
||||
static const char *nickNameMailMapKeyC = "NickNameMailMap";
|
||||
static const char *nickNameFieldListFileKeyC = "NickNameFieldListFile";
|
||||
static const char *promptForSubmitKeyC = "PromptForSubmit";
|
||||
static const char *submitMessageCheckScriptKeyC = "SubmitMessageCheckScript";
|
||||
|
||||
namespace VCSBase {
|
||||
namespace Internal {
|
||||
|
||||
VCSBaseSettings::VCSBaseSettings() :
|
||||
promptForSubmit(true)
|
||||
{
|
||||
}
|
||||
|
||||
void VCSBaseSettings::toSettings(QSettings *s) const
|
||||
{
|
||||
s->beginGroup(QLatin1String(settingsGroupC));
|
||||
s->setValue(QLatin1String(nickNameMailMapKeyC), nickNameMailMap);
|
||||
s->setValue(QLatin1String(nickNameFieldListFileKeyC), nickNameFieldListFile);
|
||||
s->setValue(QLatin1String(submitMessageCheckScriptKeyC), submitMessageCheckScript);
|
||||
s->setValue(QLatin1String(promptForSubmitKeyC), promptForSubmit);
|
||||
s->endGroup();
|
||||
}
|
||||
|
||||
void VCSBaseSettings::fromSettings(QSettings *s)
|
||||
{
|
||||
s->beginGroup(QLatin1String(settingsGroupC));
|
||||
nickNameMailMap = s->value(QLatin1String(nickNameMailMapKeyC), QString()).toString();
|
||||
nickNameFieldListFile = s->value(QLatin1String(nickNameFieldListFileKeyC), QString()).toString();
|
||||
submitMessageCheckScript = s->value(QLatin1String(submitMessageCheckScriptKeyC), QString()).toString();
|
||||
promptForSubmit = s->value(QLatin1String(promptForSubmitKeyC), QVariant(true)).toBool();
|
||||
s->endGroup();
|
||||
}
|
||||
|
||||
bool VCSBaseSettings::equals(const VCSBaseSettings &rhs) const
|
||||
{
|
||||
return promptForSubmit == rhs.promptForSubmit
|
||||
&& nickNameMailMap == rhs.nickNameMailMap
|
||||
&& nickNameFieldListFile == rhs.nickNameFieldListFile
|
||||
&& submitMessageCheckScript == rhs.submitMessageCheckScript;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
66
src/plugins/vcsbase/vcsbasesettings.h
Normal file
66
src/plugins/vcsbase/vcsbasesettings.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at qt-sales@nokia.com.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef VCSBASESETTINGS_H
|
||||
#define VCSBASESETTINGS_H
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtGui/QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QSettings;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace VCSBase {
|
||||
namespace Internal {
|
||||
|
||||
// Common VCS settings, message check script and user nick names.
|
||||
struct VCSBaseSettings {
|
||||
VCSBaseSettings();
|
||||
|
||||
bool promptForSubmit;
|
||||
|
||||
QString nickNameMailMap;
|
||||
QString nickNameFieldListFile;
|
||||
|
||||
QString submitMessageCheckScript;
|
||||
|
||||
void toSettings(QSettings *) const;
|
||||
void fromSettings(QSettings *);
|
||||
|
||||
bool equals(const VCSBaseSettings &rhs) const;
|
||||
};
|
||||
|
||||
inline bool operator==(const VCSBaseSettings &s1, const VCSBaseSettings &s2) { return s1.equals(s2); }
|
||||
inline bool operator!=(const VCSBaseSettings &s1, const VCSBaseSettings &s2) { return !s1.equals(s2); }
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace VCSBase
|
||||
|
||||
#endif // VCSBASESETTINGS_H
|
||||
145
src/plugins/vcsbase/vcsbasesettingspage.cpp
Normal file
145
src/plugins/vcsbase/vcsbasesettingspage.cpp
Normal file
@@ -0,0 +1,145 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at qt-sales@nokia.com.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "vcsbasesettingspage.h"
|
||||
#include "vcsbaseconstants.h"
|
||||
#include "nicknamedialog.h"
|
||||
|
||||
#include "ui_vcsbasesettingspage.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtGui/QMessageBox>
|
||||
|
||||
namespace VCSBase {
|
||||
namespace Internal {
|
||||
|
||||
// ------------------ VCSBaseSettingsWidget
|
||||
|
||||
VCSBaseSettingsWidget::VCSBaseSettingsWidget(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
m_ui(new Ui::VCSBaseSettingsPage)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
m_ui->submitMessageCheckScriptChooser->setExpectedKind(Core::Utils::PathChooser::Command);
|
||||
m_ui->nickNameFieldsFileChooser->setExpectedKind(Core::Utils::PathChooser::File);
|
||||
m_ui->nickNameMailMapChooser->setExpectedKind(Core::Utils::PathChooser::File);
|
||||
}
|
||||
|
||||
VCSBaseSettingsWidget::~VCSBaseSettingsWidget()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
VCSBaseSettings VCSBaseSettingsWidget::settings() const
|
||||
{
|
||||
VCSBaseSettings rc;
|
||||
rc.nickNameMailMap = m_ui->nickNameMailMapChooser->path();
|
||||
rc.nickNameFieldListFile = m_ui->nickNameFieldsFileChooser->path();
|
||||
rc.submitMessageCheckScript = m_ui->submitMessageCheckScriptChooser->path();
|
||||
rc.promptForSubmit = m_ui->promptForSubmitCheckBox->isChecked();
|
||||
return rc;
|
||||
}
|
||||
|
||||
void VCSBaseSettingsWidget::setSettings(const VCSBaseSettings &s)
|
||||
{
|
||||
|
||||
m_ui->nickNameMailMapChooser->setPath(s.nickNameMailMap);
|
||||
m_ui->nickNameFieldsFileChooser->setPath(s.nickNameFieldListFile);
|
||||
m_ui->submitMessageCheckScriptChooser->setPath(s.submitMessageCheckScript);
|
||||
m_ui->promptForSubmitCheckBox->setChecked(s.promptForSubmit);
|
||||
}
|
||||
|
||||
// --------------- VCSBaseSettingsPage
|
||||
VCSBaseSettingsPage::VCSBaseSettingsPage(QObject *parent) :
|
||||
Core::IOptionsPage(parent)
|
||||
{
|
||||
m_settings.fromSettings(Core::ICore::instance()->settings());
|
||||
updateNickNames();
|
||||
}
|
||||
|
||||
void VCSBaseSettingsPage::updateNickNames()
|
||||
{
|
||||
if (m_settings.nickNameMailMap.isEmpty()) {
|
||||
NickNameDialog::clearNickNames();
|
||||
} else {
|
||||
QString errorMessage;
|
||||
if (!NickNameDialog::readNickNamesFromMailCapFile(m_settings.nickNameMailMap, &errorMessage))
|
||||
qWarning("%s", qPrintable(errorMessage));
|
||||
}
|
||||
}
|
||||
|
||||
VCSBaseSettingsPage::~VCSBaseSettingsPage()
|
||||
{
|
||||
}
|
||||
|
||||
QString VCSBaseSettingsPage::id() const
|
||||
{
|
||||
return QLatin1String(Constants::VCS_COMMON_SETTINGS_ID);
|
||||
}
|
||||
|
||||
QString VCSBaseSettingsPage::trName() const
|
||||
{
|
||||
return QCoreApplication::translate("VCSBase", Constants::VCS_COMMON_SETTINGS_ID);
|
||||
}
|
||||
|
||||
QString VCSBaseSettingsPage::category() const
|
||||
{
|
||||
return QLatin1String(Constants::VCS_SETTINGS_CATEGORY);
|
||||
}
|
||||
|
||||
QString VCSBaseSettingsPage::trCategory() const
|
||||
{
|
||||
return QCoreApplication::translate("VCSBase", Constants::VCS_SETTINGS_CATEGORY);
|
||||
}
|
||||
|
||||
QWidget *VCSBaseSettingsPage::createPage(QWidget *parent)
|
||||
{
|
||||
m_widget = new VCSBaseSettingsWidget(parent);
|
||||
m_widget->setSettings(m_settings);
|
||||
return m_widget;
|
||||
}
|
||||
|
||||
void VCSBaseSettingsPage::apply()
|
||||
{
|
||||
if (m_widget) {
|
||||
const VCSBaseSettings newSettings = m_widget->settings();
|
||||
if (newSettings != m_settings) {
|
||||
m_settings = newSettings;
|
||||
m_settings.toSettings(Core::ICore::instance()->settings());
|
||||
updateNickNames();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
86
src/plugins/vcsbase/vcsbasesettingspage.h
Normal file
86
src/plugins/vcsbase/vcsbasesettingspage.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at qt-sales@nokia.com.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef VCSBASESETTINGSPAGE_H
|
||||
#define VCSBASESETTINGSPAGE_H
|
||||
|
||||
#include "vcsbasesettings.h"
|
||||
#include <coreplugin/dialogs/ioptionspage.h>
|
||||
#include <QtCore/QPointer>
|
||||
#include <QtGui/QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui {
|
||||
class VCSBaseSettingsPage;
|
||||
}
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace VCSBase {
|
||||
namespace Internal {
|
||||
|
||||
class VCSBaseSettingsWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VCSBaseSettingsWidget(QWidget *parent = 0);
|
||||
virtual ~VCSBaseSettingsWidget();
|
||||
|
||||
VCSBaseSettings settings() const;
|
||||
void setSettings(const VCSBaseSettings &s);
|
||||
|
||||
private:
|
||||
Ui::VCSBaseSettingsPage *m_ui;
|
||||
};
|
||||
|
||||
class VCSBaseSettingsPage : public Core::IOptionsPage
|
||||
{
|
||||
public:
|
||||
explicit VCSBaseSettingsPage(QObject *parent = 0);
|
||||
virtual ~VCSBaseSettingsPage();
|
||||
|
||||
virtual QString id() const;
|
||||
virtual QString trName() const;
|
||||
virtual QString category() const;
|
||||
virtual QString trCategory() const;
|
||||
|
||||
virtual QWidget *createPage(QWidget *parent);
|
||||
virtual void apply();
|
||||
virtual void finish() { }
|
||||
|
||||
VCSBaseSettings settings() const { return m_settings; }
|
||||
|
||||
private:
|
||||
void updateNickNames();
|
||||
QPointer<VCSBaseSettingsWidget> m_widget;
|
||||
VCSBaseSettings m_settings;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace VCSBase
|
||||
|
||||
#endif // VCSBASESETTINGSPAGE_H
|
||||
116
src/plugins/vcsbase/vcsbasesettingspage.ui
Normal file
116
src/plugins/vcsbase/vcsbasesettingspage.ui
Normal file
@@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>VCSBaseSettingsPage</class>
|
||||
<widget class="QWidget" name="VCSBaseSettingsPage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>536</width>
|
||||
<height>407</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::ExpandingFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="promptForSubmitLabel">
|
||||
<property name="text">
|
||||
<string>Prompt for submit:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="promptForSubmitCheckBox"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="submitMessageCheckScriptLabel">
|
||||
<property name="toolTip">
|
||||
<string>An executable which is called with the submit message in a temporary file as first argument. It should return with an exit != 0 and a message on standard error to indicate failure.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Submit message check script:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="Core::Utils::PathChooser" name="submitMessageCheckScriptChooser" native="true"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="nickNameMailMapLabel">
|
||||
<property name="toolTip">
|
||||
<string>A file listing user names in 2-column mailmap format:
|
||||
name <email> alias <email></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>User name file:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="Core::Utils::PathChooser" name="nickNameMailMapChooser" native="true"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="nickNameFieldsFileLabel">
|
||||
<property name="toolTip">
|
||||
<string>A simple file containing lines with field names like "Reviewed-By:" which will be added below the submit editor.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>User fields configuration file:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="Core::Utils::PathChooser" name="nickNameFieldsFileChooser" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</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>307</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>Core::Utils::PathChooser</class>
|
||||
<extends>QWidget</extends>
|
||||
<header location="global">utils/pathchooser.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -28,10 +28,14 @@
|
||||
**************************************************************************/
|
||||
|
||||
#include "vcsbasesubmiteditor.h"
|
||||
#include "vcsbasesettings.h"
|
||||
#include "vcsbaseplugin.h"
|
||||
#include "nicknamedialog.h"
|
||||
#include "submiteditorfile.h"
|
||||
|
||||
#include <aggregation/aggregate.h>
|
||||
#include <coreplugin/ifile.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/uniqueidmanager.h>
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <utils/submiteditorwidget.h>
|
||||
@@ -42,18 +46,31 @@
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QTemporaryFile>
|
||||
#include <QtCore/QProcess>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QPointer>
|
||||
#include <QtCore/QTextStream>
|
||||
#include <QtGui/QStyle>
|
||||
#include <QtGui/QToolBar>
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtGui/QMessageBox>
|
||||
#include <QtGui/QMainWindow>
|
||||
#include <QtGui/QCompleter>
|
||||
#include <QtGui/QLineEdit>
|
||||
|
||||
enum { debug = 0 };
|
||||
enum { wantToolBar = 0 };
|
||||
|
||||
namespace VCSBase {
|
||||
|
||||
static inline QString submitMessageCheckScript()
|
||||
{
|
||||
return Internal::VCSBasePlugin::instance()->settings().submitMessageCheckScript;
|
||||
}
|
||||
|
||||
struct VCSBaseSubmitEditorPrivate
|
||||
{
|
||||
VCSBaseSubmitEditorPrivate(const VCSBaseSubmitEditorParameters *parameters,
|
||||
@@ -69,6 +86,8 @@ struct VCSBaseSubmitEditorPrivate
|
||||
|
||||
QPointer<QAction> m_diffAction;
|
||||
QPointer<QAction> m_submitAction;
|
||||
|
||||
Internal::NickNameDialog *m_nickNameDialog;
|
||||
};
|
||||
|
||||
VCSBaseSubmitEditorPrivate::VCSBaseSubmitEditorPrivate(const VCSBaseSubmitEditorParameters *parameters,
|
||||
@@ -77,7 +96,8 @@ VCSBaseSubmitEditorPrivate::VCSBaseSubmitEditorPrivate(const VCSBaseSubmitEditor
|
||||
m_widget(editorWidget),
|
||||
m_toolWidget(0),
|
||||
m_parameters(parameters),
|
||||
m_file(new VCSBase::Internal::SubmitEditorFile(QLatin1String(m_parameters->mimeType), q))
|
||||
m_file(new VCSBase::Internal::SubmitEditorFile(QLatin1String(m_parameters->mimeType), q)),
|
||||
m_nickNameDialog(0)
|
||||
{
|
||||
m_contexts << Core::UniqueIDManager::instance()->uniqueIdentifier(m_parameters->context);
|
||||
}
|
||||
@@ -93,6 +113,29 @@ VCSBaseSubmitEditor::VCSBaseSubmitEditor(const VCSBaseSubmitEditorParameters *pa
|
||||
connect(m_d->m_widget, SIGNAL(diffSelected(QStringList)), this, SLOT(slotDiffSelectedVCSFiles(QStringList)));
|
||||
connect(m_d->m_widget->descriptionEdit(), SIGNAL(textChanged()), this, SLOT(slotDescriptionChanged()));
|
||||
|
||||
const Internal::VCSBaseSettings settings = Internal::VCSBasePlugin::instance()->settings();
|
||||
// Add additional context menu settings
|
||||
if (!settings.submitMessageCheckScript.isEmpty() || !settings.nickNameFieldListFile.isEmpty()) {
|
||||
QAction *sep = new QAction(this);
|
||||
sep->setSeparator(true);
|
||||
m_d->m_widget->addDescriptionEditContextMenuAction(sep);
|
||||
// Run check action
|
||||
if (!settings.submitMessageCheckScript.isEmpty()) {
|
||||
QAction *checkAction = new QAction(tr("Check message"), this);
|
||||
connect(checkAction, SIGNAL(triggered()), this, SLOT(slotCheckSubmitMessage()));
|
||||
m_d->m_widget->addDescriptionEditContextMenuAction(checkAction);
|
||||
}
|
||||
// Insert nick
|
||||
if (!settings.nickNameFieldListFile.isEmpty()) {
|
||||
QAction *insertAction = new QAction(tr("Insert name..."), this);
|
||||
connect(insertAction, SIGNAL(triggered()), this, SLOT(slotInsertNickName()));
|
||||
m_d->m_widget->addDescriptionEditContextMenuAction(insertAction);
|
||||
}
|
||||
}
|
||||
// Do we have user fields?
|
||||
if (!settings.nickNameFieldListFile.isEmpty())
|
||||
createUserFields(settings.nickNameFieldListFile);
|
||||
connect(m_d->m_widget, SIGNAL(fieldDialogRequested(int)), this, SLOT(slotSetFieldNickName(int)));
|
||||
Aggregation::Aggregate *aggregate = new Aggregation::Aggregate;
|
||||
aggregate->add(new Find::BaseTextFind(m_d->m_widget->descriptionEdit()));
|
||||
aggregate->add(this);
|
||||
@@ -105,6 +148,26 @@ VCSBaseSubmitEditor::~VCSBaseSubmitEditor()
|
||||
delete m_d;
|
||||
}
|
||||
|
||||
void VCSBaseSubmitEditor::createUserFields(const QString &fieldConfigFile)
|
||||
{
|
||||
QFile fieldFile(fieldConfigFile);
|
||||
if (!fieldFile.open(QIODevice::ReadOnly|QIODevice::Text)) {
|
||||
qWarning("%s: Unable to open %s: %s", Q_FUNC_INFO, qPrintable(fieldConfigFile), qPrintable(fieldFile.errorString()));
|
||||
return;
|
||||
}
|
||||
// Parse into fields
|
||||
const QStringList fields = QString::fromUtf8(fieldFile.readAll()).trimmed().split(QLatin1Char('\n'));
|
||||
if (fields.empty())
|
||||
return;
|
||||
// Create a completer on user names
|
||||
QCompleter *completer = new QCompleter(Internal::NickNameDialog::nickNameList(), this);
|
||||
foreach(const QString &field, fields) {
|
||||
const QString trimmedField = field.trimmed();
|
||||
if (!trimmedField.isEmpty())
|
||||
m_d->m_widget->addField(trimmedField, true)->setCompleter(completer);
|
||||
}
|
||||
}
|
||||
|
||||
void VCSBaseSubmitEditor::registerActions(QAction *editorUndoAction, QAction *editorRedoAction,
|
||||
QAction *submitAction, QAction *diffAction)\
|
||||
{
|
||||
@@ -139,7 +202,6 @@ void VCSBaseSubmitEditor::setFileListSelectionMode(QAbstractItemView::SelectionM
|
||||
m_d->m_widget->setFileListSelectionMode(sm);
|
||||
}
|
||||
|
||||
|
||||
void VCSBaseSubmitEditor::slotDescriptionChanged()
|
||||
{
|
||||
}
|
||||
@@ -304,6 +366,118 @@ bool VCSBaseSubmitEditor::setFileContents(const QString &contents)
|
||||
return true;
|
||||
}
|
||||
|
||||
enum { checkDialogMinimumWidth = 500 };
|
||||
|
||||
VCSBaseSubmitEditor::PromptSubmitResult
|
||||
VCSBaseSubmitEditor::promptSubmit(const QString &title, const QString &question, const QString &checkFailureQuestion) const
|
||||
{
|
||||
QString errorMessage;
|
||||
QMessageBox::StandardButton answer = QMessageBox::Yes;
|
||||
|
||||
QWidget *parent = Core::ICore::instance()->mainWindow();
|
||||
// Pop up a message depending on whether the check succeeded and the
|
||||
// user wants to be prompted
|
||||
if (checkSubmitMessage(&errorMessage)) {
|
||||
// Check ok, do prompt?
|
||||
if (Internal::VCSBasePlugin::instance()->settings().promptForSubmit) {
|
||||
answer = QMessageBox::question(parent, title, question,
|
||||
QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel,
|
||||
QMessageBox::Yes);
|
||||
}
|
||||
} else {
|
||||
// Check failed.
|
||||
QMessageBox msgBox(QMessageBox::Question, title, checkFailureQuestion,
|
||||
QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel, parent);
|
||||
msgBox.setDefaultButton(QMessageBox::Cancel);
|
||||
msgBox.setInformativeText(errorMessage);
|
||||
msgBox.setMinimumWidth(checkDialogMinimumWidth);
|
||||
answer = static_cast<QMessageBox::StandardButton>(msgBox.exec());
|
||||
}
|
||||
switch (answer) {
|
||||
case QMessageBox::Cancel:
|
||||
return SubmitCanceled;
|
||||
case QMessageBox::No:
|
||||
return SubmitDiscarded;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return SubmitConfirmed;
|
||||
}
|
||||
|
||||
QString VCSBaseSubmitEditor::promptForNickName()
|
||||
{
|
||||
if (!m_d->m_nickNameDialog)
|
||||
m_d->m_nickNameDialog = new Internal::NickNameDialog(m_d->m_widget);
|
||||
if (m_d->m_nickNameDialog->exec() == QDialog::Accepted)
|
||||
return m_d->m_nickNameDialog->nickName();
|
||||
return QString();
|
||||
}
|
||||
|
||||
void VCSBaseSubmitEditor::slotInsertNickName()
|
||||
{
|
||||
const QString nick = promptForNickName();
|
||||
if (!nick.isEmpty())
|
||||
m_d->m_widget->descriptionEdit()->textCursor().insertText(nick);
|
||||
}
|
||||
|
||||
void VCSBaseSubmitEditor::slotSetFieldNickName(int i)
|
||||
{
|
||||
const QString nick = promptForNickName();
|
||||
if (!nick.isEmpty())
|
||||
m_d->m_widget->fieldLineEdit(i)->setText(nick);
|
||||
}
|
||||
|
||||
void VCSBaseSubmitEditor::slotCheckSubmitMessage()
|
||||
{
|
||||
QString errorMessage;
|
||||
if (!checkSubmitMessage(&errorMessage)) {
|
||||
QMessageBox msgBox(QMessageBox::Warning, tr("Submit Message Check failed"),
|
||||
errorMessage, QMessageBox::Ok, m_d->m_widget);
|
||||
msgBox.setMinimumWidth(checkDialogMinimumWidth);
|
||||
msgBox.exec();
|
||||
}
|
||||
}
|
||||
|
||||
bool VCSBaseSubmitEditor::checkSubmitMessage(QString *errorMessage) const
|
||||
{
|
||||
const QString checkScript = submitMessageCheckScript();
|
||||
if (checkScript.isEmpty())
|
||||
return true;
|
||||
// Write out message
|
||||
QString tempFilePattern = QDir::tempPath();
|
||||
if (!tempFilePattern.endsWith(QDir::separator()))
|
||||
tempFilePattern += QDir::separator();
|
||||
tempFilePattern += QLatin1String("msgXXXXXX.txt");
|
||||
QTemporaryFile messageFile(tempFilePattern);
|
||||
messageFile.setAutoRemove(true);
|
||||
if (!messageFile.open()) {
|
||||
*errorMessage = tr("Unable to open '%1': %2").arg(messageFile.fileName(), messageFile.errorString());
|
||||
return false;
|
||||
}
|
||||
const QString messageFileName = messageFile.fileName();
|
||||
messageFile.write(fileContents().toUtf8());
|
||||
messageFile.close();
|
||||
// Run check process
|
||||
QProcess checkProcess;
|
||||
checkProcess.start(checkScript, QStringList(messageFileName));
|
||||
if (!checkProcess.waitForStarted()) {
|
||||
*errorMessage = tr("The check script '%1' could not be started: %2").arg(checkScript, checkProcess.errorString());
|
||||
return false;
|
||||
}
|
||||
if (!checkProcess.waitForFinished()) {
|
||||
*errorMessage = tr("The check script '%1' could not be run: %2").arg(checkScript, checkProcess.errorString());
|
||||
return false;
|
||||
}
|
||||
const int exitCode = checkProcess.exitCode();
|
||||
if (exitCode != 0) {
|
||||
*errorMessage = QString::fromLocal8Bit(checkProcess.readAllStandardError());
|
||||
if (errorMessage->isEmpty())
|
||||
*errorMessage = tr("The check script returned exit code %1.").arg(exitCode);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QIcon VCSBaseSubmitEditor::diffIcon()
|
||||
{
|
||||
return QIcon(QLatin1String(":/vcsbase/images/diff.png"));
|
||||
|
||||
@@ -50,7 +50,9 @@ namespace Core {
|
||||
}
|
||||
|
||||
namespace VCSBase {
|
||||
|
||||
namespace Internal {
|
||||
struct VCSBaseSettings;
|
||||
}
|
||||
struct VCSBaseSubmitEditorPrivate;
|
||||
|
||||
/* Utility struct to parametrize a VCSBaseSubmitEditor. */
|
||||
@@ -104,6 +106,12 @@ public:
|
||||
|
||||
virtual ~VCSBaseSubmitEditor();
|
||||
|
||||
// A utility routine to be called when clsing a submit editor.
|
||||
// Runs checks on the message and prompts according to configuration.
|
||||
enum PromptSubmitResult { SubmitConfirmed, SubmitCanceled, SubmitDiscarded };
|
||||
PromptSubmitResult promptSubmit(const QString &title, const QString &question,
|
||||
const QString &checkFailureQuestion) const;
|
||||
|
||||
int fileNameColumn() const;
|
||||
void setFileNameColumn(int c);
|
||||
|
||||
@@ -147,6 +155,9 @@ private slots:
|
||||
void slotDiffSelectedVCSFiles(const QStringList &rawList);
|
||||
bool save(const QString &fileName);
|
||||
void slotDescriptionChanged();
|
||||
void slotCheckSubmitMessage();
|
||||
void slotInsertNickName();
|
||||
void slotSetFieldNickName(int);
|
||||
|
||||
protected:
|
||||
/* These hooks allow for modifying the contents that goes to
|
||||
@@ -156,6 +167,10 @@ protected:
|
||||
virtual bool setFileContents(const QString &contents);
|
||||
|
||||
private:
|
||||
void createUserFields(const QString &fieldConfigFile);
|
||||
bool checkSubmitMessage(QString *errorMessage) const;
|
||||
QString promptForNickName();
|
||||
|
||||
VCSBaseSubmitEditorPrivate *m_d;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user