4#include "RabbitCommonTools.h"
5#include "RabbitCommonDir.h"
6#ifdef HAVE_ADMINAUTHORISER
7#include "AdminAuthoriser/adminauthoriser.h"
9#include "RabbitCommonRegister.h"
14#ifdef HAVE_RABBITCOMMON_GUI
16 #include <QMainWindow>
18 #include <QApplication>
20 #include <QCoreApplication>
25#include <QStandardPaths>
28#if defined(Q_OS_ANDROID)
29#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
30 #include <QtCore/private/qandroidextras_p.h>
34#if defined(HAVE_OPENSSL)
35 #include "openssl/opensslv.h"
50 #include "CoreDump/MiniDumper.h"
53#ifdef HAVE_RABBITCOMMON_GUI
54 #include "Log/DockDebugLog.h"
55 #include "Log/DlgFilter.h"
59inline void g_RabbitCommon_InitResource()
61 Q_INIT_RESOURCE(ResourceRabbitCommon);
70 Q_INIT_RESOURCE(QUIWidgetQss);
75inline void g_RabbitCommon_CleanResource()
77 Q_CLEANUP_RESOURCE(ResourceRabbitCommon);
84 Q_CLEANUP_RESOURCE(QUIWidgetQss);
91static Q_LOGGING_CATEGORY(log,
"RabbitCommon.Tools")
92static Q_LOGGING_CATEGORY(logTranslation, "
RabbitCommon.Tools.Translation")
101#if HAVE_RABBITCOMMON_GUI
103 delete g_pDcokDebugLog;
107CTools* CTools::Instance()
109 static CTools* pTools =
nullptr;
110 if(
nullptr == pTools)
111 pTools =
new CTools();
115int CTools::SetLanguage(
const QString szLanguage)
117 m_szLanguage = szLanguage;
121QString CTools::GetLanguage()
123 if(m_szLanguage.isEmpty())
124 return QLocale::system().name();
131 QString szVersion(RabbitCommon_VERSION);
132 QString szRevision(RabbitCommon_REVISION);
133 if(szRevision.isEmpty()) {
134 szReturn = QObject::tr(
"Version: ") + szVersion;
136 szReturn = QObject::tr(
"Version: ") + szVersion + QObject::tr(
" (From revision: ");
137#if (defined(HAVE_CMARK) || defined(HAVE_CMARK_GFM)) && defined(HAVE_WebEngineWidgets)
138 szReturn +=
"[" + szRevision +
"](http://github.com/KangLin/RabbitCommon/tree/" + szRevision +
")";
140 szReturn += szRevision;
150 szInfo = QObject::tr(
"- Functions:") +
"\n";
151#if defined(HAVE_RABBITCOMMON_GUI)
152 szInfo += QObject::tr(
" - Have GUI") +
"\n";
154#if defined(HAVE_ABOUT)
155 szInfo += QObject::tr(
" - Have about diaglog") +
"\n";
165#if defined(HAVE_UPDATE)
166 szInfo += QObject::tr(
" - Have update") +
"\n";
168#if defined(HAVE_OPENSSL)
169 szInfo += QObject::tr(
" - Have encrypt(OPENSSL)") +
"\n";
171#if defined(BUILD_QUIWidget)
172 szInfo += QObject::tr(
" - Have QUIWidget") +
"\n";
174 szInfo += QObject::tr(
" - Applicatoin paths and files: ") +
"\n";
175 szInfo += QObject::tr(
" - Install root path: ") + RabbitCommon::CDir::Instance()->GetDirApplicationInstallRoot() +
"\n";
176 szInfo += QObject::tr(
" - Application path: ") + RabbitCommon::CDir::Instance()->GetDirApplication() +
"\n";
177 szInfo += QObject::tr(
" - Configure path: ") + RabbitCommon::CDir::Instance()->GetDirConfig() +
"\n";
178 szInfo += QObject::tr(
" - Configure file: ") + RabbitCommon::CDir::Instance()->GetFileApplicationConfigure() +
"\n";
179 szInfo += QObject::tr(
" - Translations path: ") + RabbitCommon::CDir::Instance()->
GetDirTranslations() +
"\n";
180 szInfo += QObject::tr(
" - Log path: ") + RabbitCommon::CDir::Instance()->GetDirLog() +
"\n";
181 szInfo += QObject::tr(
" - Data path: ") + RabbitCommon::CDir::Instance()->
GetDirData() +
"\n";
182 szInfo += QObject::tr(
" - Icons path: ") + RabbitCommon::CDir::Instance()->GetDirIcons() +
"\n";
183 szInfo += QObject::tr(
" - Database path: ") + RabbitCommon::CDir::Instance()->GetDirDatabase() +
"\n";
184 szInfo += QObject::tr(
" - Database file: ") + RabbitCommon::CDir::Instance()->GetDirDatabaseFile() +
"\n";
185 szInfo += QObject::tr(
" - Plugins path: ") + RabbitCommon::CDir::Instance()->GetDirPlugins() +
"\n";
186 szInfo += QObject::tr(
" - User folders and files: ") +
"\n";
187 szInfo += QObject::tr(
" - Documents path: ") + RabbitCommon::CDir::Instance()->GetDirUserDocument() +
"\n";
188 szInfo += QObject::tr(
" - Configure path: ") + RabbitCommon::CDir::Instance()->GetDirUserConfig() +
"\n";
189 szInfo += QObject::tr(
" - Configure file: ") + RabbitCommon::CDir::Instance()->GetFileUserConfigure() +
"\n";
190 szInfo += QObject::tr(
" - Data path: ") + RabbitCommon::CDir::Instance()->GetDirUserData() +
"\n";
191 szInfo += QObject::tr(
" - Image path: ") + RabbitCommon::CDir::Instance()->GetDirUserImage() +
"\n";
192 szInfo += QObject::tr(
" - Database path: ") + RabbitCommon::CDir::Instance()->GetDirUserDatabase() +
"\n";
193 szInfo += QObject::tr(
" - Database file: ") + RabbitCommon::CDir::Instance()->GetDirUserDatabaseFile() +
"\n";
195 szInfo += QObject::tr(
"- Dependent libraries:") +
"\n";
196 szInfo += QObject::tr(
" - OpenSSL:") +
"\n";
197#if defined(HAVE_OPENSSL)
198 szInfo +=
" - " + QObject::tr(
"RabbitCommon Build Version: ") + OPENSSL_VERSION_TEXT +
"\n";
200 if(QSslSocket::supportsSsl())
202#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 3))
203 szInfo +=
" - Qt " + QObject::tr(
"Build Version: ") + QSslSocket::sslLibraryBuildVersionString() +
"\n";
205 szInfo +=
" - " + QObject::tr(
"Installed Version: ") + QSslSocket::sslLibraryVersionString() +
"\n";
207#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 3))
208 szInfo +=
" - Qt " + QObject::tr(
"Build Version: ") + QSslSocket::sslLibraryBuildVersionString() +
"\n";
210 szInfo +=
" - " + QObject::tr(
"Don't install OPENSSL dynamic library. Please install it") +
"\n";
213 szInfo += QObject::tr(
" - cmark-gfm") +
"\n";
215 szInfo += QObject::tr(
" - cmark") +
"\n";
217#ifdef HAVE_WebEngineWidgets
218 szInfo += QObject::tr(
" - WebEngineWidgets") +
"\n";
223int CTools::AndroidRequestPermission(
const QString &permission)
225#if defined (Q_OS_ANDROID)
226 #if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
230 if (QtAndroidPrivate::checkPermission(permission).result()
231 == QtAndroidPrivate::Denied)
233 QtAndroidPrivate::requestPermission(permission).waitForFinished();
235 qInfo(log) <<
"android permission" << permission <<
";status:"
236 << QtAndroidPrivate::checkPermission(permission).result();
243int CTools::AndroidRequestPermission(
const QStringList &permissions)
245 foreach (
auto p, permissions) {
246 AndroidRequestPermission(p);
256 QStringList permissions;
257 permissions <<
"android.permission.WRITE_EXTERNAL_STORAGE"
258 <<
"android.permission.INTERNET"
259 <<
"android.permission.ACCESS_NETWORK_STATE"
260 <<
"android.permission.CHANGE_WIFI_STATE"
261 <<
"android.permission.ACCESS_WIFI_STATE"
262 <<
"android.permission.ACCESS_NETWORK_STATE"
263 <<
"android.permission.CHANGE_NETWORK_STATE";
264 AndroidRequestPermission(permissions);
265 RabbitCommon::CLog::Instance();
266 SetLanguage(szLanguage);
267 qInfo(logTranslation) <<
"Language:" << szLanguage;
271 QString szQtTranslationPath;
272#if defined(Q_OS_LINUX)
273 szQtTranslationPath =
"/usr/share/qt"
274 + QString::number(QT_VERSION_MAJOR)
275 + QDir::separator() +
"translations";
276 QDir d(szQtTranslationPath);
279 szQtTranslationPath = CDir::Instance()->GetDirApplication()
280 + QDir::separator() +
"translations";
283 szQtTranslationPath = CDir::Instance()->GetDirApplication()
284 + QDir::separator() +
"translations";
286 QStringList qtTranslations;
287 qtTranslations <<
"qt" <<
"qtbase" <<
"qtmultimedia" <<
"qtwebengine"
289 foreach(
auto f, qtTranslations) {
290 QString szFile = szQtTranslationPath + QDir::separator()
291 + f +
"_" + szLanguage +
".qm";
294 InstallTranslatorFile(szFile);
296 qWarning(logTranslation) <<
"The file isn't exists:" << szFile;
299#ifdef HAVE_RABBITCOMMON_GUI
300 CStyle::Instance()->LoadStyle();
306 foreach(
auto t, m_Translator) {
307 QCoreApplication::removeTranslator(t.data());
309 m_Translator.clear();
313QSharedPointer<QTranslator> CTools::InstallTranslatorFile(
const QString szFile)
315 QSharedPointer<QTranslator> translator
316 = QSharedPointer<QTranslator>(
new QTranslator());
318 qCritical(logTranslation) <<
"new QTranslator fail";
321 bool bRet = translator->load(szFile);
324 bRet = QCoreApplication::installTranslator(translator.data());
327 m_Translator.push_back(translator);
328 qDebug(logTranslation) <<
"Install translator:" << szFile;
332 qCritical(logTranslation) <<
"Install translator fail:" << szFile;
335 qCritical(logTranslation) <<
"Load translator file fail:" << szFile;
336 return QSharedPointer<QTranslator>();
340 const QString szName,
341 TranslationType type,
342 const QString szPluginDir,
343 const QString szLanguage)
345 QString szTranslationName = szName;
349 szSuffix = QDir::separator() + szTranslationName +
"_" + szLanguage +
".qm";
351 case TranslationType::Application:
352 szPath = CDir::Instance()->GetDirTranslations();
353 if(szTranslationName.isEmpty())
354 szTranslationName = QCoreApplication::applicationName();
356 case TranslationType::Library: {
357 szPath = CDir::Instance()->GetDirTranslations();
358 if(szTranslationName.isEmpty()) {
359 qCritical(logTranslation) <<
"Please set translation name";
362#if defined(Q_OS_LINUX)
363 QFile file(szPath + szSuffix);
365 szPath = CDir::Instance()->GetDirTranslations(
"/usr/share");
366 file.setFileName(szPath + szSuffix);
368 szPath = CDir::Instance()->GetDirTranslations(
375 case TranslationType::Plugin:
376 szPath = CDir::Instance()->GetDirPluginsTranslation(szPluginDir);
377 if(szTranslationName.isEmpty()) {
378 qCritical(logTranslation) <<
"Please set translation name";
384 QString szFile = szPath + szSuffix;
388 qCritical(logTranslation) <<
"File isn't exit:" << szFile;
389 return QSharedPointer<QTranslator>();
392 return InstallTranslatorFile(szFile);
395int CTools::RemoveTranslator(QSharedPointer<QTranslator> translator)
397 foreach(
auto t, m_Translator) {
398 if(t == translator) {
399 QCoreApplication::removeTranslator(t.data());
400 m_Translator.removeAll(t);
407void CTools::InitResource()
409 g_RabbitCommon_InitResource();
412void CTools::CleanResource()
414 g_RabbitCommon_CleanResource();
422 RabbitCommon::EnableMiniDumper();
430#ifdef HAVE_ADMINAUTHORISER
431 return CAdminAuthoriser::Instance()->execute(program, arguments);
444 appPath = QCoreApplication::applicationFilePath();
446 if(!szPath.isEmpty())
448 if(appPath.isEmpty())
450 qCCritical(log) <<
"szPath is empty";
454 return RabbitCommon::CRegister::InstallStartRun();
455 return RabbitCommon::CRegister::InstallStartRunCurrentUser();
462 if(QFile::exists(szLink))
463 if(RemoveStartRun(szName, bAllUser))
465 qCCritical(log) <<
"RemoveStartRun" << szName <<
"fail";
473 qCCritical(log) <<
"The desktop file is not exist." << appPath;
476 bool ret = f.link(szLink);
479 QString szCmd =
"ln -s " + appPath +
" " + szLink;
481 qCritical(log) <<
"CTools::InstallStartRun: file link"
482 << f.fileName() <<
" to " << szLink << f.error();
489int CTools::RemoveStartRun(
const QString &szName,
bool bAllUser)
492 QString appName = QCoreApplication::applicationName();
493 if(!szName.isEmpty())
496 return RabbitCommon::CRegister::RemoveStartRun();
497 return RabbitCommon::CRegister::RemoveStartRunCurrentUser();
500 if(!QFile::exists(szLink))
return 0;
503 if(d.remove(szLink))
return 0;
505 QString szCmd =
"rm " + szLink;
507 qCritical(log) <<
"execute" << szCmd <<
"fail";
512bool CTools::IsStartRun(
const QString &szName,
bool bAllUser)
517 return RabbitCommon::CRegister::IsStartRun();
518 return RabbitCommon::CRegister::IsStartRunCurrentUser();
521 if(QFile::exists(szLink))
527 const QString &szName)
534 szContent =
"[Desktop Entry]\n";
535 szContent +=
"Name=" + QCoreApplication::applicationName() +
"\n";
536 szContent +=
"Comment=" + QCoreApplication::applicationName() +
"\n";
537#ifdef HAVE_RABBITCOMMON_GUI
538 szContent +=
"Name[" + QLocale::system().name() +
"]=" + QApplication::applicationDisplayName() +
"\n";
539 szContent +=
"Comment[" + QLocale::system().name() +
"]=" + QApplication::applicationDisplayName() +
"\n";
541 szContent +=
"Name[" + QLocale::system().name() +
"]=" + QCoreApplication::applicationName() +
"\n";
542 szContent +=
"Comment[" + QLocale::system().name() +
"]=" + QCoreApplication::applicationName() +
"\n";
544 szContent +=
"Icon=" + QCoreApplication::applicationName() +
"\n";
545 szContent +=
"Exec=" + QCoreApplication::applicationFilePath() +
"\n";
546 szContent +=
"Categories=Application;Development;\n";
547 szContent +=
"Terminal=false\n";
548 szContent +=
"StartupNotify=true\n";
551 if(!f.open(QFile::WriteOnly))
555 f.write(szContent.toStdString().c_str());
560QString CTools::GetCurrentUser()
564 pwd = getpwuid(getuid());
567 CHAR szUserName[MAX_PATH] = {0};
568 DWORD dwSize=MAX_PATH;
569 ::GetUserNameA(szUserName, &dwSize);
573 return QDir::home().dirName();
577QString CTools::GetHostName()
580 gethostname(buf,
sizeof(buf));
584#ifdef HAVE_RABBITCOMMON_GUI
585QAction* CTools::AddStyleMenu(QMenu *pMenu, QWidget *parent)
587 return pMenu->addAction(QIcon::fromTheme(
"style"),
588 QObject::tr(
"Style"),
596void CTools::InsertStyleMenu(QMenu *pMenu, QAction *before, QWidget *parent)
598 QAction* pAction =
new QAction(QIcon::fromTheme(
"style"),
599 QObject::tr(
"Style"), parent);
600 QObject::connect(pAction, &QAction::triggered, [=](){
605 pMenu->insertAction(before, pAction);
608QMenu* CTools::GetLogMenu(QWidget *parentMainWindow)
610 QMenu* pMenu =
new QMenu(QObject::tr(
"Log"), parentMainWindow);
611 if(!pMenu)
return pMenu;
612 pMenu->setIcon(QIcon::fromTheme(
"folder-open"));
613 pMenu->addAction(QIcon::fromTheme(
"emblem-system"),
614 QObject::tr(
"Settings"),
617 QString szInclude, szExclude;
618 CLog::Instance()->GetFilter(szInclude, szExclude);
619 dlg.SetFilter(szInclude, szExclude);
620 if(QDialog::Accepted == dlg.exec())
622 dlg.GetFilter(szInclude, szExclude);
623 CLog::Instance()->SetFilter(szInclude, szExclude);
626 pMenu->addAction(QIcon::fromTheme(
"document-open"),
627 QObject::tr(
"Open Log configure file"),
628 [](){RabbitCommon::OpenLogConfigureFile();});
629 pMenu->addAction(QIcon::fromTheme(
"document-open"),
630 QObject::tr(
"Open Log file"),
631 [](){RabbitCommon::OpenLogFile();});
632 pMenu->addAction(QIcon::fromTheme(
"folder-open"),
633 QObject::tr(
"Open log folder"),
634 [](){RabbitCommon::OpenLogFolder();});
635 QMainWindow* pMainWindow = qobject_cast<QMainWindow*>(parentMainWindow);
639 pMainWindow->addDockWidget(Qt::DockWidgetArea::BottomDockWidgetArea,
642 g_pDcokDebugLog->setObjectName(
"dockDebugLog");
643 QAction* pDock = g_pDcokDebugLog->toggleViewAction();
644 pMenu->addAction(pDock);
645 pDock->setText(QObject::tr(
"Log dock"));
646 pDock->setIcon(QIcon::fromTheme(
"floating"));
648 qWarning(log) <<
"CTools::GetLogMenu: Don't use dock debug log."
649 <<
"The parent suggest is MainWindow pointer";
655int CTools::RestoreWidget(QWidget *pWidget)
659 if(!pWidget)
return -1;
660 QSettings set(RabbitCommon::CDir::Instance()->GetFileUserConfigure(),
661 QSettings::IniFormat);
663 = set.value(
"MainWindow/Status/Geometry").toByteArray();
664 if(!geometry.isEmpty()) {
665 if(!pWidget->restoreGeometry(geometry))
666 qWarning(log) <<
"Restore geometry fail";
668 QMainWindow* pMainWindow = qobject_cast<QMainWindow*>(pWidget);
670 QByteArray state = set.value(
"MainWindow/Status/State").toByteArray();
671 if(!state.isEmpty()) {
672 if(!pMainWindow->restoreState(state))
673 qWarning(log) <<
"Restore state fail";
679int CTools::SaveWidget(QWidget *pWidget)
683 if(!pWidget)
return -1;
684 QSettings set(RabbitCommon::CDir::Instance()->GetFileUserConfigure(),
685 QSettings::IniFormat);
686 set.setValue(
"MainWindow/Status/Geometry", pWidget->saveGeometry());
687 QMainWindow* pMainWindow = qobject_cast<QMainWindow*>(pWidget);
689 set.setValue(
"MainWindow/Status/State", pMainWindow->saveState());
Set style and icon theme form.
QString GetDirData(bool bReadOnly=false)
Get data directory.
QString GetDirTranslations(QString szPrefix=QString())
static QString GetDesktopFileLink(const QString &szName=QString(), bool bAllUser=false)
GetDesktopFileLink.
static QString GetDesktopFileName(const QString &szPath=QString(), const QString &szName=QString())
Generate the name of desktop file.