File indexing completed on 2025-02-23 05:09:17

0001 /*
0002     SPDX-FileCopyrightText: 2016, 2019 Kai Uwe Broulik <kde@privat.broulik.de>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "smartlauncheritem.h"
0008 
0009 #include <KDesktopFile>
0010 #include <KService>
0011 
0012 using namespace SmartLauncher;
0013 
0014 Item::Item(QObject *parent)
0015     : QObject(parent)
0016 {
0017     m_backendPtr = s_backend.lock();
0018     if (!m_backendPtr) {
0019         auto ptr = std::make_shared<Backend>();
0020         s_backend = ptr;
0021         m_backendPtr = s_backend.lock();
0022     }
0023 }
0024 
0025 std::weak_ptr<Backend> Item::s_backend;
0026 
0027 void Item::init()
0028 {
0029     if (m_inited || m_storageId.isEmpty() || !m_backendPtr) {
0030         return;
0031     }
0032 
0033     connect(m_backendPtr.get(), &Backend::reloadRequested, this, [this](const QString &uri) {
0034         if (uri.isEmpty() || m_storageId == uri) {
0035             populate();
0036         }
0037     });
0038 
0039     connect(m_backendPtr.get(), &Backend::launcherRemoved, this, [this](const QString &uri) {
0040         if (uri.isEmpty() || m_storageId == uri) {
0041             clear();
0042         }
0043     });
0044 
0045     connect(m_backendPtr.get(), &Backend::countChanged, this, [this](const QString &uri, int count) {
0046         if (uri.isEmpty() || m_storageId == uri) {
0047             setCount(count);
0048         }
0049     });
0050 
0051     connect(m_backendPtr.get(), &Backend::countVisibleChanged, this, [this](const QString &uri, bool countVisible) {
0052         if (uri.isEmpty() || m_storageId == uri) {
0053             setCountVisible(countVisible);
0054         }
0055     });
0056 
0057     connect(m_backendPtr.get(), &Backend::progressChanged, this, [this](const QString &uri, int progress) {
0058         if (uri.isEmpty() || m_storageId == uri) {
0059             setProgress(progress);
0060         }
0061     });
0062 
0063     connect(m_backendPtr.get(), &Backend::progressVisibleChanged, this, [this](const QString &uri, bool progressVisible) {
0064         if (uri.isEmpty() || m_storageId == uri) {
0065             setProgressVisible(progressVisible);
0066         }
0067     });
0068 
0069     connect(m_backendPtr.get(), &Backend::urgentChanged, this, [this](const QString &uri, bool urgent) {
0070         if (uri.isEmpty() || m_storageId == uri) {
0071             setUrgent(urgent);
0072         }
0073     });
0074 
0075     m_inited = true;
0076 }
0077 
0078 void Item::populate()
0079 {
0080     if (!m_backendPtr || m_storageId.isEmpty()) {
0081         return;
0082     }
0083 
0084     if (!m_backendPtr->hasLauncher(m_storageId)) {
0085         return;
0086     }
0087 
0088     setCount(m_backendPtr->count(m_storageId));
0089     setCountVisible(m_backendPtr->countVisible(m_storageId));
0090     setProgress(m_backendPtr->progress(m_storageId));
0091     setProgressVisible(m_backendPtr->progressVisible(m_storageId));
0092     setUrgent(m_backendPtr->urgent(m_storageId));
0093 }
0094 
0095 void Item::clear()
0096 {
0097     setCount(0);
0098     setCountVisible(false);
0099     setProgress(0);
0100     setProgressVisible(false);
0101     setUrgent(false);
0102 }
0103 
0104 QUrl Item::launcherUrl() const
0105 {
0106     return m_launcherUrl;
0107 }
0108 
0109 void Item::setLauncherUrl(const QUrl &launcherUrl)
0110 {
0111     if (launcherUrl != m_launcherUrl) {
0112         m_launcherUrl = launcherUrl;
0113         Q_EMIT launcherUrlChanged(launcherUrl);
0114 
0115         m_storageId.clear();
0116         clear();
0117 
0118         if (launcherUrl.scheme() == QLatin1String("applications")) {
0119             const KService::Ptr service = KService::serviceByMenuId(launcherUrl.path());
0120 
0121             if (service && launcherUrl.path() == service->menuId()) {
0122                 m_storageId = service->menuId();
0123             }
0124         }
0125 
0126         if (launcherUrl.isLocalFile() && KDesktopFile::isDesktopFile(launcherUrl.toLocalFile())) {
0127             KDesktopFile f(launcherUrl.toLocalFile());
0128 
0129             const KService::Ptr service = KService::serviceByStorageId(f.fileName());
0130             if (service) {
0131                 m_storageId = service->storageId();
0132             }
0133         }
0134 
0135         if (m_storageId.isEmpty()) {
0136             return;
0137         }
0138 
0139         if (m_backendPtr) {
0140             // check if we have a mapping to a different desktop file
0141             const QString &overrideStorageId = m_backendPtr->unityMappingRules().value(m_storageId);
0142             if (!overrideStorageId.isEmpty()) {
0143                 m_storageId = overrideStorageId;
0144             }
0145         }
0146 
0147         init();
0148         populate();
0149     }
0150 }
0151 
0152 int Item::count() const
0153 {
0154     return m_count;
0155 }
0156 
0157 void Item::setCount(int count)
0158 {
0159     if (m_count != count) {
0160         m_count = count;
0161         Q_EMIT countChanged(count);
0162     }
0163 }
0164 
0165 bool Item::countVisible() const
0166 {
0167     return m_countVisible;
0168 }
0169 
0170 void Item::setCountVisible(bool countVisible)
0171 {
0172     if (m_countVisible != countVisible) {
0173         m_countVisible = countVisible;
0174         Q_EMIT countVisibleChanged(countVisible);
0175     }
0176 }
0177 
0178 int Item::progress() const
0179 {
0180     return m_progress;
0181 }
0182 
0183 void Item::setProgress(int progress)
0184 {
0185     int boundedProgress = std::clamp(progress, 0, 100);
0186 
0187     if (progress != boundedProgress) {
0188         qWarning().nospace() << qUtf8Printable(m_launcherUrl.toString()) << ": Progress value " << progress << " is out of bounds!";
0189     }
0190 
0191     if (m_progress != boundedProgress) {
0192         m_progress = boundedProgress;
0193         Q_EMIT progressChanged(boundedProgress);
0194     }
0195 }
0196 
0197 bool Item::progressVisible() const
0198 {
0199     return m_progressVisible;
0200 }
0201 
0202 void Item::setProgressVisible(bool progressVisible)
0203 {
0204     if (m_progressVisible != progressVisible) {
0205         m_progressVisible = progressVisible;
0206         Q_EMIT progressVisibleChanged(progressVisible);
0207     }
0208 }
0209 
0210 bool Item::urgent() const
0211 {
0212     return m_urgent;
0213 }
0214 
0215 void Item::setUrgent(bool urgent)
0216 {
0217     if (m_urgent != urgent) {
0218         m_urgent = urgent;
0219         Q_EMIT urgentChanged(urgent);
0220     }
0221 }