File indexing completed on 2024-04-28 13:25:46

0001 /*
0002     SPDX-FileCopyrightText: 2020 Michail Vourlakos <mvourlakos@gmail.com>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "indicatoruimanager.h"
0007 
0008 // local
0009 #include "primaryconfigview.h"
0010 #include "../view.h"
0011 #include "../indicator/indicator.h"
0012 #include "../../lattecorona.h"
0013 #include "../../indicator/factory.h"
0014 
0015 // Qt
0016 #include <QFileDialog>
0017 #include <QFileInfo>
0018 #include <QTimer>
0019 
0020 // KDE
0021 #include <KLocalizedString>
0022 #include <KPluginMetaData>
0023 #include <KDeclarative/QmlObjectSharedEngine>
0024 
0025 namespace Latte {
0026 namespace ViewPart {
0027 namespace Config {
0028 
0029 IndicatorUiManager::IndicatorUiManager(ViewPart::PrimaryConfigView *parent)
0030     : QObject(parent),
0031       m_primary(parent)
0032 {
0033     qmlRegisterAnonymousType<Latte::ViewPart::Config::IndicatorUiManager>("latte-dock", 1);
0034 }
0035 
0036 IndicatorUiManager::~IndicatorUiManager()
0037 {
0038     m_uidata.clear();
0039 }
0040 
0041 bool IndicatorUiManager::contains(const QString &type)
0042 {
0043     return (index(type) >= 0);
0044 }
0045 
0046 int IndicatorUiManager::index(const QString &type)
0047 {
0048     for (int i=0; i<m_uidata.count(); ++i) {
0049         if (m_uidata[i].type == type) {
0050             return i;
0051         }
0052     }
0053 
0054     return -1;
0055 }
0056 
0057 void IndicatorUiManager::setParentItem(QQuickItem *parentItem)
0058 {
0059     m_parentItem = parentItem;
0060 }
0061 
0062 void IndicatorUiManager::hideAllUi()
0063 {
0064     for (int i=0; i<m_uidata.count(); ++i) {
0065         if (m_uidata[i].ui) {
0066             //! config ui has already been created and can be provided again
0067             QQuickItem *qmlItem = qobject_cast<QQuickItem*>(m_uidata[i].ui->rootObject());
0068             if (qmlItem) {
0069                 qmlItem->setVisible(false);
0070             }
0071         }
0072     }
0073 }
0074 
0075 void IndicatorUiManager::showNextIndicator()
0076 {
0077     if (!m_parentItem) {
0078         return;
0079     }
0080 
0081     if (auto *metaObject = m_parentItem->metaObject()) {
0082         int methodIndex = metaObject->indexOfMethod("showNextIndicator()");
0083 
0084         if (methodIndex == -1) {
0085             qDebug() << "indicator parent page function showNextIndicator() was not found...";
0086             return;
0087         }
0088 
0089         QMetaMethod method = metaObject->method(methodIndex);
0090         method.invoke(m_parentItem);
0091     }
0092 }
0093 
0094 void IndicatorUiManager::ui(const QString &type, Latte::View *view)
0095 {
0096     if (!m_parentItem) {
0097         return;
0098     }
0099 
0100     int typeIndex = index(type);
0101 
0102     if (typeIndex > -1 && m_uidata[typeIndex].ui) {
0103         m_uidata[typeIndex].ui->rootContext()->setContextProperty(QStringLiteral("indicator"), view->indicator());
0104         m_uidata[typeIndex].view = view;
0105 
0106         //! config ui has already been created and can be provided again
0107         QQuickItem *qmlItem = qobject_cast<QQuickItem*>(m_uidata[typeIndex].ui->rootObject());
0108         if (qmlItem) {
0109             qmlItem->setParentItem(m_parentItem);
0110             showNextIndicator();
0111         }
0112         return;
0113     }
0114 
0115     //! type needs to be created again
0116     KPluginMetaData metadata = m_primary->corona()->indicatorFactory()->metadata(type);
0117 
0118     if (metadata.isValid()) {
0119         QString uiPath = metadata.value("X-Latte-ConfigUi");
0120 
0121         if (!uiPath.isEmpty()) {
0122             IndicatorUiData uidata;
0123 
0124             uidata.ui = new KDeclarative::QmlObjectSharedEngine(this);
0125             uidata.pluginPath = QFileInfo(metadata.fileName()).absolutePath();
0126             uidata.type = type;
0127             uidata.view = view;
0128 
0129             uidata.ui->setTranslationDomain(QLatin1String("latte_indicator_") + metadata.pluginId());
0130             uidata.ui->setInitializationDelayed(true);
0131             uiPath = uidata.pluginPath + "/package/" + uiPath;
0132             uidata.ui->setSource(QUrl::fromLocalFile(uiPath));
0133             uidata.ui->rootContext()->setContextProperty(QStringLiteral("dialog"), m_parentItem);
0134             uidata.ui->rootContext()->setContextProperty(QStringLiteral("indicator"), view->indicator());
0135             uidata.ui->completeInitialization();
0136 
0137             int newTypeIndex = view->indicator()->index(type);
0138             int newPos = -1;
0139 
0140             for (int i=0; i<m_uidata.count(); ++i) {
0141                 int oldTypeIndex = view->indicator()->index(m_uidata[i].type);
0142 
0143                 if (oldTypeIndex > newTypeIndex) {
0144                     newPos = i;
0145                     break;
0146                 }
0147             }
0148 
0149             if (newPos == -1) {
0150                 m_uidata << uidata;
0151             } else {
0152                 m_uidata.insert(newPos, uidata);
0153             }
0154 
0155             QQuickItem *qmlItem = qobject_cast<QQuickItem*>(uidata.ui->rootObject());
0156             if (qmlItem) {
0157                 qmlItem->setParentItem(m_parentItem);
0158                 showNextIndicator();
0159             }
0160         }
0161     }
0162 }
0163 
0164 void IndicatorUiManager::addIndicator()
0165 {
0166     QFileDialog *fileDialog = new QFileDialog(nullptr
0167                                               , i18nc("add indicator", "Add Indicator")
0168                                               , QDir::homePath()
0169                                               , QStringLiteral("indicator.latte"));
0170 
0171     fileDialog->setFileMode(QFileDialog::AnyFile);
0172     fileDialog->setAcceptMode(QFileDialog::AcceptOpen);
0173     fileDialog->setDefaultSuffix("indicator.latte");
0174 
0175     QStringList filters;
0176     filters << QString(i18nc("add indicator file", "Latte Indicator") + "(*.indicator.latte)");
0177     fileDialog->setNameFilters(filters);
0178 
0179     connect(fileDialog, &QFileDialog::finished, fileDialog, &QFileDialog::deleteLater);
0180 
0181     connect(fileDialog, &QFileDialog::fileSelected, this, [&](const QString & file) {
0182         qDebug() << "Trying to import indicator file ::: " << file;
0183         m_primary->corona()->indicatorFactory()->importIndicatorFile(file);
0184     });
0185 
0186     fileDialog->open();
0187 }
0188 
0189 void IndicatorUiManager::downloadIndicator()
0190 {
0191     //! call asynchronously in order to not crash when view settings window
0192     //! loses focus and it closes
0193     QTimer::singleShot(0, [this]() {
0194         m_primary->corona()->indicatorFactory()->downloadIndicator();
0195     });
0196 }
0197 
0198 void IndicatorUiManager::removeIndicator(QString pluginId)
0199 {    //! call asynchronously in order to not crash when view settings window
0200     //! loses focus and it closes
0201     QTimer::singleShot(0, [this, pluginId]() {
0202         m_primary->corona()->indicatorFactory()->removeIndicator(pluginId);
0203     });
0204 }
0205 
0206 
0207 }
0208 }
0209 }