8#include <KLocalizedQmlContext>
10#include "Plasma/Applet"
11#include "Plasma/Containment"
12#include "appletcontext_p.h"
13#include "appletquickitem.h"
14#include "configcategory_p.h"
15#include "configmodel.h"
20#include <QLoggingCategory>
21#include <QQmlComponent>
24#include <QQmlFileSelector>
28#include <KLocalizedContext>
29#include <KLocalizedString>
30#include <KPackage/Package>
32#include <Plasma/Corona>
33#include <Plasma/PluginLoader>
34#include <qqmlengine.h>
37#define DIALOGSIZE_MAX ((1 << 24) - 1)
43class ConfigViewPrivate
46 ConfigViewPrivate(Plasma::Applet *appl, ConfigView *view);
47 ~ConfigViewPrivate() =
default;
51 void updateMinimumWidth();
52 void updateMinimumHeight();
53 void updateMaximumWidth();
54 void updateMaximumHeight();
56 void mainItemLoaded();
59 QPointer<Plasma::Applet> applet;
60 ConfigModel *configModel;
61 ConfigModel *kcmConfigModel;
62 Plasma::Corona *corona;
63 AppletContext *rootContext;
64 QQmlEngine *engine =
nullptr;
65 QQuickItem *rootItem =
nullptr;
68 QPointer<QObject> mainItemLayout;
71ConfigViewPrivate::ConfigViewPrivate(Plasma::Applet *appl, ConfigView *view)
79void ConfigViewPrivate::init()
82 qCWarning(LOG_PLASMAQUICK) <<
"Null applet passed to constructor";
85 if (!applet.data()->pluginMetaData().isValid()) {
86 qCWarning(LOG_PLASMAQUICK) <<
"Invalid applet passed to constructor";
87 if (applet->containment()) {
88 corona = applet->containment()->corona();
93 rootContext =
new AppletContext(q->engine(), applet,
nullptr);
94 rootContext->setParent(q->engine());
96 applet.data()->setUserConfiguring(
true);
99 localizedContextObject->setTranslationDomain(applet->translationDomain());
100 rootContext->setContextObject(localizedContextObject);
106 if (!applet.data()->containment()->corona()->kPackage().isValid()) {
107 qCWarning(LOG_PLASMAQUICK) <<
"Invalid home screen package";
109 corona = applet.data()->containment()->corona();
112 qCWarning(LOG_PLASMAQUICK) <<
"Cannot find a Corona, this should never happen!";
116 const auto pkg = corona->kPackage();
121 if (!qEnvironmentVariableIntValue(
"PLASMA_NO_CONTEXTPROPERTIES")) {
127 QQmlComponent component(q->engine(), applet.data()->configModel());
128 QObject *
object = component.create(rootContext);
129 configModel = qobject_cast<ConfigModel *>(
object);
132 configModel->setApplet(applet.data());
133 configModel->setParent(q);
146 return !KAuthorized::authorizeControlModule(kcm + QLatin1String(
".desktop"));
152 configModel =
new ConfigModel(q);
155 for (
const QString &kcm : std::as_const(kcms)) {
161 qCWarning(LOG_PLASMAQUICK)
162 <<
"Could not find" << kcm
163 <<
"requested by X-Plasma-ConfigPlugins. Ensure that it exists, is a QML KCM, and lives in the 'kcms/' subdirectory.";
172void ConfigViewPrivate::updateMinimumWidth()
174 if (mainItemLayout) {
175 q->setMinimumWidth(mainItemLayout.data()->property(
"minimumWidth").toInt());
178 q->setWidth(qMax(q->width(), q->minimumWidth()));
180 q->setMinimumWidth(-1);
184void ConfigViewPrivate::updateMinimumHeight()
186 if (mainItemLayout) {
187 q->setMinimumHeight(mainItemLayout.data()->property(
"minimumHeight").toInt());
190 q->setHeight(qMax(q->height(), q->minimumHeight()));
192 q->setMinimumHeight(-1);
196void ConfigViewPrivate::updateMaximumWidth()
198 if (mainItemLayout) {
199 const int hint = mainItemLayout.
data()->property(
"maximumWidth").
toInt();
202 q->setMaximumWidth(hint);
204 q->setMaximumWidth(DIALOGSIZE_MAX);
207 q->setMaximumWidth(DIALOGSIZE_MAX);
211void ConfigViewPrivate::updateMaximumHeight()
213 if (mainItemLayout) {
214 const int hint = mainItemLayout.
data()->property(
"maximumHeight").
toInt();
217 q->setMaximumHeight(hint);
219 q->setMaximumHeight(DIALOGSIZE_MAX);
222 q->setMaximumHeight(DIALOGSIZE_MAX);
226void ConfigViewPrivate::updateTitle()
230 :
i18n(
"%1 Settings", applet.data()->title()));
233void ConfigViewPrivate::mainItemLoaded()
238 q->resize(cg.
readEntry(
"DialogWidth", q->width()), cg.
readEntry(
"DialogHeight", q->height()));
240 if (rootItem->property(
"title").isValid()) {
251 const auto children = rootItem->
children();
252 for (
QObject *child : children) {
254 if (child->property(
"minimumWidth").isValid() && child->property(
"minimumHeight").isValid() && child->property(
"preferredWidth").isValid()
255 && child->property(
"preferredHeight").isValid() && child->property(
"maximumWidth").isValid() && child->property(
"maximumHeight").isValid()
256 && child->property(
"fillWidth").isValid() && child->property(
"fillHeight").isValid()) {
261 mainItemLayout = layout;
264 QObject::connect(layout, SIGNAL(minimumWidthChanged()), q, SLOT(updateMinimumWidth()));
265 QObject::connect(layout, SIGNAL(minimumHeightChanged()), q, SLOT(updateMinimumHeight()));
266 QObject::connect(layout, SIGNAL(maximumWidthChanged()), q, SLOT(updateMaximumWidth()));
267 QObject::connect(layout, SIGNAL(maximumHeightChanged()), q, SLOT(updateMaximumHeight()));
269 updateMinimumWidth();
270 updateMinimumHeight();
271 updateMaximumWidth();
272 updateMaximumHeight();
278 , d(new ConfigViewPrivate(applet, this))
282 [[maybe_unused]]
static int configModelRegisterResult = qmlRegisterType<ConfigModel>(
"org.kde.plasma.configuration", 2, 0,
"ConfigModel");
283 [[maybe_unused]]
static int configCategoryRegisterResult = qmlRegisterType<ConfigCategory>(
"org.kde.plasma.configuration", 2, 0,
"ConfigCategory");
288ConfigView::~ConfigView()
291 d->applet.data()->setUserConfiguring(
false);
292 if (d->applet.data()->containment() && d->applet.data()->containment()->corona()) {
293 d->applet.data()->containment()->corona()->requestConfigSync();
306 return d->rootContext;
309void ConfigView::setSource(
const QUrl &src)
312 if (uiComponent.isError()) {
313 for (
const auto &error : uiComponent.errors()) {
314 qCWarning(LOG_PLASMAQUICK) <<
error;
318 std::unique_ptr<QObject> object(uiComponent.createWithInitialProperties({{QStringLiteral(
"parent"), QVariant::fromValue(contentItem())}}, d->rootContext));
319 d->rootItem = qobject_cast<QQuickItem *>(
object.
get());
323 Q_UNUSED(
object.release());
326 if (d->rootItem->implicitHeight() > 0 || d->rootItem->implicitWidth() > 0) {
327 resize(
QSize(d->rootItem->implicitWidth(), d->rootItem->implicitHeight()));
329 d->rootItem->setSize(
QSizeF(width(), height()));
332 setWidth(d->rootItem->implicitWidth());
335 setWidth(d->rootItem->implicitHeight());
344void ConfigView::init()
346 setSource(d->corona->kPackage().fileUrl(
"appletconfigurationui"));
351 return d->applet.data();
354ConfigModel *ConfigView::configModel()
const
356 return d->configModel;
359QString ConfigView::appletGlobalShortcut()
const
365 return d->applet.
data()->globalShortcut().toString();
368void ConfigView::setAppletGlobalShortcut(
const QString &shortcut)
370 if (!d->applet || d->applet.data()->globalShortcut().toString().toLower() ==
shortcut.toLower()) {
374 d->applet.data()->setGlobalShortcut(shortcut);
375 Q_EMIT appletGlobalShortcutChanged();
391 d->rootItem->setSize(re->
size());
405#include "moc_configview.cpp"
void writeEntry(const char *key, const char *value, WriteConfigFlags pFlags=Normal)
QString readEntry(const char *key, const char *aDefault=nullptr) const
QString i18n(const char *text, const TYPE &arg...)
QAction * hint(const QObject *recvr, const char *slot, QObject *parent)
KIOCORE_EXPORT TransferJob * get(const QUrl &url, LoadType reload=NoReload, JobFlags flags=DefaultFlags)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
const QList< QKeySequence > & shortcut(StandardShortcut id)
The EdgeEventForwarder class This class forwards edge events to be replayed within the given margin T...
QVariant data() const const
QIcon fromTheme(const QString &name)
iterator erase(const_iterator begin, const_iterator end)
bool isEmpty() const const
const QObjectList & children() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void destroyed(QObject *obj)
void implicitHeightChanged()
void implicitWidthChanged()
virtual void hideEvent(QHideEvent *) override
virtual void resizeEvent(QResizeEvent *ev) override
const QSize & size() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
bool canConvert() const const
QVariant fromValue(T &&value)
int toInt(bool *ok) const const
QString toString() const const