forked from Qortal/Brooklyn
282 lines
11 KiB
C++
282 lines
11 KiB
C++
/*
|
|
SPDX-FileCopyrightText: 2015-2016 Ivan Cukic <ivan.cukic@kde.org>
|
|
|
|
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
*/
|
|
|
|
#include "dialog.h"
|
|
|
|
#include <QAction>
|
|
#include <QDialogButtonBox>
|
|
#include <QGuiApplication>
|
|
#include <QPushButton>
|
|
#include <QQmlContext>
|
|
#include <QQmlEngine>
|
|
#include <QQuickItem>
|
|
#include <QQuickView>
|
|
#include <QQuickWidget>
|
|
#include <QString>
|
|
#include <QTabWidget>
|
|
#include <QTimer>
|
|
#include <QVBoxLayout>
|
|
|
|
#include <KGlobalAccel>
|
|
#include <KLocalizedString>
|
|
#include <KMessageWidget>
|
|
|
|
#include "../kactivities-kcm-features.h"
|
|
|
|
#include "features_interface.h"
|
|
#include "kactivities/controller.h"
|
|
#include "kactivities/info.h"
|
|
|
|
#include "common/dbus/common.h"
|
|
#include "utils/continue_with.h"
|
|
#include "utils/d_ptr_implementation.h"
|
|
|
|
class Dialog::Private
|
|
{
|
|
public:
|
|
Private(Dialog *parent)
|
|
: q(parent)
|
|
, activityName(QStringLiteral("activityName"))
|
|
, activityDescription(QStringLiteral("activityDescription"))
|
|
, activityIcon(QStringLiteral("activityIcon"))
|
|
, activityWallpaper(QStringLiteral("activityWallpaper"))
|
|
, activityIsPrivate(true)
|
|
, activityShortcut(QStringLiteral("activityShortcut"))
|
|
, features(new org::kde::ActivityManager::Features(QStringLiteral(KAMD_DBUS_SERVICE),
|
|
QStringLiteral(KAMD_DBUS_FEATURES_PATH),
|
|
QDBusConnection::sessionBus(),
|
|
q))
|
|
{
|
|
}
|
|
|
|
Dialog *const q;
|
|
QVBoxLayout *layout;
|
|
QTabWidget *tabs;
|
|
|
|
QQuickWidget *tabGeneral;
|
|
KMessageWidget *message;
|
|
QDialogButtonBox *buttons;
|
|
QString defaultOKText;
|
|
|
|
QQuickWidget *createTab(const QString &title, const QString &file)
|
|
{
|
|
auto view = new QQuickWidget();
|
|
|
|
view->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
|
|
|
view->setClearColor(QGuiApplication::palette().window().color());
|
|
|
|
view->rootContext()->setContextProperty(QStringLiteral("dialog"), q);
|
|
|
|
view->rootContext()->setContextObject(new KLocalizedContext(view));
|
|
|
|
const QString sourceFile = QStringLiteral(KAMD_KCM_DATADIR) + "qml/activityDialog/" + file;
|
|
|
|
if (QFile::exists(sourceFile)) {
|
|
view->setSource(QUrl::fromLocalFile(sourceFile));
|
|
tabs->addTab(view, title);
|
|
} else {
|
|
message->setText(i18n("Error loading the QML files. Check your installation.\nMissing %1", sourceFile));
|
|
message->setVisible(true);
|
|
}
|
|
|
|
return view;
|
|
}
|
|
|
|
void setFocus(QQuickWidget *widget)
|
|
{
|
|
// TODO: does not work...
|
|
widget->setFocus();
|
|
auto root = widget->rootObject();
|
|
|
|
if (!root)
|
|
return;
|
|
|
|
QMetaObject::invokeMethod(widget->rootObject(), "setFocus", Qt::DirectConnection);
|
|
}
|
|
|
|
QString activityId;
|
|
|
|
QString activityName;
|
|
QString activityDescription;
|
|
QString activityIcon;
|
|
QString activityWallpaper;
|
|
bool activityIsPrivate;
|
|
QString activityShortcut;
|
|
|
|
KActivities::Controller activities;
|
|
org::kde::ActivityManager::Features *features;
|
|
};
|
|
|
|
void Dialog::showDialog(const QString &id)
|
|
{
|
|
static Dialog *dialog = nullptr;
|
|
|
|
// If we use the regular singleton here (static value instead of static ptr),
|
|
// we will crash on exit because of Qt...
|
|
if (!dialog) {
|
|
dialog = new Dialog();
|
|
}
|
|
|
|
dialog->init(id);
|
|
dialog->show();
|
|
}
|
|
|
|
Dialog::Dialog(QObject *parent)
|
|
: QDialog()
|
|
, d(this)
|
|
{
|
|
resize(550, 400);
|
|
|
|
d->layout = new QVBoxLayout(this);
|
|
|
|
// Message widget for showing errors
|
|
d->message = new KMessageWidget(this);
|
|
d->message->setMessageType(KMessageWidget::Error);
|
|
d->message->setVisible(false);
|
|
d->message->setWordWrap(true);
|
|
d->layout->addWidget(d->message);
|
|
|
|
// Tabs
|
|
d->tabs = new QTabWidget(this);
|
|
d->layout->addWidget(d->tabs);
|
|
d->tabGeneral = d->createTab(i18n("General"), QStringLiteral("GeneralTab.qml"));
|
|
|
|
// Buttons
|
|
d->buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
|
|
d->layout->QLayout::addWidget(d->buttons);
|
|
|
|
connect(d->buttons->button(QDialogButtonBox::Ok), &QAbstractButton::clicked, this, &Dialog::save);
|
|
connect(d->buttons, &QDialogButtonBox::rejected, this, &Dialog::close);
|
|
|
|
d->defaultOKText = d->buttons->button(QDialogButtonBox::Ok)->text();
|
|
}
|
|
|
|
void Dialog::init(const QString &activityId)
|
|
{
|
|
setWindowTitle(activityId.isEmpty() ? i18nc("@title:window", "Create a New Activity") //
|
|
: i18nc("@title:window", "Activity Settings"));
|
|
|
|
d->buttons->button(QDialogButtonBox::Ok)->setText(activityId.isEmpty() ? i18nc("@action:button", "Create") : d->defaultOKText);
|
|
|
|
d->tabs->setCurrentIndex(0);
|
|
|
|
setActivityId(activityId);
|
|
setActivityName(QString());
|
|
setActivityDescription(QString());
|
|
setActivityIcon(QStringLiteral("activities"));
|
|
setActivityIsPrivate(false);
|
|
|
|
setActivityShortcut(QKeySequence());
|
|
|
|
if (!activityId.isEmpty()) {
|
|
KActivities::Info activityInfo(activityId);
|
|
|
|
setActivityName(activityInfo.name());
|
|
setActivityDescription(activityInfo.description());
|
|
setActivityIcon(activityInfo.icon());
|
|
|
|
// finding the key shortcut
|
|
const auto shortcuts = KGlobalAccel::self()->globalShortcut(QStringLiteral("ActivityManager"), QStringLiteral("switch-to-activity-") + activityId);
|
|
setActivityShortcut(shortcuts.isEmpty() ? QKeySequence() : shortcuts.first());
|
|
|
|
// is private?
|
|
auto result = d->features->GetValue(QStringLiteral("org.kde.ActivityManager.Resources.Scoring/isOTR/") + activityId);
|
|
|
|
auto watcher = new QDBusPendingCallWatcher(result, this);
|
|
|
|
QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, [&](QDBusPendingCallWatcher *watcher) mutable {
|
|
QDBusPendingReply<QDBusVariant> reply = *watcher;
|
|
setActivityIsPrivate(reply.value().variant().toBool());
|
|
watcher->deleteLater();
|
|
});
|
|
}
|
|
}
|
|
|
|
Dialog::~Dialog()
|
|
{
|
|
}
|
|
|
|
void Dialog::showEvent(QShowEvent *event)
|
|
{
|
|
Q_UNUSED(event);
|
|
// Setting the focus
|
|
d->setFocus(d->tabGeneral);
|
|
}
|
|
|
|
#define IMPLEMENT_PROPERTY(Scope, Type, PType, PropName) \
|
|
Type Dialog::activity##PropName() const \
|
|
{ \
|
|
auto root = d->tab##Scope->rootObject(); \
|
|
\
|
|
if (!root) { \
|
|
qDebug() << "Root does not exist"; \
|
|
return Type(); \
|
|
} \
|
|
\
|
|
return root->property("activity" #PropName).value<Type>(); \
|
|
} \
|
|
\
|
|
void Dialog::setActivity##PropName(PType value) \
|
|
{ \
|
|
auto root = d->tab##Scope->rootObject(); \
|
|
\
|
|
if (!root) { \
|
|
qDebug() << "Root does not exist"; \
|
|
return; \
|
|
} \
|
|
\
|
|
root->setProperty("activity" #PropName, value); \
|
|
}
|
|
|
|
IMPLEMENT_PROPERTY(General, QString, const QString &, Id)
|
|
IMPLEMENT_PROPERTY(General, QString, const QString &, Name)
|
|
IMPLEMENT_PROPERTY(General, QString, const QString &, Description)
|
|
IMPLEMENT_PROPERTY(General, QString, const QString &, Icon)
|
|
IMPLEMENT_PROPERTY(General, QString, const QString &, Wallpaper)
|
|
IMPLEMENT_PROPERTY(General, QKeySequence, const QKeySequence &, Shortcut)
|
|
IMPLEMENT_PROPERTY(General, bool, bool, IsPrivate)
|
|
#undef IMPLEMENT_PROPERTY
|
|
|
|
void Dialog::save()
|
|
{
|
|
if (activityId().isEmpty()) {
|
|
create();
|
|
|
|
} else {
|
|
saveChanges(activityId());
|
|
}
|
|
}
|
|
|
|
void Dialog::create()
|
|
{
|
|
using namespace kamd::utils;
|
|
continue_with(d->activities.addActivity(activityName()), [this](const optional_view<QString> &activityId) {
|
|
if (activityId.is_initialized()) {
|
|
saveChanges(activityId.get());
|
|
}
|
|
});
|
|
}
|
|
|
|
void Dialog::saveChanges(const QString &activityId)
|
|
{
|
|
d->activities.setActivityName(activityId, activityName());
|
|
d->activities.setActivityDescription(activityId, activityDescription());
|
|
d->activities.setActivityIcon(activityId, activityIcon());
|
|
|
|
// setting the key shortcut
|
|
QAction action(nullptr);
|
|
action.setProperty("isConfigurationAction", true);
|
|
action.setProperty("componentName", QStringLiteral("ActivityManager"));
|
|
action.setObjectName(QStringLiteral("switch-to-activity-") + activityId);
|
|
KGlobalAccel::self()->setShortcut(&action, {activityShortcut()}, KGlobalAccel::NoAutoloading);
|
|
|
|
// is private?
|
|
d->features->SetValue(QStringLiteral("org.kde.ActivityManager.Resources.Scoring/isOTR/") + activityId, QDBusVariant(activityIsPrivate()));
|
|
|
|
close();
|
|
}
|