GerritDialog: Support multiple remotes

Still SSH only for now...

Change-Id: I9b007253bcf6c65d4d44a3ad5792ea1e886707d0
Reviewed-by: André Hartmann <aha_1980@gmx.de>
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
Orgad Shaneh
2017-02-12 23:09:07 +02:00
committed by Orgad Shaneh
parent 75194a06e6
commit 336adaa604
3 changed files with 75 additions and 24 deletions

View File

@@ -47,6 +47,8 @@
#include <QStringListModel> #include <QStringListModel>
#include <QUrl> #include <QUrl>
Q_DECLARE_METATYPE(Gerrit::Internal::GerritServer);
namespace Gerrit { namespace Gerrit {
namespace Internal { namespace Internal {
@@ -67,7 +69,7 @@ GerritDialog::GerritDialog(const QSharedPointer<GerritParameters> &p,
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
m_ui->setupUi(this); m_ui->setupUi(this);
setCurrentPath(repository); setWindowTitle(tr("Gerrit"));
m_queryModel->setStringList(m_parameters->savedQueries); m_queryModel->setStringList(m_parameters->savedQueries);
QCompleter *completer = new QCompleter(this); QCompleter *completer = new QCompleter(this);
completer->setModel(m_queryModel); completer->setModel(m_queryModel);
@@ -82,6 +84,8 @@ GerritDialog::GerritDialog(const QSharedPointer<GerritParameters> &p,
m_filterModel, &QSortFilterProxyModel::setFilterFixedString); m_filterModel, &QSortFilterProxyModel::setFilterFixedString);
connect(m_ui->queryLineEdit, &QLineEdit::returnPressed, this, &GerritDialog::slotRefresh); connect(m_ui->queryLineEdit, &QLineEdit::returnPressed, this, &GerritDialog::slotRefresh);
connect(m_model, &GerritModel::stateChanged, m_ui->queryLineEdit, &Utils::FancyLineEdit::validate); connect(m_model, &GerritModel::stateChanged, m_ui->queryLineEdit, &Utils::FancyLineEdit::validate);
connect(m_ui->remoteComboBox, &QComboBox::currentTextChanged,
this, &GerritDialog::remoteChanged);
m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive); m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
m_filterModel->setSourceModel(m_model); m_filterModel->setSourceModel(m_model);
m_filterModel->setFilterRole(GerritModel::FilterRole); m_filterModel->setFilterRole(GerritModel::FilterRole);
@@ -117,8 +121,8 @@ GerritDialog::GerritDialog(const QSharedPointer<GerritParameters> &p,
connect(m_model, &GerritModel::refreshStateChanged, connect(m_model, &GerritModel::refreshStateChanged,
this, &GerritDialog::slotRefreshStateChanged); this, &GerritDialog::slotRefreshStateChanged);
setCurrentPath(repository);
slotCurrentChanged(); slotCurrentChanged();
slotRefresh();
m_ui->treeView->setFocus(); m_ui->treeView->setFocus();
m_refreshButton->setDefault(true); m_refreshButton->setDefault(true);
@@ -135,6 +139,7 @@ void GerritDialog::setCurrentPath(const QString &path)
return; return;
m_repository = path; m_repository = path;
m_ui->repositoryLabel->setText(Git::Internal::GitPlugin::msgRepositoryLabel(path)); m_ui->repositoryLabel->setText(Git::Internal::GitPlugin::msgRepositoryLabel(path));
updateRemotes();
} }
QPushButton *GerritDialog::addActionButton(const QString &text, QPushButton *GerritDialog::addActionButton(const QString &text,
@@ -204,37 +209,44 @@ void GerritDialog::slotRefresh()
{ {
const QString &query = m_ui->queryLineEdit->text().trimmed(); const QString &query = m_ui->queryLineEdit->text().trimmed();
updateCompletions(query); updateCompletions(query);
updateRemote();
m_model->refresh(m_server, query); m_model->refresh(m_server, query);
m_ui->treeView->sortByColumn(-1); m_ui->treeView->sortByColumn(-1);
} }
void GerritDialog::updateRemote() void GerritDialog::remoteChanged()
{ {
if (m_updatingRemotes || m_ui->remoteComboBox->count() == 0)
return;
const GerritServer server = m_ui->remoteComboBox->currentData().value<GerritServer>();
if (m_server->host == server.host)
return;
*m_server = server;
slotRefresh();
}
void GerritDialog::updateRemotes()
{
m_ui->remoteComboBox->clear();
if (m_repository.isEmpty() || !QFileInfo(m_repository).isDir()) if (m_repository.isEmpty() || !QFileInfo(m_repository).isDir())
return; return;
m_updatingRemotes = true;
static const QRegularExpression sshPattern( static const QRegularExpression sshPattern(
"^(?:(?<protocol>[^:]+)://)?(?:(?<user>[^@]+)@)?(?<host>[^:/]+)(?::(?<port>\\d+))?"); "^(?:(?<protocol>[^:]+)://)?(?:(?<user>[^@]+)@)?(?<host>[^:/]+)(?::(?<port>\\d+))?");
*m_server = m_parameters->server; *m_server = m_parameters->server;
QString errorMessage; // Mute errors. We'll just fallback to the defaults QString errorMessage; // Mute errors. We'll just fallback to the defaults
QMap<QString, QString> remotesList = QMap<QString, QString> remotesList =
Git::Internal::GitPlugin::client()->synchronousRemotesList(m_repository, &errorMessage); Git::Internal::GitPlugin::client()->synchronousRemotesList(m_repository, &errorMessage);
QStringList remoteUrls; QMapIterator<QString, QString> mapIt(remotesList);
// Prefer a remote named gerrit while (mapIt.hasNext()) {
const QString gerritRemote = remotesList.value("gerrit"); mapIt.next();
if (!gerritRemote.isEmpty()) { const QString r = mapIt.value();
remoteUrls << gerritRemote;
remotesList.remove("gerrit");
}
remoteUrls.append(remotesList.values());
GerritServer server;
for (const QString &r : Utils::asConst(remoteUrls)) {
// Skip local remotes (refer to the root or relative path) // Skip local remotes (refer to the root or relative path)
if (r.isEmpty() || r.startsWith('/') || r.startsWith('.')) if (r.isEmpty() || r.startsWith('/') || r.startsWith('.'))
continue; continue;
// On Windows, local paths typically starts with <drive>: // On Windows, local paths typically starts with <drive>:
if (Utils::HostOsInfo::isWindowsHost() && r[1] == ':') if (Utils::HostOsInfo::isWindowsHost() && r[1] == ':')
continue; continue;
GerritServer server;
QRegularExpressionMatch match = sshPattern.match(r); QRegularExpressionMatch match = sshPattern.match(r);
if (match.hasMatch()) { if (match.hasMatch()) {
const QString protocol = match.captured("protocol"); const QString protocol = match.captured("protocol");
@@ -253,16 +265,29 @@ void GerritDialog::updateRemote()
// Only Ssh is currently supported. In order to extend support for http[s], // Only Ssh is currently supported. In order to extend support for http[s],
// we need to move this logic to the model, and attempt connection to each // we need to move this logic to the model, and attempt connection to each
// remote (do it only on refresh, not on each path change) // remote (do it only on refresh, not on each path change)
if (server.type == GerritServer::Ssh) { if (server.type == GerritServer::Ssh)
*m_server = server; addRemote(server, mapIt.key());
break;
}
} }
} }
QString user = m_server->user; addRemote(m_parameters->server, tr("Fallback"));
if (!user.isEmpty()) m_updatingRemotes = false;
user.append('@'); remoteChanged();
setWindowTitle(tr("Gerrit %1%2").arg(user, m_server->host)); }
void GerritDialog::addRemote(const GerritServer &server, const QString &name)
{
// Clearly not gerrit
if (server.host.contains("github.com"))
return;
for (int i = 0, total = m_ui->remoteComboBox->count(); i < total; ++i) {
const GerritServer s = m_ui->remoteComboBox->itemData(i).value<GerritServer>();
if (s.host == server.host)
return;
}
m_ui->remoteComboBox->addItem(server.host + QString(" (%1)").arg(name),
QVariant::fromValue(server));
if (name == "gerrit")
m_ui->remoteComboBox->setCurrentIndex(m_ui->remoteComboBox->count() - 1);
} }
void GerritDialog::manageProgressIndicator() void GerritDialog::manageProgressIndicator()

View File

@@ -77,7 +77,9 @@ private:
void slotFetchCherryPick(); void slotFetchCherryPick();
void slotFetchCheckout(); void slotFetchCheckout();
void slotRefresh(); void slotRefresh();
void updateRemote(); void remoteChanged();
void updateRemotes();
void addRemote(const GerritServer &server, const QString &name);
void manageProgressIndicator(); void manageProgressIndicator();
@@ -101,6 +103,7 @@ private:
QTimer m_progressIndicatorTimer; QTimer m_progressIndicatorTimer;
QString m_repository; QString m_repository;
bool m_fetchRunning = false; bool m_fetchRunning = false;
bool m_updatingRemotes = false;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>950</width> <width>950</width>
<height>700</height> <height>706</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@@ -42,6 +42,29 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item>
<widget class="QLabel" name="remoteLabel">
<property name="text">
<string>Remote:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="remoteComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>