Commit bb4031dc authored by Friedemann Kleint's avatar Friedemann Kleint
Browse files

Gerrit: Refactor preparing the introduction of a hierarchical model.



Change model and dialog methods to use QModelIndex and remove
obsolete methods. Split out method to populate a list of standard items
from a change. Change GerritModel::itemForId() to recurse
over the tree.

Change-Id: I9393f498ffbdf63ba3ad78146d041bcda3835527
Reviewed-by: Orgad Shaneh's avatarOrgad Shaneh <orgads@gmail.com>
parent d33b27e6
......@@ -228,8 +228,9 @@ GerritDialog::~GerritDialog()
void GerritDialog::slotActivated(const QModelIndex &i)
{
if (const QStandardItem *item = itemAt(i))
QDesktopServices::openUrl(QUrl(m_model->change(item->row())->url));
const QModelIndex source = m_filterModel->mapToSource(i);
if (source.isValid())
QDesktopServices::openUrl(QUrl(m_model->change(source)->url));
}
void GerritDialog::slotRefreshStateChanged(bool v)
......@@ -244,20 +245,23 @@ void GerritDialog::slotRefreshStateChanged(bool v)
void GerritDialog::slotFetchDisplay()
{
if (const QStandardItem *item = currentItem())
emit fetchDisplay(m_model->change(item->row()));
const QModelIndex index = currentIndex();
if (index.isValid())
emit fetchDisplay(m_model->change(index));
}
void GerritDialog::slotFetchCherryPick()
{
if (const QStandardItem *item = currentItem())
emit fetchCherryPick(m_model->change(item->row()));
const QModelIndex index = currentIndex();
if (index.isValid())
emit fetchCherryPick(m_model->change(index));
}
void GerritDialog::slotFetchCheckout()
{
if (const QStandardItem *item = currentItem())
emit fetchCheckout(m_model->change(item->row()));
const QModelIndex index = currentIndex();
if (index.isValid())
emit fetchCheckout(m_model->change(index));
}
void GerritDialog::slotRefresh()
......@@ -268,22 +272,10 @@ void GerritDialog::slotRefresh()
m_treeView->sortByColumn(-1);
}
const QStandardItem *GerritDialog::itemAt(const QModelIndex &i, int column) const
{
if (i.isValid()) {
const QModelIndex source = m_filterModel->mapToSource(i);
if (source.isValid())
return m_model->item(source.row(), column);
}
return 0;
}
const QStandardItem *GerritDialog::currentItem(int column) const
QModelIndex GerritDialog::currentIndex() const
{
const QModelIndex index = m_treeView->selectionModel()->currentIndex();
if (index.isValid())
return itemAt(index, column);
return 0;
return index.isValid() ? m_filterModel->mapToSource(index) : QModelIndex();
}
void GerritDialog::updateButtons()
......@@ -296,14 +288,8 @@ void GerritDialog::updateButtons()
void GerritDialog::slotCurrentChanged()
{
const QModelIndex current = m_treeView->selectionModel()->currentIndex();
const bool valid = current.isValid();
if (valid) {
const int row = m_filterModel->mapToSource(current).row();
m_detailsBrowser->setText(m_model->toHtml(row));
} else {
m_detailsBrowser->setText(QString());
}
const QModelIndex current = currentIndex();
m_detailsBrowser->setText(current.isValid() ? m_model->toHtml(current) : QString());
updateButtons();
}
......
......@@ -103,8 +103,7 @@ private slots:
void slotRefresh();
private:
const QStandardItem *itemAt(const QModelIndex &i, int column = 0) const;
const QStandardItem *currentItem(int column = 0) const;
QModelIndex currentIndex() const;
QPushButton *addActionButton(const QString &text, const char *buttonSlot);
void updateCompletions(const QString &query);
void updateButtons();
......
......@@ -417,10 +417,10 @@ static inline GerritChangePtr changeFromItem(const QStandardItem *item)
return qvariant_cast<GerritChangePtr>(item->data(GerritModel::GerritChangeRole));
}
GerritChangePtr GerritModel::change(int row) const
GerritChangePtr GerritModel::change(const QModelIndex &index) const
{
if (row >= 0 && row < rowCount())
return changeFromItem(item(row, 0));
if (index.isValid())
return changeFromItem(itemFromIndex(index));
return GerritChangePtr(new GerritChange);
}
......@@ -439,7 +439,7 @@ QString GerritModel::dependencyHtml(const QString &header, const QString &change
return res;
}
QString GerritModel::toHtml(int row) const
QString GerritModel::toHtml(const QModelIndex& index) const
{
static const QString subjectHeader = GerritModel::tr("Subject");
static const QString numberHeader = GerritModel::tr("Number");
......@@ -451,9 +451,9 @@ QString GerritModel::toHtml(int row) const
static const QString dependsOnHeader = GerritModel::tr("Depends on");
static const QString neededByHeader = GerritModel::tr("Needed by");
if (row < 0 || row >= rowCount())
if (!index.isValid())
return QString();
const GerritChangePtr c = change(row);
const GerritChangePtr c = change(index);
const QString serverPrefix = c->url.left(c->url.lastIndexOf(QLatin1Char('/')) + 1);
QString result;
QTextStream str(&result);
......@@ -474,12 +474,27 @@ QString GerritModel::toHtml(int row) const
return result;
}
static QStandardItem *idSearchRecursion(QStandardItem *item, const QString &id)
{
if (changeFromItem(item)->id == id)
return item;
const int rowCount = item->rowCount();
for (int r = 0; r < rowCount; ++r) {
if (QStandardItem *i = idSearchRecursion(item->child(r, 0), id))
return i;
}
return 0;
}
QStandardItem *GerritModel::itemForId(const QString &id) const
{
if (id.isEmpty())
return 0;
const int numRows = rowCount();
for (int r = 0; r < numRows; ++r)
if (change(r)->id == id)
return item(r, 0);
for (int r = 0; r < numRows; ++r) {
if (QStandardItem *i = idSearchRecursion(item(r, 0), id))
return i;
}
return 0;
}
......@@ -839,9 +854,52 @@ bool changeDateLessThan(const GerritChangePtr &c1, const GerritChangePtr &c2)
return c1->lastUpdated < c2->lastUpdated;
}
QList<QStandardItem *> GerritModel::changeToRow(const GerritChangePtr &c) const
{
QList<QStandardItem *> row;
const QVariant filterV = QVariant(c->filterString());
const QVariant changeV = qVariantFromValue(c);
for (int i = 0; i < GerritModel::ColumnCount; ++i) {
QStandardItem *item = new QStandardItem;
item->setData(changeV, GerritModel::GerritChangeRole);
item->setData(filterV, GerritModel::FilterRole);
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
row.append(item);
}
row[NumberColumn]->setText(QString::number(c->number));
row[TitleColumn]->setText(c->title);
row[OwnerColumn]->setText(c->owner);
// Shorten columns: Display time if it is today, else date
const QString dateString = c->lastUpdated.date() == QDate::currentDate() ?
c->lastUpdated.time().toString(Qt::SystemLocaleShortDate) :
c->lastUpdated.date().toString(Qt::SystemLocaleShortDate);
row[DateColumn]->setText(dateString);
QString project = c->project;
if (c->branch != QLatin1String("master"))
project += QLatin1String(" (") + c->branch + QLatin1Char(')');
row[ProjectColumn]->setText(project);
row[StatusColumn]->setText(c->status);
row[ApprovalsColumn]->setText(c->currentPatchSet.approvalsColumn());
// Mark changes awaiting action using a bold font.
bool bold = false;
if (c->owner == m_userName) { // Owned changes: Review != 0,1. Submit or amend.
const int level = c->currentPatchSet.approvalLevel();
bold = level != 0 && level != 1;
} else if (m_query->currentQuery() == 1) { // Changes pending for review: No review yet.
bold = !m_userName.isEmpty() && !c->currentPatchSet.hasApproval(m_userName);
}
if (bold) {
QFont font = row.first()->font();
font.setBold(true);
for (int i = 0; i < GerritModel::ColumnCount; ++i)
row[i]->setFont(font);
}
return row;
}
void GerritModel::queryFinished(const QByteArray &output)
{
const QDate today = QDate::currentDate();
QList<GerritChangePtr> changes;
if (!parseOutput(m_parameters, output, changes))
emit queryError();
......@@ -854,46 +912,7 @@ void GerritModel::queryFinished(const QByteArray &output)
// It used for marking the changes pending for review in bold.
if (m_userName.isEmpty() && !m_query->currentQuery())
m_userName = c->owner;
const QVariant filterV = QVariant(c->filterString());
const QVariant changeV = qVariantFromValue(c);
QList<QStandardItem *> row;
for (int i = 0; i < GerritModel::ColumnCount; ++i) {
QStandardItem *item = new QStandardItem;
item->setData(changeV, GerritModel::GerritChangeRole);
item->setData(filterV, GerritModel::FilterRole);
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
row.append(item);
}
row[NumberColumn]->setText(QString::number(c->number));
row[TitleColumn]->setText(c->title);
row[OwnerColumn]->setText(c->owner);
// Shorten columns: Display time if it is today, else date
const QString dateString = c->lastUpdated.date() == today ?
c->lastUpdated.time().toString(Qt::SystemLocaleShortDate) :
c->lastUpdated.date().toString(Qt::SystemLocaleShortDate);
row[DateColumn]->setText(dateString);
QString project = c->project;
if (c->branch != QLatin1String("master"))
project += QLatin1String(" (") + c->branch + QLatin1Char(')');
row[ProjectColumn]->setText(project);
row[StatusColumn]->setText(c->status);
row[ApprovalsColumn]->setText(c->currentPatchSet.approvalsColumn());
// Mark changes awaiting action using a bold font.
bool bold = false;
if (c->owner == m_userName) { // Owned changes: Review != 0,1. Submit or amend.
const int level = c->currentPatchSet.approvalLevel();
bold = level != 0 && level != 1;
} else if (m_query->currentQuery() == 1) { // Changes pending for review: No review yet.
bold = !m_userName.isEmpty() && !c->currentPatchSet.hasApproval(m_userName);
}
if (bold) {
QFont font = row.first()->font();
font.setBold(true);
for (int i = 0; i < GerritModel::ColumnCount; ++i)
row[i]->setFont(font);
}
appendRow(row);
appendRow(changeToRow(c));
}
}
}
......
......@@ -115,8 +115,8 @@ public:
GerritModel(const QSharedPointer<GerritParameters> &, QObject *parent = 0);
~GerritModel();
GerritChangePtr change(int row) const;
QString toHtml(int row) const;
GerritChangePtr change(const QModelIndex &index) const;
QString toHtml(const QModelIndex &index) const;
QStandardItem *itemForId(const QString &id) const;
......@@ -133,9 +133,9 @@ private slots:
void clearData();
private:
inline bool evaluateQuery(QString *errorMessage);
QString dependencyHtml(const QString &header, const QString &changeId,
const QString &serverPrefix) const;
QList<QStandardItem *> changeToRow(const GerritChangePtr &c) const;
const QSharedPointer<GerritParameters> m_parameters;
QueryContext *m_query;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment