diff --git a/src/plugins/git/gerrit/gerritdialog.cpp b/src/plugins/git/gerrit/gerritdialog.cpp
index 70fb173a287..b9b80a55842 100644
--- a/src/plugins/git/gerrit/gerritdialog.cpp
+++ b/src/plugins/git/gerrit/gerritdialog.cpp
@@ -300,7 +300,7 @@ void GerritDialog::slotCurrentChanged()
const bool valid = current.isValid();
if (valid) {
const int row = m_filterModel->mapToSource(current).row();
- m_detailsBrowser->setText(m_model->change(row)->toHtml());
+ m_detailsBrowser->setText(m_model->toHtml(row));
} else {
m_detailsBrowser->setText(QString());
}
diff --git a/src/plugins/git/gerrit/gerritmodel.cpp b/src/plugins/git/gerrit/gerritmodel.cpp
index dd5dcfcf755..000140c5766 100644
--- a/src/plugins/git/gerrit/gerritmodel.cpp
+++ b/src/plugins/git/gerrit/gerritmodel.cpp
@@ -187,26 +187,6 @@ int GerritPatchSet::approvalLevel() const
return value;
}
-QString GerritChange::toHtml() const
-{
- // Keep in sync with list model headers.
- static const QString format = GerritModel::tr(
- "
"
- "Subject | %1 |
"
- "Number | %2 |
"
- "Owner | %3 %4 |
"
- "Project | %5 (%6) |
"
- "Status | %7, %8 |
"
- "Patch set | %9 |
"
- "%10"
- "URL | %11 |
"
- "
");
- return format.arg(title).arg(number).arg(owner, email, project, branch)
- .arg(status, lastUpdated.toString(Qt::DefaultLocaleShortDate))
- .arg(currentPatchSet.patchSetNumber)
- .arg(currentPatchSet.approvalsToHtml(), url);
-}
-
QString GerritChange::filterString() const
{
const QChar blank = QLatin1Char(' ');
@@ -300,7 +280,8 @@ QueryContext::QueryContext(const QStringList &queries,
m_progress.setProgressRange(0, m_queries.size());
// Determine binary and common command line arguments.
- m_baseArguments << QLatin1String("query") << QLatin1String("--current-patch-set")
+ m_baseArguments << QLatin1String("query") << QLatin1String("--dependencies")
+ << QLatin1String("--current-patch-set")
<< QLatin1String("--format=JSON");
m_binary = m_baseArguments.front();
m_baseArguments.pop_front();
@@ -431,20 +412,75 @@ GerritModel::~GerritModel()
{
}
+static inline GerritChangePtr changeFromItem(const QStandardItem *item)
+{
+ return qvariant_cast(item->data(GerritModel::GerritChangeRole));
+}
+
GerritChangePtr GerritModel::change(int row) const
{
if (row >= 0 && row < rowCount())
- return qvariant_cast(item(row, 0)->data(GerritChangeRole));
+ return changeFromItem(item(row, 0));
return GerritChangePtr(new GerritChange);
}
-int GerritModel::indexOf(int gerritNumber) const
+QString GerritModel::dependencyHtml(const QString &header, const QString &changeId,
+ const QString &serverPrefix) const
+{
+ QString res;
+ if (changeId.isEmpty())
+ return res;
+ QTextStream str(&res);
+ str << "" << header << " | ' << changeId << "";
+ if (const QStandardItem *item = itemForId(changeId))
+ str << " (" << changeFromItem(item)->title << ')';
+ str << " |
";
+ return res;
+}
+
+QString GerritModel::toHtml(int row) const
+{
+ static const QString subjectHeader = GerritModel::tr("Subject");
+ static const QString numberHeader = GerritModel::tr("Number");
+ static const QString ownerHeader = GerritModel::tr("Owner");
+ static const QString projectHeader = GerritModel::tr("Project");
+ static const QString statusHeader = GerritModel::tr("Status");
+ static const QString patchSetHeader = GerritModel::tr("Patch set");
+ static const QString urlHeader = GerritModel::tr("URL");
+ static const QString dependsOnHeader = GerritModel::tr("Depends on");
+ static const QString neededByHeader = GerritModel::tr("Needed by");
+
+ if (row < 0 || row >= rowCount())
+ return QString();
+ const GerritChangePtr c = change(row);
+ const QString serverPrefix = c->url.left(c->url.lastIndexOf(QLatin1Char('/')) + 1);
+ QString result;
+ QTextStream str(&result);
+ str << ""
+ << "" << subjectHeader << " | " << c->title << " |
"
+ << "" << numberHeader << " | url << "\">" << c->number << " |
"
+ << "" << ownerHeader << " | " << c->owner << ' '
+ << "email << "\">" << c->email << " |
"
+ << "" << projectHeader << " | " << c->project << " (" << c->branch << ") |
"
+ << dependencyHtml(dependsOnHeader, c->dependsOnId, serverPrefix)
+ << dependencyHtml(neededByHeader, c->neededById, serverPrefix)
+ << "" << statusHeader << " | " << c->status
+ << ", " << c->lastUpdated.toString(Qt::DefaultLocaleShortDate) << " |
"
+ << "" << patchSetHeader << " | " << " |
" << c->currentPatchSet.patchSetNumber << ""
+ << c->currentPatchSet.approvalsToHtml()
+ << "" << urlHeader << " | url << "\">" << c->url << " |
"
+ << "
";
+ return result;
+}
+
+QStandardItem *GerritModel::itemForId(const QString &id) const
{
const int numRows = rowCount();
for (int r = 0; r < numRows; ++r)
- if (change(r)->number == gerritNumber)
- return r;
- return -1;
+ if (change(r)->id == id)
+ return item(r, 0);
+ return 0;
}
void GerritModel::refresh(const QString &query)
@@ -515,6 +551,8 @@ static bool parseOutput(const QSharedPointer ¶meters,
// The output consists of separate lines containing a document each
const QString typeKey = QLatin1String("type");
const QString idKey = QLatin1String("id");
+ const QString dependsOnKey = QLatin1String("dependsOn");
+ const QString neededByKey = QLatin1String("neededBy");
const QString branchKey = QLatin1String("branch");
const QString numberKey = QLatin1String("number");
const QString ownerKey = QLatin1String("owner");
@@ -601,6 +639,26 @@ static bool parseOutput(const QSharedPointer ¶meters,
.arg(QString::fromLocal8Bit(line)));
res = false;
}
+ // Read out dependencies
+ const QJsonValue dependsOnValue = object.value(dependsOnKey);
+ if (dependsOnValue.isArray()) {
+ const QJsonArray dependsOnArray = dependsOnValue.toArray();
+ if (!dependsOnArray.isEmpty()) {
+ const QJsonValue first = dependsOnArray.at(0);
+ if (first.isObject())
+ change->dependsOnId = first.toObject()[idKey].toString();
+ }
+ }
+ // Read out needed by
+ const QJsonValue neededByValue = object.value(neededByKey);
+ if (neededByValue.isArray()) {
+ const QJsonArray neededByArray = neededByValue.toArray();
+ if (!neededByArray.isEmpty()) {
+ const QJsonValue first = neededByArray.at(0);
+ if (first.isObject())
+ change->neededById = first.toObject()[idKey].toString();
+ }
+ }
}
return res;
}
@@ -641,6 +699,8 @@ static bool parseOutput(const QSharedPointer ¶meters,
const QList lines = output.split('\n');
const QString typeKey = QLatin1String("type");
const QString idKey = QLatin1String("id");
+ const QString dependsOnKey = QLatin1String("dependsOn");
+ const QString neededByKey = QLatin1String("neededBy");
const QString branchKey = QLatin1String("branch");
const QString numberKey = QLatin1String("number");
const QString ownerKey = QLatin1String("owner");
@@ -746,6 +806,24 @@ static bool parseOutput(const QSharedPointer ¶meters,
qWarning("%s: Parse error in line '%s'.", Q_FUNC_INFO, line.constData());
res = false;
}
+ // Read out dependencies
+ if (Utils::JsonValue *dependsOnValue = object->member(dependsOnKey)) {
+ if (Utils::JsonArrayValue *dependsOnArray = dependsOnValue->toArray()) {
+ if (dependsOnArray->size()) {
+ if (Utils::JsonObjectValue *dependsOnObject = dependsOnArray->elements().first()->toObject())
+ change->dependsOnId = jsonStringMember(dependsOnObject, idKey);
+ }
+ }
+ }
+ // Read out needed by
+ if (Utils::JsonValue *neededByValue = object->member(neededByKey)) {
+ if (Utils::JsonArrayValue *neededByArray = neededByValue->toArray()) {
+ if (neededByArray->size()) {
+ if (Utils::JsonObjectValue *neededByObject = neededByArray->elements().first()->toObject())
+ change->neededById = jsonStringMember(neededByObject, idKey);
+ }
+ }
+ }
}
if (debug) {
qDebug() << __FUNCTION__;
@@ -771,7 +849,7 @@ void GerritModel::queryFinished(const QByteArray &output)
foreach (const GerritChangePtr &c, changes) {
// Avoid duplicate entries for example in the (unlikely)
// case people do self-reviews.
- if (indexOf(c->number) == -1) {
+ if (!itemForId(c->id)) {
// Determine the verbose user name from the owner of the first query.
// It used for marking the changes pending for review in bold.
if (m_userName.isEmpty() && !m_query->currentQuery())
diff --git a/src/plugins/git/gerrit/gerritmodel.h b/src/plugins/git/gerrit/gerritmodel.h
index 61a526ccf0c..d4bfcc774ba 100644
--- a/src/plugins/git/gerrit/gerritmodel.h
+++ b/src/plugins/git/gerrit/gerritmodel.h
@@ -73,13 +73,14 @@ public:
GerritChange() : number(0) {}
bool isValid() const { return number && !url.isEmpty() && !project.isEmpty(); }
- QString toHtml() const;
QString filterString() const;
QStringList gitFetchArguments(const QSharedPointer &p) const;
QString url;
int number;
QString id;
+ QString dependsOnId;
+ QString neededById;
QString title;
QString owner;
QString email;
@@ -115,8 +116,9 @@ public:
~GerritModel();
GerritChangePtr change(int row) const;
+ QString toHtml(int row) const;
- int indexOf(int gerritNumber) const;
+ QStandardItem *itemForId(const QString &id) const;
public slots:
void refresh(const QString &query);
@@ -132,6 +134,8 @@ private slots:
private:
inline bool evaluateQuery(QString *errorMessage);
+ QString dependencyHtml(const QString &header, const QString &changeId,
+ const QString &serverPrefix) const;
const QSharedPointer m_parameters;
QueryContext *m_query;