kdeconnect-kde/plugins/sendnotifications/notifyingapplicationmodel.cpp
Alexander Lohnau 2e67f95017 Add explicit moc includes to cpp files
The rationale is explained in https://planet.kde.org/friedrich-kossebau-2023-06-28-include-also-moc-files-of-headers/

In case of KDEConnect, it impressively speeds up compilation. Before it
took 390 seconds on a clean build and with this change it took 330 seconds.
This is due to the mocs_compilation having to include the header files
and thus all their headers. Due to the lots of small plugins we have,
this means that the same headers must be compiled plenty of times.
When we include the moc files directly in the C++ file, they are already
available.
2023-07-30 07:27:45 +00:00

212 lines
6.2 KiB
C++

/**
* SPDX-FileCopyrightText: 2015 Holger Kaelberer <holger.k@elberer.de>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#include "notifyingapplicationmodel.h"
#include <algorithm>
#include <QDebug>
#include <QIcon>
#include <QString>
#include <KLocalizedString>
// #include "modeltest.h"
NotifyingApplicationModel::NotifyingApplicationModel(QObject *parent)
: QAbstractTableModel(parent)
{
}
QVector<NotifyingApplication> NotifyingApplicationModel::apps()
{
return m_apps;
}
void NotifyingApplicationModel::appendApp(const NotifyingApplication &app)
{
if (app.name.isEmpty() || apps().contains(app))
return;
beginInsertRows(QModelIndex(), m_apps.size(), m_apps.size());
m_apps.append(app);
endInsertRows();
}
bool NotifyingApplicationModel::containsApp(const QString &name) const
{
for (const auto &a : m_apps)
if (a.name == name)
return true;
return false;
}
Qt::ItemFlags NotifyingApplicationModel::flags(const QModelIndex &index) const
{
Qt::ItemFlags flags = Qt::ItemIsEnabled;
if (index.isValid() && index.row() >= 0 && index.row() < m_apps.size() && index.column() < 3) {
if (index.column() == 0)
flags |= Qt::ItemIsEditable | Qt::ItemIsUserCheckable;
else if (index.column() == 2) {
if (m_apps[index.row()].active)
flags |= Qt::ItemIsEditable;
else
flags ^= Qt::ItemIsEnabled;
} else if (index.column() == 1) {
if (!m_apps[index.row()].active)
flags ^= Qt::ItemIsEnabled;
}
}
return flags;
}
void NotifyingApplicationModel::clearApplications()
{
if (!m_apps.isEmpty()) {
beginRemoveRows(QModelIndex(), 0, m_apps.size() - 1);
m_apps.clear();
endRemoveRows();
}
}
QVariant NotifyingApplicationModel::data(const QModelIndex &index, int role) const
{
Q_UNUSED(role);
if (!index.isValid() || index.row() < 0 || index.row() >= m_apps.size() || index.column() > 3) {
return QVariant();
}
switch (role) {
case Qt::TextAlignmentRole: {
if (index.column() == 0)
return int(Qt::AlignCenter | Qt::AlignVCenter);
else
return int(Qt::AlignLeft | Qt::AlignVCenter);
break;
}
case Qt::DisplayRole: {
if (index.column() == 1)
return m_apps[index.row()].name;
else if (index.column() == 0)
return QVariant(); // m_apps[index.row()].active;
else if (index.column() == 2)
return m_apps[index.row()].blacklistExpression.pattern();
else
return QVariant();
break;
}
case Qt::DecorationRole: {
if (index.column() == 1)
return QIcon::fromTheme(m_apps[index.row()].icon, QIcon::fromTheme(QStringLiteral("application-x-executable")));
else
return QVariant();
break;
}
case Qt::EditRole: {
if (index.column() == 0)
return m_apps[index.row()].active ? Qt::Checked : Qt::Unchecked;
else if (index.column() == 2)
return m_apps[index.row()].blacklistExpression.pattern();
else
return QVariant();
break;
}
case Qt::CheckStateRole: {
if (index.column() == 0)
return m_apps[index.row()].active ? Qt::Checked : Qt::Unchecked;
else
return QVariant();
break;
}
}
return QVariant();
}
bool NotifyingApplicationModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (!index.isValid() || (index.column() != 0 && index.column() != 2) || index.row() < 0 || index.row() >= m_apps.size())
return false;
bool res = false;
QModelIndex bottomRight = createIndex(index.row(), index.column());
switch (role) {
case Qt::CheckStateRole: {
if (index.column() == 0) {
m_apps[index.row()].active = ((Qt::CheckState)value.toInt() == Qt::Checked);
bottomRight = createIndex(index.row(), index.column() + 1);
res = true;
}
break;
}
case Qt::EditRole: {
if (index.column() == 2) {
m_apps[index.row()].blacklistExpression.setPattern(value.toString());
res = true;
}
}
}
if (res) {
Q_EMIT dataChanged(index, bottomRight);
Q_EMIT applicationsChanged(); // -> notify config that we need to save
}
return res;
}
void NotifyingApplicationModel::sort(int column, Qt::SortOrder order)
{
if (column != 1)
return;
if (order == Qt::AscendingOrder)
std::sort(m_apps.begin(), m_apps.end(), [](const NotifyingApplication &a, const NotifyingApplication &b) {
return (a.name.compare(b.name, Qt::CaseInsensitive) < 1);
});
else
std::sort(m_apps.begin(), m_apps.end(), [](const NotifyingApplication &a, const NotifyingApplication &b) {
return (b.name.compare(a.name, Qt::CaseInsensitive) < 1);
});
Q_EMIT dataChanged(createIndex(0, 0), createIndex(m_apps.size(), 2));
}
QVariant NotifyingApplicationModel::headerData(int section, Qt::Orientation /*orientation*/, int role) const
{
switch (role) {
case Qt::DisplayRole: {
if (section == 1)
return i18n("Name");
else if (section == 0)
return QVariant(); // i18n("Sync");
else
return i18n("Blacklisted");
}
case Qt::ToolTipRole: {
if (section == 1)
return i18n("Name of a notifying application.");
else if (section == 0)
return i18n("Synchronize notifications of an application?");
else
return i18n(
"Regular expression defining which notifications should not be sent.\nThis pattern is applied to the summary and, if selected above, the body "
"of notifications.");
}
}
return QVariant();
}
int NotifyingApplicationModel::columnCount(const QModelIndex &) const
{
return 3;
}
int NotifyingApplicationModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid()) {
// Return size 0 if we are a child because this is not a tree
return 0;
}
return m_apps.size();
}
#include "moc_notifyingapplicationmodel.cpp"