You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
latte-dock/app/view/settings/indicatoruimanager.cpp

227 lines
6.7 KiB
C++

/*
* Copyright 2020 Michail Vourlakos <mvourlakos@gmail.com>
*
* This file is part of Latte-Dock
*
* Latte-Dock is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* Latte-Dock is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "indicatoruimanager.h"
// local
#include "primaryconfigview.h"
#include "../view.h"
#include "../indicator/indicator.h"
#include "../../lattecorona.h"
#include "../../indicator/factory.h"
// Qt
#include <QFileDialog>
#include <QTimer>
// KDE
#include <KLocalizedString>
#include <KPluginMetaData>
#include <KDeclarative/QmlObjectSharedEngine>
namespace Latte {
namespace ViewPart {
namespace Config {
IndicatorUiManager::IndicatorUiManager(ViewPart::PrimaryConfigView *parent)
: QObject(parent),
m_primary(parent)
{
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
qmlRegisterType<Latte::ViewPart::Config::IndicatorUiManager>();
#else
qmlRegisterAnonymousType<Latte::ViewPart::Config::IndicatorUiManager>("latte-dock", 1);
#endif
}
IndicatorUiManager::~IndicatorUiManager()
{
m_uidata.clear();
}
bool IndicatorUiManager::contains(const QString &type)
{
return (index(type) >= 0);
}
int IndicatorUiManager::index(const QString &type)
{
for (int i=0; i<m_uidata.count(); ++i) {
if (m_uidata[i].type == type) {
return i;
}
}
return -1;
}
void IndicatorUiManager::setParentItem(QQuickItem *parentItem)
{
m_parentItem = parentItem;
}
void IndicatorUiManager::hideAllUi()
{
for (int i=0; i<m_uidata.count(); ++i) {
if (m_uidata[i].ui) {
//! config ui has already been created and can be provided again
QQuickItem *qmlItem = qobject_cast<QQuickItem*>(m_uidata[i].ui->rootObject());
if (qmlItem) {
qmlItem->setVisible(false);
}
}
}
}
void IndicatorUiManager::showNextIndicator()
{
if (!m_parentItem) {
return;
}
if (auto *metaObject = m_parentItem->metaObject()) {
int methodIndex = metaObject->indexOfMethod("showNextIndicator()");
if (methodIndex == -1) {
qDebug() << "indicator parent page function showNextIndicator() was not found...";
return;
}
QMetaMethod method = metaObject->method(methodIndex);
method.invoke(m_parentItem);
}
}
void IndicatorUiManager::ui(const QString &type, Latte::View *view)
{
if (!m_parentItem) {
return;
}
int typeIndex = index(type);
if (typeIndex > -1 && m_uidata[typeIndex].ui) {
m_uidata[typeIndex].ui->rootContext()->setContextProperty(QStringLiteral("indicator"), view->indicator());
m_uidata[typeIndex].view = view;
//! config ui has already been created and can be provided again
QQuickItem *qmlItem = qobject_cast<QQuickItem*>(m_uidata[typeIndex].ui->rootObject());
if (qmlItem) {
qmlItem->setParentItem(m_parentItem);
showNextIndicator();
}
return;
}
//! type needs to be created again
KPluginMetaData metadata = m_primary->corona()->indicatorFactory()->metadata(type);;
if (metadata.isValid()) {
QString uiPath = metadata.value("X-Latte-ConfigUi");
if (!uiPath.isEmpty()) {
IndicatorUiData uidata;
uidata.ui = new KDeclarative::QmlObjectSharedEngine(this);
uidata.pluginPath = metadata.fileName().remove("metadata.desktop");
uidata.type = type;
uidata.view = view;
uidata.ui->setTranslationDomain(QLatin1String("latte_indicator_") + metadata.pluginId());
uidata.ui->setInitializationDelayed(true);
uiPath = uidata.pluginPath + "package/" + uiPath;
uidata.ui->setSource(QUrl::fromLocalFile(uiPath));
uidata.ui->rootContext()->setContextProperty(QStringLiteral("dialog"), m_parentItem);
uidata.ui->rootContext()->setContextProperty(QStringLiteral("indicator"), view->indicator());
uidata.ui->completeInitialization();
int newTypeIndex = view->indicator()->index(type);
int newPos = -1;
for (int i=0; i<m_uidata.count(); ++i) {
int oldTypeIndex = view->indicator()->index(m_uidata[i].type);
if (oldTypeIndex > newTypeIndex) {
newPos = i;
break;
}
}
if (newPos == -1) {
m_uidata << uidata;
} else {
m_uidata.insert(newPos, uidata);
}
QQuickItem *qmlItem = qobject_cast<QQuickItem*>(uidata.ui->rootObject());
if (qmlItem) {
qmlItem->setParentItem(m_parentItem);
showNextIndicator();
}
}
}
}
void IndicatorUiManager::addIndicator()
{
QFileDialog *fileDialog = new QFileDialog(nullptr
, i18nc("add indicator", "Add Indicator")
, QDir::homePath()
, QStringLiteral("indicator.latte"));
fileDialog->setFileMode(QFileDialog::AnyFile);
fileDialog->setAcceptMode(QFileDialog::AcceptOpen);
fileDialog->setDefaultSuffix("indicator.latte");
QStringList filters;
filters << QString(i18nc("add indicator file", "Latte Indicator") + "(*.indicator.latte)");
fileDialog->setNameFilters(filters);
connect(fileDialog, &QFileDialog::finished, fileDialog, &QFileDialog::deleteLater);
connect(fileDialog, &QFileDialog::fileSelected, this, [&](const QString & file) {
qDebug() << "Trying to import indicator file ::: " << file;
m_primary->corona()->indicatorFactory()->importIndicatorFile(file);
});
fileDialog->open();
}
void IndicatorUiManager::downloadIndicator()
{
//! call asynchronously in order to not crash when view settings window
//! loses focus and it closes
QTimer::singleShot(0, [this]() {
m_primary->corona()->indicatorFactory()->downloadIndicator();
});
}
void IndicatorUiManager::removeIndicator(QString pluginId)
{ //! call asynchronously in order to not crash when view settings window
//! loses focus and it closes
QTimer::singleShot(0, [this, pluginId]() {
m_primary->corona()->indicatorFactory()->removeIndicator(pluginId);
});
}
}
}
}