File indexing completed on 2024-05-05 04:46:58

0001 /*
0002  *   Copyright 2018 Camilo Higuita <milo.h@aol.com>
0003  *
0004  *   This program is free software; you can redistribute it and/or modify
0005  *   it under the terms of the GNU Library General Public License as
0006  *   published by the Free Software Foundation; either version 2, or
0007  *   (at your option) any later version.
0008  *
0009  *   This program is distributed in the hope that it will be useful,
0010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012  *   GNU General Public License for more details
0013  *
0014  *   You should have received a copy of the GNU Library General Public
0015  *   License along with this program; if not, write to the
0016  *   Free Software Foundation, Inc.,
0017  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
0018  */
0019 
0020 #pragma once
0021 #include <QObject>
0022 #include <QQmlEngine>
0023 
0024 #include <QVariantMap>
0025 
0026 namespace MauiMan
0027 {
0028     class FormFactorManager;
0029     class AccessibilityManager;
0030 }
0031 
0032 /**
0033  * @brief The Handy class.
0034  * 
0035  * Contains useful static methods to be used in the MauiKit application.
0036  * 
0037  * @note This class is exposed as the singleton type `Handy` to the QML engine.
0038  * 
0039  */
0040 class Handy : public QObject
0041 {
0042     Q_OBJECT
0043     QML_ELEMENT
0044     QML_SINGLETON
0045     Q_DISABLE_COPY(Handy)
0046     
0047     /**
0048      * Whether the host platform is set as mobile. Either by the `QT_QUICK_CONTROLS_MOBILE` environment variable on, or from the MauiMan form factor mode to mobile.
0049      */
0050     Q_PROPERTY(bool isMobile READ isMobile NOTIFY isMobileChanged)
0051     
0052     /**
0053      * Whether the target device has a touch screen
0054      */
0055     Q_PROPERTY(bool isTouch READ isTouch NOTIFY isTouchChanged)
0056     
0057     /**
0058      * Whether the target device has a physical mouse attached
0059      */
0060     Q_PROPERTY(bool hasMouse READ hasMouse NOTIFY hasMouseChanged)
0061     
0062     /**
0063      * Whether the target device has a physical keyboard attached
0064      */
0065     Q_PROPERTY(bool hasKeyboard READ hasKeyboard NOTIFY hasKeyboardChanged)
0066     
0067     /**
0068      * Whether the current press input has been received from a touch screen
0069      */
0070     Q_PROPERTY(bool hasTransientTouchInput READ hasTransientTouchInput NOTIFY hasTransientTouchInputChanged)
0071         
0072     /**
0073      * Whether the host platform is an Android device
0074      */
0075     Q_PROPERTY(bool isAndroid READ isAndroid CONSTANT FINAL)
0076     
0077     /**
0078      * Whether the host platform is a GNU/Linux distribution
0079      */
0080     Q_PROPERTY(bool isLinux READ isLinux CONSTANT FINAL)
0081     
0082     /**
0083      * Whether the host platform is running Windows OS
0084      */
0085     Q_PROPERTY(bool isWindows READ isWindows CONSTANT FINAL)
0086     
0087     /**
0088      * Whether the host platform is running MacOS
0089      */
0090     Q_PROPERTY(bool isMac READ isMac CONSTANT FINAL)
0091     
0092     /**
0093      * Whether the host platform is running IOS
0094      */
0095     Q_PROPERTY(bool isIOS READ isIOS CONSTANT FINAL)
0096 
0097     /**
0098      * Whether the system preference is to open/trigger items with a single click
0099      * @note This preference is taken from MauiMan global preference. 
0100      */
0101     Q_PROPERTY(bool singleClick MEMBER m_singleClick NOTIFY singleClickChanged)
0102     
0103     /**
0104      * The current preferred from factor the user has selected.
0105      * @note This preference can be set using MauiMan, and it is exposed to the end user via the Maui Settings.
0106      * 
0107      * This property allows the user to manually pick between a mobile, tablet or desktop mode.  This can be consumed by the applications to position elements in a fitting manner.
0108      */
0109     Q_PROPERTY(FFactor formFactor READ formFactor NOTIFY formFactorChanged)
0110 
0111 public:
0112         Handy(QObject *parent = nullptr);    
0113 
0114     /**
0115      * @brief The different form factor options.
0116      */
0117     enum FFactor
0118     {
0119         /**
0120          * Desktop form factor assumes there is a physical mouse and keyboard, and the screen area is wide and spacious.
0121          */
0122         Desktop = 0,
0123         
0124         /**
0125          * Tablet form factor assumes a hand held device with touch screen, maybe there is a physical keyboard attached. The screen area is spacious enough still, not as wide as a desktop or as narrow as a mobile phone.
0126          */
0127         Tablet,
0128         
0129         /**
0130          * Mobile form factor mode assumes a phone is the target device. A small touch screen and not mouse or keyboard attached.
0131          */
0132         Phone
0133     }; Q_ENUM(FFactor)
0134     
0135     /**
0136      * @private
0137      */
0138     static Handy *qmlAttachedProperties(QObject *object);
0139     
0140     /**
0141      * @private
0142      */
0143     static Handy *instance()
0144     {
0145         if (m_instance)
0146             return m_instance;
0147         
0148         m_instance = new Handy;
0149         return m_instance;
0150     }
0151     
0152     void setTransientTouchInput(bool touch);
0153     bool hasTransientTouchInput() const;    
0154     
0155 protected:
0156     
0157     /**
0158      * @private
0159      */
0160     bool eventFilter(QObject *watched, QEvent *event) override;
0161     
0162 private:
0163     
0164     static Handy *m_instance;
0165     
0166     MauiMan::FormFactorManager *m_formFactor;
0167     MauiMan::AccessibilityManager *m_accessibility;
0168     
0169     FFactor m_ffactor = FFactor::Desktop;
0170     bool m_isTouch = false;
0171     bool m_singleClick = true;
0172     bool m_mobile = 1;
0173     bool m_hasTransientTouchInput = 1;
0174 
0175 public Q_SLOTS:
0176     
0177     /**
0178      * @brief Returns the major version of the current OS
0179      *
0180      * This function is static.
0181      * @return Major OS version number
0182      */
0183     static int version();
0184 
0185     /**
0186      * @brief Returns a key-value map containing basic information about the current user
0187      *
0188      * The pairs keys for the information returned are:
0189      * - name
0190      * 
0191      * @return with user info map
0192      */
0193     static QVariantMap userInfo();
0194 
0195     /**
0196      * @brief Returns the text contained in the clipboard
0197      * @return text string
0198      */
0199     static QString getClipboardText();
0200     
0201     /**
0202      * @brief Retrieves the data in the clipboard into a key-value map.
0203      * The possible keys available are [only if there is any metadata]:
0204      * - text
0205      * - urls
0206      * - image
0207      * - cut
0208      * 
0209      * @note This can invoked from QML and the data extracted as `Handy.getClipboard().text` for example.
0210      */
0211     static QVariantMap getClipboard();
0212 
0213     /**
0214      * @brief Copies a text string to the clipboard
0215      * @param text text to be copied to the clipboard
0216      * @return whether the operation was successful
0217      */
0218     static bool copyTextToClipboard(const QString &text);
0219 
0220     /**
0221      * @brief Adds a key-value map to the clipboard.
0222      * Possible keys can be:
0223      * - text
0224      * - urls
0225      * - image
0226      * 
0227      * There can be more than one.
0228      * @param value the data
0229      * @param cut whether to add the metadata information necessary for it to be read as a cut operation by third party.
0230      * @return whether the operation was successful
0231      */
0232     static bool copyToClipboard(const QVariantMap &value, const bool &cut = false);
0233 
0234     bool hasKeyboard();
0235     
0236     bool hasMouse();
0237 
0238     static bool isAndroid();
0239 
0240     static bool isWindows();
0241 
0242     static bool isMac();
0243 
0244     static bool isLinux();
0245 
0246     static bool isIOS();
0247 
0248     bool isMobile() const;   
0249     
0250     bool isTouch();
0251     
0252     FFactor formFactor();
0253     
0254     /**
0255      * @brief Format a size value to the a readable locale size format.
0256      * @param size the size value in bits
0257      * @return Formatted into a readable string using the preferred locale settings.
0258      */
0259     static QString formatSize(quint64 size);
0260     
0261     /**
0262      * @brief Format a milliseconds value to a readable format
0263      * @param value milliseconds
0264      * @return readable formatted value
0265      */
0266     static QString formatTime(const qint64 &value);
0267     
0268     /**
0269      * @brief Given a date string, its original format and an intended format, return a readable string
0270      * @param dateStr date string
0271      * @param format Intended format, by default `"dd/MM/yyyy"`
0272      * @param initFormat the original date format. This is optional and by default it will try to be auto determined.
0273      * @return
0274      */
0275     static QString formatDate(const QString &dateStr, const QString &format = QString("dd/MM/yyyy"), const QString &initFormat = QString());   
0276     
0277 Q_SIGNALS:
0278     
0279     void singleClickChanged();
0280     void hasKeyboardChanged();
0281     void hasMouseChanged();
0282     void isMobileChanged();
0283     void hasTransientTouchInputChanged();
0284     void formFactorChanged();
0285     void isTouchChanged();
0286 };
0287