forked from qt-creator/qt-creator
Fixes: Start a git branch dialog.
This commit is contained in:
174
src/plugins/git/branchdialog.cpp
Normal file
174
src/plugins/git/branchdialog.cpp
Normal file
@@ -0,0 +1,174 @@
|
||||
#include "branchdialog.h"
|
||||
#include "branchmodel.h"
|
||||
#include "gitclient.h"
|
||||
#include "ui_branchdialog.h"
|
||||
|
||||
#include <QtGui/QItemSelectionModel>
|
||||
#include <QtGui/QPushButton>
|
||||
#include <QtGui/QMessageBox>
|
||||
|
||||
// Single selection helper
|
||||
static inline int selectedRow(const QAbstractItemView *listView)
|
||||
{
|
||||
const QModelIndexList indexList = listView->selectionModel()->selectedIndexes();
|
||||
if (indexList.size() == 1)
|
||||
return indexList.front().row();
|
||||
return -1;
|
||||
}
|
||||
|
||||
namespace Git {
|
||||
namespace Internal {
|
||||
|
||||
BranchDialog::BranchDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
m_client(0),
|
||||
m_ui(new Ui::BranchDialog),
|
||||
m_checkoutButton(0),
|
||||
m_deleteButton(0),
|
||||
m_localModel(0),
|
||||
m_remoteModel(0)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
m_checkoutButton = m_ui->buttonBox->addButton(tr("Checkout"), QDialogButtonBox::AcceptRole);
|
||||
connect(m_checkoutButton, SIGNAL(clicked()), this, SLOT(slotCheckoutSelectedBranch()));
|
||||
|
||||
m_deleteButton = m_ui->buttonBox->addButton(tr("Delete"), QDialogButtonBox::ActionRole);
|
||||
connect(m_deleteButton, SIGNAL(clicked()), this, SLOT(slotDeleteSelectedBranch()));
|
||||
|
||||
connect(m_ui->localBranchListView, SIGNAL(doubleClicked(QModelIndex)), this,
|
||||
SLOT(slotLocalBranchActivated()));
|
||||
}
|
||||
|
||||
BranchDialog::~BranchDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
bool BranchDialog::init(GitClient *client, const QString &workingDirectory, QString *errorMessage)
|
||||
{
|
||||
// Find repository and populate models.
|
||||
m_client = client;
|
||||
m_repoDirectory = GitClient::findRepositoryForDirectory(workingDirectory);
|
||||
if (m_repoDirectory.isEmpty()) {
|
||||
*errorMessage = tr("Unable to find the repository directory for '%1'.").arg(workingDirectory);
|
||||
return false;
|
||||
}
|
||||
m_ui->repositoryFieldLabel->setText(m_repoDirectory);
|
||||
|
||||
m_localModel = new BranchModel(client, BranchModel::LocalBranches, this);
|
||||
m_remoteModel = new BranchModel(client, BranchModel::RemoteBranches, this);
|
||||
if (!m_localModel->refresh(workingDirectory, errorMessage)
|
||||
|| !m_remoteModel->refresh(workingDirectory, errorMessage))
|
||||
return false;
|
||||
|
||||
m_ui->localBranchListView->setModel(m_localModel);
|
||||
m_ui->remoteBranchListView->setModel(m_remoteModel);
|
||||
// Selection model comes into existence only now
|
||||
connect(m_ui->localBranchListView->selectionModel(),
|
||||
SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
||||
this, SLOT(slotEnableButtons()));
|
||||
connect(m_ui->remoteBranchListView->selectionModel(),
|
||||
SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
||||
this, SLOT(slotEnableButtons()));
|
||||
slotEnableButtons();
|
||||
return true;
|
||||
}
|
||||
|
||||
int BranchDialog::selectedLocalBranchIndex() const
|
||||
{
|
||||
return selectedRow(m_ui->localBranchListView);
|
||||
}
|
||||
|
||||
int BranchDialog::selectedRemoteBranchIndex() const
|
||||
{
|
||||
return selectedRow(m_ui->remoteBranchListView);
|
||||
}
|
||||
|
||||
void BranchDialog::slotEnableButtons()
|
||||
{
|
||||
// We can switch to or delete branches that are not current.
|
||||
const int selectedLocalRow = selectedLocalBranchIndex();
|
||||
const int currentLocalBranch = m_localModel->currentBranch();
|
||||
|
||||
const bool hasSelection = selectedLocalRow != -1;
|
||||
const bool currentIsNotSelected = hasSelection && selectedLocalRow != currentLocalBranch;
|
||||
|
||||
m_checkoutButton->setEnabled(currentIsNotSelected);
|
||||
m_deleteButton->setEnabled(currentIsNotSelected);
|
||||
}
|
||||
|
||||
bool BranchDialog::ask(const QString &title, const QString &what, bool defaultButton)
|
||||
{
|
||||
return QMessageBox::question(this, title, what, QMessageBox::Yes|QMessageBox::No,
|
||||
defaultButton ? QMessageBox::Yes : QMessageBox::No) == QMessageBox::Yes;
|
||||
}
|
||||
|
||||
/* Prompt to delete a local branch and do so. */
|
||||
void BranchDialog::slotDeleteSelectedBranch()
|
||||
{
|
||||
const int idx = selectedLocalBranchIndex();
|
||||
if (idx == -1)
|
||||
return;
|
||||
const QString name = m_localModel->branchName(idx);
|
||||
if (!ask(tr("Delete Branch"), tr("Would you like to delete the branch '%1'?").arg(name), true))
|
||||
return;
|
||||
QString errorMessage;
|
||||
bool ok = false;
|
||||
do {
|
||||
QString output;
|
||||
QStringList args(QLatin1String("-D"));
|
||||
args << name;
|
||||
if (!m_client->synchronousBranchCmd(m_repoDirectory, args, &output, &errorMessage))
|
||||
break;
|
||||
if (!m_localModel->refresh(m_repoDirectory, &errorMessage))
|
||||
break;
|
||||
ok = true;
|
||||
} while (false);
|
||||
slotEnableButtons();
|
||||
if (!ok)
|
||||
QMessageBox::warning(this, tr("Failed to delete branch"), errorMessage);
|
||||
}
|
||||
|
||||
void BranchDialog::slotLocalBranchActivated()
|
||||
{
|
||||
if (m_checkoutButton->isEnabled())
|
||||
m_checkoutButton->animateClick();
|
||||
}
|
||||
|
||||
/* Ask to stash away changes and then close dialog and do an asynchronous
|
||||
* checkout. */
|
||||
void BranchDialog::slotCheckoutSelectedBranch()
|
||||
{
|
||||
const int idx = selectedLocalBranchIndex();
|
||||
if (idx == -1)
|
||||
return;
|
||||
const QString name = m_localModel->branchName(idx);
|
||||
QString errorMessage;
|
||||
switch (m_client->ensureStash(m_repoDirectory, &errorMessage)) {
|
||||
case GitClient::StashUnchanged:
|
||||
case GitClient::Stashed:
|
||||
case GitClient::NotStashed:
|
||||
break;
|
||||
case GitClient::StashCanceled:
|
||||
return;
|
||||
case GitClient::StashFailed:
|
||||
QMessageBox::warning(this, tr("Failed to stash"), errorMessage);
|
||||
return;
|
||||
}
|
||||
accept();
|
||||
m_client->checkoutBranch(m_repoDirectory, name);
|
||||
}
|
||||
|
||||
void BranchDialog::changeEvent(QEvent *e)
|
||||
{
|
||||
switch (e->type()) {
|
||||
case QEvent::LanguageChange:
|
||||
m_ui->retranslateUi(this);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Git
|
||||
Reference in New Issue
Block a user