summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/plugins/git/git.pro15
-rw-r--r--src/plugins/git/gitclient.cpp15
-rw-r--r--src/plugins/git/gitclient.h2
-rw-r--r--src/plugins/git/gitplugin.cpp12
-rw-r--r--src/plugins/git/gitplugin.h3
-rw-r--r--src/plugins/git/remoteadditiondialog.ui84
-rw-r--r--src/plugins/git/remotedialog.cpp168
-rw-r--r--src/plugins/git/remotedialog.h103
-rw-r--r--src/plugins/git/remotedialog.ui119
-rw-r--r--src/plugins/git/remotemodel.cpp232
-rw-r--r--src/plugins/git/remotemodel.h97
11 files changed, 847 insertions, 3 deletions
diff --git a/src/plugins/git/git.pro b/src/plugins/git/git.pro
index 435519768a..f0ee631596 100644
--- a/src/plugins/git/git.pro
+++ b/src/plugins/git/git.pro
@@ -24,7 +24,10 @@ HEADERS += gitplugin.h \
clonewizard.h \
clonewizardpage.h \
stashdialog.h \
- gitutils.h
+ gitutils.h \
+ remotemodel.h \
+ remotedialog.h \
+
SOURCES += gitplugin.cpp \
gitclient.cpp \
changeselectiondialog.cpp \
@@ -42,12 +45,18 @@ SOURCES += gitplugin.cpp \
clonewizard.cpp \
clonewizardpage.cpp \
stashdialog.cpp \
- gitutils.cpp
+ gitutils.cpp \
+ remotemodel.cpp \
+ remotedialog.cpp \
+
FORMS += changeselectiondialog.ui \
settingspage.ui \
gitsubmitpanel.ui \
branchdialog.ui \
- stashdialog.ui
+ stashdialog.ui \
+ remotedialog.ui \
+ remoteadditiondialog.ui \
+
include(gitorious/gitorious.pri)
RESOURCES += \
diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp
index c543cbf769..1ddae48c76 100644
--- a/src/plugins/git/gitclient.cpp
+++ b/src/plugins/git/gitclient.cpp
@@ -1340,6 +1340,21 @@ bool GitClient::synchronousBranchCmd(const QString &workingDirectory, QStringLis
return true;
}
+bool GitClient::synchronousRemoteCmd(const QString &workingDirectory, QStringList remoteArgs,
+ QString *output, QString *errorMessage)
+{
+ remoteArgs.push_front(QLatin1String("remote"));
+ QByteArray outputText;
+ QByteArray errorText;
+ const bool rc = fullySynchronousGit(workingDirectory, remoteArgs, &outputText, &errorText);
+ if (!rc) {
+ *errorMessage = tr("Unable to run a 'git remote' command in %1: %2").arg(QDir::toNativeSeparators(workingDirectory), commandOutputFromLocal8Bit(errorText));
+ return false;
+ }
+ *output = commandOutputFromLocal8Bit(outputText);
+ return true;
+}
+
bool GitClient::synchronousShow(const QString &workingDirectory, const QString &id,
QString *output, QString *errorMessage)
{
diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h
index 3b9588882a..1e9c49338d 100644
--- a/src/plugins/git/gitclient.h
+++ b/src/plugins/git/gitclient.h
@@ -143,6 +143,8 @@ public:
QString *errorMessage = 0);
bool synchronousBranchCmd(const QString &workingDirectory, QStringList branchArgs,
QString *output, QString *errorMessage);
+ bool synchronousRemoteCmd(const QString &workingDirectory, QStringList remoteArgs,
+ QString *output, QString *errorMessage);
bool synchronousShow(const QString &workingDirectory, const QString &id,
QString *output, QString *errorMessage);
bool synchronousParentRevisions(const QString &workingDirectory,
diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp
index 76d681b7d3..f192b97054 100644
--- a/src/plugins/git/gitplugin.cpp
+++ b/src/plugins/git/gitplugin.cpp
@@ -40,6 +40,7 @@
#include "gitsubmiteditor.h"
#include "gitversioncontrol.h"
#include "branchdialog.h"
+#include "remotedialog.h"
#include "clonewizard.h"
#include "gitoriousclonewizard.h"
#include "stashdialog.h"
@@ -432,6 +433,10 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage)
tr("Branches..."), QLatin1String("Git.BranchList"),
globalcontext, false, SLOT(branchList()));
+ createRepositoryAction(actionManager, gitContainer,
+ tr("Remotes..."), QLatin1String("Git.RemoteList"),
+ globalcontext, false, SLOT(remoteList()));
+
m_showAction = new QAction(tr("Show Commit..."), this);
Core::Command *showCommitCommand = actionManager->registerAction(m_showAction, "Git.ShowCommit", globalcontext);
connect(m_showAction, SIGNAL(triggered()), this, SLOT(showCommit()));
@@ -1000,6 +1005,11 @@ void GitPlugin::branchList()
showNonModalDialog(currentState().topLevel(), m_branchDialog);
}
+void GitPlugin::remoteList()
+{
+ showNonModalDialog(currentState().topLevel(), m_remoteDialog);
+}
+
void GitPlugin::stashList()
{
showNonModalDialog(currentState().topLevel(), m_stashDialog);
@@ -1012,6 +1022,8 @@ void GitPlugin::updateActions(VCSBase::VCSBasePlugin::ActionState as)
m_stashDialog->refresh(currentState().topLevel(), false);
if (m_branchDialog)
m_branchDialog->refresh(currentState().topLevel(), false);
+ if (m_remoteDialog)
+ m_remoteDialog->refresh(currentState().topLevel(), false);
m_commandLocator->setEnabled(repositoryEnabled);
if (!enableMenuAction(as, m_menuAction))
diff --git a/src/plugins/git/gitplugin.h b/src/plugins/git/gitplugin.h
index 37ad4debcf..96039a0fd7 100644
--- a/src/plugins/git/gitplugin.h
+++ b/src/plugins/git/gitplugin.h
@@ -78,6 +78,7 @@ struct CommitData;
struct GitSettings;
class StashDialog;
class BranchDialog;
+class RemoteDialog;
typedef void (GitClient::*GitClientMemberFunc)(const QString &);
@@ -129,6 +130,7 @@ private slots:
void stash();
void stashSnapshot();
void branchList();
+ void remoteList();
void stashList();
void fetch();
void pull();
@@ -203,6 +205,7 @@ private:
ChangeSelectionDialog *m_changeSelectionDialog;
QPointer<StashDialog> m_stashDialog;
QPointer<BranchDialog> m_branchDialog;
+ QPointer<RemoteDialog> m_remoteDialog;
QString m_submitRepository;
QStringList m_submitOrigCommitFiles;
QStringList m_submitOrigDeleteFiles;
diff --git a/src/plugins/git/remoteadditiondialog.ui b/src/plugins/git/remoteadditiondialog.ui
new file mode 100644
index 0000000000..a05dcdf14c
--- /dev/null
+++ b/src/plugins/git/remoteadditiondialog.ui
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Git::Internal::RemoteAdditionDialog</class>
+ <widget class="QDialog" name="Git::Internal::RemoteAdditionDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>381</width>
+ <height>93</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Add Remote</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="nameLabel">
+ <property name="text">
+ <string>Name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="nameEdit"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="urlLabel">
+ <property name="text">
+ <string>Url:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="urlEdit"/>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <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>rejected()</signal>
+ <receiver>Git::Internal::RemoteAdditionDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>283</x>
+ <y>81</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>380</x>
+ <y>27</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>Git::Internal::RemoteAdditionDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>211</x>
+ <y>81</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>182</x>
+ <y>92</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/plugins/git/remotedialog.cpp b/src/plugins/git/remotedialog.cpp
new file mode 100644
index 0000000000..7698999518
--- /dev/null
+++ b/src/plugins/git/remotedialog.cpp
@@ -0,0 +1,168 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+
+#include "remotedialog.h"
+
+#include "gitclient.h"
+#include "gitplugin.h"
+#include "remotemodel.h"
+#include "stashdialog.h" // for messages
+#include "ui_remotedialog.h"
+#include "ui_remoteadditiondialog.h"
+
+#include <vcsbase/vcsbaseoutputwindow.h>
+
+#include <QtGui/QItemSelectionModel>
+#include <QtGui/QPushButton>
+#include <QtGui/QMessageBox>
+
+namespace Git {
+namespace Internal {
+
+// --------------------------------------------------------------------------
+// RemoteAdditionDialog:
+// --------------------------------------------------------------------------
+
+RemoteAdditionDialog::RemoteAdditionDialog(QWidget *parent) :
+ QDialog(parent),
+ m_ui(new Ui::RemoteAdditionDialog)
+{
+ m_ui->setupUi(this);
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+}
+
+QString RemoteAdditionDialog::remoteName() const
+{
+ return m_ui->nameEdit->text();
+}
+
+QString RemoteAdditionDialog::remoteUrl() const
+{
+ return m_ui->urlEdit->text();
+}
+
+void RemoteAdditionDialog::clear()
+{
+ m_ui->nameEdit->setText(QString());
+ m_ui->urlEdit->setText(QString());
+}
+
+// --------------------------------------------------------------------------
+// RemoteDialog:
+// --------------------------------------------------------------------------
+
+
+RemoteDialog::RemoteDialog(QWidget *parent) :
+ QDialog(parent),
+ m_ui(new Ui::RemoteDialog),
+ m_remoteModel(new RemoteModel(GitPlugin::instance()->gitClient(), this)),
+ m_addDialog(0)
+{
+ setModal(false);
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ setAttribute(Qt::WA_DeleteOnClose, true); // Do not update unnecessarily
+
+ m_ui->setupUi(this);
+
+ m_ui->remoteView->setModel(m_remoteModel);
+ m_ui->remoteView->setMinimumHeight(400);
+ m_ui->remoteView->horizontalHeader()->setStretchLastSection(true);
+ m_ui->remoteView->horizontalHeader()->setResizeMode(0, QHeaderView::ResizeToContents);
+ QFontMetrics fm(font());
+ m_ui->remoteView->verticalHeader()->setDefaultSectionSize(qMax(static_cast<int>(fm.height() * 1.2), fm.height() + 4));
+
+ connect(m_ui->addButton, SIGNAL(clicked()), this, SLOT(addRemote()));
+ connect(m_ui->removeButton, SIGNAL(clicked()), this, SLOT(removeRemote()));
+}
+
+RemoteDialog::~RemoteDialog()
+{
+ delete m_ui;
+}
+
+void RemoteDialog::refresh(const QString &repository, bool force)
+{
+ if (m_repository == repository && !force)
+ return;
+ // Refresh
+ m_repository = repository;
+ m_ui->repositoryLabel->setText(StashDialog::msgRepositoryLabel(m_repository));
+ if (m_repository.isEmpty()) {
+ m_remoteModel->clear();
+ } else {
+ QString errorMessage;
+ if (!m_remoteModel->refresh(m_repository, &errorMessage))
+ VCSBase::VCSBaseOutputWindow::instance()->appendError(errorMessage);
+ }
+}
+
+void RemoteDialog::addRemote()
+{
+ if (!m_addDialog)
+ m_addDialog = new RemoteAdditionDialog;
+ m_addDialog->clear();
+
+ if (m_addDialog->exec() != QDialog::Accepted)
+ return;
+
+ m_remoteModel->addRemote(m_addDialog->remoteName(), m_addDialog->remoteUrl());
+}
+
+void RemoteDialog::removeRemote()
+{
+ const QModelIndexList indexList = m_ui->remoteView->selectionModel()->selectedIndexes();
+ if (indexList.count() == 0)
+ return;
+
+ int row = indexList.at(0).row();
+ const QString remoteName = m_remoteModel->remoteName(row);
+ if (QMessageBox::question(this, tr("Delete Remote"),
+ tr("Would you like to delete the remote '%1'?").arg(remoteName),
+ QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes) {
+ m_remoteModel->removeRemote(row);
+ }
+}
+
+void RemoteDialog::changeEvent(QEvent *e)
+{
+ QDialog::changeEvent(e);
+ switch (e->type()) {
+ case QEvent::LanguageChange:
+ m_ui->retranslateUi(this);
+ break;
+ default:
+ break;
+ }
+}
+
+} // namespace Internal
+} // namespace Git
diff --git a/src/plugins/git/remotedialog.h b/src/plugins/git/remotedialog.h
new file mode 100644
index 0000000000..3c6b10a115
--- /dev/null
+++ b/src/plugins/git/remotedialog.h
@@ -0,0 +1,103 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+
+#ifndef REMOTEDIALOG_H
+#define REMOTEDIALOG_H
+
+#include <QtGui/QDialog>
+
+namespace Git {
+namespace Internal {
+
+namespace Ui {
+class RemoteDialog;
+class RemoteAdditionDialog;
+}
+
+class GitClient;
+class RemoteModel;
+
+// --------------------------------------------------------------------------
+// RemoteAdditionDialog:
+// --------------------------------------------------------------------------
+
+class RemoteAdditionDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit RemoteAdditionDialog(QWidget *parent = 0);
+
+ QString remoteName() const;
+ QString remoteUrl() const;
+
+ void clear();
+
+private:
+ Ui::RemoteAdditionDialog *m_ui;
+};
+
+// --------------------------------------------------------------------------
+// RemoteDialog:
+// --------------------------------------------------------------------------
+
+class RemoteDialog : public QDialog {
+ Q_OBJECT
+
+public:
+ explicit RemoteDialog(QWidget *parent = 0);
+ ~RemoteDialog();
+
+public slots:
+ void refresh(const QString &repository, bool force);
+
+ void addRemote();
+ void removeRemote();
+
+private slots:
+
+protected:
+ virtual void changeEvent(QEvent *e);
+
+private:
+ Ui::RemoteDialog *m_ui;
+
+ RemoteModel *m_remoteModel;
+ RemoteAdditionDialog *m_addDialog;
+
+ QString m_repository;
+};
+
+} // namespace Internal
+} // namespace Git
+
+#endif // REMOTEDIALOG_H
diff --git a/src/plugins/git/remotedialog.ui b/src/plugins/git/remotedialog.ui
new file mode 100644
index 0000000000..b80f598f02
--- /dev/null
+++ b/src/plugins/git/remotedialog.ui
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Git::Internal::RemoteDialog</class>
+ <widget class="QDialog" name="Git::Internal::RemoteDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>514</width>
+ <height>527</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Remotes</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QGroupBox" name="infoGroupBox">
+ <layout class="QFormLayout" name="formLayout">
+ <item row="0" column="0" colspan="2">
+ <widget class="QLabel" name="repositoryLabel">
+ <property name="text">
+ <string notr="true">Repository: Dummy</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="remoteGroupBox">
+ <property name="title">
+ <string>Remotes</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTableView" name="remoteView">
+ <property name="editTriggers">
+ <set>QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed</set>
+ </property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::SingleSelection</enum>
+ </property>
+ <property name="selectionBehavior">
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ <property name="showGrid">
+ <bool>false</bool>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ <attribute name="horizontalHeaderVisible">
+ <bool>false</bool>
+ </attribute>
+ <attribute name="verticalHeaderVisible">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="addButton">
+ <property name="text">
+ <string>Add...</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="removeButton">
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Close</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>Git::Internal::RemoteDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>466</x>
+ <y>614</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>544</x>
+ <y>23</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/plugins/git/remotemodel.cpp b/src/plugins/git/remotemodel.cpp
new file mode 100644
index 0000000000..3e7b21d3ec
--- /dev/null
+++ b/src/plugins/git/remotemodel.cpp
@@ -0,0 +1,232 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+
+#include "remotemodel.h"
+#include "gitclient.h"
+
+namespace Git {
+namespace Internal {
+
+// Parse a branch line: " *name sha description".
+bool RemoteModel::Remote::parse(const QString &line)
+{
+ if (!line.endsWith(" (fetch)"))
+ return false;
+
+ QStringList tokens = line.split(QRegExp("\\s"), QString::SkipEmptyParts);
+ if (tokens.count() != 3)
+ return false;
+
+ name = tokens.at(0);
+ url = tokens.at(1);
+ return true;
+}
+
+// ------ RemoteModel
+RemoteModel::RemoteModel(GitClient *client, QObject *parent) :
+ QAbstractTableModel(parent),
+ m_flags(Qt::ItemIsSelectable|Qt::ItemIsEnabled|Qt::ItemIsEditable),
+ m_client(client)
+{ }
+
+bool RemoteModel::refresh(const QString &workingDirectory, QString *errorMessage)
+{
+ return refreshRemotes(workingDirectory, errorMessage);
+}
+
+QString RemoteModel::remoteName(int row) const
+{
+ return m_remotes.at(row).name;
+}
+
+QString RemoteModel::remoteUrl(int row) const
+{
+ return m_remotes.at(row).url;
+}
+
+bool RemoteModel::removeRemote(int row)
+{
+ QString output;
+ QString error;
+ bool success = runGitRemoteCommand(m_workingDirectory,
+ QStringList() << QLatin1String("rm") << remoteName(row),
+ &output, &error);
+ if (success)
+ success = refreshRemotes(m_workingDirectory, &error);
+ return success;
+}
+
+bool RemoteModel::addRemote(const QString &name, const QString &url)
+{
+ QString output;
+ QString error;
+ if (name.isEmpty() || url.isEmpty())
+ return false;
+
+ bool success = runGitRemoteCommand(m_workingDirectory,
+ QStringList() << QLatin1String("add") << name << url,
+ &output, &error);
+ if (success)
+ success = refreshRemotes(m_workingDirectory, &error);
+ return success;
+}
+
+bool RemoteModel::renameRemote(const QString &oldName, const QString &newName)
+{
+ QString output;
+ QString error;
+ bool success = runGitRemoteCommand(m_workingDirectory,
+ QStringList() << QLatin1String("rename") << oldName << newName,
+ &output, &error);
+ if (success)
+ success = refreshRemotes(m_workingDirectory, &error);
+ return success;
+}
+
+bool RemoteModel::updateUrl(const QString &name, const QString &newUrl)
+{
+ QString output;
+ QString error;
+ bool success = runGitRemoteCommand(m_workingDirectory,
+ QStringList() << QLatin1String("set-url") << name << newUrl,
+ &output, &error);
+ if (success)
+ success = refreshRemotes(m_workingDirectory, &error);
+ return success;
+}
+
+QString RemoteModel::workingDirectory() const
+{
+ return m_workingDirectory;
+}
+
+int RemoteModel::remoteCount() const
+{
+ return m_remotes.size();
+}
+
+int RemoteModel::rowCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent);
+ return remoteCount();
+}
+
+int RemoteModel::columnCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent);
+ return 2;
+}
+
+QVariant RemoteModel::data(const QModelIndex &index, int role) const
+{
+ const int row = index.row();
+ switch (role) {
+ case Qt::DisplayRole:
+ case Qt::EditRole:
+ if (index.column() == 0)
+ return remoteName(row);
+ else
+ return remoteUrl(row);
+ default:
+ break;
+ }
+ return QVariant();
+}
+
+bool RemoteModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ if (role != Qt::EditRole)
+ return false;
+
+ const QString name = remoteName(index.row());
+ switch (index.column()) {
+ case 0:
+ return renameRemote(name, value.toString());
+ case 1:
+ return updateUrl(name, value.toString());
+ default:
+ return false;
+ }
+}
+
+Qt::ItemFlags RemoteModel::flags(const QModelIndex &index) const
+{
+ Q_UNUSED(index);
+ return m_flags;
+}
+
+bool RemoteModel::runGitRemoteCommand(const QString &workingDirectory, const QStringList &additionalArgs, QString *output, QString *errorMessage)
+{
+ return m_client->synchronousRemoteCmd(workingDirectory, additionalArgs, output, errorMessage);
+}
+
+void RemoteModel::clear()
+{
+ if (m_remotes.isEmpty())
+ return;
+ m_remotes.clear();
+ reset();
+}
+
+bool RemoteModel::refreshRemotes(const QString &workingDirectory, QString *errorMessage)
+{
+ // Run branch command with verbose.
+ QStringList remoteArgs;
+ remoteArgs << QLatin1String("-v");
+ QString output;
+ if (!runGitRemoteCommand(workingDirectory, remoteArgs, &output, errorMessage))
+ return false;
+ // Parse output
+ m_workingDirectory = workingDirectory;
+ m_remotes.clear();
+ const QStringList lines = output.split(QLatin1Char('\n'));
+ for (int r = 0; r < lines.count(); ++r) {
+ Remote newRemote;
+ if (newRemote.parse(lines.at(r)))
+ m_remotes.push_back(newRemote);
+ }
+ reset();
+ return true;
+}
+
+int RemoteModel::findRemoteByName(const QString &name) const
+{
+ const int count = remoteCount();
+ for (int i = 0; i < count; i++)
+ if (remoteName(i) == name)
+ return i;
+ return -1;
+}
+
+} // namespace Internal
+} // namespace Git
+
diff --git a/src/plugins/git/remotemodel.h b/src/plugins/git/remotemodel.h
new file mode 100644
index 0000000000..f54d73fc90
--- /dev/null
+++ b/src/plugins/git/remotemodel.h
@@ -0,0 +1,97 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+
+#ifndef REMOTEMODEL_H
+#define REMOTEMODEL_H
+
+#include <QtCore/QAbstractTableModel>
+#include <QtCore/QList>
+#include <QtCore/QVariant>
+
+namespace Git {
+namespace Internal {
+
+class GitClient;
+
+class RemoteModel : public QAbstractTableModel {
+ Q_OBJECT
+public:
+ explicit RemoteModel(GitClient *client, QObject *parent = 0);
+
+ virtual void clear();
+ virtual bool refresh(const QString &workingDirectory, QString *errorMessage);
+
+ QString remoteName(int row) const;
+ QString remoteUrl(int row) const;
+
+ bool removeRemote(int row);
+ bool addRemote(const QString &name, const QString &url);
+ bool renameRemote(const QString &oldName, const QString &newName);
+ bool updateUrl(const QString &name, const QString &newUrl);
+
+ // QAbstractListModel
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ bool setData(const QModelIndex &index, const QVariant &value, int role);
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+
+ int remoteCount() const;
+
+ QString workingDirectory() const;
+ int findRemoteByName(const QString &name) const;
+
+protected:
+ struct Remote {
+ bool parse(const QString &line);
+
+ QString name;
+ QString url;
+ };
+ typedef QList<Remote> RemoteList;
+
+ /* Parse git output and populate m_branches. */
+ bool refreshRemotes(const QString &workingDirectory, QString *errorMessage);
+ bool runGitRemoteCommand(const QString &workingDirectory, const QStringList &additionalArgs, QString *output, QString *errorMessage);
+
+private:
+ const Qt::ItemFlags m_flags;
+
+ GitClient *m_client;
+ QString m_workingDirectory;
+ RemoteList m_remotes;
+};
+
+} // namespace Internal
+} // namespace Git
+
+#endif // REMOTEMODEL_H