File indexing completed on 2024-04-21 14:43:47
0001 /* GCompris - ApplicationInfo.h 0002 * 0003 * SPDX-FileCopyrightText: 2014-2015 Bruno Coudoin <bruno.coudoin@gcompris.net> 0004 * 0005 * Authors: 0006 * Bruno Coudoin <bruno.coudoin@gcompris.net> 0007 * 0008 * This file was originally created from Digia example code under BSD license 0009 * and heavily modified since then. 0010 * 0011 * SPDX-License-Identifier: GPL-3.0-or-later 0012 */ 0013 #ifndef APPLICATIONINFO_H 0014 #define APPLICATIONINFO_H 0015 0016 #include <config.h> 0017 #include "ApplicationSettings.h" 0018 0019 #include <QObject> 0020 #include <QSslSocket> 0021 0022 class QQmlEngine; 0023 class QQuickWindow; 0024 0025 /** 0026 * @class ApplicationInfo 0027 * @short A general purpose singleton that exposes miscellaneous native 0028 * functions to the QML layer. 0029 * @ingroup infrastructure 0030 */ 0031 class ApplicationInfo : public QObject 0032 { 0033 Q_OBJECT 0034 0035 /** 0036 * Width of the application viewport. 0037 */ 0038 Q_PROPERTY(int applicationWidth READ applicationWidth WRITE setApplicationWidth NOTIFY applicationWidthChanged) 0039 0040 /** 0041 * Platform the application is currently running on. 0042 */ 0043 Q_PROPERTY(Platform platform READ platform CONSTANT) 0044 0045 /** 0046 * Whether the application is currently running on a mobile platform. 0047 * 0048 * Mobile platforms are Android, Ios (not supported yet), 0049 * Blackberry (not supported) 0050 */ 0051 Q_PROPERTY(bool isMobile READ isMobile CONSTANT) 0052 0053 /** 0054 * Whether the current platform supports fragment shaders. 0055 * 0056 * This flag is used in some core modules to selectively deactivate 0057 * particle effects which cause crashes on some Android devices. 0058 * 0059 * cf. https://bugreports.qt.io/browse/QTBUG-44194 0060 * 0061 * For now always set to false, to prevent crashes. 0062 */ 0063 Q_PROPERTY(bool hasShader READ hasShader CONSTANT) 0064 0065 /** 0066 * Whether currently in portrait mode, on mobile platforms. 0067 * 0068 * Based on viewport geometry. 0069 */ 0070 Q_PROPERTY(bool isPortraitMode READ isPortraitMode WRITE setIsPortraitMode NOTIFY portraitModeChanged) 0071 0072 /** 0073 * Ratio factor used for scaling of sizes on high-dpi devices. 0074 * 0075 * Must be used by activities as a scaling factor to all pixel values. 0076 */ 0077 Q_PROPERTY(qreal ratio READ ratio NOTIFY ratioChanged) 0078 0079 /** 0080 * Ratio factor used for font scaling. 0081 * 0082 * On some low-dpi Android devices with high res (e.g. Galaxy Tab 4) the 0083 * fonts in Text-like elements appear too small with respect to the other 0084 * graphics -- also if we are using font.pointSize. 0085 * 0086 * For these cases we calculate a fontRatio in ApplicationInfo that takes 0087 * dpi information into account, as proposed on 0088 * https://doc.qt.io/qt-5/scalability.html#calculating-scaling-ratio 0089 * 0090 * GCText applies this factor automatically on its new fontSize property. 0091 */ 0092 Q_PROPERTY(qreal fontRatio READ fontRatio NOTIFY fontRatioChanged) 0093 0094 /** 0095 * Short (2-letter) locale string of the currently active language. 0096 */ 0097 Q_PROPERTY(QString localeShort READ localeShort CONSTANT) 0098 0099 /** 0100 * GCompris version string (compile time). 0101 */ 0102 Q_PROPERTY(QString GCVersion READ GCVersion CONSTANT) 0103 0104 /** 0105 * GCompris version code (compile time). 0106 */ 0107 Q_PROPERTY(int GCVersionCode READ GCVersionCode CONSTANT) 0108 0109 /** 0110 * Qt version string (runtime). 0111 */ 0112 Q_PROPERTY(QString QTVersion READ QTVersion CONSTANT) 0113 0114 /** 0115 * OpenSSL version string (runtime). 0116 */ 0117 Q_PROPERTY(QString OpenSSLVersion READ OpenSSLVersion CONSTANT) 0118 0119 /** 0120 * Audio codec used for voices resources. 0121 * 0122 * This is determined at compile time (ogg for free platforms, aac on 0123 * MacOSX and IOS). 0124 */ 0125 Q_PROPERTY(QString CompressedAudio READ CompressedAudio CONSTANT) 0126 0127 /** 0128 * Download allowed 0129 * 0130 * This is determined at compile time. If set to NO GCompris will 0131 * never download anything. 0132 */ 0133 Q_PROPERTY(bool isDownloadAllowed READ isDownloadAllowed CONSTANT) 0134 0135 /** 0136 * Whether the application is currently using OpenGL or not. 0137 * 0138 * Use to deactivate some effects if OpenGL not used. 0139 */ 0140 Q_PROPERTY(bool useOpenGL READ useOpenGL WRITE setUseOpenGL NOTIFY useOpenGLChanged) 0141 0142 /** 0143 * Whether Box2D is installed or not. 0144 * 0145 * Use to disable activities that use Box2D when it's not installed. 0146 */ 0147 Q_PROPERTY(bool isBox2DInstalled READ isBox2DInstalled NOTIFY isBox2DInstalledChanged) 0148 0149 public: 0150 /** 0151 * Known host platforms. 0152 */ 0153 enum Platform { 0154 Linux, /**< Linux (except Android) */ 0155 Windows, /**< Windows */ 0156 MacOSX, /**< MacOSX */ 0157 Android, /**< Android */ 0158 Ios, /**< IOS (not supported) */ 0159 Blackberry, /**< Blackberry (not supported) */ 0160 UbuntuTouchOS /**< UbuntuTouch OS */ 0161 }; 0162 0163 Q_ENUM(Platform) 0164 0165 /** 0166 * Returns an absolute and platform independent path to the passed @p file 0167 * 0168 * @param file A relative filename. 0169 * @returns Absolute path to the file. 0170 */ 0171 static QString getFilePath(const QString &file); 0172 0173 /** 0174 * Returns the short locale name for the passed @p locale. 0175 * 0176 * Handles also 'system' (GC_DEFAULT_LOCALE) correctly which resolves to 0177 * QLocale::system().name(). 0178 * 0179 * @param locale A locale string of the form \<language\>_\<country\> 0180 * @returns A short locale string of the form \<language\> 0181 */ 0182 static QString localeShort(const QString &locale) 0183 { 0184 QString _locale = locale; 0185 if (_locale == GC_DEFAULT_LOCALE) { 0186 _locale = QLocale::system().name(); 0187 } 0188 if (_locale == "C") { 0189 _locale = "en_US"; 0190 } 0191 // Can't use left(2) because of Asturian where there are 3 chars 0192 return _locale.left(_locale.indexOf('_')); 0193 } 0194 0195 /** 0196 * Returns a locale string that can be used in voices filenames. 0197 * 0198 * @param locale A locale string of the form \<language\>_\<country\> 0199 * @returns A locale string as used in voices filenames. 0200 */ 0201 Q_INVOKABLE QString getVoicesLocale(const QString &locale); 0202 0203 /** 0204 * Request GCompris to take the Audio Focus at the system level. 0205 * 0206 * On systems that support it, it will mute a running audio player. 0207 */ 0208 Q_INVOKABLE bool requestAudioFocus() const; 0209 0210 /** 0211 * Abandon the Audio Focus. 0212 * 0213 * On systems that support it, it will let an audio player start again. 0214 */ 0215 Q_INVOKABLE void abandonAudioFocus() const; 0216 0217 /** 0218 * Compare two strings respecting locale specific sort order. 0219 * 0220 * @param a First string to compare 0221 * @param b Second string to compare 0222 * @param locale Locale to respect for comparison in any of the forms 0223 * used in GCompris xx[_XX][.codeset]. Defaults to currently 0224 * set language from global configuration. 0225 * @returns -1, 0 or 1 if a is less than, equal to or greater than b 0226 */ 0227 Q_INVOKABLE int localeCompare(const QString &a, const QString &b, const QString &locale = "") const; 0228 0229 /** 0230 * Sort a list of strings respecting locale specific sort order. 0231 * 0232 * This function is supposed to be called from QML/JS. As there are still 0233 * problems marshalling QStringList from C++ to QML/JS we use QVariantList 0234 * both for argument and return value. 0235 * 0236 * @param list List of strings to be sorted. 0237 * @param locale Locale to respect for sorting in any of the forms 0238 * used in GCompris xx[_XX][.codeset]. 0239 * @returns List sorted by the sort order of the passed locale. 0240 */ 0241 Q_INVOKABLE QVariantList localeSort(QVariantList list, const QString &locale = "") const; 0242 0243 /// @cond INTERNAL_DOCS 0244 0245 static ApplicationInfo *getInstance() 0246 { 0247 if (!m_instance) { 0248 m_instance = new ApplicationInfo(); 0249 } 0250 return m_instance; 0251 } 0252 static QObject *applicationInfoProvider(QQmlEngine *engine, 0253 QJSEngine *scriptEngine); 0254 static void setWindow(QQuickWindow *window); 0255 explicit ApplicationInfo(QObject *parent = nullptr); 0256 ~ApplicationInfo(); 0257 int applicationWidth() const { return m_applicationWidth; } 0258 void setApplicationWidth(const int newWidth); 0259 Platform platform() const { return m_platform; } 0260 bool isPortraitMode() const { return m_isPortraitMode; } 0261 void setIsPortraitMode(const bool newMode); 0262 bool isMobile() const { return m_isMobile; } 0263 bool hasShader() const 0264 { 0265 #if defined(Q_OS_ANDROID) 0266 return false; 0267 #else 0268 return true; 0269 #endif 0270 } 0271 qreal ratio() const { return m_ratio; } 0272 qreal fontRatio() const { return m_fontRatio; } 0273 QString localeShort() const 0274 { 0275 return localeShort(ApplicationSettings::getInstance()->locale()); 0276 } 0277 static QString GCVersion() { return VERSION; } 0278 static int GCVersionCode() { return VERSION_CODE; } 0279 static QString QTVersion() { return qVersion(); } 0280 static QString OpenSSLVersion() { return QSslSocket::sslLibraryVersionString(); } 0281 static QString CompressedAudio() { return COMPRESSED_AUDIO; } 0282 static bool isDownloadAllowed() { return QString(DOWNLOAD_ALLOWED) == "ON"; } 0283 bool useOpenGL() const { return m_useOpenGL; } 0284 void setUseOpenGL(bool useOpenGL) { m_useOpenGL = useOpenGL; } 0285 0286 bool isBox2DInstalled() const { return m_isBox2DInstalled; } 0287 void setBox2DInstalled(const QQmlEngine &engine); 0288 0289 /** 0290 * Returns the native screen orientation. 0291 * 0292 * Wraps QScreen::nativeOrientation: The native orientation of the screen 0293 * is the orientation where the logo sticker of the device appears the 0294 * right way up, or Qt::PrimaryOrientation if the platform does not support 0295 * this functionality. 0296 * 0297 * The native orientation is a property of the hardware, and does not change 0298 */ 0299 Q_INVOKABLE Qt::ScreenOrientation getNativeOrientation(); 0300 0301 /** 0302 * Change the desired orientation of the application. 0303 * 0304 * Android specific function, cf. https://developer.android.com/reference/android/app/Activity.html#setRequestedOrientation(int) 0305 * 0306 * @param orientation Desired orientation of the application. For possible 0307 * values cf. https://developer.android.com/reference/android/content/pm/ActivityInfo.html#screenOrientation . 0308 * Some useful values: 0309 * - -1: SCREEN_ORIENTATION_UNSPECIFIED 0310 * - 0: SCREEN_ORIENTATION_LANDSCAPE: forces landscape 0311 * - 1: SCREEN_ORIENTATION_PORTRAIT: forces portrait 0312 * - 5: SCREEN_ORIENTATION_NOSENSOR: forces native 0313 * orientation mode on each device (portrait on 0314 * smartphones, landscape on tablet) 0315 * - 14: SCREEN_ORIENTATION_LOCKED: lock current orientation 0316 */ 0317 Q_INVOKABLE void setRequestedOrientation(int orientation); 0318 0319 /** 0320 * Query the desired orientation of the application. 0321 * 0322 * @sa setRequestedOrientation 0323 */ 0324 Q_INVOKABLE int getRequestedOrientation(); 0325 0326 /** 0327 * Checks whether a sensor type from the QtSensor module is supported on 0328 * the current platform. 0329 * 0330 * @param sensorType Classname of a sensor from the QtSensor module 0331 * to be checked (e.g. "QTiltSensor"). 0332 */ 0333 Q_INVOKABLE bool sensorIsSupported(const QString &sensorType); 0334 0335 /** 0336 * Toggles activation of screensaver on android 0337 * 0338 * @param value Whether screensaver should be disabled (true) or 0339 * enabled (false). 0340 */ 0341 Q_INVOKABLE void setKeepScreenOn(bool value); 0342 0343 /** 0344 * Ask for permissions for reading/writing in storage for android. 0345 * Do nothing for other platforms. 0346 * 0347 * https://developer.android.com/training/permissions/requesting 0348 * https://doc.qt.io/qt-5/qtandroid.html#requestPermissions 0349 * Needed for android above 6.0 0350 */ 0351 bool checkPermissions() const; 0352 0353 /// @endcond 0354 0355 public Q_SLOTS: 0356 /** 0357 * Returns the resource root-paths used for GCompris resources. 0358 * First look in a local folder if exists, else will look into the rcc files. 0359 */ 0360 QStringList getResourceDataPaths(); 0361 0362 /** 0363 * Returns an absolute path to a language specific sound/voices file. If 0364 * the file is already absolute only the token replacement is applied. 0365 * 0366 * @param file A templated relative path to a language specific file. Any 0367 * occurrence of the '$LOCALE' placeholder will be replaced by 0368 * the currently active locale string. 0369 * Any occurrence of '$CA' placeholder will be replaced by 0370 * the current compressed audio format ('ogg' or 'aac). 0371 * Example: 'voices-$CA/$LOCALE/misc/click_on_letter.$CA' 0372 * @returns An absolute path to the corresponding resource file. 0373 */ 0374 Q_INVOKABLE QString getAudioFilePath(const QString &file); 0375 0376 /** 0377 * Returns an absolute path to a language specific sound/voices file. If 0378 * the file is already absolute only the token replacement is applied. 0379 * 0380 * @param file A templated relative path to a language specific file. Any 0381 * occurrence of the '$LOCALE' placeholder will be replaced by 0382 * the currently active locale string. 0383 * Any occurrence of '$CA' placeholder will be replaced by 0384 * the current compressed audio format ('ogg' or 'aac). 0385 * Example: 'voices-$CA/$LOCALE/misc/click_on_letter.$CA' 0386 * @param localeName the locale for which to get this audio file 0387 * @returns An absolute path to the corresponding resource file. 0388 */ 0389 Q_INVOKABLE QString getAudioFilePathForLocale(const QString &file, 0390 const QString &localeName); 0391 0392 /** 0393 * Returns an absolute path to a language specific resource file. 0394 * 0395 * Generalization of getAudioFilePath(). 0396 * @sa getAudioFilePath 0397 */ 0398 Q_INVOKABLE QString getLocaleFilePath(const QString &file); 0399 0400 /** 0401 * @returns A list of systems-fonts that should be excluded from font 0402 * selection. 0403 */ 0404 Q_INVOKABLE QStringList getSystemExcludedFonts(); 0405 0406 /** 0407 * @returns A list of fonts contained in the fonts resources. 0408 */ 0409 Q_INVOKABLE QStringList getFontsFromRcc(); 0410 /** 0411 * @returns A list of background music contained in the background music resources. 0412 */ 0413 Q_INVOKABLE QStringList getBackgroundMusicFromRcc(); 0414 /** 0415 * Stores a screenshot in the passed @p file. 0416 * 0417 * @param file Absolute destination filename. 0418 */ 0419 Q_INVOKABLE void screenshot(const QString &file); 0420 0421 void notifyPortraitMode(); 0422 Q_INVOKABLE void notifyFullscreenChanged(); 0423 0424 protected: 0425 qreal getSizeWithRatio(const qreal height) { return ratio() * height; } 0426 0427 Q_SIGNALS: 0428 void applicationWidthChanged(); 0429 void portraitModeChanged(); 0430 void ratioChanged(); 0431 void fontRatioChanged(); 0432 void applicationSettingsChanged(); 0433 void fullscreenChanged(); 0434 void useOpenGLChanged(); 0435 void isBox2DInstalledChanged(); 0436 0437 private: 0438 static ApplicationInfo *m_instance; 0439 int m_applicationWidth; 0440 Platform m_platform; 0441 bool m_isPortraitMode; 0442 bool m_isMobile; 0443 bool m_useOpenGL; 0444 bool m_isBox2DInstalled; 0445 qreal m_ratio; 0446 qreal m_fontRatio; 0447 0448 // Symbols fonts that user can't see 0449 QStringList m_excludedFonts; 0450 QStringList m_fontsFromRcc; 0451 QStringList m_backgroundMusicFromRcc; 0452 0453 static QQuickWindow *m_window; 0454 }; 0455 0456 #endif // APPLICATIONINFO_H