7#include <QStandardPaths>
12#include <QProcessEnvironment>
14#if defined(Q_OS_ANDROID)
15#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
16#include <QtCore/private/qandroidextras_p.h>
20#ifdef HAVE_RABBITCOMMON_GUI
22 #include <QMainWindow>
23 #include <QMessageBox>
24 #include <QPushButton>
25 #include <QApplication>
26 #include <QDesktopServices>
30 #include "Information.h"
33 #include <QCoreApplication>
36#include "RabbitCommonTools.h"
37#include "RabbitCommonDir.h"
38#ifdef HAVE_ADMINAUTHORISER
39#include "AdminAuthoriser/adminauthoriser.h"
41#include "RabbitCommonRegister.h"
44#if defined(HAVE_OPENSSL)
45 #include "openssl/opensslv.h"
46 #include "openssl/crypto.h"
47 #include "openssl/ssl.h"
63 #include "CoreDump/MiniDumper.h"
65#include "CoreDump/StackTrace.h"
67#ifdef HAVE_RABBITCOMMON_GUI
68 #include "Log/DockDebugLog.h"
69 #include "Log/DlgFilter.h"
78#include "cmark-gfm-core-extensions.h"
81inline void g_RabbitCommon_InitResource()
83 Q_INIT_RESOURCE(ResourceRabbitCommon);
92 Q_INIT_RESOURCE(QUIWidgetQss);
97inline void g_RabbitCommon_CleanResource()
99 Q_CLEANUP_RESOURCE(ResourceRabbitCommon);
100#ifdef BUILD_QUIWidget
105#ifdef BUILD_QUIWidget
106 Q_CLEANUP_RESOURCE(QUIWidgetQss);
113static Q_LOGGING_CATEGORY(log,
"RabbitCommon.Tools")
114static Q_LOGGING_CATEGORY(logTranslation, "
RabbitCommon.Tools.Translation")
116static CCallTrace* g_pCallStack =
nullptr;
118CTools::CTools() : QObject()
119 , m_Initialized(false)
120#if defined(Q_OS_ANDROID)
121 , m_bShowMaxWindow(
true)
123 , m_bShowMaxWindow(
false)
127 cmark_gfm_core_extensions_ensure_registered();
135 qDebug(log) <<
"CTools::~CTools()";
136#if HAVE_RABBITCOMMON_GUI
138 delete g_pDcokDebugLog;
142CTools* CTools::Instance()
144 static CTools* pTools =
nullptr;
145 if(
nullptr == pTools)
146 pTools =
new CTools();
150static QString g_szLanguage;
151int CTools::SetLanguage(
const QString szLanguage)
153 g_szLanguage = szLanguage;
159 QString szLANG = QProcessEnvironment::systemEnvironment().value(
"LANG");
160 if(szLANG.isEmpty()) {
161 if(g_szLanguage.isEmpty())
162 return QLocale::system().name();
165 int underscoreIndex = szLANG.indexOf(
'.');
166 if (underscoreIndex != -1) {
167 szLANG.truncate(underscoreIndex);
177 QString szVersion(RabbitCommon_VERSION);
178 QString szRevision(RabbitCommon_REVISION);
179 if(szRevision.isEmpty()) {
180 szReturn = tr(
"Version: ") + szVersion;
182 szReturn = tr(
"Version: ") + szVersion + tr(
" (From revision: ");
183#if (defined(HAVE_CMARK) || defined(HAVE_CMARK_GFM))
184 szReturn +=
"[" + szRevision +
"](http://github.com/KangLin/RabbitCommon/tree/" + szRevision +
")";
186 szReturn += szRevision;
196 szInfo = tr(
"- Functions:") +
"\n";
197 szInfo += tr(
" - Locale: ") +
GetLanguage() +
"\n";
198#if defined(HAVE_RABBITCOMMON_GUI)
199 szInfo += tr(
" - Have GUI") +
"\n";
200#if defined(HAVE_ABOUT)
201 szInfo += tr(
" - Have About dialog") +
"\n";
203 szInfo += tr(
" - Use cmark-gfm") +
"\n";
205 szInfo += tr(
" - Use cmark") +
"\n";
208#if defined(HAVE_UPDATE)
209 szInfo += tr(
" - Have Update") +
"\n";
211 szInfo += tr(
" - Custom title bar for QWidget") +
"\n";
212 szInfo += tr(
" - Dock Folder browser") +
"\n";
213 szInfo += tr(
" - Recent menu") +
"\n";
214 szInfo += tr(
" - Style") +
"\n";
215 szInfo += tr(
" - Icon theme: ") + QIcon::themeName() +
"\n";
216 #if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
217 szInfo += tr(
" - Fall back icon theme: ") + QIcon::fallbackThemeName() +
"\n";
220 szInfo += tr(
" - Log") +
"\n";
221 szInfo += tr(
" - Core dump") +
"\n";
222 szInfo += tr(
" - Log file: ") + CLog::Instance()->GetLogFile() +
"\n";
223#if defined(HAVE_OPENSSL)
224 szInfo += tr(
" - Have encrypt(OPENSSL)") +
"\n";
226#if defined(BUILD_QUIWidget)
227 szInfo += tr(
" - Have QUIWidget") +
"\n";
229 szInfo += tr(
" - Application paths and files: ") +
"\n";
230 szInfo += tr(
" - Installation root path: ") + RabbitCommon::CDir::Instance()->GetDirApplicationInstallRoot() +
"\n";
231 szInfo += tr(
" - Application path: ") + RabbitCommon::CDir::Instance()->GetDirApplication() +
"\n";
232 szInfo += tr(
" - Configure path: ") + RabbitCommon::CDir::Instance()->GetDirConfig() +
"\n";
233 szInfo += tr(
" - Configure file: ") + RabbitCommon::CDir::Instance()->GetFileApplicationConfigure() +
"\n";
234 szInfo += tr(
" - Translations path: ") + RabbitCommon::CDir::Instance()->
GetDirTranslations() +
"\n";
235 szInfo += tr(
" - Log path: ") + RabbitCommon::CDir::Instance()->GetDirLog() +
"\n";
236 szInfo += tr(
" - Data path: ") + RabbitCommon::CDir::Instance()->
GetDirData() +
"\n";
237 szInfo += tr(
" - Icons path: ") + RabbitCommon::CDir::Instance()->GetDirIcons() +
"\n";
238 szInfo += tr(
" - Database path: ") + RabbitCommon::CDir::Instance()->GetDirDatabase() +
"\n";
239 szInfo += tr(
" - Database file: ") + RabbitCommon::CDir::Instance()->GetDirDatabaseFile() +
"\n";
240 szInfo += tr(
" - Plugins path: ") + RabbitCommon::CDir::Instance()->GetDirPlugins() +
"\n";
241 szInfo += tr(
" - User folders and files: ") +
"\n";
242 szInfo += tr(
" - Documents path: ") + RabbitCommon::CDir::Instance()->GetDirUserDocument() +
"\n";
243 szInfo += tr(
" - Configure path: ") + RabbitCommon::CDir::Instance()->GetDirUserConfig() +
"\n";
244 szInfo += tr(
" - Configure file: ") + RabbitCommon::CDir::Instance()->GetFileUserConfigure() +
"\n";
245 szInfo += tr(
" - Data path: ") + RabbitCommon::CDir::Instance()->GetDirUserData() +
"\n";
246 szInfo += tr(
" - Image path: ") + RabbitCommon::CDir::Instance()->GetDirUserImage() +
"\n";
247 szInfo += tr(
" - Database path: ") + RabbitCommon::CDir::Instance()->GetDirUserDatabase() +
"\n";
248 szInfo += tr(
" - Database file: ") + RabbitCommon::CDir::Instance()->GetDirUserDatabaseFile() +
"\n";
250 szInfo += tr(
"- Dependent libraries:") +
"\n";
251 szInfo += tr(
" - OpenSSL:") +
"\n";
252#if defined(HAVE_OPENSSL)
253 szInfo +=
" - " + tr(
"Build Version: ") + OPENSSL_VERSION_TEXT +
"\n";
254 szInfo +=
" - " + tr(
"Runtime Version: ") + OpenSSL_version(OPENSSL_VERSION) +
"\n";
256 if(QSslSocket::supportsSsl())
258#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 3))
259 szInfo +=
" - Qt " + tr(
"Build Version: ") + QSslSocket::sslLibraryBuildVersionString() +
"\n";
261 szInfo +=
" - Qt " + tr(
"Installed Version: ") + QSslSocket::sslLibraryVersionString() +
"\n";
263#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 3))
264 szInfo +=
" - Qt " + tr(
"Build Version: ") + QSslSocket::sslLibraryBuildVersionString() +
"\n";
266 szInfo +=
" - Qt " + tr(
"Don't install OPENSSL dynamic library. Please install it") +
"\n";
269 szInfo += tr(
" - StackWalker") +
"\n";
272 szInfo += tr(
" - cmark-gfm") +
"\n";
274 szInfo += tr(
" - cmark") +
"\n";
279int CTools::AndroidRequestPermission(
const QString &permission)
281#if defined (Q_OS_ANDROID)
282 #if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
286 if (QtAndroidPrivate::checkPermission(permission).result()
287 == QtAndroidPrivate::Denied)
289 QtAndroidPrivate::requestPermission(permission).waitForFinished();
291 qInfo(log) <<
"android permission" << permission <<
";status:"
292 << QtAndroidPrivate::checkPermission(permission).result();
299int CTools::AndroidRequestPermission(
const QStringList &permissions)
301 foreach (
auto p, permissions) {
302 AndroidRequestPermission(p);
309 if(1 > argc || !argv) {
310 qCritical(log) <<
"The parameters is error";
316 QFileInfo fi(argv[0]);
317 if(szApplicationName.isEmpty())
318 szName = fi.baseName();
320 szName = szApplicationName;
321 szPath = fi.absolutePath();
322 Init(szName, szPath, szPath + QDir::separator() +
"..");
326 QString szApplicationDirPath,
327 QString szApplicationInstallRoot,
328 const QString szLanguage)
331 qWarning(log) <<
"CTools is already initialized";
335#if defined(HAVE_WebEngineWidgets)
337 if(!qEnvironmentVariable(
"SNAP").isEmpty()) {
338 qputenv(
"QTWEBENGINE_DISABLE_SANDBOX",
"1");
341 if(QCoreApplication::applicationName().isEmpty())
343 QCoreApplication::setApplicationName(szApplicationName);
344 CDir::Instance()->SetDirUserDocument();
346 if(QCoreApplication::applicationDirPath().isEmpty()
347 && CDir::Instance()->GetDirApplication().isEmpty())
348 CDir::Instance()->SetDirApplication(szApplicationDirPath);
349 if(CDir::Instance()->GetDirApplicationInstallRoot().isEmpty())
350 CDir::Instance()->SetDirApplicationInstallRoot(szApplicationInstallRoot);
351 if(QCoreApplication::applicationName().isEmpty()
352 || CDir::Instance()->GetDirApplication().isEmpty()
353 || CDir::Instance()->GetDirApplicationInstallRoot().isEmpty())
356 <<
"CTools::Instance()->Init() is called after QApplication a(argc, argv);"
357 "Or call this function with the parameters"
358 "szApplicationName, "
359 "szApplicationDirPath, "
360 "and szApplicationInstallRoot";
365 QStringList permissions;
366 permissions <<
"android.permission.WRITE_EXTERNAL_STORAGE"
367 <<
"android.permission.INTERNET"
368 <<
"android.permission.ACCESS_NETWORK_STATE"
369 <<
"android.permission.CHANGE_WIFI_STATE"
370 <<
"android.permission.ACCESS_WIFI_STATE"
371 <<
"android.permission.ACCESS_NETWORK_STATE"
372 <<
"android.permission.CHANGE_NETWORK_STATE";
373 AndroidRequestPermission(permissions);
375 RabbitCommon::CLog::Instance();
376 SetLanguage(szLanguage);
377 qInfo(logTranslation) <<
"Language:" << szLanguage;
381 QString szQtTranslationPath;
382#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
383 szQtTranslationPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
385 szQtTranslationPath = QLibraryInfo::path(QLibraryInfo::TranslationsPath);
387 QStringList qtTranslations;
388 qtTranslations <<
"qt" <<
"qtbase" <<
"qtmultimedia"
390#if HAVE_WebEngineWidgets
391 qtTranslations <<
"qtwebengine";
393 foreach(
auto f, qtTranslations) {
394 QString szFile = szQtTranslationPath + QDir::separator()
395 + f +
"_" + szLanguage +
".qm";
398 InstallTranslatorFile(szFile);
400 qWarning(logTranslation) <<
"The file doesn't exists: " << szFile;
403#ifdef HAVE_RABBITCOMMON_GUI
404 QSettings set(RabbitCommon::CDir::Instance()->GetFileUserConfigure(),
405 QSettings::IniFormat);
406 m_bShowMaxWindow = set.value(
"Tools/Window/ShowMax", m_bShowMaxWindow).toBool();
408 CStyle::Instance()->LoadStyle();
410 CInformation info(
"RabbitCommon, Qt and System information:",
"");
413 qDebug(log) <<
"RabbitCommon:" <<
"\n" <<
Information();
419 foreach(
auto t, m_Translator) {
420 QCoreApplication::removeTranslator(t.data());
422 m_Translator.clear();
424 delete RabbitCommon::CLog::Instance();
427QSharedPointer<QTranslator> CTools::InstallTranslatorFile(
const QString szFile)
429 QSharedPointer<QTranslator> translator
430 = QSharedPointer<QTranslator>(
new QTranslator());
432 qCritical(logTranslation) <<
"new QTranslator fail";
435 bool bRet = translator->load(szFile);
438 bRet = QCoreApplication::installTranslator(translator.data());
441 m_Translator.push_back(translator);
442 qDebug(logTranslation) <<
"Install translator:" << szFile;
446 qCritical(logTranslation) <<
"Install translator fail:" << szFile;
449 qCritical(logTranslation) <<
"Load translator file fail:" << szFile;
450 return QSharedPointer<QTranslator>();
454 const QString szName,
455 TranslationType type,
456 const QString szPluginDir,
457 const QString szLanguage)
459 QString szTranslationName = szName;
463 szSuffix = QDir::separator() + szTranslationName +
"_" + szLanguage +
".qm";
465 case TranslationType::Application:
466 szPath = CDir::Instance()->GetDirTranslations();
467 if(szTranslationName.isEmpty()) {
468 szTranslationName = QCoreApplication::applicationName();
469 szSuffix = QDir::separator() + szTranslationName +
"_" + szLanguage +
".qm";
472 case TranslationType::Library: {
473 szPath = CDir::Instance()->GetDirTranslations();
474 if(szTranslationName.isEmpty()) {
475 qCritical(logTranslation) <<
"Please set translation name";
478#if defined(Q_OS_LINUX)
479 QFile file(szPath + szSuffix);
481 szPath = CDir::Instance()->GetDirTranslations(
"/usr/share");
482 file.setFileName(szPath + szSuffix);
484 szPath = CDir::Instance()->GetDirTranslations(
491 case TranslationType::Plugin:
492 szPath = CDir::Instance()->GetDirPluginsTranslation(szPluginDir);
493 if(szTranslationName.isEmpty()) {
494 qCritical(logTranslation) <<
"Please set translation name";
500 QString szFile = szPath + szSuffix;
504 qCritical(logTranslation) <<
"File isn't exit:" << szFile;
505 return QSharedPointer<QTranslator>();
508 return InstallTranslatorFile(szFile);
511int CTools::RemoveTranslator(QSharedPointer<QTranslator> translator)
513 foreach(
auto t, m_Translator) {
514 if(t == translator) {
515 QCoreApplication::removeTranslator(t.data());
516 m_Translator.removeAll(t);
523void CTools::InitResource()
525 g_RabbitCommon_InitResource();
528void CTools::CleanResource()
530 g_RabbitCommon_CleanResource();
533#if defined(Q_OS_UNIX)
534void SigHandler(
int sig)
541 qCritical(log) <<
"Receive exception signal:" << sig <<
"\n"
542 << g_pCallStack->GetStack(3).toStdString().c_str();
545 qDebug(log) <<
"Receive signal:" << sig;
559 RabbitCommon::EnableMiniDumper();
562 signal(SIGSEGV, SigHandler);
564 signal(SIGBUS, SigHandler);
566 signal(SIGILL, SigHandler);
573#ifdef HAVE_ADMINAUTHORISER
574 return CAdminAuthoriser::Instance()->hasAdminRights();
580bool CTools::ExecuteWithAdministratorPrivilege(
const QString &program,
581 const QStringList &arguments,
584#ifdef HAVE_ADMINAUTHORISER
585 CAdminAuthoriser::Instance()->SetDetached(bDetached);
586 return CAdminAuthoriser::Instance()->execute(program, arguments);
594 return ExecuteWithAdministratorPrivilege(program, arguments);
601 auto para = QApplication::arguments();
602 QString szApp = QApplication::applicationFilePath();
604#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0) && defined(Q_OS_WIN)
605 szAppImage = qEnvironmentVariable(
"APPIMAGE");
607 szAppImage = QString::fromLocal8Bit(qgetenv(
"APPIMAGE"));
609 qDebug(log) <<
"App:" << szApp << szAppImage;
610 if(!szAppImage.isEmpty())
615 bRet = ExecuteWithAdministratorPrivilege(szApp);
617 bRet = ExecuteWithAdministratorPrivilege(szApp, para);
620#ifdef HAVE_RABBITCOMMON_GUI
621 auto pMainWindow = GetMainWindow();
624 QMetaObject::invokeMethod(pMainWindow,
"close", Qt::QueuedConnection);
629 QMetaObject::invokeMethod(qApp,
"quit", Qt::QueuedConnection);
633 qCritical(log) <<
"Start by root fail:" << QCoreApplication::applicationFilePath()
646 appPath = QCoreApplication::applicationFilePath();
648 if(!szPath.isEmpty())
650 if(appPath.isEmpty())
652 qCCritical(log) <<
"szPath is empty";
656 return RabbitCommon::CRegister::InstallStartRun();
657 return RabbitCommon::CRegister::InstallStartRunCurrentUser();
664 if(QFile::exists(szLink))
665 if(RemoveStartRun(szName, bAllUser))
667 qCCritical(log) <<
"RemoveStartRun" << szName <<
"fail";
675 qCCritical(log) <<
"The desktop file doesn't exist: " << appPath;
678 bool ret = f.link(szLink);
681 QString szCmd =
"ln -s " + appPath +
" " + szLink;
682 if(!ExecuteWithAdministratorPrivilege(szCmd))
683 qCritical(log) <<
"CTools::InstallStartRun: file link"
684 << f.fileName() <<
" to " << szLink << f.error();
691int CTools::RemoveStartRun(
const QString &szName,
bool bAllUser)
694 QString appName = QCoreApplication::applicationName();
695 if(!szName.isEmpty())
698 return RabbitCommon::CRegister::RemoveStartRun();
699 return RabbitCommon::CRegister::RemoveStartRunCurrentUser();
702 if(!QFile::exists(szLink))
return 0;
705 if(d.remove(szLink))
return 0;
707 QString szCmd =
"rm " + szLink;
708 if(ExecuteWithAdministratorPrivilege(szCmd))
return 0;
709 qCritical(log) <<
"execute" << szCmd <<
"fail";
714bool CTools::IsStartRun(
const QString &szName,
bool bAllUser)
719 return RabbitCommon::CRegister::IsStartRun();
720 return RabbitCommon::CRegister::IsStartRunCurrentUser();
723 if(QFile::exists(szLink))
729 const QString &szName)
736 szContent =
"[Desktop Entry]\n";
737 szContent +=
"Name=" + QCoreApplication::applicationName() +
"\n";
738 szContent +=
"Comment=" + QCoreApplication::applicationName() +
"\n";
739#ifdef HAVE_RABBITCOMMON_GUI
740 szContent +=
"Name[" + QLocale::system().name() +
"]=" + QApplication::applicationDisplayName() +
"\n";
741 szContent +=
"Comment[" + QLocale::system().name() +
"]=" + QApplication::applicationDisplayName() +
"\n";
743 szContent +=
"Name[" + QLocale::system().name() +
"]=" + QCoreApplication::applicationName() +
"\n";
744 szContent +=
"Comment[" + QLocale::system().name() +
"]=" + QCoreApplication::applicationName() +
"\n";
746 szContent +=
"Icon=" + QCoreApplication::applicationName() +
"\n";
747 szContent +=
"Exec=" + QCoreApplication::applicationFilePath() +
"\n";
748 szContent +=
"Categories=Application;Development;\n";
749 szContent +=
"Terminal=false\n";
750 szContent +=
"StartupNotify=true\n";
753 if(!f.open(QFile::WriteOnly))
757 f.write(szContent.toStdString().c_str());
762QString CTools::GetCurrentUser()
766 pwd = getpwuid(getuid());
769 CHAR szUserName[MAX_PATH] = {0};
770 DWORD dwSize=MAX_PATH;
771 ::GetUserNameA(szUserName, &dwSize);
775 return QDir::home().dirName();
779QString CTools::GetHostName()
782 gethostname(buf,
sizeof(buf));
786QString CTools::MarkDownToHtml(
const QString &szText)
788 QString szHtml = szText;
789#if defined(HAVE_CMARK_GFM) || defined(HAVE_CMARK)
790 char* pHtml = cmark_markdown_to_html(szText.toStdString().c_str(),
791 szText.toStdString().length(),
798 qCritical(log) <<
"cmark_markdown_to_html fail";
834#ifdef HAVE_RABBITCOMMON_GUI
835QAction* CTools::AddStyleMenu(QMenu *pMenu, QWidget *parent)
837 return pMenu->addAction(QIcon::fromTheme(
"style"),
846void CTools::InsertStyleMenu(QMenu *pMenu, QAction *before, QWidget *parent)
848 QAction* pAction =
new QAction(QIcon::fromTheme(
"style"),
849 tr(
"Style"), parent);
852 pAction->setStatusTip(tr(
"Style"));
853 QObject::connect(pAction, &QAction::triggered, [=](){
858 pMenu->insertAction(before, pAction);
861QMenu* CTools::GetLogMenu(QWidget *parentMainWindow)
863 QMenu* pMenu =
new QMenu(tr(
"Log"), parentMainWindow);
864 if(!pMenu)
return pMenu;
865 pMenu->setStatusTip(tr(
"Log"));
866 pMenu->setIcon(QIcon::fromTheme(
"folder-open"));
867 QAction* pAction = pMenu->addAction(QIcon::fromTheme(
"emblem-system"),
871 QString szInclude, szExclude;
872 CLog::Instance()->GetFilter(szInclude, szExclude);
873 dlg.SetFilter(szInclude, szExclude);
874 if(QDialog::Accepted == RC_SHOW_WINDOW(&dlg))
876 dlg.GetFilter(szInclude, szExclude);
877 CLog::Instance()->SetFilter(szInclude, szExclude);
880 pAction->setStatusTip(pAction->text());
881 pAction = pMenu->addAction(QIcon::fromTheme(
"document-open"),
882 tr(
"Open Log configure file"),
883 [](){RabbitCommon::OpenLogConfigureFile();});
884 pAction->setStatusTip(pAction->text());
885 pAction = pMenu->addAction(QIcon::fromTheme(
"document-open"),
887 [](){RabbitCommon::OpenLogFile();});
888 pAction->setStatusTip(pAction->text());
889 pAction = pMenu->addAction(QIcon::fromTheme(
"folder-open"),
890 tr(
"Open Log folder"),
891 [](){RabbitCommon::OpenLogFolder();});
892 pAction->setStatusTip(pAction->text());
894 QMainWindow* pMainWindow = qobject_cast<QMainWindow*>(parentMainWindow);
896 pMenu->addSeparator();
899 pMainWindow->addDockWidget(Qt::DockWidgetArea::BottomDockWidgetArea,
902 g_pDcokDebugLog->setObjectName(
"dockDebugLog");
903 QAction* pDock = g_pDcokDebugLog->toggleViewAction();
904 pMenu->addAction(pDock);
905 pDock->setText(tr(
"Log dock"));
906 pDock->setIcon(QIcon::fromTheme(
"floating"));
907 pDock->setStatusTip(tr(
"Log dock"));
909 qWarning(log) <<
"CTools::GetLogMenu: Don't use dock debug log."
910 <<
"The parent suggest is MainWindow pointer";
913 pMenu->addSeparator();
914 pAction = pMenu->addAction(QIcon::fromTheme(
"edit-copy"),
915 tr(
"Copy log file path to clipboard"),
916 [](){RabbitCommon::CopyLogFileToClipboard();});
917 pAction->setStatusTip(pAction->text());
918 pAction = pMenu->addAction(QIcon::fromTheme(
"edit-copy"),
919 tr(
"Copy log folder to clipboard"),
920 [](){RabbitCommon::CopyLogFolderToClipboard();});
921 pAction->setStatusTip(pAction->text());
926int CTools::RestoreWidget(QWidget *pWidget)
930 if(!pWidget)
return -1;
931 QSettings set(RabbitCommon::CDir::Instance()->GetFileUserConfigure(),
932 QSettings::IniFormat);
934 = set.value(
"MainWindow/Status/Geometry").toByteArray();
935 if(!geometry.isEmpty()) {
936 if(!pWidget->restoreGeometry(geometry))
937 qWarning(log) <<
"Restore geometry fail";
939 QMainWindow* pMainWindow = qobject_cast<QMainWindow*>(pWidget);
941 QByteArray state = set.value(
"MainWindow/Status/State").toByteArray();
942 if(!state.isEmpty()) {
943 if(!pMainWindow->restoreState(state))
944 qWarning(log) <<
"Restore state fail";
950int CTools::SaveWidget(QWidget *pWidget)
954 if(!pWidget)
return -1;
955 QSettings set(RabbitCommon::CDir::Instance()->GetFileUserConfigure(),
956 QSettings::IniFormat);
957 set.setValue(
"MainWindow/Status/Geometry", pWidget->saveGeometry());
958 QMainWindow* pMainWindow = qobject_cast<QMainWindow*>(pWidget);
960 set.setValue(
"MainWindow/Status/State", pMainWindow->saveState());
965int CTools::ShowWidget(QWidget *pWin)
968 qCritical(log) << Q_FUNC_INFO <<
"The parameter is nullptr";
973 QDialog* pDlg = qobject_cast<QDialog*>(pWin);
975 if(m_bShowMaxWindow) {
976 pDlg->showMaximized();
980 if(m_bShowMaxWindow) {
981 pWin->showMaximized();
988void CTools::ShowCoreDialog(QString szTitle, QString szContent, QString szDetail, QString szCoreDumpFile)
990 g_pCallStack->ShowCoreDialog(szTitle, szContent, szDetail, szCoreDumpFile);
993#if defined(Q_OS_LINUX)
995QString detectDesktopEnvironment() {
996 QString desktop = qgetenv(
"XDG_CURRENT_DESKTOP");
997 if (desktop.isEmpty()) {
998 desktop = qgetenv(
"DESKTOP_SESSION");
1000 return desktop.toLower();
1004bool openFileLocation(
const QString &szFile) {
1006 QFileInfo fileInfo(szFile);
1007 if (!fileInfo.exists()) {
1008 qCritical(log) <<
"File does not exist:" << szFile;
1012 QString desktopEnv = detectDesktopEnvironment();
1013 qDebug(log) <<
"Detected desktop environment:" << desktopEnv;
1014 QStringList lstPara;
1016 lstPara <<
"--select" << fileInfo.absoluteFilePath();
1017 if (desktopEnv.contains(
"gnome") || desktopEnv.contains(
"ubuntu") || desktopEnv.contains(
"unity")) {
1018 szProgram =
"nautilus";
1019 }
else if (desktopEnv.contains(
"kde") || desktopEnv.contains(
"plasma")) {
1020 szProgram =
"dolphin";
1021 }
else if (desktopEnv.contains(
"xfce")) {
1022 szProgram =
"thunar";
1023 }
else if (desktopEnv.contains(
"lxde") || desktopEnv.contains(
"lubuntu")) {
1024 szProgram =
"pcmanfm";
1025 }
else if(desktopEnv.contains(
"mate")) {
1028 qDebug(log) <<
"Program:" << szProgram <<
"Para:" << lstPara;
1029 if(!szProgram.isEmpty()) {
1030 bRet = QProcess::startDetached(szProgram, lstPara);
1032 bRet = QDesktopServices::openUrl(QUrl::fromLocalFile(fileInfo.absolutePath()));
1052bool CTools::LocateFileWithExplorer(
const QString szFile)
1056 QString command =
"explorer";
1057 QStringList args = {
"/select,", QDir::toNativeSeparators(szFile)};
1058 bRet = QProcess::startDetached(command, args);
1059#elif defined(Q_OS_MAC)
1061 args <<
"-e" << QString(
"tell application \"Finder\" to reveal POSIX file \"%1\"").arg(szFile);
1062 args <<
"-e" <<
"tell application \"Finder\" to activate";
1063 bRet = QProcess::startDetached(
"osascript", args);
1064#elif defined(Q_OS_LINUX)
1065 bRet = openFileLocation(szFile);
1069 QFileInfo fileInfo(szFile);
1070 if (!fileInfo.exists()) {
1071 qCritical(log) <<
"File does not exist:" << szFile;
1074 bRet = QDesktopServices::openUrl(QUrl::fromLocalFile(fileInfo.absolutePath()));
1079QMainWindow* CTools::GetMainWindow()
1081 foreach (QWidget *w, qApp->topLevelWidgets()) {
1082 if (QMainWindow* mainWin = qobject_cast<QMainWindow*>(w)) {
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.