File indexing completed on 2024-05-05 04:39:54

0001 /*
0002     SPDX-FileCopyrightText: 2012-2013 Miquel Sabaté <mikisabate@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include <ghproviderwidget.h>
0008 
0009 #include <QLabel>
0010 #include <QListView>
0011 #include <QComboBox>
0012 #include <QHBoxLayout>
0013 #include <QVBoxLayout>
0014 #include <QPushButton>
0015 
0016 #include <interfaces/icore.h>
0017 #include <interfaces/iplugincontroller.h>
0018 #include <vcs/interfaces/ibasicversioncontrol.h>
0019 #include <vcs/vcslocation.h>
0020 
0021 #include <ghaccount.h>
0022 #include <ghdialog.h>
0023 #include <ghresource.h>
0024 #include <ghlineedit.h>
0025 #include <ghprovidermodel.h>
0026 
0027 #include <KLocalizedString>
0028 #include <KMessageBox>
0029 
0030 using namespace KDevelop;
0031 namespace gh
0032 {
0033 
0034 ProviderWidget::ProviderWidget(QWidget *parent)
0035     : IProjectProviderWidget(parent)
0036 {
0037     auto* widgetLayout = new QVBoxLayout;
0038     widgetLayout->setContentsMargins(0, 0, 0, 0);
0039     setLayout(widgetLayout);
0040 
0041     m_projects = new QListView(this);
0042     connect(m_projects, &QListView::clicked, this, &ProviderWidget::projectIndexChanged);
0043 
0044     m_waiting = new QLabel(i18n("Waiting for response"), this);
0045     m_waiting->setAlignment(Qt::AlignCenter);
0046     m_waiting->hide();
0047 
0048     auto *model = new ProviderModel(this);
0049     m_projects->setModel(model);
0050     m_projects->setEditTriggers(QAbstractItemView::NoEditTriggers);
0051     m_resource = new Resource(this, model);
0052     m_account = new Account(m_resource);
0053     connect(m_resource, &Resource::reposUpdated, m_waiting, &QLabel::hide);
0054 
0055     auto *topLayout = new QHBoxLayout();
0056     m_edit = new LineEdit(this);
0057     m_edit->setPlaceholderText(i18nc("@info:placeholder", "Search..."));
0058     m_edit->setToolTip(i18nc("@info:tooltip", "You can press the Return key if you do not want to wait."));
0059     connect(m_edit, &LineEdit::returnPressed, this, &ProviderWidget::searchRepo);
0060     topLayout->addWidget(m_edit);
0061 
0062     m_combo = new QComboBox(this);
0063     m_combo->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
0064     connect(m_combo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ProviderWidget::searchRepo);
0065     fillCombo();
0066     topLayout->addWidget(m_combo);
0067 
0068     auto* settings = new QPushButton(QIcon::fromTheme(QStringLiteral("configure")), QString(), this);
0069     settings->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
0070     settings->setToolTip(i18nc("@info:tooltip", "Configure your GitHub account"));
0071     connect(settings, &QPushButton::clicked, this, &ProviderWidget::showSettings);
0072     topLayout->addWidget(settings);
0073 
0074     layout()->addItem(topLayout);
0075     layout()->addWidget(m_waiting);
0076     layout()->addWidget(m_projects);
0077 }
0078 
0079 KDevelop::VcsJob * ProviderWidget::createWorkingCopy(const QUrl &dest)
0080 {
0081     QModelIndex pos = m_projects->currentIndex();
0082     if (!pos.isValid())
0083         return nullptr;
0084 
0085     auto plugin = ICore::self()->pluginController()->pluginForExtension(QStringLiteral("org.kdevelop.IBasicVersionControl"), QStringLiteral("kdevgit"));
0086     if (!plugin) {
0087         KMessageBox::error(nullptr, i18n("The Git plugin could not be loaded which is required to import a GitHub project."), i18nc("@title:window", "GitHub Provider Error"));
0088         return nullptr;
0089     }
0090 
0091     QString url = pos.data(ProviderModel::VcsLocationRole).toString();
0092     if (m_account->validAccount())
0093       url = QLatin1String("https://") + m_account->token() + QLatin1Char('@') + url.midRef(8);
0094     QUrl real = QUrl(url);
0095     VcsLocation loc(real);
0096 
0097     auto vc = plugin->extension<IBasicVersionControl>();
0098     Q_ASSERT(vc);
0099     return vc->createWorkingCopy(loc, dest);
0100 }
0101 
0102 void ProviderWidget::fillCombo()
0103 {
0104     m_combo->clear();
0105     m_combo->addItem(i18nc("@item:inlistbox", "User"), 1);
0106     m_combo->addItem(i18nc("@item:inlistbox", "Organization"), 3);
0107     if (m_account->validAccount()) {
0108         m_combo->addItem(m_account->name(), 0);
0109         m_combo->setCurrentIndex(2);
0110     }
0111     const QStringList &orgs = m_account->orgs();
0112     for (const QString& org : orgs)
0113         m_combo->addItem(org, 2);
0114 }
0115 
0116 bool ProviderWidget::isCorrect() const
0117 {
0118     return m_projects->currentIndex().isValid();
0119 }
0120 
0121 void ProviderWidget::projectIndexChanged(const QModelIndex &currentIndex)
0122 {
0123     if (currentIndex.isValid()) {
0124         QString name = currentIndex.data().toString();
0125         emit changed(name);
0126     }
0127 }
0128 
0129 void ProviderWidget::showSettings()
0130 {
0131     auto *dialog = new Dialog(this, m_account);
0132     connect(dialog, &Dialog::shouldUpdate, this, &ProviderWidget::fillCombo);
0133     dialog->show();
0134 }
0135 
0136 void ProviderWidget::searchRepo()
0137 {
0138     bool enabled = true;
0139     QString uri, text = m_edit->text();
0140     int idx = m_combo->itemData(m_combo->currentIndex()).toInt();
0141 
0142     switch (idx) {
0143     case 0: /* Looking for this user's repo */
0144         uri = QStringLiteral("/user/repos");
0145         enabled = false;
0146         break;
0147     case 1: /* Looking for some user's repo */
0148         if (text == m_account->name())
0149             uri = QStringLiteral("/user/repos");
0150         else
0151             uri = QStringLiteral("/users/%1/repos").arg(text);
0152         break;
0153     case 2: /* Known organization */
0154         text = m_combo->currentText();
0155         enabled = false;
0156         [[fallthrough]];
0157     default:/* Looking for some organization's repo. */
0158         uri = QStringLiteral("/orgs/%1/repos").arg(text);
0159         break;
0160     }
0161     m_edit->setEnabled(enabled);
0162     m_waiting->show();
0163     m_resource->searchRepos(uri, m_account->token());
0164 }
0165 
0166 } // End of namespace gh
0167 
0168 #include "moc_ghproviderwidget.cpp"