File indexing completed on 2024-04-21 15:08:49

0001 /***************************************************************************
0002  *   Copyright (C) 2012 by Daniel Nicoletti                                *
0003  *   dantti12@gmail.com                                                    *
0004  *   2022 by Han Young <hanyoung@protonmail.com                            *
0005  *                                                                         *
0006  *   This program is free software; you can redistribute it and/or modify  *
0007  *   it under the terms of the GNU General Public License as published by  *
0008  *   the Free Software Foundation; either version 2 of the License, or     *
0009  *   (at your option) any later version.                                   *
0010  *                                                                         *
0011  *   This program is distributed in the hope that it will be useful,       *
0012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0014  *   GNU General Public License for more details.                          *
0015  *                                                                         *
0016  *   You should have received a copy of the GNU General Public License     *
0017  *   along with this program; see the file COPYING. If not, write to       *
0018  *   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,  *
0019  *   Boston, MA 02110-1301, USA.                                           *
0020  ***************************************************************************/
0021 
0022 #include <set>
0023 
0024 #include <KPluginFactory>
0025 #include <KSharedConfig>
0026 #include <klocalizedstring.h>
0027 
0028 #include "CdDeviceInterface.h"
0029 #include "CdInterface.h"
0030 #include "CdProfileInterface.h"
0031 
0032 #include "ColordKCM.h"
0033 #include "DeviceDescription.h"
0034 #include "DeviceModel.h"
0035 #include "ProfileDescription.h"
0036 #include "ProfileMetaDataModel.h"
0037 #include "ProfileModel.h"
0038 #include "ProfileNamedColorsModel.h"
0039 
0040 #include "qdbusconnection.h"
0041 K_PLUGIN_CLASS_WITH_JSON(KCMColord, "kcm_colord.json")
0042 
0043 KCMColord::KCMColord(QObject *parent, const KPluginMetaData &data, const QVariantList &args)
0044     : KQuickConfigModule(parent, data)
0045     , m_cdInterface(
0046           new CdInterface(QStringLiteral("org.freedesktop.ColorManager"), QStringLiteral("/org/freedesktop/ColorManager"), QDBusConnection::systemBus(), this))
0047     , m_deviceModel(new DeviceModel(m_cdInterface, this))
0048     , m_profileModel(new ProfileModel(m_cdInterface, this))
0049     , m_deviceDescription(new DeviceDescription(this))
0050     , m_profileDescription(new ProfileDescription(this))
0051     , m_filterModel(new QSortFilterProxyModel(this))
0052 {
0053     qmlRegisterAnonymousType<DeviceModel>("kcmcolord", 1);
0054     qmlRegisterAnonymousType<ProfileModel>("kcmcolord", 1);
0055     qmlRegisterAnonymousType<ProfileMetaDataModel>("kcmcolord", 1);
0056     qmlRegisterAnonymousType<ProfileNamedColorsModel>("kcmcolord", 1);
0057     qmlRegisterAnonymousType<DeviceDescription>("kcmcolord", 1);
0058     qmlRegisterAnonymousType<ProfileDescription>("kcmcolord", 1);
0059     qmlRegisterAnonymousType<AddProfileComboBoxItem>("kcmcolord", 1);
0060     // Make sure we know is colord is running
0061     auto watcher =
0062         new QDBusServiceWatcher(QStringLiteral("org.freedesktop.ColorManager"), QDBusConnection::systemBus(), QDBusServiceWatcher::WatchForOwnerChange, this);
0063     connect(watcher, &QDBusServiceWatcher::serviceOwnerChanged, m_deviceModel, &DeviceModel::serviceOwnerChanged);
0064     connect(watcher, &QDBusServiceWatcher::serviceOwnerChanged, m_profileModel, &ProfileModel::serviceOwnerChanged);
0065     connect(watcher, &QDBusServiceWatcher::serviceOwnerChanged, m_deviceDescription, &DeviceDescription::serviceOwnerChanged);
0066 }
0067 
0068 ProfileModel *KCMColord::profileModel() const
0069 {
0070     return m_profileModel;
0071 }
0072 
0073 DeviceModel *KCMColord::deviceModel() const
0074 {
0075     return m_deviceModel;
0076 }
0077 
0078 DeviceDescription *KCMColord::deviceDescription() const
0079 {
0080     return m_deviceDescription;
0081 }
0082 
0083 ProfileDescription *KCMColord::profileDescription() const
0084 {
0085     return m_profileDescription;
0086 }
0087 
0088 void KCMColord::assignProfileToDevice(const QDBusObjectPath &profile, const QDBusObjectPath &devicePath) const
0089 {
0090     CdDeviceInterface device(QStringLiteral("org.freedesktop.ColorManager"), devicePath.path(), QDBusConnection::systemBus());
0091     if (device.isValid()) {
0092         device.AddProfile(QStringLiteral("hard"), profile);
0093     }
0094 }
0095 
0096 void KCMColord::makeProfileDefault(const QDBusObjectPath &profilePath, const QDBusObjectPath &devicePath)
0097 {
0098     CdDeviceInterface device(QStringLiteral("org.freedesktop.ColorManager"), devicePath.path(), QDBusConnection::systemBus());
0099     if (device.isValid()) {
0100         device.MakeProfileDefault(profilePath);
0101     }
0102 }
0103 
0104 void KCMColord::importProfile(const QUrl &filepath)
0105 {
0106     QProcess::execute(QStringLiteral("colord-kde-icc-importer"), {QStringLiteral("--yes"), filepath.path()});
0107 }
0108 
0109 void KCMColord::removeProfile(const QString &filename)
0110 {
0111     // TODO: capture error and display it
0112     QFile::remove(filename);
0113 }
0114 
0115 bool KCMColord::canAddProfileForDevice(const QDBusObjectPath &device)
0116 {
0117     auto index = m_deviceModel->findDeviceIndex(device);
0118     if (index < 0) {
0119         return {};
0120     }
0121     auto modelIndex = m_deviceModel->index(index, 0);
0122     auto colorspace = m_deviceModel->data(modelIndex, DeviceModel::ColorspaceRole).toString();
0123     auto profileKind = m_deviceModel->data(modelIndex, DeviceModel::ProfileKindRole).toString();
0124     auto item = m_deviceModel->item(index);
0125     if (item) {
0126         auto rowCount = item->rowCount();
0127         std::set<QDBusObjectPath> assigned;
0128         for (int i = 0; i < rowCount; ++i) {
0129             assigned.insert(item->child(i, 0)->data(DeviceModel::ObjectPathRole).value<QDBusObjectPath>());
0130         }
0131 
0132         auto profileCount = m_profileModel->rowCount();
0133         for (int i = 0; i < profileCount; i++) {
0134             auto pColorspace = m_profileModel->data(m_profileModel->index(i, 0), ProfileModel::ColorspaceRole).toString();
0135             auto pProfileKind = m_profileModel->data(m_profileModel->index(i, 0), ProfileModel::ProfileKindRole).toString();
0136             if (pColorspace != colorspace || pProfileKind != profileKind) {
0137                 continue;
0138             }
0139             auto objectPath = m_profileModel->data(m_profileModel->index(i, 0), ProfileModel::ObjectPathRole).value<QDBusObjectPath>();
0140             if (assigned.count(objectPath)) {
0141                 continue;
0142             }
0143 
0144             return true;
0145         }
0146     }
0147     return false;
0148 }
0149 
0150 QList<QObject *> KCMColord::getComboBoxItemsForDevice(const QDBusObjectPath &device)
0151 {
0152     auto index = m_deviceModel->findDeviceIndex(device);
0153     if (index < 0) {
0154         return {};
0155     }
0156 
0157     auto modelIndex = m_deviceModel->index(index, 0);
0158     auto colorspace = m_deviceModel->data(modelIndex, DeviceModel::ColorspaceRole).toString();
0159     auto profileKind = m_deviceModel->data(modelIndex, DeviceModel::ProfileKindRole).toString();
0160     auto item = m_deviceModel->item(index);
0161     if (item) {
0162         auto rowCount = item->rowCount();
0163         std::set<QDBusObjectPath> assigned;
0164         for (int i = 0; i < rowCount; ++i) {
0165             assigned.insert(item->child(i, 0)->data(DeviceModel::ObjectPathRole).value<QDBusObjectPath>());
0166         }
0167         QList<QObject *> result;
0168         auto profileCount = m_profileModel->rowCount();
0169         for (int i = 0; i < profileCount; i++) {
0170             auto pColorspace = m_profileModel->data(m_profileModel->index(i, 0), ProfileModel::ColorspaceRole).toString();
0171             auto pProfileKind = m_profileModel->data(m_profileModel->index(i, 0), ProfileModel::ProfileKindRole).toString();
0172             if (pColorspace != colorspace || pProfileKind != profileKind) {
0173                 continue;
0174             }
0175             auto objectPath = m_profileModel->data(m_profileModel->index(i, 0), ProfileModel::ObjectPathRole).value<QDBusObjectPath>();
0176             if (assigned.count(objectPath)) {
0177                 continue;
0178             }
0179             auto name = m_profileModel->data(m_profileModel->index(i, 0), Qt::DisplayRole).toString();
0180 
0181             result.append(new AddProfileComboBoxItem(this, objectPath, name));
0182         }
0183 
0184         for (auto obj : std::as_const(m_comboBoxItemsToBeDestroyed)) {
0185             obj->deleteLater();
0186         }
0187         m_comboBoxItemsToBeDestroyed = result;
0188 
0189         return result;
0190     }
0191     return {};
0192 }
0193 
0194 #include "ColordKCM.moc"
0195 #include "moc_ColordKCM.cpp"