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

0001 /***************************************************************************
0002  *   Copyright (C) 2012-2016 by Daniel Nicoletti <dantti12@gmail.com>      *
0003  *   2022 by Han Young <hanyoung@protonmail.com>                           *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; see the file COPYING. If not, write to       *
0017  *   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,  *
0018  *   Boston, MA 02110-1301, USA.                                           *
0019  ***************************************************************************/
0020 
0021 #include "DeviceDescription.h"
0022 
0023 #include "CdDeviceInterface.h"
0024 #include "CdInterface.h"
0025 #include "CdProfileInterface.h"
0026 #include "CdSensorInterface.h"
0027 
0028 #include <QDateTime>
0029 #include <QDebug>
0030 #include <QFileInfo>
0031 #include <QStringBuilder>
0032 
0033 #include <KFormat>
0034 #include <KLocalizedString>
0035 #include <KMessageWidget>
0036 
0037 typedef QList<QDBusObjectPath> ObjectPathList;
0038 
0039 DeviceDescription::DeviceDescription(QObject *parent)
0040     : QObject(parent)
0041 {
0042 }
0043 
0044 void DeviceDescription::setCdInterface(CdInterface *interface)
0045 {
0046     // listen to colord for events
0047     connect(interface, &CdInterface::SensorAdded, this, &DeviceDescription::sensorAddedUpdateCalibrateButton);
0048     connect(interface, &CdInterface::SensorRemoved, this, &DeviceDescription::sensorRemovedUpdateCalibrateButton);
0049 
0050     auto async = interface->GetSensors();
0051     auto watcher = new QDBusPendingCallWatcher(async, this);
0052     connect(watcher, &QDBusPendingCallWatcher::finished, this, &DeviceDescription::gotSensors);
0053 }
0054 
0055 void DeviceDescription::serviceOwnerChanged(const QString &serviceName, const QString &oldOwner, const QString &newOwner)
0056 {
0057     Q_UNUSED(serviceName)
0058     if (newOwner.isEmpty() || oldOwner != newOwner) {
0059         // colord has quit or restarted
0060         m_sensors.clear();
0061     }
0062 }
0063 
0064 void DeviceDescription::gotSensors(QDBusPendingCallWatcher *call)
0065 {
0066     QDBusPendingReply<ObjectPathList> reply = *call;
0067     if (reply.isError()) {
0068         qWarning() << "Unexpected message" << reply.error().message();
0069     } else {
0070         const ObjectPathList sensors = reply.argumentAt<0>();
0071         for (const QDBusObjectPath &sensor : sensors) {
0072             // Add the sensors but don't update the Calibrate message
0073             sensorAdded(sensor, false);
0074         }
0075 
0076         // Update the calibrate message later
0077         generateCalibrateMessage(m_currentDeviceKind);
0078     }
0079 }
0080 
0081 void DeviceDescription::sensorAdded(const QDBusObjectPath &sensorPath, bool updateCalibrateMessage)
0082 {
0083     if (!m_sensors.contains(sensorPath)) {
0084         m_sensors.append(sensorPath);
0085     }
0086 
0087     if (updateCalibrateMessage) {
0088         generateCalibrateMessage(m_currentDeviceKind);
0089     }
0090 }
0091 
0092 void DeviceDescription::sensorAddedUpdateCalibrateButton(const QDBusObjectPath &sensorPath)
0093 {
0094     sensorAdded(sensorPath);
0095 }
0096 
0097 void DeviceDescription::sensorRemoved(const QDBusObjectPath &sensorPath, bool updateCalibrateMessage)
0098 {
0099     m_sensors.removeOne(sensorPath);
0100     if (updateCalibrateMessage) {
0101         generateCalibrateMessage(m_currentDeviceKind);
0102     }
0103 }
0104 
0105 void DeviceDescription::sensorRemovedUpdateCalibrateButton(const QDBusObjectPath &sensorPath)
0106 {
0107     sensorRemoved(sensorPath);
0108 }
0109 
0110 void DeviceDescription::setDevice(const QDBusObjectPath &objectPath)
0111 {
0112     CdDeviceInterface device(QStringLiteral("org.freedesktop.ColorManager"), objectPath.path(), QDBusConnection::systemBus());
0113     if (!device.isValid()) {
0114         return;
0115     }
0116 
0117     m_currentDeviceID = device.deviceId();
0118     const QString model = device.model();
0119     const QString vendor = device.vendor();
0120     if (model.isEmpty() && vendor.isEmpty()) {
0121         m_deviceTitle = m_currentDeviceID;
0122     } else if (model.isEmpty()) {
0123         m_deviceTitle = vendor;
0124     } else if (vendor.isEmpty()) {
0125         m_deviceTitle = model;
0126     } else {
0127         m_deviceTitle = vendor % QLatin1String(" - ") % model;
0128     }
0129 
0130     const QString kind = device.kind();
0131     if (kind == QLatin1String("printer")) {
0132         m_currentDeviceKind = i18nc("device type", "Printer");
0133     } else if (kind == QLatin1String("display")) {
0134         m_currentDeviceKind = i18nc("device type", "Display");
0135     } else if (kind == QLatin1String("webcam")) {
0136         m_currentDeviceKind = i18nc("device type", "Webcam");
0137     } else if (kind == QLatin1String("scanner")) {
0138         m_currentDeviceKind = i18nc("device type", "Scanner");
0139     } else {
0140         m_currentDeviceKind = i18nc("device type", "Unknown");
0141     }
0142 
0143     const QString scope = device.scope();
0144     if (scope == QLatin1String("temp")) {
0145         m_deviceScope = i18nc("device scope", "User session");
0146     } else if (scope == QLatin1String("disk")) {
0147         m_deviceScope = i18nc("device scope", "Auto restore");
0148     } else if (scope == QLatin1String("normal")) {
0149         m_deviceScope = i18nc("device scope", "System wide");
0150     } else {
0151         m_deviceScope = i18nc("device scope", "Unknown");
0152     }
0153 
0154     const QString colorspace = device.colorspace();
0155     if (colorspace == QLatin1String("rgb")) {
0156         m_colorSpace = i18nc("colorspace", "RGB");
0157     } else if (colorspace == QLatin1String("cmyk")) {
0158         m_colorSpace = i18nc("colorspace", "CMYK");
0159     } else if (colorspace == QLatin1String("gray")) {
0160         m_colorSpace = i18nc("colorspace", "Gray");
0161     }
0162 
0163     ObjectPathList profiles = device.profiles();
0164 
0165     QString profileTitle = i18n("This device has no profile assigned to it");
0166     if (!profiles.isEmpty()) {
0167         CdProfileInterface profile(QStringLiteral("org.freedesktop.ColorManager"), profiles.first().path(), QDBusConnection::systemBus());
0168         if (profile.isValid()) {
0169             profileTitle = profile.title();
0170             if (profileTitle.isEmpty()) {
0171                 profileTitle = profile.profileId();
0172             }
0173         }
0174     }
0175     m_currentProfileTitle = profileTitle;
0176 
0177     generateCalibrateMessage(kind);
0178 
0179     Q_EMIT dataChanged();
0180 }
0181 
0182 void DeviceDescription::generateCalibrateMessage(const QString &kind)
0183 {
0184     m_calibrateMsg = i18n("You can use 'displaycal' to calibrate this device");
0185 
0186     if (m_currentDeviceID.isEmpty()) {
0187         // No device was selected
0188         return;
0189     }
0190 
0191     if (kind == QLatin1String("display")) {
0192         if (m_sensors.isEmpty()) {
0193             m_calibrateMsg = i18n("The measuring instrument for calibrating is not detected. Please check it is turned on and correctly connected.");
0194         }
0195     } else if (kind == QLatin1String("printer")) {
0196         // Check if we have any sensor
0197         if (m_sensors.isEmpty()) {
0198             m_calibrateMsg = i18n("The measuring instrument for calibrating is not detected. Please check it is turned on and correctly connected.");
0199         } else {
0200             bool canCalibrate = false;
0201             // Search for a suitable sensor
0202             for (const QDBusObjectPath &sensorPath : std::as_const(m_sensors)) {
0203                 CdSensorInterface sensor(QStringLiteral("org.freedesktop.ColorManager"), sensorPath.path(), QDBusConnection::systemBus());
0204                 if (!sensor.isValid()) {
0205                     continue;
0206                 }
0207 
0208                 QStringList capabilities = sensor.capabilities();
0209                 if (capabilities.contains(QStringLiteral("printer"))) {
0210                     canCalibrate = true;
0211                     break;
0212                 }
0213             }
0214 
0215             // If we did not find a suitable sensor, display a warning
0216             if (!canCalibrate) {
0217                 m_calibrateMsg = i18n("The measuring instrument does not support printer profiling.");
0218             }
0219         }
0220     } else if (kind != QLatin1String("camera") && kind != QLatin1String("scanner") && kind != QLatin1String("webcam")) {
0221         m_calibrateMsg = i18n("The device type is not currently supported for calibrating.");
0222     }
0223 
0224     Q_EMIT calibrateMessageChanged();
0225 }
0226 
0227 #include "moc_DeviceDescription.cpp"