diff options
-rw-r--r-- | src/plugins/git/git.pro | 15 | ||||
-rw-r--r-- | src/plugins/git/gitclient.cpp | 15 | ||||
-rw-r--r-- | src/plugins/git/gitclient.h | 2 | ||||
-rw-r--r-- | src/plugins/git/gitplugin.cpp | 12 | ||||
-rw-r--r-- | src/plugins/git/gitplugin.h | 3 | ||||
-rw-r--r-- | src/plugins/git/remoteadditiondialog.ui | 84 | ||||
-rw-r--r-- | src/plugins/git/remotedialog.cpp | 168 | ||||
-rw-r--r-- | src/plugins/git/remotedialog.h | 103 | ||||
-rw-r--r-- | src/plugins/git/remotedialog.ui | 119 | ||||
-rw-r--r-- | src/plugins/git/remotemodel.cpp | 232 | ||||
-rw-r--r-- | src/plugins/git/remotemodel.h | 97 |
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 |