/* * This file is part of KDevelop * Copyright 2010 Aleix Pol Gonzalez * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "reviewpatchdialog.h" #include #include #include #include #include "ui_reviewpatch.h" #include "reviewboardjobs.h" ReviewPatchDialog::ReviewPatchDialog(const KUrl& dirUrl, QWidget* parent) : KDialog(parent) { m_ui = new Ui::ReviewPatch; QWidget* w = new QWidget(this); m_ui->setupUi(w); setMainWidget(w); connect(m_ui->server, SIGNAL(textChanged(QString)), SLOT(serverChanged())); connect(m_ui->reviewCheckbox, SIGNAL(stateChanged(int)), SLOT(reviewCheckboxChanged(int))); enableButtonOk(false); if (dirUrl.isLocalFile()) { QDir d(dirUrl.toLocalFile()); while(!QFile::exists(d.filePath(".reviewboardrc"))) { if(!d.cdUp()) break; } if(!d.isRoot()) initializeFromRC(d.filePath(".reviewboardrc")); } } ReviewPatchDialog::~ReviewPatchDialog() { delete m_ui; } void ReviewPatchDialog::setBaseDir(const QString& repo) { m_ui->basedir->setText(repo); } void ReviewPatchDialog::setServer(const KUrl& server) { m_ui->server->setUrl(server); } void ReviewPatchDialog::setUsername(const QString& user) { m_ui->username->setText(user); } void ReviewPatchDialog::setRepository(const QString& repo) { m_preferredRepository = repo; } QString ReviewPatchDialog::baseDir() const { return m_ui->basedir->text(); } KUrl ReviewPatchDialog::server() const { KUrl server=m_ui->server->url(); server.setUser(m_ui->username->text()); server.setPassword(m_ui->password->text()); return server; } QString ReviewPatchDialog::username() const { return m_ui->username->text(); } void ReviewPatchDialog::serverChanged() { m_ui->repositories->clear(); //TODO reviewboards with private repositories don't work. Use user/pass if set. ReviewBoard::ProjectsListRequest* repo = new ReviewBoard::ProjectsListRequest(m_ui->server->url(), this); connect(repo, SIGNAL(finished(KJob*)), SLOT(receivedProjects(KJob*))); repo->start(); } void ReviewPatchDialog::receivedProjects(KJob* job) { // TODO: check error ReviewBoard::ProjectsListRequest* pl=dynamic_cast(job); QVariantList repos = pl->repositories(); // Add default value with no repo selected. m_ui->repositories->addItem(i18n("Repository not selected"), 0); foreach(const QVariant& repo, repos) { QVariantMap repoMap=repo.toMap(); m_ui->repositories->addItem(repoMap["name"].toString(), repoMap["path"]); } connect(m_ui->repositories, SIGNAL(currentIndexChanged(int)), SLOT(repositoryChanged(int))); QAbstractItemModel* model = m_ui->repositories->model(); if(!m_preferredRepository.isEmpty()) { QModelIndexList idxs = model->match(model->index(0,0), Qt::UserRole, m_preferredRepository, 1, Qt::MatchExactly); if(idxs.isEmpty()) { idxs = model->match(model->index(0,0), Qt::DisplayRole, KUrl(m_preferredRepository).fileName(), 1, Qt::MatchExactly); } if(!idxs.isEmpty()) { m_ui->repositories->setCurrentIndex(idxs.first().row()); } else qDebug() << "couldn't fucking find it" << m_preferredRepository; } m_ui->repositoriesBox->setEnabled(job->error()==0); } QString ReviewPatchDialog::repository() const { QComboBox* repositories = m_ui->repositories; if(repositories->currentIndex() != -1) { return repositories->itemData(repositories->currentIndex(), Qt::UserRole).toString(); } return QString(); } void ReviewPatchDialog::repositoryChanged(int index) { enableButtonOk((!isUpdateReview() && index > 0) || m_ui->reviews->currentIndex() != -1); } void ReviewPatchDialog::reviewCheckboxChanged(int status) { if (status == Qt::Checked) { m_ui->reviews->setEnabled(true); connect(m_ui->username, SIGNAL(editingFinished()), SLOT(updateReviews())); connect(m_ui->password, SIGNAL(editingFinished()), SLOT(updateReviews())); connect(m_ui->server, SIGNAL(returnPressed()), SLOT(updateReviews())); connect(m_ui->repositories, SIGNAL(currentIndexChanged(int)), SLOT(updateReviewsList())); } else { m_ui->reviews->setEnabled(false); disconnect(m_ui->username, SIGNAL(editingFinished()), this, SLOT(updateReviews())); disconnect(m_ui->password, SIGNAL(editingFinished()), this, SLOT(updateReviews())); disconnect(m_ui->server, SIGNAL(returnPressed()), this, SLOT(updateReviews())); disconnect(m_ui->repositories, SIGNAL(currentIndexChanged(int)), this, SLOT(updateReviewsList())); } updateReviews(); } void ReviewPatchDialog::receivedReviews(KJob* job) { m_reviews.clear(); // TODO: check errors QVariantList reviews = dynamic_cast(job)->reviews(); foreach(const QVariant& review, reviews) { QVariantMap reviewMap = review.toMap(); QVariantMap repoMap = reviewMap["links"].toMap()["repository"].toMap(); m_reviews.insert(repoMap["title"].toString(), qMakePair(reviewMap["summary"].toString(), reviewMap["id"])); } updateReviewsList(); } QString ReviewPatchDialog::review() const { return m_ui->reviews->itemData(m_ui->reviews->currentIndex(), Qt::UserRole).toString(); } void ReviewPatchDialog::updateReviews() { if (isUpdateReview()) { //TODO: reviewboards with private reviews don't work. Use user/pass if set. if (!m_ui->server->text().isEmpty() && !m_ui->username->text().isEmpty()) { ReviewBoard::ReviewListRequest* repo = new ReviewBoard::ReviewListRequest(m_ui->server->url(), username(), "pending", this); connect(repo, SIGNAL(finished(KJob*)), SLOT(receivedReviews(KJob*))); repo->start(); } } else { // Clear reviews combobox and enable OK Button if a repository is selected. enableButtonOk(m_ui->repositories->currentIndex() != -1); } } bool ReviewPatchDialog::isUpdateReview() { return m_ui->reviewCheckbox->checkState() == Qt::Checked; } void ReviewPatchDialog::updateReviewsList() { QString repo = m_ui->repositories->currentText(); QPair kv; m_ui->reviews->clear(); if (m_ui->repositories->currentIndex() < 1) { // Show all Review foreach (const QString& key, m_reviews.uniqueKeys()) { foreach (kv, m_reviews.values(key)) { m_ui->reviews->addItem(kv.first, kv.second); } } } else { // Filter using actual repository. foreach (kv, m_reviews.values(repo)) { m_ui->reviews->addItem(kv.first, kv.second); } } enableButtonOk(m_ui->reviews->currentIndex() != -1); } void ReviewPatchDialog::initializeFromRC(const QString& filePath) { //The .reviewboardrc files are python files, we'll read and if it doesn't work //Well bad luck. See: http://www.reviewboard.org/docs/rbtools/dev/rbt/configuration/ QRegExp rx("([\\w_]+) *= *[\"'](.*)[\"']"); QFile f(filePath); if(!f.open(QFile::ReadOnly | QFile::Text)) return; QHash values; QTextStream stream(&f); for(; !stream.atEnd(); ) { if(rx.exactMatch(stream.readLine())) { values.insert(rx.cap(1), rx.cap(2)); } } if(values.contains("REVIEWBOARD_URL")) setServer(KUrl(values["REVIEWBOARD_URL"])); if(values.contains("REPOSITORY")) setRepository(values["REPOSITORY"]); kDebug() << "found:" << values; }