diff options
-rw-r--r-- | src/libs/utils/submiteditorwidget.cpp | 110 | ||||
-rw-r--r-- | src/libs/utils/submiteditorwidget.h | 11 | ||||
-rw-r--r-- | src/plugins/cvs/cvsplugin.cpp | 1 | ||||
-rw-r--r-- | src/plugins/git/gitplugin.cpp | 1 | ||||
-rw-r--r-- | src/plugins/mercurial/mercurialplugin.cpp | 1 | ||||
-rw-r--r-- | src/plugins/perforce/perforceplugin.cpp | 1 | ||||
-rw-r--r-- | src/plugins/subversion/subversionplugin.cpp | 1 |
7 files changed, 105 insertions, 21 deletions
diff --git a/src/libs/utils/submiteditorwidget.cpp b/src/libs/utils/submiteditorwidget.cpp index cbece7aa5b..7594c5d8a1 100644 --- a/src/libs/utils/submiteditorwidget.cpp +++ b/src/libs/utils/submiteditorwidget.cpp @@ -34,6 +34,7 @@ #include <QtCore/QDebug> #include <QtCore/QPointer> #include <QtCore/QTimer> +#include <QtCore/QScopedPointer> #include <QtGui/QPushButton> #include <QtGui/QMenu> @@ -44,6 +45,8 @@ enum { debug = 0 }; enum { defaultLineWidth = 72 }; +enum { checkableColumn = 0 }; + namespace Utils { // QActionPushButton: A push button tied to an action @@ -68,10 +71,27 @@ QActionPushButton::QActionPushButton(QAction *a) : void QActionPushButton::actionChanged() { - if (const QAction *a = qobject_cast<QAction*>(sender())) + if (const QAction *a = qobject_cast<QAction*>(sender())) { setEnabled(a->isEnabled()); + setText(a->text()); + } } +// A helper parented on a QAction, +// making QAction::setText() a slot (which it currently is not). +class QActionSetTextSlotHelper : public QObject +{ + Q_OBJECT +public: + explicit QActionSetTextSlotHelper(QAction *a) : QObject(a) {} + +public slots: + void setText(const QString &t) { + if (QAction *action = qobject_cast<QAction *>(parent())) + action->setText(t); + } +}; + // Helpers to retrieve model data static inline bool listModelChecked(const QAbstractItemModel *model, int row, int column = 0) { @@ -79,20 +99,20 @@ static inline bool listModelChecked(const QAbstractItemModel *model, int row, in return model->data(checkableIndex, Qt::CheckStateRole).toInt() == Qt::Checked; } -static inline QString listModelText(const QAbstractItemModel *model, int row, int column) +static void setListModelChecked(QAbstractItemModel *model, bool checked, int column = 0) { - const QModelIndex index = model->index(row, column, QModelIndex()); - return model->data(index, Qt::DisplayRole).toString(); + const QVariant data = QVariant(int(checked ? Qt::Checked : Qt::Unchecked)); + const int count = model->rowCount(); + for (int i = 0; i < count; i++) { + const QModelIndex checkableIndex = model->index(i, column, QModelIndex()); + model->setData(checkableIndex, data, Qt::CheckStateRole); + } } -// Find a check item in a model -static bool listModelContainsCheckedItem(const QAbstractItemModel *model) +static inline QString listModelText(const QAbstractItemModel *model, int row, int column) { - const int count = model->rowCount(); - for (int i = 0; i < count; i++) - if (listModelChecked(model, i, 0)) - return true; - return false; + const QModelIndex index = model->index(row, column, QModelIndex()); + return model->data(index, Qt::DisplayRole).toString(); } // Convenience to extract a list of selected indexes @@ -151,6 +171,9 @@ SubmitEditorWidget::SubmitEditorWidget(QWidget *parent) : this, SLOT(editorCustomContextMenuRequested(QPoint))); // File List + m_d->m_ui.fileView->setContextMenuPolicy(Qt::CustomContextMenu); + connect(m_d->m_ui.fileView, SIGNAL(customContextMenuRequested(QPoint)), + this, SLOT(fileListCustomContextMenuRequested(QPoint))); m_d->m_ui.fileView->setSelectionMode(QAbstractItemView::ExtendedSelection); m_d->m_ui.fileView->setRootIsDecorated(false); connect(m_d->m_ui.fileView, SIGNAL(doubleClicked(QModelIndex)), @@ -188,6 +211,11 @@ void SubmitEditorWidget::registerActions(QAction *editorUndoAction, QAction *edi } submitAction->setEnabled(m_d->m_filesChecked); connect(this, SIGNAL(fileCheckStateChanged(bool)), submitAction, SLOT(setEnabled(bool))); + // Wire setText via QActionSetTextSlotHelper. + QActionSetTextSlotHelper *actionSlotHelper = submitAction->findChild<QActionSetTextSlotHelper *>(); + if (!actionSlotHelper) + actionSlotHelper = new QActionSetTextSlotHelper(submitAction); + connect(this, SIGNAL(submitActionTextChanged(QString)), actionSlotHelper, SLOT(setText(QString))); m_d->m_ui.buttonLayout->addWidget(new QActionPushButton(submitAction)); } if (diffAction) { @@ -212,8 +240,11 @@ void SubmitEditorWidget::unregisterActions(QAction *editorUndoAction, QAction * disconnect(editorRedoAction, SIGNAL(triggered()), m_d->m_ui.description, SLOT(redo())); } - if (submitAction) + if (submitAction) { disconnect(this, SIGNAL(fileCheckStateChanged(bool)), submitAction, SLOT(setEnabled(bool))); + // Just deactivate the QActionSetTextSlotHelper on the action + disconnect(this, SIGNAL(submitActionTextChanged(QString)), 0, 0); + } if (diffAction) { disconnect(this, SIGNAL(fileSelectionChanged(bool)), diffAction, SLOT(setEnabled(bool))); @@ -374,7 +405,7 @@ QStringList SubmitEditorWidget::checkedFiles() const return rc; const int count = model->rowCount(); for (int i = 0; i < count; i++) - if (listModelChecked(model, i, 0)) + if (listModelChecked(model, i, checkableColumn)) rc.push_back(listModelText(model, i, fileNameColumn())); return rc; } @@ -414,11 +445,19 @@ void SubmitEditorWidget::updateActions() // Enable submit depending on having checked files void SubmitEditorWidget::updateSubmitAction() { - const bool newFilesCheckedState = hasCheckedFiles(); + const unsigned checkedCount = checkedFilesCount(); + const bool newFilesCheckedState = checkedCount; + // Emit signal to update action if (m_d->m_filesChecked != newFilesCheckedState) { m_d->m_filesChecked = newFilesCheckedState; emit fileCheckStateChanged(m_d->m_filesChecked); } + // Update button text. + const int fileCount = m_d->m_ui.fileView->model()->rowCount(); + const QString msg = checkedCount ? + tr("Commit %1/%2 Files").arg(checkedCount).arg(fileCount) : + tr("Commit"); + emit submitActionTextChanged(msg); } // Enable diff depending on selected files @@ -439,11 +478,16 @@ bool SubmitEditorWidget::hasSelection() const return false; } -bool SubmitEditorWidget::hasCheckedFiles() const +unsigned SubmitEditorWidget::checkedFilesCount() const { - if (const QAbstractItemModel *model = m_d->m_ui.fileView->model()) - return listModelContainsCheckedItem(model); - return false; + unsigned checkedCount = 0; + if (const QAbstractItemModel *model = m_d->m_ui.fileView->model()) { + const int count = model->rowCount(); + for (int i = 0; i < count; i++) + if (listModelChecked(model, i, checkableColumn)) + checkedCount++; + } + return checkedCount; } void SubmitEditorWidget::changeEvent(QEvent *e) @@ -496,7 +540,7 @@ void SubmitEditorWidget::insertDescriptionEditContextMenuAction(int pos, QAction void SubmitEditorWidget::editorCustomContextMenuRequested(const QPoint &pos) { - QMenu *menu = m_d->m_ui.description->createStandardContextMenu(); + QScopedPointer<QMenu> menu(m_d->m_ui.description->createStandardContextMenu()); // Extend foreach (const SubmitEditorWidgetPrivate::AdditionalContextMenuAction &a, m_d->descriptionEditContextMenuActions) { if (a.second) { @@ -508,7 +552,33 @@ void SubmitEditorWidget::editorCustomContextMenuRequested(const QPoint &pos) } } menu->exec(m_d->m_ui.description->mapToGlobal(pos)); - delete menu; +} + +void SubmitEditorWidget::checkAll() +{ + setListModelChecked(m_d->m_ui.fileView->model(), true, checkableColumn); +} + +void SubmitEditorWidget::uncheckAll() +{ + setListModelChecked(m_d->m_ui.fileView->model(), false, checkableColumn); +} + +void SubmitEditorWidget::fileListCustomContextMenuRequested(const QPoint & pos) +{ + // Execute menu offering to check/uncheck all + QMenu menu; + QAction *checkAllAction = menu.addAction(tr("Check All")); + QAction *uncheckAllAction = menu.addAction(tr("Uncheck All")); + QAction *action = menu.exec(m_d->m_ui.fileView->mapToGlobal(pos)); + if (action == checkAllAction) { + checkAll(); + return; + } + if (action == uncheckAllAction) { + uncheckAll(); + return; + } } } // namespace Utils diff --git a/src/libs/utils/submiteditorwidget.h b/src/libs/utils/submiteditorwidget.h index 03f98ace98..e31fb8cd3c 100644 --- a/src/libs/utils/submiteditorwidget.h +++ b/src/libs/utils/submiteditorwidget.h @@ -80,6 +80,9 @@ public: explicit SubmitEditorWidget(QWidget *parent = 0); virtual ~SubmitEditorWidget(); + // Register/Unregister actions that are managed by ActionManager with this widget. + // The submit action should have Core::Command::CA_UpdateText set as its text will + // be updated. void registerActions(QAction *editorUndoAction, QAction *editorRedoAction, QAction *submitAction = 0, QAction *diffAction = 0); void unregisterActions(QAction *editorUndoAction, QAction *editorRedoAction, @@ -121,6 +124,11 @@ signals: void diffSelected(const QStringList &); void fileSelectionChanged(bool someFileSelected); void fileCheckStateChanged(bool someFileChecked); + void submitActionTextChanged(const QString &); + +public slots: + void checkAll(); + void uncheckAll(); protected: virtual void changeEvent(QEvent *e); @@ -134,10 +142,11 @@ private slots: void updateSubmitAction(); void updateDiffAction(); void editorCustomContextMenuRequested(const QPoint &); + void fileListCustomContextMenuRequested(const QPoint & pos); private: bool hasSelection() const; - bool hasCheckedFiles() const; + unsigned checkedFilesCount() const; SubmitEditorWidgetPrivate *m_d; }; diff --git a/src/plugins/cvs/cvsplugin.cpp b/src/plugins/cvs/cvsplugin.cpp index 84f7dc19f3..a7a1b273be 100644 --- a/src/plugins/cvs/cvsplugin.cpp +++ b/src/plugins/cvs/cvsplugin.cpp @@ -450,6 +450,7 @@ bool CVSPlugin::initialize(const QStringList & /*arguments */, QString *errorMes m_submitCurrentLogAction = new QAction(VCSBase::VCSBaseSubmitEditor::submitIcon(), tr("Commit"), this); command = ami->registerAction(m_submitCurrentLogAction, Constants::SUBMIT_CURRENT, cvscommitcontext); + command->setAttribute(Core::Command::CA_UpdateText); connect(m_submitCurrentLogAction, SIGNAL(triggered()), this, SLOT(submitCurrentLog())); m_submitDiffAction = new QAction(VCSBase::VCSBaseSubmitEditor::diffIcon(), tr("Diff Selected Files"), this); diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index 25ca3fd89e..efc7af9b2f 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -500,6 +500,7 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) Core::Context submitContext(Constants::C_GITSUBMITEDITOR); m_submitCurrentAction = new QAction(VCSBase::VCSBaseSubmitEditor::submitIcon(), tr("Commit"), this); Core::Command *command = actionManager->registerAction(m_submitCurrentAction, Constants::SUBMIT_CURRENT, submitContext); + command->setAttribute(Core::Command::CA_UpdateText); connect(m_submitCurrentAction, SIGNAL(triggered()), this, SLOT(submitCurrentLog())); m_diffSelectedFilesAction = new QAction(VCSBase::VCSBaseSubmitEditor::diffIcon(), tr("Diff Selected Files"), this); diff --git a/src/plugins/mercurial/mercurialplugin.cpp b/src/plugins/mercurial/mercurialplugin.cpp index 3a0a4372e0..4495cbddce 100644 --- a/src/plugins/mercurial/mercurialplugin.cpp +++ b/src/plugins/mercurial/mercurialplugin.cpp @@ -538,6 +538,7 @@ void MercurialPlugin::createSubmitEditorActions() editorCommit = new QAction(VCSBase::VCSBaseSubmitEditor::submitIcon(), tr("Commit"), this); command = actionManager->registerAction(editorCommit, QLatin1String(Constants::COMMIT), context); + command->setAttribute(Core::Command::CA_UpdateText); connect(editorCommit, SIGNAL(triggered()), this, SLOT(commitFromEditor())); editorDiff = new QAction(VCSBase::VCSBaseSubmitEditor::diffIcon(), tr("Diff Selected Files"), this); diff --git a/src/plugins/perforce/perforceplugin.cpp b/src/plugins/perforce/perforceplugin.cpp index ea8e0cd64c..c338cdd59d 100644 --- a/src/plugins/perforce/perforceplugin.cpp +++ b/src/plugins/perforce/perforceplugin.cpp @@ -435,6 +435,7 @@ bool PerforcePlugin::initialize(const QStringList & /* arguments */, QString *er m_submitCurrentLogAction = new QAction(VCSBase::VCSBaseSubmitEditor::submitIcon(), tr("Submit"), this); command = am->registerAction(m_submitCurrentLogAction, Constants::SUBMIT_CURRENT, perforcesubmitcontext); + command->setAttribute(Core::Command::CA_UpdateText); connect(m_submitCurrentLogAction, SIGNAL(triggered()), this, SLOT(submitCurrentLog())); m_diffSelectedFiles = new QAction(VCSBase::VCSBaseSubmitEditor::diffIcon(), tr("Diff Selected Files"), this); diff --git a/src/plugins/subversion/subversionplugin.cpp b/src/plugins/subversion/subversionplugin.cpp index 089b1c38a1..5fb3c1b382 100644 --- a/src/plugins/subversion/subversionplugin.cpp +++ b/src/plugins/subversion/subversionplugin.cpp @@ -458,6 +458,7 @@ bool SubversionPlugin::initialize(const QStringList & /*arguments */, QString *e m_submitCurrentLogAction = new QAction(VCSBase::VCSBaseSubmitEditor::submitIcon(), tr("Commit"), this); command = ami->registerAction(m_submitCurrentLogAction, Constants::SUBMIT_CURRENT, svncommitcontext); + command->setAttribute(Core::Command::CA_UpdateText); connect(m_submitCurrentLogAction, SIGNAL(triggered()), this, SLOT(submitCurrentLog())); m_submitDiffAction = new QAction(VCSBase::VCSBaseSubmitEditor::diffIcon(), tr("Diff Selected Files"), this); |