| 1 | // Copyright (C) 2017 The Qt Company Ltd. | 
| 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only | 
| 3 |  | 
| 4 | #include "qquickimaginestyle_p.h" | 
| 5 |  | 
| 6 | #if QT_CONFIG(settings) | 
| 7 | #include <QtCore/qsettings.h> | 
| 8 | #endif | 
| 9 | #include <QtQuickControls2/private/qquickstyle_p.h> | 
| 10 |  | 
| 11 | QT_BEGIN_NAMESPACE | 
| 12 |  | 
| 13 | Q_GLOBAL_STATIC_WITH_ARGS(QString, GlobalPath, (QLatin1String("qrc:/qt-project.org/imports/QtQuick/Controls/Imagine/images/" ))) | 
| 14 |  | 
| 15 | static QString ensureSlash(const QString &path) | 
| 16 | { | 
| 17 |     const QChar slash = QLatin1Char('/'); | 
| 18 |     return path.endsWith(c: slash) ? path : path + slash; | 
| 19 | } | 
| 20 |  | 
| 21 | QQuickImagineStyle::QQuickImagineStyle(QObject *parent) | 
| 22 |     : QQuickAttachedPropertyPropagator(parent), | 
| 23 |       m_path(*GlobalPath()) | 
| 24 | { | 
| 25 |     init(); | 
| 26 | } | 
| 27 |  | 
| 28 | QQuickImagineStyle *QQuickImagineStyle::qmlAttachedProperties(QObject *object) | 
| 29 | { | 
| 30 |     return new QQuickImagineStyle(object); | 
| 31 | } | 
| 32 |  | 
| 33 | QString QQuickImagineStyle::path() const | 
| 34 | { | 
| 35 |     return m_path; | 
| 36 | } | 
| 37 |  | 
| 38 | void QQuickImagineStyle::setPath(const QString &path) | 
| 39 | { | 
| 40 |     m_explicitPath = true; | 
| 41 |     if (m_path == path) | 
| 42 |         return; | 
| 43 |  | 
| 44 |     m_path = path; | 
| 45 |     propagatePath(); | 
| 46 |  | 
| 47 |     emit pathChanged(); | 
| 48 | } | 
| 49 |  | 
| 50 | void QQuickImagineStyle::inheritPath(const QString &path) | 
| 51 | { | 
| 52 |     if (m_explicitPath || m_path == path) | 
| 53 |         return; | 
| 54 |  | 
| 55 |     m_path = path; | 
| 56 |     propagatePath(); | 
| 57 |     emit pathChanged(); | 
| 58 | } | 
| 59 |  | 
| 60 | void QQuickImagineStyle::propagatePath() | 
| 61 | { | 
| 62 |     const auto styles = attachedChildren(); | 
| 63 |     for (QQuickAttachedPropertyPropagator *child : styles) { | 
| 64 |         QQuickImagineStyle *imagine = qobject_cast<QQuickImagineStyle *>(object: child); | 
| 65 |         if (imagine) | 
| 66 |             imagine->inheritPath(path: m_path); | 
| 67 |     } | 
| 68 | } | 
| 69 |  | 
| 70 | void QQuickImagineStyle::resetPath() | 
| 71 | { | 
| 72 |     if (!m_explicitPath) | 
| 73 |         return; | 
| 74 |  | 
| 75 |     m_explicitPath = false; | 
| 76 |     QQuickImagineStyle *imagine = qobject_cast<QQuickImagineStyle *>(object: attachedParent()); | 
| 77 |     inheritPath(path: imagine ? imagine->path() : *GlobalPath()); | 
| 78 | } | 
| 79 |  | 
| 80 | QUrl QQuickImagineStyle::url() const | 
| 81 | { | 
| 82 |     // Using ApplicationWindow as an example, its NinePatchImage url | 
| 83 |     // was previously assigned like this: | 
| 84 |     // | 
| 85 |     // soruce: Imagine.path + "applicationwindow-background" | 
| 86 |     // | 
| 87 |     // If Imagine.path is set to ":/images" by the user, then the final URL would be: | 
| 88 |     // | 
| 89 |     // QUrl("file:///home/user/qt/qtbase/qml/QtQuick/Controls/Imagine/:/images/applicationwindow-background") | 
| 90 |     // | 
| 91 |     // To ensure that the correct URL is constructed, we do it ourselves here, | 
| 92 |     // and then the control QML files use the "url" property instead. | 
| 93 |     const QString path = ensureSlash(path: m_path); | 
| 94 |     if (path.startsWith(s: QLatin1String("qrc" ))) | 
| 95 |         return QUrl(path); | 
| 96 |  | 
| 97 |     if (path.startsWith(s: QLatin1String(":/" ))) | 
| 98 |         return QUrl(QLatin1String("qrc" ) + path); | 
| 99 |  | 
| 100 |     return QUrl::fromLocalFile(localfile: path); | 
| 101 | } | 
| 102 |  | 
| 103 | void QQuickImagineStyle::attachedParentChange(QQuickAttachedPropertyPropagator *newParent, QQuickAttachedPropertyPropagator *oldParent) | 
| 104 | { | 
| 105 |     Q_UNUSED(oldParent); | 
| 106 |     QQuickImagineStyle *imagine = qobject_cast<QQuickImagineStyle *>(object: newParent); | 
| 107 |     if (imagine) | 
| 108 |         inheritPath(path: imagine->path()); | 
| 109 | } | 
| 110 |  | 
| 111 | static QByteArray resolveSetting(const QByteArray &env, const QSharedPointer<QSettings> &settings, const QString &name) | 
| 112 | { | 
| 113 |     QByteArray value = qgetenv(varName: env); | 
| 114 | #if QT_CONFIG(settings) | 
| 115 |     if (value.isNull() && !settings.isNull()) | 
| 116 |         value = settings->value(key: name).toByteArray(); | 
| 117 | #endif | 
| 118 |     return value; | 
| 119 | } | 
| 120 |  | 
| 121 | void QQuickImagineStyle::init() | 
| 122 | { | 
| 123 |     static bool globalsInitialized = false; | 
| 124 |     if (!globalsInitialized) { | 
| 125 |         QSharedPointer<QSettings> settings = QQuickStylePrivate::settings(QStringLiteral("Imagine" )); | 
| 126 |  | 
| 127 |         QString path = QString::fromUtf8(ba: resolveSetting(env: "QT_QUICK_CONTROLS_IMAGINE_PATH" , settings, QStringLiteral("Path" ))); | 
| 128 |         if (!path.isEmpty()) | 
| 129 |             *GlobalPath() = m_path = ensureSlash(path); | 
| 130 |  | 
| 131 |         globalsInitialized = true; | 
| 132 |     } | 
| 133 |  | 
| 134 |     QQuickAttachedPropertyPropagator::initialize(); // TODO: lazy init? | 
| 135 | } | 
| 136 |  | 
| 137 | QT_END_NAMESPACE | 
| 138 |  | 
| 139 | #include "moc_qquickimaginestyle_p.cpp" | 
| 140 |  |