Files
DbZeiterfassung/zeiterfassungguilib/projectsmodel.cpp
T

227 lines
5.9 KiB
C++

#include "projectsmodel.h"
#include <QFont>
#include "zeiterfassungapi.h"
ProjectsModel::ProjectsModel(int userId, const QDate &date, ZeiterfassungApi &api, QObject *parent) :
QAbstractListModel(parent),
m_userId(userId),
m_date(date),
m_api(api)
{
m_getProjectsReply = m_api.doGetProjects(m_userId, m_date);
connect(m_getProjectsReply.get(), &ZeiterfassungReply::finished, this, &ProjectsModel::getProjectsFinished);
}
int ProjectsModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
if (m_getProjectsReply != nullptr)
return 1;
int rows { 0 };
for (const auto &project : m_projects)
{
rows++; // header
if (project.getWorkpackagesReply != nullptr)
rows++; // loading or failed
else
rows += project.workpackages.size();
}
return rows;
}
QVariant ProjectsModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.column() != 0 || index.row() < 0)
return {};
if (m_getProjectsReply != nullptr)
{
if (index.row() != 0)
return {};
switch (role)
{
case Qt::DisplayRole:
if (m_getProjectsReply->isFinished())
{
Q_ASSERT(!m_getProjectsReply->success());
return m_getProjectsReply->message();
}
else
return tr("Loading projects...");
default:
return {};
}
}
int row { 0 };
for (const auto &project : m_projects)
{
if (row++ == index.row())
{
switch (role)
{
case Qt::DisplayRole:
return project.value + " (" + project.label + ')';
case Qt::EditRole:
return project.value;
case Qt::FontRole:
{
QFont font;
font.setBold(true);
return font;
}
default:
return {};
}
}
if (project.getWorkpackagesReply != nullptr)
{
if (row++ == index.row())
{
switch (role)
{
case Qt::DisplayRole:
if (project.getWorkpackagesReply->isFinished())
{
Q_ASSERT(!project.getWorkpackagesReply->success());
return project.getWorkpackagesReply->message();
}
else
return tr("Loading workpackages...");
default:
return {};
}
}
}
else
{
for (const auto &workpackage : project.workpackages)
{
if (row++ == index.row())
{
switch (role)
{
case Qt::DisplayRole:
return workpackage.label + " (" + workpackage.value + ')';
case Qt::EditRole:
return workpackage.label;
case Qt::UserRole:
return project.value;
default:
return {};
}
}
}
}
}
return {};
}
Qt::ItemFlags ProjectsModel::flags(const QModelIndex &index) const
{
auto flags = QAbstractListModel::flags(index);
if (!isSelectable(index))
flags &=~Qt::ItemIsSelectable;
return flags;
}
QString ProjectsModel::getProjectLabel(const QString &projectId) const
{
const auto iter = std::find_if(m_projects.begin(), m_projects.end(), [&projectId](const Project &project){ return project.value == projectId; });
if (iter == m_projects.end())
return {};
return iter->label;
}
void ProjectsModel::getProjectsFinished()
{
if (!m_getProjectsReply->success())
{
emit dataChanged(createIndex(0, 0), createIndex(0, 0), { Qt::DisplayRole, Qt::EditRole });
return;
}
emit beginResetModel();
for (const auto &item : m_getProjectsReply->items())
{
const auto index = m_projects.size();
m_projects.emplace_back(item.label, item.value, m_api.doGetWorkpackages(m_userId, m_date, item.value));
auto &project = m_projects.back();
connect(project.getWorkpackagesReply.get(), &ZeiterfassungReply::finished, this, [this,index](){ getWorkspacesFinished(index); });
}
m_getProjectsReply = nullptr;
emit endResetModel();
}
void ProjectsModel::getWorkspacesFinished(int index)
{
getWorkspacesFinished(m_projects[index]);
}
void ProjectsModel::getWorkspacesFinished(ProjectsModel::Project &project)
{
if (!project.getWorkpackagesReply->success())
{
//TODO: improve performance
emit beginResetModel();
emit endResetModel();
return;
}
for (const auto &item : project.getWorkpackagesReply->items())
project.workpackages.emplace_back(item.value, item.label);
project.getWorkpackagesReply = nullptr;
//TODO: improve performance
emit beginResetModel();
emit endResetModel();
}
bool ProjectsModel::isSelectable(const QModelIndex &index) const
{
if (!index.isValid() || index.column() != 0 || index.row() < 0)
return {};
if (m_getProjectsReply != nullptr)
{
if (index.row() != 0)
return {};
return false;
}
int row { 0 };
for (const auto &project : m_projects)
{
if (row++ == index.row())
return false;
if (project.getWorkpackagesReply != nullptr)
{
if (row++ == index.row())
return false;
}
else
{
for (const auto &workpackage : project.workpackages)
{
Q_UNUSED(workpackage)
if (row++ == index.row())
return true;
}
}
}
return {};
}