Rabbit Remote Control 0.1.0-bate10
Loading...
Searching...
No Matches
main.cpp
1// Author: Kang Lin <kl222@126.com>
2
16#include <QtGlobal>
17#include <QLoggingCategory>
18#include <QApplication>
19#include <QSettings>
20#include <QDebug>
21#include <QtGlobal>
22#include <QSharedPointer>
23#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
24 #include <QRegularExpression>
25 #include <QRandomGenerator>
26#endif
27#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
28 #include <QRandomGenerator>
29#endif
30#if defined(Q_OS_ANDROID) && (QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
31#include <QtAndroid>
32#endif
33
34#include "RabbitCommonTools.h"
35
36#ifdef HAVE_UPDATE
37#include "FrmUpdater.h"
38#endif
39#ifdef BUILD_QUIWidget
40 #include "QUIWidget/QUIWidget.h"
41#endif
42
43#include "StatsAppUsage.h"
44#include "mainwindow.h"
45
46static Q_LOGGING_CATEGORY(log, "App.Main")
47
48// Android平台的专用初始化函数(必须在QGuiApplication之前)
49void InitAndroidVirtualKeyboard()
50{
51 // 设置输入法模块(必须在QGuiApplication之前)
52 qputenv("QT_IM_MODULE", "qtvirtualkeyboard");
53
54 // Android特定环境变量
55 //qputenv("QT_VIRTUALKEYBOARD_ANDROID_HEIGHT", "400"); // 设置键盘高度
56 // 设置键盘样式
57 //qputenv("QT_VIRTUALKEYBOARD_STYLE", QByteArray("default")); // 可选: default, retro, etc.
58
59 // 设置布局(可选中文)
60 //qputenv("QT_VIRTUALKEYBOARD_LAYOUT", "en_US");
61 // qputenv("QT_VIRTUALKEYBOARD_LAYOUT", "zh_CN");
62
63 // 禁用硬件键盘检测(强制显示虚拟键盘)
64 //qputenv("QT_VIRTUALKEYBOARD_FORCE_ANDROID", "1");
65
66 // 设置手写识别(如果需要)
67 //qputenv("QT_VIRTUALKEYBOARD_HANDWRITING", QByteArray("1"));
68
69 // 启用调试
70 //qputenv("QT_DEBUG_IM", "1");
71}
72
73int main(int argc, char *argv[])
74{
75 int nRet = 0;
76
77//#if defined (_DEBUG) || !defined(BUILD_SHARED_LIBS)
78// Q_INIT_RESOURCE(translations_RabbitRemoteControlApp);
79//#endif
80
81//#if HAVE_VirtualKeyboard && defined(Q_OS_ANDROID)
82// InitAndroidVirtualKeyboard();
83//#endif
84
85 // 检查环境变量是否设置成功
86 QByteArray imModule = qgetenv("QT_IM_MODULE");
87 qDebug(log) << "QT_IM_MODULE set to:" << imModule;
88
89 QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
90
91 /* 移到 snapcraft.yaml 和 io.github.KangLin.RabbitRemoteControl.yml
92 // 修复 qtwebengine 沙箱权限问题
93 if(!qEnvironmentVariable("SNAP").isEmpty()) {
94 qputenv("QTWEBENGINE_DISABLE_SANDBOX", "1");
95 }//*/
96
97 //qputenv("QT_MEDIA_BACKEND", "ffmpeg");
98
99#if (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) \
100 && (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)))
101 /* 修复使用 Qt6 时,最大化时,工具栏位置错误。
102 现在很多 linux 用 wayland 或 wayland-egl 作为桌面显示,这样会出现一个问题,
103 由于没有坐标系统,导致无边框窗体无法拖动和定位(即 QWidge::move 失效)。
104 (Qt6 开始强制默认优先用 wayland ,Qt5 默认有 xcb 则优先用 xcb),
105 所以需要在 main 函数最前面加一行 `qputenv("QT_QPA_PLATFORM", "xcb")`;
106 */
107 QString szPlatform = qEnvironmentVariable("QT_QPA_PLATFORM");
108 if(szPlatform.isEmpty()
109 || -1 != szPlatform.indexOf(QRegularExpression("wayland.*")))
110 qputenv("QT_QPA_PLATFORM", "xcb");
111 qInfo(log) << "QT_QPA_PLATFORM:" << szPlatform << "\nCurrent Qt Platform is:"
112 << qEnvironmentVariable("QT_QPA_PLATFORM")
113 << "; This can be modified with the environment variables QT_QPA_PLATFORM:\n"
114 << "export QT_QPA_PLATFORM=xcb\n Optional: xcb; vnc";
115#endif
116#if (QT_VERSION > QT_VERSION_CHECK(5,6,0)) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
117 QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
118#endif
119#if defined(Q_OS_ANDROID) && (QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
120 QtAndroid::hideSplashScreen();
121#endif
122
123 QApplication::setApplicationVersion(RabbitRemoteControl_VERSION);
124 QApplication::setApplicationName("RabbitRemoteControl");
125#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
126 QApplication::setDesktopFileName(QLatin1String("io.github.KangLin.RabbitRemoteControl.desktop"));
127#endif
128
129 QApplication app(argc, argv);
130
131 QInputMethod *inputMethod = app.inputMethod();
132 qDebug(log) << "Input method available:" << (inputMethod != nullptr);
133 if(inputMethod)
134 qDebug(log) << "Input method locale:" << inputMethod->locale();
135
136 RabbitCommon::CTools::Instance()->Init();
137
138 qInfo(log) << app.applicationName() + " " + app.applicationVersion()
139 + " " + QObject::tr("Start") + " ......"
140 << "\n" << app.arguments();
141
142 {
143 QStringList permissions;
144 permissions << "android.permission.WRITE_EXTERNAL_STORAGE"
145 << "android.permission.READ_EXTERNAL_STORAGE"
146 << "android.permission.INTERNET"
147 << "android.permission.WAKE_LOCK";
148 RabbitCommon::CTools::AndroidRequestPermission(permissions);
149
150 QSharedPointer<QTranslator> tApp =
151 RabbitCommon::CTools::Instance()->InstallTranslator("RabbitRemoteControlApp");
152
153 app.setApplicationDisplayName(QObject::tr("Rabbit Remote Control"));
154 app.setOrganizationName(QObject::tr("Kang Lin Studio"));
155
156#ifdef HAVE_UPDATE
157 // Check update version
158 QScopedPointer<CFrmUpdater> pUpdater(new CFrmUpdater());
159#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
160 if(qEnvironmentVariable("SNAP").isEmpty()
161 && qEnvironmentVariable("FLATPAK_ID").isEmpty())
162#else
163 if(qgetenv("SNAP").isEmpty()
164 && qgetenv("FLATPAK_ID").isEmpty())
165#endif
166 {
167 if(pUpdater) {
168 pUpdater->setAttribute(Qt::WA_DeleteOnClose, false);
169 QIcon icon = QIcon::fromTheme("app");
170 if(!icon.isNull()) {
171 auto sizeList = icon.availableSizes();
172 if(!sizeList.isEmpty()) {
173 QPixmap p = icon.pixmap(*sizeList.begin());
174 pUpdater->SetTitle(p.toImage());
175 }
176 }
177 if(app.arguments().length() > 1) {
178 try {
179 pUpdater->GenerateUpdateJson();
180 pUpdater->GenerateUpdateXml();
181 } catch(...) {
182 qCritical(log) << "Generate update fail";
183 }
184 qInfo(log) << app.applicationName() + " " + app.applicationVersion()
185 + " " + QObject::tr("Generate update json file End");
186 return 0;
187 }
188 } else {
189 qCritical(log) << "new CFrmUpdater() fail";
190 }
191 }
192#endif // #ifdef HAVE_UPDATE
193
194 CStatsAppUsage* pStats = nullptr;
195 /*
196 QTimer::singleShot(RabbitCommon::CTools::GetRandomNumber(10, 50), [&]() {
197 pStats = new CStatsAppUsage("v" + QApplication::applicationVersion());
198 app.processEvents();
199 });//*/
200
201 MainWindow* w = new MainWindow();
202
203 try {
204 //w->setWindowIcon(QIcon::themeName("app"));
205 //w->setWindowTitle(app.applicationDisplayName());
206 app.processEvents();
207 RC_SHOW_WINDOW(w);
208 app.processEvents();
209 // For time-consuming operations
210 nRet = w->Initial();
211 if(!nRet)
212 nRet = app.exec();
213 } catch (std::exception &e) {
214 qCritical(log) << "exception:" << e.what();
215 } catch(...) {
216 qCritical(log) << "exception:";
217 }
218
219 delete w;
220 if(pStats) {
221 pStats->Stop();
222 delete pStats;
223 }
224
225 if(tApp)
226 RabbitCommon::CTools::Instance()->RemoveTranslator(tApp);
227 }
228
229 qInfo(log) << app.applicationName() + " " + app.applicationVersion() + " " + "End";
230
231 RabbitCommon::CTools::Instance()->Clean();
232
233//#if defined (_DEBUG) || !defined(BUILD_SHARED_LIBS)
234// Q_CLEANUP_RESOURCE(translations_RabbitRemoteControlApp);
235//#endif
236
237 return nRet;
238}
应用使用统计信息
The MainWindow class.
Definition mainwindow.h:36
int Initial()
For time-consuming operations.