#include
#include "Data.h"
#include "RemoteCommitsModel.h"
#include "Settings.h"
using json = nlohmann::json;
RemoteCommitsModel::RemoteCommitsModel(QObject* parent) :
QAbstractItemModel(parent)
{
QStringList header;
header << tr("Commit ID") << tr("Message") << tr("Date") << tr("Author") << tr("Size");
rootItem = new QTreeWidgetItem(header);
}
RemoteCommitsModel::~RemoteCommitsModel()
{
delete rootItem;
}
void RemoteCommitsModel::clear()
{
beginResetModel();
// Remove all data except for the root item
while(rootItem->childCount())
delete rootItem->child(0);
endResetModel();
}
void RemoteCommitsModel::refresh(const std::string& json_data, const std::string& last_commit_id, const std::string& current_commit_id)
{
// Clear previous items
clear();
beginResetModel();
// Read in all commits
json j = json::parse(json_data, nullptr, false);
std::unordered_map<:string json::iterator> commit_to_iterator;
for(auto it=j.begin();it!=j.end();++it)
commit_to_iterator.insert({it.value()["id"], it});
// Starting from the last commit add follow the chain up to the first commit
std::string parent_id = last_commit_id;
while(true)
{
if(commit_to_iterator.find(parent_id) == commit_to_iterator.end())
break;
json commit = commit_to_iterator[parent_id].value();
QTreeWidgetItem* item = new QTreeWidgetItem(rootItem);
item->setText(ColumnCommitId, QString::fromStdString(commit["id"]));
item->setText(ColumnMessage, QString::fromStdString(commit["message"]));
item->setToolTip(ColumnMessage, QString::fromStdString(commit["message"]));
item->setText(ColumnDate, isoDateTimeStringToLocalDateTimeString(QString::fromStdString(commit["timestamp"])));
QString authored_by = QString::fromStdString(commit["author_name"]) + " <" + QString::fromStdString(commit["author_email"]) + ">";
QString committed_by = QString::fromStdString(commit["committer_name"]) + " <" + QString::fromStdString(commit["committer_email"]) + ">";
item->setText(ColumnAuthor, authored_by);
if(committed_by == " <>" || authored_by == committed_by) // The first check effectively checks for no committer details
item->setToolTip(ColumnAuthor, tr("Authored and committed by %1").arg(authored_by));
else
item->setToolTip(ColumnAuthor, tr("Authored by %1, committed by %2").arg(authored_by, committed_by));
for(const auto& e : commit["tree"]["entries"])
{
if(e["entry_type"] == "db")
{
item->setText(ColumnSize, humanReadableSize(e["size"]));
break;
}
}
// Make the currently checked out commit id bold
if(current_commit_id == commit["id"])
{
QFont bold_font = item->font(ColumnCommitId);
bold_font.setBold(true);
item->setFont(0, bold_font);
}
parent_id = commit["parent"].get<:string>();
}
// Refresh the view
endResetModel();
}
QModelIndex RemoteCommitsModel::index(int row, int column, const QModelIndex& parent) const
{
if(!hasIndex(row, column, parent))
return QModelIndex();
QTreeWidgetItem *parentItem;
if(!parent.isValid())
parentItem = rootItem;
else
parentItem = static_cast(parent.internalPointer());
QTreeWidgetItem* childItem = parentItem->child(row);
if(childItem)
return createIndex(row, column, childItem);
else
return QModelIndex();
}
QModelIndex RemoteCommitsModel::parent(const QModelIndex& index) const
{
if(!index.isValid())
return QModelIndex();
QTreeWidgetItem* childItem = static_cast(index.internalPointer());
QTreeWidgetItem* parentItem = childItem->parent();
if(parentItem == rootItem)
return QModelIndex();
else
return createIndex(0, 0, parentItem);
}
QVariant RemoteCommitsModel::data(const QModelIndex& index, int role) const
{
if(!index.isValid())
return QVariant();
// Get the item the index points at
QTreeWidgetItem* item = static_cast(index.internalPointer());
// Return data depending on the role
switch(role)
{
case Qt::DisplayRole:
case Qt::EditRole:
return item->text(index.column());
case Qt::ToolTipRole:
return item->toolTip(index.column());
case Qt::FontRole:
return item->font(0); // Choose font for the entire row depending on the first column
default:
return QVariant();
}
}
QVariant RemoteCommitsModel::headerData(int section, Qt::Orientation orientation, int role) const
{
// Get the header string from the root item
if(orientation == Qt::Horizontal && role == Qt::DisplayRole)
return rootItem->data(section, role);
return QVariant();
}
int RemoteCommitsModel::rowCount(const QModelIndex& parent) const
{
if(parent.column() > 0)
return 0;
if(!parent.isValid())
return rootItem->childCount();
else
return static_cast(parent.internalPointer())->childCount();
}
int RemoteCommitsModel::columnCount(const QModelIndex& /*parent*/) const
{
return rootItem->columnCount();
}