diff --git a/src/plugins/git/branchcheckoutdialog.cpp b/src/plugins/git/branchcheckoutdialog.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fc0c34aefa7b842e537e6d69a5036b66a69ea5eb --- /dev/null +++ b/src/plugins/git/branchcheckoutdialog.cpp @@ -0,0 +1,88 @@ +#include "branchcheckoutdialog.h" +#include "ui_branchcheckoutdialog.h" + +namespace Git { +namespace Internal { + +BranchCheckoutDialog::BranchCheckoutDialog(QWidget *parent, + const QString& currentBranch, + const QString& nextBranch) : + QDialog(parent), + m_ui(new Ui::BranchCheckoutDialog), + m_foundStashForNextBranch(false), + m_hasLocalChanges(true) +{ + m_ui->setupUi(this); + + setWindowTitle(tr("Checkout branch \"%1\"").arg(nextBranch)); + m_ui->moveChangesRadioButton->setText(tr("Move Local Changes to \"%1\"").arg(nextBranch)); + m_ui->popStashCheckBox->setText(tr("Pop Stash of \"%1\"").arg(nextBranch)); + + if (!currentBranch.isEmpty()) { + m_ui->makeStashRadioButton->setText(tr("Create Branch Stash for \"%1\"").arg(currentBranch)); + } else { + m_ui->makeStashRadioButton->setText(tr("Create Branch Stash for Current Branch")); + foundNoLocalChanges(); + } + + connect(m_ui->moveChangesRadioButton, SIGNAL(toggled(bool)), this, SLOT(updatePopStashCheckBox(bool))); +} + +BranchCheckoutDialog::~BranchCheckoutDialog() +{ + delete m_ui; +} + +void BranchCheckoutDialog::foundNoLocalChanges() +{ + m_ui->discardChangesRadioButton->setChecked(true); + m_ui->localChangesGroupBox->setEnabled(false); + m_hasLocalChanges = false; +} + +void BranchCheckoutDialog::foundStashForNextBranch() +{ + m_ui->popStashCheckBox->setChecked(true); + m_ui->popStashCheckBox->setEnabled(true); + m_foundStashForNextBranch = true; +} + +bool BranchCheckoutDialog::makeStashOfCurrentBranch() +{ + return m_ui->makeStashRadioButton->isChecked(); +} + +bool BranchCheckoutDialog::moveLocalChangesToNextBranch() +{ + return m_ui->moveChangesRadioButton->isChecked(); +} + +bool BranchCheckoutDialog::discardLocalChanges() +{ + return m_ui->discardChangesRadioButton->isChecked() && m_ui->localChangesGroupBox->isEnabled(); +} + +bool BranchCheckoutDialog::popStashOfNextBranch() +{ + return m_ui->popStashCheckBox->isChecked(); +} + +bool BranchCheckoutDialog::hasStashForNextBranch() +{ + return m_foundStashForNextBranch; +} + +bool BranchCheckoutDialog::hasLocalChanges() +{ + return m_hasLocalChanges; +} + +void BranchCheckoutDialog::updatePopStashCheckBox(bool moveChangesChecked) +{ + m_ui->popStashCheckBox->setChecked(!moveChangesChecked && m_foundStashForNextBranch); + m_ui->popStashCheckBox->setEnabled(!moveChangesChecked && m_foundStashForNextBranch); +} + +} // namespace Internal +} // namespace Git + diff --git a/src/plugins/git/branchcheckoutdialog.h b/src/plugins/git/branchcheckoutdialog.h new file mode 100644 index 0000000000000000000000000000000000000000..a794b8ef3666cecc9b938e7ddcc856e944881563 --- /dev/null +++ b/src/plugins/git/branchcheckoutdialog.h @@ -0,0 +1,45 @@ +#ifndef BRANCHCHECKOUTDIALOG_H +#define BRANCHCHECKOUTDIALOG_H + +#include <QDialog> + +namespace Git { +namespace Internal { + +namespace Ui { + class BranchCheckoutDialog; +} + +class BranchCheckoutDialog : public QDialog +{ + Q_OBJECT + +public: + explicit BranchCheckoutDialog(QWidget *parent, const QString& currentBranch, + const QString& nextBranch); + ~BranchCheckoutDialog(); + + void foundNoLocalChanges(); + void foundStashForNextBranch(); + + bool makeStashOfCurrentBranch(); + bool moveLocalChangesToNextBranch(); + bool discardLocalChanges(); + bool popStashOfNextBranch(); + + bool hasStashForNextBranch(); + bool hasLocalChanges(); + +private slots: + void updatePopStashCheckBox(bool moveChangesChecked); + +private: + Ui::BranchCheckoutDialog *m_ui; + bool m_foundStashForNextBranch; + bool m_hasLocalChanges; +}; + +} // namespace Internal +} // namespace Git + +#endif // BRANCHCHECKOUTDIALOG_H diff --git a/src/plugins/git/branchcheckoutdialog.ui b/src/plugins/git/branchcheckoutdialog.ui new file mode 100644 index 0000000000000000000000000000000000000000..b8cbc406a9b56acc43c3de4fe8bb63abf59a8319 --- /dev/null +++ b/src/plugins/git/branchcheckoutdialog.ui @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Git::Internal::BranchCheckoutDialog</class> + <widget class="QDialog" name="Git::Internal::BranchCheckoutDialog"> + <property name="windowModality"> + <enum>Qt::WindowModal</enum> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>394</width> + <height>199</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <property name="modal"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QGroupBox" name="localChangesGroupBox"> + <property name="title"> + <string>Local Changes Found. Choose Action:</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QRadioButton" name="makeStashRadioButton"> + <property name="text"> + <string>RadioButton</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="moveChangesRadioButton"> + <property name="text"> + <string>RadioButton</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="discardChangesRadioButton"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>Discard Local Changes</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QCheckBox" name="popStashCheckBox"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>CheckBox</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </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> + <tabstops> + <tabstop>discardChangesRadioButton</tabstop> + <tabstop>buttonBox</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>Git::Internal::BranchCheckoutDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>227</x> + <y>219</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>179</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>Git::Internal::BranchCheckoutDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>295</x> + <y>219</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>179</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/plugins/git/branchdialog.cpp b/src/plugins/git/branchdialog.cpp index b39adce43c9d112005fc15be5fbc82da645b09ae..bf36548700649ff22a2081379b74b362f442970b 100644 --- a/src/plugins/git/branchdialog.cpp +++ b/src/plugins/git/branchdialog.cpp @@ -29,9 +29,11 @@ #include "branchdialog.h" #include "branchadddialog.h" +#include "branchcheckoutdialog.h" #include "branchmodel.h" #include "gitclient.h" #include "gitplugin.h" +#include "gitutils.h" #include "ui_branchdialog.h" #include "stashdialog.h" // Label helpers @@ -42,6 +44,7 @@ #include <QItemSelectionModel> #include <QPushButton> #include <QMessageBox> +#include <QList> #include <QDebug> @@ -159,7 +162,59 @@ void BranchDialog::checkout() QModelIndex idx = selectedIndex(); QTC_CHECK(m_model->isLocal(idx)); - m_model->checkoutBranch(idx); + const QString currentBranch = m_model->branchName(m_model->currentBranch()); + const QString nextBranch = m_model->branchName(idx); + const QString popMessageStart = QCoreApplication::applicationName() + + QLatin1String(" ") + nextBranch + QLatin1String("-AutoStash "); + + BranchCheckoutDialog branchCheckoutDialog(this, currentBranch, nextBranch); + GitClient *gitClient = GitPlugin::instance()->gitClient(); + + if (gitClient->gitStatus(m_repository, StatusMode(NoUntracked | NoSubmodules)) != GitClient::StatusChanged) + branchCheckoutDialog.foundNoLocalChanges(); + + QList<Stash> stashes; + gitClient->synchronousStashList(m_repository, &stashes); + foreach (const Stash &stash, stashes) { + if (stash.message.startsWith(popMessageStart)) { + branchCheckoutDialog.foundStashForNextBranch(); + break; + } + } + + if (!branchCheckoutDialog.hasLocalChanges() && + !branchCheckoutDialog.hasStashForNextBranch()) { + // No local changes and no Auto Stash - no need to open dialog + m_model->checkoutBranch(idx); + } else if (branchCheckoutDialog.exec() == QDialog::Accepted && m_model) { + + QString stashMessage; + if (branchCheckoutDialog.makeStashOfCurrentBranch() + || branchCheckoutDialog.moveLocalChangesToNextBranch()) { + stashMessage = gitClient->synchronousStash(m_repository, currentBranch + QLatin1String("-AutoStash")); + } else if (branchCheckoutDialog.discardLocalChanges()) { + gitClient->synchronousReset(m_repository); + } + + m_model->checkoutBranch(idx); + + QString stashName; + gitClient->synchronousStashList(m_repository, &stashes); + foreach (const Stash &stash, stashes) { + if (stash.message.startsWith(popMessageStart)) { + stashName = stash.name; + break; + } + } + + if (!stashMessage.isEmpty() && branchCheckoutDialog.moveLocalChangesToNextBranch()) + gitClient->stashPop(m_repository); + else if (branchCheckoutDialog.popStashOfNextBranch()) + gitClient->synchronousStashRestore(m_repository, stashName); + + if (branchCheckoutDialog.hasStashForNextBranch()) + gitClient->synchronousStashRemove(m_repository, stashName); + } enableButtons(); } diff --git a/src/plugins/git/git.pro b/src/plugins/git/git.pro index 873ad6bacd8274daac73b7f4c68a1f59470488a7..7ddef370978bbcc632cc4062a60b4179aff9ac9d 100644 --- a/src/plugins/git/git.pro +++ b/src/plugins/git/git.pro @@ -29,7 +29,8 @@ HEADERS += gitplugin.h \ remotedialog.h \ branchadddialog.h \ resetdialog.h \ - mergetool.h + mergetool.h \ + branchcheckoutdialog.h SOURCES += gitplugin.cpp \ gitclient.cpp \ @@ -52,7 +53,8 @@ SOURCES += gitplugin.cpp \ remotedialog.cpp \ branchadddialog.cpp \ resetdialog.cpp \ - mergetool.cpp + mergetool.cpp \ + branchcheckoutdialog.cpp FORMS += changeselectiondialog.ui \ settingspage.ui \ @@ -61,7 +63,8 @@ FORMS += changeselectiondialog.ui \ stashdialog.ui \ remotedialog.ui \ remoteadditiondialog.ui \ - branchadddialog.ui + branchadddialog.ui \ + branchcheckoutdialog.ui include(gitorious/gitorious.pri) diff --git a/src/plugins/git/git.qbs b/src/plugins/git/git.qbs index ec5a0af2927b8e37f7956f55a7bc3ebba5e492c7..92c2597219cdfe797e2f43a922beee5e14540661 100644 --- a/src/plugins/git/git.qbs +++ b/src/plugins/git/git.qbs @@ -21,6 +21,9 @@ QtcPlugin { "branchadddialog.cpp", "branchadddialog.h", "branchadddialog.ui", + "branchcheckoutdialog.cpp", + "branchcheckoutdialog.h", + "branchcheckoutdialog.ui", "branchdialog.cpp", "branchdialog.h", "branchdialog.ui",