Files
Kareer/src/jobsmodel.cpp
T
austin 078343ff96 v0.1.2: Preferences page, About page, full icon set, redesigned edit form
- Rework the add/edit form onto a generic, catalog-driven field model
  (JobFieldCatalog + JobEditModel), replacing the old hand-written
  ApplicationEditDialog with ApplicationEditPage
- Add a Preferences page (reachable from the hamburger menu) with a
  KColorSchemeManager-backed color scheme switcher
- Add an About page reading from KAboutData
- Ship a full hicolor icon set (16-128px + scalable) via ecm_install_icons
  instead of a single flat SVG
- Restyle the edit form after KDE System Settings' Audio page:
  Kirigami.ListSectionHeader per category, flat separated rows, no card
  borders
- Explicitly declare Kirigami/KirigamiAddons/ColorScheme as CMake
  dependencies instead of relying on the QML import scanner alone
- Add KDEClangFormat/KDEGitCommitHooks, a CMakePresets.json, and a
  REUSE + clang-format lint CI workflow
- Reformat SPDX headers to include copyright, remove debug screenshot
  scaffolding
2026-07-03 16:25:42 -05:00

212 lines
5.2 KiB
C++

/*
SPDX-FileCopyrightText: 2026 ToServeTheKing <[email protected]>
SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "jobsmodel.h"
#include "jobstage.h"
using namespace Qt::Literals::StringLiterals;
JobsModel::JobsModel(QObject *parent)
: QAbstractListModel(parent)
{
refresh();
}
void JobsModel::refresh()
{
beginResetModel();
m_jobs = m_db.allJobs();
endResetModel();
Q_EMIT countChanged();
}
int JobsModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid()) {
return 0;
}
return m_jobs.size();
}
QVariant JobsModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() < 0 || index.row() >= m_jobs.size()) {
return {};
}
const Job &job = m_jobs.at(index.row());
switch (role) {
case IdRole:
return job.id;
case CompanyRole:
return job.company;
case TitleRole:
return job.title;
case LocationRole:
return job.location;
case RemoteTypeRole:
return job.remoteType;
case SourceRole:
return job.source;
case UrlRole:
return job.url;
case DateAppliedRole:
return job.dateApplied;
case SalaryMinRole:
return job.salaryMin;
case SalaryMaxRole:
return job.salaryMax;
case SalaryExpectationRole:
return job.salaryExpectation;
case CurrencyRole:
return job.currency;
case NotesRole:
return job.notes;
case ContactRole:
return job.contact;
case StageRole:
return job.stage;
case StageColorRole:
return JobStage::color(job.stage);
case CreatedAtRole:
return job.createdAt;
case UpdatedAtRole:
return job.updatedAt;
default:
return {};
}
}
QHash<int, QByteArray> JobsModel::roleNames() const
{
return {
{IdRole, "jobId"},
{CompanyRole, "company"},
{TitleRole, "title"},
{LocationRole, "location"},
{RemoteTypeRole, "remoteType"},
{SourceRole, "source"},
{UrlRole, "url"},
{DateAppliedRole, "dateApplied"},
{SalaryMinRole, "salaryMin"},
{SalaryMaxRole, "salaryMax"},
{SalaryExpectationRole, "salaryExpectation"},
{CurrencyRole, "currency"},
{NotesRole, "notes"},
{ContactRole, "contact"},
{StageRole, "stage"},
{StageColorRole, "stageColor"},
{CreatedAtRole, "createdAt"},
{UpdatedAtRole, "updatedAt"},
};
}
QStringList JobsModel::stages() const
{
return JobStage::canonicalStages();
}
Job JobsModel::jobFromMap(const QVariantMap &fields)
{
Job job;
job.company = fields.value(u"company"_s).toString();
job.title = fields.value(u"title"_s).toString();
job.location = fields.value(u"location"_s).toString();
job.remoteType = fields.value(u"remoteType"_s).toString();
job.source = fields.value(u"source"_s).toString();
job.url = fields.value(u"url"_s).toString();
const QVariant dateValue = fields.value(u"dateApplied"_s);
job.dateApplied = dateValue.canConvert<QDate>() ? dateValue.toDate() : QDate::fromString(dateValue.toString(), Qt::ISODate);
job.salaryMin = fields.value(u"salaryMin"_s, -1).toInt();
job.salaryMax = fields.value(u"salaryMax"_s, -1).toInt();
job.salaryExpectation = fields.value(u"salaryExpectation"_s, -1).toInt();
job.currency = fields.value(u"currency"_s, u"USD"_s).toString();
if (job.currency.isEmpty()) {
job.currency = u"USD"_s;
}
job.notes = fields.value(u"notes"_s).toString();
job.contact = fields.value(u"contact"_s).toString();
job.stage = fields.value(u"stage"_s).toString();
return job;
}
QVariantMap JobsModel::mapFromJob(const Job &job)
{
return {
{u"id"_s, job.id},
{u"company"_s, job.company},
{u"title"_s, job.title},
{u"location"_s, job.location},
{u"remoteType"_s, job.remoteType},
{u"source"_s, job.source},
{u"url"_s, job.url},
{u"dateApplied"_s, job.dateApplied},
{u"salaryMin"_s, job.salaryMin},
{u"salaryMax"_s, job.salaryMax},
{u"salaryExpectation"_s, job.salaryExpectation},
{u"currency"_s, job.currency},
{u"notes"_s, job.notes},
{u"contact"_s, job.contact},
{u"stage"_s, job.stage},
{u"createdAt"_s, job.createdAt},
{u"updatedAt"_s, job.updatedAt},
};
}
QVariantMap JobsModel::jobData(int id) const
{
const auto job = m_db.jobById(id);
if (!job) {
return {};
}
return mapFromJob(*job);
}
bool JobsModel::addJob(const QVariantMap &fields)
{
Job job = jobFromMap(fields);
const bool ok = m_db.addJob(job);
if (ok) {
refresh();
}
return ok;
}
bool JobsModel::updateJob(int id, const QVariantMap &fields)
{
Job job = jobFromMap(fields);
job.id = id;
const bool ok = m_db.updateJob(job);
if (ok) {
refresh();
}
return ok;
}
bool JobsModel::setStage(int id, const QString &stage)
{
const bool ok = m_db.setStage(id, stage);
if (ok) {
refresh();
}
return ok;
}
bool JobsModel::removeJob(int id)
{
const bool ok = m_db.deleteJob(id);
if (ok) {
refresh();
}
return ok;
}
QString JobsModel::lastError() const
{
return m_db.lastError();
}