From 81c0bb15b25bd2f907696b35e6dbb54a2aff2732 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 23 Mar 2009 12:03:20 +0100 Subject: [PATCH] Add a submit field widget modeled after mail client address controls --- src/libs/utils/images/removesubmitfield.png | Bin 0 -> 578 bytes src/libs/utils/submiteditorwidget.cpp | 85 ++----- src/libs/utils/submiteditorwidget.h | 9 +- src/libs/utils/submitfieldwidget.cpp | 344 +++++++++++++++++++++++++++ src/libs/utils/submitfieldwidget.h | 71 ++++++ src/libs/utils/utils.pro | 10 +- src/libs/utils/utils.qrc | 5 + src/plugins/vcsbase/vcsbasesubmiteditor.cpp | 39 ++- src/tools/qtcreatorwidgets/customwidgets.cpp | 12 + src/tools/qtcreatorwidgets/customwidgets.h | 11 + 10 files changed, 508 insertions(+), 78 deletions(-) create mode 100644 src/libs/utils/images/removesubmitfield.png create mode 100644 src/libs/utils/submitfieldwidget.cpp create mode 100644 src/libs/utils/submitfieldwidget.h create mode 100644 src/libs/utils/utils.qrc diff --git a/src/libs/utils/images/removesubmitfield.png b/src/libs/utils/images/removesubmitfield.png new file mode 100644 index 0000000000000000000000000000000000000000..e4139afc552b36d5d1aabf2fe2697d00d61b6d70 GIT binary patch literal 578 zcmV-I0=@l-P)H>R(_STm*;ep#Ow+ z)4?TMham0X>L68cXi`H%p$>8ey)&1T(4^@N*N@M|9Pypr;o*Vz$Eyh;^c%qTRif%| zDc2i~#y3oj5W*=C9Y#{t0$_`l4dd;7DXS0X=i!dWcgeC^zVEyL!j)BE=cQ@tsnb*E zM-(wyoSWOb-RWQ>2yio>*MCY`AO+FnT(^AId`u0db@W# zuk>VQ2EC;vyh%Ww~dj`G7p%|8sp|q2&=(RKKtDFa%Ghu@Obk zT^IG?5Fc#YJu}Tm2hHZ!__#9X&StTw_KB2ACY4Gi)jpBhEEZLnb7zvfGFgZrf;Q zvp^8w)@X#qLLt`E?yan-XWcH=MkBnFGS&cqiQZ!(v@#jI&gVg9E?4?B7&z@P#OEoE zX}!*1pnpju;AOKlO$edW#l^NJWmV43t{*g;|Gh?;bBE5)4;4{Orqf%00UKq>;&)>- Q4*&oF07*qoM6N<$g03C?VE_OC literal 0 HcmV?d00001 diff --git a/src/libs/utils/submiteditorwidget.cpp b/src/libs/utils/submiteditorwidget.cpp index 687813c197..0a283c62a0 100644 --- a/src/libs/utils/submiteditorwidget.cpp +++ b/src/libs/utils/submiteditorwidget.cpp @@ -28,17 +28,15 @@ **************************************************************************/ #include "submiteditorwidget.h" +#include "submitfieldwidget.h" #include "ui_submiteditorwidget.h" #include #include #include -#include #include #include -#include -#include #include #include #include @@ -127,11 +125,8 @@ struct SubmitEditorWidgetPrivate int m_activatedRow; QList descriptionEditContextMenuActions; - QFormLayout *m_fieldLayout; - // Field entries (label, line edits) - typedef QPair FieldEntry; - QList m_fieldEntries; - QSignalMapper *m_fieldSignalMapper; + QVBoxLayout *m_fieldLayout; + QList m_fieldWidgets; int m_lineWidth; }; @@ -141,7 +136,6 @@ SubmitEditorWidgetPrivate::SubmitEditorWidgetPrivate() : m_fileNameColumn(1), m_activatedRow(-1), m_fieldLayout(0), - m_fieldSignalMapper(0), m_lineWidth(defaultLineWidth) { } @@ -259,15 +253,8 @@ QString SubmitEditorWidget::descriptionText() const { QString rc = trimMessageText(lineWrap() ? wrappedText(m_d->m_ui.description) : m_d->m_ui.description->toPlainText()); // append field entries - foreach(const SubmitEditorWidgetPrivate::FieldEntry &fe, m_d->m_fieldEntries) { - const QString fieldText = fe.second->text().trimmed(); - if (!fieldText.isEmpty()) { - rc += fe.first; - rc += QLatin1Char(' '); - rc += fieldText; - rc += QLatin1Char('\n'); - } - } + foreach(const SubmitFieldWidget *fw, m_d->m_fieldWidgets) + rc += fw->fieldValues(); return rc; } @@ -470,6 +457,27 @@ void SubmitEditorWidget::insertTopWidget(QWidget *w) m_d->m_ui.vboxLayout->insertWidget(0, w); } +void SubmitEditorWidget::addSubmitFieldWidget(SubmitFieldWidget *f) +{ + if (!m_d->m_fieldLayout) { + // VBox with horizontal, expanding spacer + m_d->m_fieldLayout = new QVBoxLayout; + QHBoxLayout *outerLayout = new QHBoxLayout; + outerLayout->addLayout(m_d->m_fieldLayout); + outerLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored)); + QBoxLayout *descrLayout = qobject_cast(m_d->m_ui.descriptionBox->layout()); + Q_ASSERT(descrLayout); + descrLayout->addLayout(outerLayout); + } + m_d->m_fieldLayout->addWidget(f); + m_d->m_fieldWidgets.push_back(f); +} + +QList SubmitEditorWidget::submitFieldWidgets() const +{ + return m_d->m_fieldWidgets; +} + void SubmitEditorWidget::addDescriptionEditContextMenuAction(QAction *a) { m_d->descriptionEditContextMenuActions.push_back(SubmitEditorWidgetPrivate::AdditionalContextMenuAction(-1, a)); @@ -497,47 +505,6 @@ void SubmitEditorWidget::editorCustomContextMenuRequested(const QPoint &pos) delete menu; } -QLineEdit *SubmitEditorWidget::addField(const QString &label, bool hasDialogButton) -{ - // Insert the form layout below the editor - if (!m_d->m_fieldLayout) { - QHBoxLayout *outerLayout = new QHBoxLayout; - m_d->m_fieldLayout = new QFormLayout; - outerLayout->addLayout(m_d->m_fieldLayout); - outerLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored)); - QBoxLayout *descrLayout = qobject_cast(m_d->m_ui.descriptionBox->layout()); - Q_ASSERT(descrLayout); - descrLayout->addLayout(outerLayout); - } - if (hasDialogButton && !m_d->m_fieldSignalMapper) { - m_d->m_fieldSignalMapper = new QSignalMapper; - connect(m_d->m_fieldSignalMapper, SIGNAL(mapped(int)), this, SIGNAL(fieldDialogRequested(int))); - } - // Add a field row consisting of label and line edit - QLineEdit *lineEdit = new QLineEdit; - QHBoxLayout *fieldLayout = new QHBoxLayout; - fieldLayout->addWidget(lineEdit); - if (hasDialogButton) { - QToolButton *dialogButton = new QToolButton; - dialogButton->setText(tr("...")); - connect(dialogButton, SIGNAL(clicked()), m_d->m_fieldSignalMapper, SLOT(map())); - m_d->m_fieldSignalMapper->setMapping(dialogButton, m_d->m_fieldEntries.size()); - fieldLayout->addWidget(dialogButton); - } - QToolButton *clearButton = new QToolButton; - clearButton->setText(tr("Clear")); - connect(clearButton, SIGNAL(clicked()), lineEdit, SLOT(clear())); - fieldLayout->addWidget(clearButton); - m_d->m_fieldLayout->addRow(label, fieldLayout); - m_d->m_fieldEntries.push_back(SubmitEditorWidgetPrivate::FieldEntry(label, lineEdit)); - return lineEdit; -} - -QLineEdit *SubmitEditorWidget::fieldLineEdit(int i) const -{ - return m_d->m_fieldEntries.at(i).second; -} - } // namespace Utils } // namespace Core diff --git a/src/libs/utils/submiteditorwidget.h b/src/libs/utils/submiteditorwidget.h index 9ed5ecfb11..2cf9c09635 100644 --- a/src/libs/utils/submiteditorwidget.h +++ b/src/libs/utils/submiteditorwidget.h @@ -47,6 +47,7 @@ QT_END_NAMESPACE namespace Core { namespace Utils { +class SubmitFieldWidget; struct SubmitEditorWidgetPrivate; /* The submit editor presents the commit message in a text editor and an @@ -114,17 +115,13 @@ public: void addDescriptionEditContextMenuAction(QAction *a); void insertDescriptionEditContextMenuAction(int pos, QAction *a); - // Fields are additional fields consisting of a Label and a Line Edit. - // A field dialog is wired to a button labeled "..." that pops up a chooser - // resulting in text being set - QLineEdit *addField(const QString &label, bool hasDialogButton); - QLineEdit *fieldLineEdit(int i) const; + void addSubmitFieldWidget(SubmitFieldWidget *f); + QList submitFieldWidgets() const; signals: void diffSelected(const QStringList &); void fileSelectionChanged(bool someFileSelected); void fileCheckStateChanged(bool someFileChecked); - void fieldDialogRequested(int); protected: virtual void changeEvent(QEvent *e); diff --git a/src/libs/utils/submitfieldwidget.cpp b/src/libs/utils/submitfieldwidget.cpp new file mode 100644 index 0000000000..d371595218 --- /dev/null +++ b/src/libs/utils/submitfieldwidget.cpp @@ -0,0 +1,344 @@ +#include "submitfieldwidget.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +enum { debug = 0 }; +enum { spacing = 2 }; + +static void inline setComboBlocked(QComboBox *cb, int index) +{ + const bool blocked = cb->blockSignals(true); + cb->setCurrentIndex(index); + cb->blockSignals(blocked); +} + +namespace Core { + namespace Utils { + +// Field/Row entry +struct FieldEntry { + FieldEntry(); + void createGui(const QIcon &removeIcon); + void deleteGuiLater(); + + QComboBox *combo; + QHBoxLayout *layout; + QLineEdit *lineEdit; + QToolBar *toolBar; + QToolButton *clearButton; + QToolButton *browseButton; + int comboIndex; +}; + +FieldEntry::FieldEntry() : + combo(0), + layout(0), + lineEdit(0), + toolBar(0), + clearButton(0), + browseButton(0), + comboIndex(0) +{ +} + +void FieldEntry::createGui(const QIcon &removeIcon) +{ + layout = new QHBoxLayout; + layout->setMargin(0); + layout ->setSpacing(spacing); + combo = new QComboBox; + layout->addWidget(combo); + lineEdit = new QLineEdit; + layout->addWidget(lineEdit); + toolBar = new QToolBar; + toolBar->setProperty("_q_custom_style_disabled", QVariant(true)); + layout->addWidget(toolBar); + clearButton = new QToolButton; + clearButton->setIcon(removeIcon); + toolBar->addWidget(clearButton); + browseButton = new QToolButton; + browseButton->setText(QLatin1String("...")); + toolBar->addWidget(browseButton); +} + +void FieldEntry::deleteGuiLater() +{ + clearButton->deleteLater(); + browseButton->deleteLater(); + toolBar->deleteLater(); + lineEdit->deleteLater(); + combo->deleteLater(); + layout->deleteLater(); +} + +// ------- SubmitFieldWidgetPrivate +struct SubmitFieldWidgetPrivate { + SubmitFieldWidgetPrivate(); + + int findSender(const QObject *o) const; + int findField(const QString &f, int excluded = -1) const; + inline QString fieldText(int) const; + inline QString fieldValue(int) const; + inline void focusField(int); + + const QIcon removeFieldIcon; + QStringList fields; + QCompleter *completer; + bool hasBrowseButton; + bool allowDuplicateFields; + + QList fieldEntries; + QVBoxLayout *layout; +}; + +SubmitFieldWidgetPrivate::SubmitFieldWidgetPrivate() : + removeFieldIcon(QLatin1String(":/utils/images/removesubmitfield.png")), + completer(0), + hasBrowseButton(false), + allowDuplicateFields(false), + layout(0) +{ +} + +int SubmitFieldWidgetPrivate::findSender(const QObject *o) const +{ + const int count = fieldEntries.size(); + for (int i = 0; i < count; i++) { + const FieldEntry &fe = fieldEntries.at(i); + if (fe.combo == o || fe.browseButton == o || fe.clearButton == o || fe.lineEdit == o) + return i; + } + return -1; +} + +int SubmitFieldWidgetPrivate::findField(const QString &ft, int excluded) const +{ + const int count = fieldEntries.size(); + for (int i = 0; i < count; i++) + if (i != excluded && fieldText(i) == ft) + return i; + return -1; +} + +QString SubmitFieldWidgetPrivate::fieldText(int pos) const +{ + return fieldEntries.at(pos).combo->currentText(); +} + +QString SubmitFieldWidgetPrivate::fieldValue(int pos) const +{ + return fieldEntries.at(pos).lineEdit->text(); +} + +void SubmitFieldWidgetPrivate::focusField(int pos) +{ + fieldEntries.at(pos).lineEdit->setFocus(Qt::TabFocusReason); +} + +// SubmitFieldWidget +SubmitFieldWidget::SubmitFieldWidget(QWidget *parent) : + QWidget(parent), + m_d(new SubmitFieldWidgetPrivate) +{ + m_d->layout = new QVBoxLayout; + m_d->layout->setMargin(0); + m_d->layout->setSpacing(spacing); + setLayout(m_d->layout); +} + +SubmitFieldWidget::~SubmitFieldWidget() +{ + delete m_d; +} + +void SubmitFieldWidget::setFields(const QStringList & f) +{ + // remove old fields + for (int i = m_d->fieldEntries.size() - 1 ; i >= 0 ; i--) + removeField(i); + + m_d->fields = f; + if (!f.empty()) + createField(f.front()); +} + +QStringList SubmitFieldWidget::fields() const +{ + return m_d->fields; +} + +bool SubmitFieldWidget::hasBrowseButton() const +{ + return m_d->hasBrowseButton; +} + +void SubmitFieldWidget::setHasBrowseButton(bool d) +{ + if (m_d->hasBrowseButton == d) + return; + m_d->hasBrowseButton = d; + foreach(const FieldEntry &fe, m_d->fieldEntries) + fe.browseButton->setVisible(d); +} + +bool SubmitFieldWidget::allowDuplicateFields() const +{ + return m_d->allowDuplicateFields; +} + +void SubmitFieldWidget::setAllowDuplicateFields(bool v) +{ + m_d->allowDuplicateFields = v; +} + +QCompleter *SubmitFieldWidget::completer() const +{ + return m_d->completer; +} + +void SubmitFieldWidget::setCompleter(QCompleter *c) +{ + if (c == m_d->completer) + return; + m_d->completer = c; + foreach(const FieldEntry &fe, m_d->fieldEntries) + fe.lineEdit->setCompleter(c); +} + +QString SubmitFieldWidget::fieldValue(int pos) const +{ + return m_d->fieldValue(pos); +} + +void SubmitFieldWidget::setFieldValue(int pos, const QString &value) +{ + m_d->fieldEntries.at(pos).lineEdit->setText(value); +} + +QString SubmitFieldWidget::fieldValues() const +{ + const QChar blank = QLatin1Char(' '); + const QChar newLine = QLatin1Char('\n'); + // Format as "RevBy: value\nSigned-Off: value\n" + QString rc; + foreach(const FieldEntry &fe, m_d->fieldEntries) { + const QString value = fe.lineEdit->text().trimmed(); + if (!value.isEmpty()) { + rc += fe.combo->currentText(); + rc += blank; + rc += value; + rc += newLine; + } + } + return rc; +} + +void SubmitFieldWidget::createField(const QString &f) +{ + FieldEntry fe; + fe.createGui(m_d->removeFieldIcon); + fe.combo->addItems(m_d->fields); + if (!f.isEmpty()) { + const int index = fe.combo->findText(f); + if (index != -1) { + setComboBlocked(fe.combo, index); + fe.comboIndex = index; + } + } + + connect(fe.browseButton, SIGNAL(clicked()), this, SLOT(slotBrowseButtonClicked())); + if (!m_d->hasBrowseButton) + fe.browseButton->setVisible(false); + + if (m_d->completer) + fe.lineEdit->setCompleter(m_d->completer); + + connect(fe.combo, SIGNAL(currentIndexChanged(int)), + this, SLOT(slotComboIndexChanged(int))); + connect(fe.clearButton, SIGNAL(clicked()), + this, SLOT(slotRemove())); + m_d->layout->addLayout(fe.layout); + m_d->fieldEntries.push_back(fe); +} + +void SubmitFieldWidget::slotRemove() +{ + // Never remove first entry + const int index = m_d->findSender(sender()); + switch (index) { + case -1: + break; + case 0: + m_d->fieldEntries.front().lineEdit->clear(); + break; + default: + removeField(index); + break; + } +} + +void SubmitFieldWidget::removeField(int index) +{ + FieldEntry fe = m_d->fieldEntries.takeAt(index); + QLayoutItem * item = m_d->layout->takeAt(index); + fe.deleteGuiLater(); + delete item; +} + +void SubmitFieldWidget::slotComboIndexChanged(int comboIndex) +{ + const int pos = m_d->findSender(sender()); + if (debug) + qDebug() << '>' << Q_FUNC_INFO << pos; + if (pos == -1) + return; + // Accept new index or reset combo to previous value? + int &previousIndex = m_d->fieldEntries[pos].comboIndex; + if (comboIndexChange(pos, comboIndex)) { + previousIndex = comboIndex; + } else { + setComboBlocked(m_d->fieldEntries.at(pos).combo, previousIndex); + } + if (debug) + qDebug() << '<' << Q_FUNC_INFO << pos; +} + +// Handle change of a combo. Return "false" if the combo +// is to be reset (refuse new field). +bool SubmitFieldWidget::comboIndexChange(int pos, int index) +{ + const QString newField = m_d->fieldEntries.at(pos).combo->itemText(index); + // If the field is visible elsewhere: focus the existing one and refuse + if (!m_d->allowDuplicateFields) { + const int existingFieldIndex = m_d->findField(newField, pos); + if (existingFieldIndex != -1) { + m_d->focusField(existingFieldIndex); + return false; + } + } + // Empty value: just change the field + if (m_d->fieldValue(pos).isEmpty()) + return true; + // Non-empty: Create a new field and reset the triggering combo + createField(newField); + return false; +} + +void SubmitFieldWidget::slotBrowseButtonClicked() +{ + const int pos = m_d->findSender(sender()); + emit browseButtonClicked(pos, m_d->fieldText(pos)); +} + +} +} diff --git a/src/libs/utils/submitfieldwidget.h b/src/libs/utils/submitfieldwidget.h new file mode 100644 index 0000000000..34a959c5ef --- /dev/null +++ b/src/libs/utils/submitfieldwidget.h @@ -0,0 +1,71 @@ +#ifndef SUBMITFIELDWIDGET_H +#define SUBMITFIELDWIDGET_H + +#include "utils_global.h" + +#include + +QT_BEGIN_NAMESPACE +class QCompleter; +QT_END_NAMESPACE + +namespace Core { + namespace Utils { + +struct SubmitFieldWidgetPrivate; + +/* A widget for editing submit message fields like "reviewed-by:", + * "signed-off-by:". It displays them in a vertical row of combo/line edit fields + * that is modeled after the target address controls of mail clients. + * When choosing a different field in the combo, a new row is opened if text + * has been entered for the current field. Optionally, a "Browse..." button and + * completer can be added. */ +class QWORKBENCH_UTILS_EXPORT SubmitFieldWidget : public QWidget +{ + Q_OBJECT + Q_PROPERTY(QStringList fields READ fields WRITE setFields DESIGNABLE true) + Q_PROPERTY(bool hasBrowseButton READ hasBrowseButton WRITE setHasBrowseButton DESIGNABLE true) + Q_PROPERTY(bool allowDuplicateFields READ allowDuplicateFields WRITE setAllowDuplicateFields DESIGNABLE true) + +public: + explicit SubmitFieldWidget(QWidget *parent = 0); + virtual ~SubmitFieldWidget(); + + QStringList fields() const; + void setFields(const QStringList&); + + bool hasBrowseButton() const; + void setHasBrowseButton(bool d); + + // Allow several entries for fields ("reviewed-by: a", "reviewed-by: b") + bool allowDuplicateFields() const; + void setAllowDuplicateFields(bool); + + QCompleter *completer() const; + void setCompleter(QCompleter *c); + + QString fieldValue(int pos) const; + void setFieldValue(int pos, const QString &value); + + QString fieldValues() const; + +signals: + void browseButtonClicked(int pos, const QString &field); + +private slots: + void slotRemove(); + void slotComboIndexChanged(int); + void slotBrowseButtonClicked(); + +private: + void removeField(int index); + bool comboIndexChange(int fieldNumber, int index); + void createField(const QString &f); + + SubmitFieldWidgetPrivate *m_d; +}; + +} +} + +#endif // SUBMITFIELDWIDGET_H diff --git a/src/libs/utils/utils.pro b/src/libs/utils/utils.pro index 7649ab8748..9d9e6c76a1 100644 --- a/src/libs/utils/utils.pro +++ b/src/libs/utils/utils.pro @@ -1,6 +1,6 @@ TEMPLATE = lib TARGET = Utils -QT += network +QT += gui network DEFINES += QWORKBENCH_UTILS_LIBRARY @@ -24,7 +24,8 @@ SOURCES += \ fancylineedit.cpp \ qtcolorbutton.cpp \ submiteditorwidget.cpp \ - synchronousprocess.cpp + synchronousprocess.cpp \ + submitfieldwidget.cpp win32 { SOURCES += abstractprocess_win.cpp \ @@ -57,9 +58,12 @@ HEADERS += \ submiteditorwidget.h \ abstractprocess.h \ consoleprocess.h \ - synchronousprocess.h + synchronousprocess.h \ + submitfieldwidget.h FORMS += filewizardpage.ui \ projectintropage.ui \ newclasswidget.ui \ submiteditorwidget.ui + +RESOURCES += utils.qrc diff --git a/src/libs/utils/utils.qrc b/src/libs/utils/utils.qrc new file mode 100644 index 0000000000..ef180b21fe --- /dev/null +++ b/src/libs/utils/utils.qrc @@ -0,0 +1,5 @@ + + + images/removesubmitfield.png + + diff --git a/src/plugins/vcsbase/vcsbasesubmiteditor.cpp b/src/plugins/vcsbase/vcsbasesubmiteditor.cpp index e696f46b12..62ea9417b8 100644 --- a/src/plugins/vcsbase/vcsbasesubmiteditor.cpp +++ b/src/plugins/vcsbase/vcsbasesubmiteditor.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -135,7 +136,6 @@ VCSBaseSubmitEditor::VCSBaseSubmitEditor(const VCSBaseSubmitEditorParameters *pa // Do we have user fields? if (!settings.nickNameFieldListFile.isEmpty()) createUserFields(settings.nickNameFieldListFile); - connect(m_d->m_widget, SIGNAL(fieldDialogRequested(int)), this, SLOT(slotSetFieldNickName(int))); // wrapping. etc slotUpdateEditorSettings(settings); @@ -161,6 +161,19 @@ void VCSBaseSubmitEditor::slotUpdateEditorSettings(const Internal::VCSBaseSettin setLineWrap(s.lineWrap); } +// Return a trimmed list of non-empty field texts +static inline QStringList fieldTexts(const QString &fileContents) +{ + QStringList rc; + const QStringList rawFields = fileContents.trimmed().split(QLatin1Char('\n')); + foreach(const QString &field, rawFields) { + const QString trimmedField = field.trimmed(); + if (!trimmedField.isEmpty()) + rc.push_back(trimmedField); + } + return rc; +} + void VCSBaseSubmitEditor::createUserFields(const QString &fieldConfigFile) { QFile fieldFile(fieldConfigFile); @@ -169,17 +182,21 @@ void VCSBaseSubmitEditor::createUserFields(const QString &fieldConfigFile) return; } // Parse into fields - const QStringList fields = QString::fromUtf8(fieldFile.readAll()).trimmed().split(QLatin1Char('\n')); + const QStringList fields = fieldTexts(QString::fromUtf8(fieldFile.readAll())); if (fields.empty()) return; // Create a completer on user names const QStandardItemModel *nickNameModel = Internal::VCSBasePlugin::instance()->nickNameModel(); QCompleter *completer = new QCompleter(Internal::NickNameDialog::nickNameList(nickNameModel), this); - foreach(const QString &field, fields) { - const QString trimmedField = field.trimmed(); - if (!trimmedField.isEmpty()) - m_d->m_widget->addField(trimmedField, true)->setCompleter(completer); - } + + Core::Utils::SubmitFieldWidget *fieldWidget = new Core::Utils::SubmitFieldWidget; + connect(fieldWidget, SIGNAL(browseButtonClicked(int,QString)), + this, SLOT(slotSetFieldNickName(int))); + fieldWidget->setCompleter(completer); + fieldWidget->setAllowDuplicateFields(true); + fieldWidget->setHasBrowseButton(true); + fieldWidget->setFields(fields); + m_d->m_widget->addSubmitFieldWidget(fieldWidget); } void VCSBaseSubmitEditor::registerActions(QAction *editorUndoAction, QAction *editorRedoAction, @@ -461,9 +478,11 @@ void VCSBaseSubmitEditor::slotInsertNickName() void VCSBaseSubmitEditor::slotSetFieldNickName(int i) { - const QString nick = promptForNickName(); - if (!nick.isEmpty()) - m_d->m_widget->fieldLineEdit(i)->setText(nick); + if (Core::Utils::SubmitFieldWidget *sfw =m_d->m_widget->submitFieldWidgets().front()) { + const QString nick = promptForNickName(); + if (!nick.isEmpty()) + sfw->setFieldValue(i, nick); + } } void VCSBaseSubmitEditor::slotCheckSubmitMessage() diff --git a/src/tools/qtcreatorwidgets/customwidgets.cpp b/src/tools/qtcreatorwidgets/customwidgets.cpp index de1831cd23..758fcb1ed2 100644 --- a/src/tools/qtcreatorwidgets/customwidgets.cpp +++ b/src/tools/qtcreatorwidgets/customwidgets.cpp @@ -143,6 +143,17 @@ SubmitEditorWidget_CW::SubmitEditorWidget_CW(QObject *parent) : { } +SubmitFieldWidget_CW::SubmitFieldWidget_CW(QObject *parent) : + QObject(parent), + CustomWidget + (QLatin1String(""), + false, + QLatin1String(groupC), + QIcon(), + tr("Show predefined fields of a submit message in a control based on mail address controls")) +{ +} + // -------------- WidgetCollection WidgetCollection::WidgetCollection(QObject *parent) : QObject(parent) @@ -157,6 +168,7 @@ WidgetCollection::WidgetCollection(QObject *parent) : m_plugins.push_back(new FancyLineEdit_CW(this)); m_plugins.push_back(new QtColorButton_CW(this)); m_plugins.push_back(new SubmitEditorWidget_CW(this)); + m_plugins.push_back(new SubmitFieldWidget_CW(this)); } QList WidgetCollection::customWidgets() const diff --git a/src/tools/qtcreatorwidgets/customwidgets.h b/src/tools/qtcreatorwidgets/customwidgets.h index 191f3e1d3d..7f9bd4efeb 100644 --- a/src/tools/qtcreatorwidgets/customwidgets.h +++ b/src/tools/qtcreatorwidgets/customwidgets.h @@ -41,6 +41,7 @@ #include #include #include +#include #include @@ -141,6 +142,16 @@ public: explicit SubmitEditorWidget_CW(QObject *parent = 0); }; +class SubmitFieldWidget_CW : + public QObject, + public CustomWidget +{ + Q_OBJECT + Q_INTERFACES(QDesignerCustomWidgetInterface) +public: + explicit SubmitFieldWidget_CW(QObject *parent = 0); +}; + // Collection class WidgetCollection : public QObject, public QDesignerCustomWidgetCollectionInterface -- 2.11.0