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 ¤tIndex) 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"