From ac9ad08f67a0f6e28a4c00db7edcc1b7052696e8 Mon Sep 17 00:00:00 2001
From: Orgad Shaneh <orgad.shaneh@audiocodes.com>
Date: Tue, 27 Jun 2017 00:04:23 +0300
Subject: [PATCH] Gerrit: Factor out remote server chooser
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Preparing for re-use in Push to Gerrit dialog.

Task-number: QTCREATORBUG-16367
Change-Id: Ic72f72024d6b6b5a525f6855a9947d4c2dc6de48
Reviewed-by: André Hartmann <aha_1980@gmx.de>
---
 src/plugins/git/gerrit/gerrit.pri             |   2 +
 src/plugins/git/gerrit/gerritdialog.cpp       |  45 +------
 src/plugins/git/gerrit/gerritdialog.h         |   1 -
 src/plugins/git/gerrit/gerritdialog.ui        |  15 +--
 .../git/gerrit/gerritremotechooser.cpp        | 126 ++++++++++++++++++
 src/plugins/git/gerrit/gerritremotechooser.h  |  66 +++++++++
 src/plugins/git/git.qbs                       |   2 +
 7 files changed, 208 insertions(+), 49 deletions(-)
 create mode 100644 src/plugins/git/gerrit/gerritremotechooser.cpp
 create mode 100644 src/plugins/git/gerrit/gerritremotechooser.h

diff --git a/src/plugins/git/gerrit/gerrit.pri b/src/plugins/git/gerrit/gerrit.pri
index 6e430c538e..437a923e31 100644
--- a/src/plugins/git/gerrit/gerrit.pri
+++ b/src/plugins/git/gerrit/gerrit.pri
@@ -7,6 +7,7 @@ SOURCES += \
     $$PWD/gerritparameters.cpp \
     $$PWD/gerritplugin.cpp \
     $$PWD/gerritpushdialog.cpp \
+    $$PWD/gerritremotechooser.cpp \
     $$PWD/gerritserver.cpp
 
 HEADERS += \
@@ -18,6 +19,7 @@ HEADERS += \
     $$PWD/gerritparameters.h \
     $$PWD/gerritplugin.h \
     $$PWD/gerritpushdialog.h \
+    $$PWD/gerritremotechooser.h \
     $$PWD/gerritserver.h
 
 FORMS += \
diff --git a/src/plugins/git/gerrit/gerritdialog.cpp b/src/plugins/git/gerrit/gerritdialog.cpp
index 58d35390e8..9f1df2a9aa 100644
--- a/src/plugins/git/gerrit/gerritdialog.cpp
+++ b/src/plugins/git/gerrit/gerritdialog.cpp
@@ -37,7 +37,6 @@
 #include <utils/hostosinfo.h>
 #include <utils/progressindicator.h>
 #include <utils/qtcassert.h>
-#include <utils/utilsicons.h>
 #include <utils/theme/theme.h>
 
 #include <QCompleter>
@@ -48,8 +47,6 @@
 #include <QStringListModel>
 #include <QUrl>
 
-Q_DECLARE_METATYPE(Gerrit::Internal::GerritServer);
-
 namespace Gerrit {
 namespace Internal {
 
@@ -70,6 +67,7 @@ GerritDialog::GerritDialog(const QSharedPointer<GerritParameters> &p,
     setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
 
     m_ui->setupUi(this);
+    m_ui->remoteComboBox->setParameters(m_parameters);
     m_queryModel->setStringList(m_parameters->savedQueries);
     QCompleter *completer = new QCompleter(this);
     completer->setModel(m_queryModel);
@@ -84,7 +82,7 @@ GerritDialog::GerritDialog(const QSharedPointer<GerritParameters> &p,
             m_filterModel, &QSortFilterProxyModel::setFilterFixedString);
     connect(m_ui->queryLineEdit, &QLineEdit::returnPressed, this, &GerritDialog::refresh);
     connect(m_model, &GerritModel::stateChanged, m_ui->queryLineEdit, &Utils::FancyLineEdit::validate);
-    connect(m_ui->remoteComboBox, &QComboBox::currentTextChanged,
+    connect(m_ui->remoteComboBox, &GerritRemoteChooser::remoteChanged,
             this, &GerritDialog::remoteChanged);
     m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
     m_filterModel->setSourceModel(m_model);
@@ -111,10 +109,6 @@ GerritDialog::GerritDialog(const QSharedPointer<GerritParameters> &p,
     connect(m_ui->treeView, &QAbstractItemView::activated,
             this, &GerritDialog::slotActivated);
 
-    m_ui->resetRemoteButton->setIcon(Utils::Icons::RESET_TOOLBAR.icon());
-    connect(m_ui->resetRemoteButton, &QToolButton::clicked,
-            this, [this] { updateRemotes(true); });
-
     m_displayButton = addActionButton(tr("&Show"), [this]() { slotFetchDisplay(); });
     m_cherryPickButton = addActionButton(tr("Cherry &Pick"), [this]() { slotFetchCherryPick(); });
     m_checkoutButton = addActionButton(tr("C&heckout"), [this]() { slotFetchCheckout(); });
@@ -224,9 +218,7 @@ void GerritDialog::refresh()
 
 void GerritDialog::remoteChanged()
 {
-    if (m_updatingRemotes || m_ui->remoteComboBox->count() == 0)
-        return;
-    const GerritServer server = m_ui->remoteComboBox->currentData().value<GerritServer>();
+    const GerritServer server = m_ui->remoteComboBox->currentServer();
     if (QSharedPointer<GerritServer> modelServer = m_model->server()) {
         if (*modelServer == server)
            return;
@@ -237,38 +229,11 @@ void GerritDialog::remoteChanged()
 
 void GerritDialog::updateRemotes(bool forceReload)
 {
-    m_ui->remoteComboBox->clear();
+    m_ui->remoteComboBox->setRepository(m_repository);
     if (m_repository.isEmpty() || !QFileInfo(m_repository).isDir())
         return;
-    m_updatingRemotes = true;
     *m_server = m_parameters->server;
-    QString errorMessage; // Mute errors. We'll just fallback to the defaults
-    QMap<QString, QString> remotesList =
-            Git::Internal::GitPlugin::client()->synchronousRemotesList(m_repository, &errorMessage);
-    QMapIterator<QString, QString> mapIt(remotesList);
-    while (mapIt.hasNext()) {
-        mapIt.next();
-        GerritServer server;
-        if (!server.fillFromRemote(mapIt.value(), *m_parameters, forceReload))
-            continue;
-        addRemote(server, mapIt.key());
-    }
-    addRemote(m_parameters->server, tr("Fallback"));
-    m_updatingRemotes = false;
-    remoteChanged();
-}
-
-void GerritDialog::addRemote(const GerritServer &server, const QString &name)
-{
-    for (int i = 0, total = m_ui->remoteComboBox->count(); i < total; ++i) {
-        const GerritServer s = m_ui->remoteComboBox->itemData(i).value<GerritServer>();
-        if (s == server)
-            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);
+    m_ui->remoteComboBox->updateRemotes(forceReload);
 }
 
 void GerritDialog::manageProgressIndicator()
diff --git a/src/plugins/git/gerrit/gerritdialog.h b/src/plugins/git/gerrit/gerritdialog.h
index 4959a0bf70..e51a7c0339 100644
--- a/src/plugins/git/gerrit/gerritdialog.h
+++ b/src/plugins/git/gerrit/gerritdialog.h
@@ -77,7 +77,6 @@ private:
     void slotFetchCheckout();
     void remoteChanged();
     void updateRemotes(bool forceReload = false);
-    void addRemote(const GerritServer &server, const QString &name);
 
     void manageProgressIndicator();
 
diff --git a/src/plugins/git/gerrit/gerritdialog.ui b/src/plugins/git/gerrit/gerritdialog.ui
index c7be2cd2cd..56938f0a01 100644
--- a/src/plugins/git/gerrit/gerritdialog.ui
+++ b/src/plugins/git/gerrit/gerritdialog.ui
@@ -50,7 +50,7 @@
       </widget>
      </item>
      <item>
-      <widget class="QComboBox" name="remoteComboBox">
+      <widget class="Gerrit::Internal::GerritRemoteChooser" name="remoteComboBox" native="true">
        <property name="sizePolicy">
         <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
          <horstretch>0</horstretch>
@@ -65,13 +65,6 @@
        </property>
       </widget>
      </item>
-     <item>
-      <widget class="QToolButton" name="resetRemoteButton">
-       <property name="toolTip">
-        <string>Refresh Remote Servers</string>
-       </property>
-      </widget>
-     </item>
     </layout>
    </item>
    <item>
@@ -251,6 +244,12 @@
    <extends>QTreeView</extends>
    <header location="global">utils/itemviews.h</header>
   </customwidget>
+  <customwidget>
+   <class>Gerrit::Internal::GerritRemoteChooser</class>
+   <extends>QWidget</extends>
+   <header location="global">git/gerrit/gerritremotechooser.h</header>
+   <container>1</container>
+  </customwidget>
  </customwidgets>
  <resources/>
  <connections>
diff --git a/src/plugins/git/gerrit/gerritremotechooser.cpp b/src/plugins/git/gerrit/gerritremotechooser.cpp
new file mode 100644
index 0000000000..cc8e82e83d
--- /dev/null
+++ b/src/plugins/git/gerrit/gerritremotechooser.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Orgad Shaneh <orgads@gmail.com>.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "gerritremotechooser.h"
+#include "gerritparameters.h"
+#include "gerritserver.h"
+#include "../gitclient.h"
+#include "../gitplugin.h"
+
+#include <utils/qtcassert.h>
+#include <utils/utilsicons.h>
+
+#include <QFileInfo>
+#include <QHBoxLayout>
+
+Q_DECLARE_METATYPE(Gerrit::Internal::GerritServer);
+
+namespace Gerrit {
+namespace Internal {
+
+GerritRemoteChooser::GerritRemoteChooser(QWidget *parent) :
+    QWidget(parent)
+{
+    auto horizontalLayout = new QHBoxLayout(this);
+    m_remoteComboBox = new QComboBox(this);
+    QSizePolicy sizePolicy1(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
+    sizePolicy1.setHorizontalStretch(0);
+    sizePolicy1.setVerticalStretch(0);
+    sizePolicy1.setHeightForWidth(m_remoteComboBox->sizePolicy().hasHeightForWidth());
+    m_remoteComboBox->setSizePolicy(sizePolicy1);
+    m_remoteComboBox->setMinimumSize(QSize(40, 0));
+
+    horizontalLayout->addWidget(m_remoteComboBox);
+
+    m_resetRemoteButton = new QToolButton(this);
+    m_resetRemoteButton->setToolTip(tr("Refresh Remote Servers"));
+
+    horizontalLayout->addWidget(m_resetRemoteButton);
+
+    connect(m_remoteComboBox, &QComboBox::currentTextChanged,
+            this, &GerritRemoteChooser::handleRemoteChanged);
+    m_resetRemoteButton->setIcon(Utils::Icons::RESET_TOOLBAR.icon());
+    connect(m_resetRemoteButton, &QToolButton::clicked,
+            this, [this] { updateRemotes(true); });
+}
+
+void GerritRemoteChooser::setRepository(const QString &repository)
+{
+    m_repository = repository;
+}
+
+void GerritRemoteChooser::setParameters(QSharedPointer<GerritParameters> parameters)
+{
+    m_parameters = parameters;
+}
+
+bool GerritRemoteChooser::updateRemotes(bool forceReload)
+{
+    QTC_ASSERT(!m_repository.isEmpty(), return false);
+    m_remoteComboBox->clear();
+    m_updatingRemotes = true;
+    QString errorMessage; // Mute errors. We'll just fallback to the defaults
+    QMap<QString, QString> remotesList =
+            Git::Internal::GitPlugin::client()->synchronousRemotesList(m_repository, &errorMessage);
+    QMapIterator<QString, QString> mapIt(remotesList);
+    while (mapIt.hasNext()) {
+        mapIt.next();
+        GerritServer server;
+        if (!server.fillFromRemote(mapIt.value(), *m_parameters, forceReload))
+            continue;
+        addRemote(server, mapIt.key());
+    }
+    addRemote(m_parameters->server, tr("Fallback"));
+    m_updatingRemotes = false;
+    handleRemoteChanged();
+    return true;
+}
+
+void GerritRemoteChooser::addRemote(const GerritServer &server, const QString &name)
+{
+    for (int i = 0, total = m_remoteComboBox->count(); i < total; ++i) {
+        const GerritServer s = m_remoteComboBox->itemData(i).value<GerritServer>();
+        if (s == server)
+            return;
+    }
+    m_remoteComboBox->addItem(server.host + QString(" (%1)").arg(name), QVariant::fromValue(server));
+    if (name == "gerrit")
+        m_remoteComboBox->setCurrentIndex(m_remoteComboBox->count() - 1);
+}
+
+GerritServer GerritRemoteChooser::currentServer() const
+{
+    return m_remoteComboBox->currentData().value<GerritServer>();
+}
+
+void GerritRemoteChooser::handleRemoteChanged()
+{
+    if (m_updatingRemotes || m_remoteComboBox->count() == 0)
+        return;
+    emit remoteChanged();
+}
+
+} // namespace Internal
+} // namespace Gerrit
diff --git a/src/plugins/git/gerrit/gerritremotechooser.h b/src/plugins/git/gerrit/gerritremotechooser.h
new file mode 100644
index 0000000000..a9eda95535
--- /dev/null
+++ b/src/plugins/git/gerrit/gerritremotechooser.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Orgad Shaneh <orgads@gmail.com>.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QComboBox>
+#include <QSharedPointer>
+#include <QToolButton>
+#include <QWidget>
+
+namespace Gerrit {
+namespace Internal {
+
+class GerritServer;
+class GerritParameters;
+
+class GerritRemoteChooser : public QWidget
+{
+    Q_OBJECT
+
+public:
+    GerritRemoteChooser(QWidget *parent = nullptr);
+    void setRepository(const QString  &repository);
+    void setParameters(QSharedPointer<GerritParameters> parameters);
+
+    bool updateRemotes(bool forceReload);
+    GerritServer currentServer() const;
+
+signals:
+    void remoteChanged();
+
+private:
+    void addRemote(const GerritServer &server, const QString &name);
+    void handleRemoteChanged();
+
+    QString m_repository;
+    QSharedPointer<GerritParameters> m_parameters;
+    QComboBox *m_remoteComboBox = nullptr;
+    QToolButton *m_resetRemoteButton = nullptr;
+    bool m_updatingRemotes = false;
+};
+
+} // namespace Internal
+} // namespace Gerrit
diff --git a/src/plugins/git/git.qbs b/src/plugins/git/git.qbs
index 8c87dab277..41a032ba7c 100644
--- a/src/plugins/git/git.qbs
+++ b/src/plugins/git/git.qbs
@@ -93,6 +93,8 @@ QtcPlugin {
             "gerritparameters.h",
             "gerritplugin.cpp",
             "gerritplugin.h",
+            "gerritremotechooser.cpp",
+            "gerritremotechooser.h",
             "gerritserver.cpp",
             "gerritserver.h",
             "gerritpushdialog.cpp",
-- 
GitLab