File indexing completed on 2024-05-05 03:56:27

0001 /*
0002  *  SPDX-FileCopyrightText: 2016 Marco Martin <mart@kde.org>
0003  *
0004  *  SPDX-License-Identifier: LGPL-2.0-or-later
0005  */
0006 
0007 #include "settings.h"
0008 
0009 #include <QDebug>
0010 #include <QFile>
0011 #include <QGuiApplication>
0012 #include <QIcon>
0013 #include <QInputDevice>
0014 #include <QMouseEvent>
0015 #include <QSettings>
0016 #include <QStandardPaths>
0017 #include <QWindow>
0018 
0019 #include <QtGui/private/qguiapplication_p.h>
0020 #include <QtGui/qpa/qplatformmenu.h>
0021 #include <QtGui/qpa/qplatformtheme.h>
0022 
0023 #include "kirigamiplatform_version.h"
0024 #include "tabletmodewatcher.h"
0025 
0026 namespace Kirigami
0027 {
0028 namespace Platform
0029 {
0030 
0031 class SettingsSingleton
0032 {
0033 public:
0034     Settings self;
0035 };
0036 
0037 Settings::Settings(QObject *parent)
0038     : QObject(parent)
0039     , m_hasTouchScreen(false)
0040     , m_hasTransientTouchInput(false)
0041 {
0042     m_tabletModeAvailable = TabletModeWatcher::self()->isTabletModeAvailable();
0043     connect(TabletModeWatcher::self(), &TabletModeWatcher::tabletModeAvailableChanged, this, [this](bool tabletModeAvailable) {
0044         setTabletModeAvailable(tabletModeAvailable);
0045     });
0046 
0047     m_tabletMode = TabletModeWatcher::self()->isTabletMode();
0048     connect(TabletModeWatcher::self(), &TabletModeWatcher::tabletModeChanged, this, [this](bool tabletMode) {
0049         setTabletMode(tabletMode);
0050     });
0051 
0052 #if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(UBUNTU_TOUCH)
0053     m_mobile = true;
0054     m_hasTouchScreen = true;
0055 #else
0056     // Mostly for debug purposes and for platforms which are always mobile,
0057     // such as Plasma Mobile
0058     if (qEnvironmentVariableIsSet("QT_QUICK_CONTROLS_MOBILE")) {
0059         m_mobile = QByteArrayList{"1", "true"}.contains(qgetenv("QT_QUICK_CONTROLS_MOBILE"));
0060     } else {
0061         m_mobile = false;
0062     }
0063 
0064     const auto touchDevices = QInputDevice::devices();
0065     const auto touchDeviceType = QInputDevice::DeviceType::TouchScreen;
0066     for (const auto &device : touchDevices) {
0067         if (device->type() == touchDeviceType) {
0068             m_hasTouchScreen = true;
0069             break;
0070         }
0071     }
0072     if (m_hasTouchScreen) {
0073         connect(qApp, &QGuiApplication::focusWindowChanged, this, [this](QWindow *win) {
0074             if (win) {
0075                 win->installEventFilter(this);
0076             }
0077         });
0078     }
0079 #endif
0080 
0081     auto bar = QGuiApplicationPrivate::platformTheme()->createPlatformMenuBar();
0082     m_hasPlatformMenuBar = bar != nullptr;
0083     if (bar != nullptr) {
0084         bar->deleteLater();
0085     }
0086 
0087     const QString configPath = QStandardPaths::locate(QStandardPaths::ConfigLocation, QStringLiteral("kdeglobals"));
0088     if (QFile::exists(configPath)) {
0089         QSettings globals(configPath, QSettings::IniFormat);
0090         globals.beginGroup(QStringLiteral("KDE"));
0091         m_scrollLines = qMax(1, globals.value(QStringLiteral("WheelScrollLines"), 3).toInt());
0092     } else {
0093         m_scrollLines = 3;
0094     }
0095 }
0096 
0097 Settings::~Settings()
0098 {
0099 }
0100 
0101 bool Settings::eventFilter(QObject *watched, QEvent *event)
0102 {
0103     Q_UNUSED(watched)
0104     switch (event->type()) {
0105     case QEvent::TouchBegin:
0106         setTransientTouchInput(true);
0107         break;
0108     case QEvent::MouseButtonPress:
0109     case QEvent::MouseMove: {
0110         QMouseEvent *me = static_cast<QMouseEvent *>(event);
0111         if (me->source() == Qt::MouseEventNotSynthesized) {
0112             setTransientTouchInput(false);
0113         }
0114         break;
0115     }
0116     case QEvent::Wheel:
0117         setTransientTouchInput(false);
0118     default:
0119         break;
0120     }
0121 
0122     return false;
0123 }
0124 
0125 void Settings::setTabletModeAvailable(bool mobileAvailable)
0126 {
0127     if (mobileAvailable == m_tabletModeAvailable) {
0128         return;
0129     }
0130 
0131     m_tabletModeAvailable = mobileAvailable;
0132     Q_EMIT tabletModeAvailableChanged();
0133 }
0134 
0135 bool Settings::isTabletModeAvailable() const
0136 {
0137     return m_tabletModeAvailable;
0138 }
0139 
0140 void Settings::setIsMobile(bool mobile)
0141 {
0142     if (mobile == m_mobile) {
0143         return;
0144     }
0145 
0146     m_mobile = mobile;
0147     Q_EMIT isMobileChanged();
0148 }
0149 
0150 bool Settings::isMobile() const
0151 {
0152     return m_mobile;
0153 }
0154 
0155 void Settings::setTabletMode(bool tablet)
0156 {
0157     if (tablet == m_tabletMode) {
0158         return;
0159     }
0160 
0161     m_tabletMode = tablet;
0162     Q_EMIT tabletModeChanged();
0163 }
0164 
0165 bool Settings::tabletMode() const
0166 {
0167     return m_tabletMode;
0168 }
0169 
0170 void Settings::setTransientTouchInput(bool touch)
0171 {
0172     if (touch == m_hasTransientTouchInput) {
0173         return;
0174     }
0175 
0176     m_hasTransientTouchInput = touch;
0177     if (!m_tabletMode) {
0178         Q_EMIT hasTransientTouchInputChanged();
0179     }
0180 }
0181 
0182 bool Settings::hasTransientTouchInput() const
0183 {
0184     return m_hasTransientTouchInput || m_tabletMode;
0185 }
0186 
0187 QString Settings::style() const
0188 {
0189     return m_style;
0190 }
0191 
0192 void Settings::setStyle(const QString &style)
0193 {
0194     m_style = style;
0195 }
0196 
0197 int Settings::mouseWheelScrollLines() const
0198 {
0199     return m_scrollLines;
0200 }
0201 
0202 QStringList Settings::information() const
0203 {
0204     return {
0205 #ifndef KIRIGAMI_BUILD_TYPE_STATIC
0206         tr("KDE Frameworks %1").arg(QStringLiteral(KIRIGAMIPLATFORM_VERSION_STRING)),
0207 #endif
0208         tr("The %1 windowing system").arg(QGuiApplication::platformName()),
0209         tr("Qt %2 (built against %3)").arg(QString::fromLocal8Bit(qVersion()), QStringLiteral(QT_VERSION_STR))};
0210 }
0211 
0212 QVariant Settings::applicationWindowIcon() const
0213 {
0214     const QIcon &windowIcon = qApp->windowIcon();
0215     if (windowIcon.isNull()) {
0216         return QVariant();
0217     }
0218     return windowIcon;
0219 }
0220 
0221 bool Settings::hasPlatformMenuBar() const
0222 {
0223     return m_hasPlatformMenuBar;
0224 }
0225 
0226 }
0227 }
0228 
0229 #include "moc_settings.cpp"