Support running on systems without a system tray. Fixes #3316

This commit is contained in:
Akshay Joshi
2018-07-17 12:10:35 +01:00
committed by Dave Page
parent 0137cfaee3
commit 765a88addf
11 changed files with 567 additions and 212 deletions

View File

@@ -9,22 +9,11 @@
//
//////////////////////////////////////////////////////////////////////////
#include "pgAdmin4.h"
// QT headers
#include <QMessageBox>
// App headers
#include "ConfigWindow.h"
#include "LogWindow.h"
#include "TrayIcon.h"
TrayIcon::TrayIcon(QString logFile) :
m_logFile(logFile)
TrayIcon::TrayIcon()
{
m_logWindow = NULL;
m_trayIcon = NULL;
m_trayIconMenu = NULL;
@@ -32,74 +21,22 @@ TrayIcon::TrayIcon(QString logFile) :
m_configAction = NULL;
m_logAction = NULL;
m_quitAction = NULL;
m_menuActions = NULL;
}
TrayIcon::~TrayIcon()
{
}
bool TrayIcon::Init()
void TrayIcon::Init()
{
if (! isSystemTrayAvailable())
return false;
createTrayIcon();
if (m_trayIcon)
m_trayIcon->show();
return true;
}
void TrayIcon::setAppServerUrl(QString appServerUrl)
{
m_appServerUrl = appServerUrl;
}
// Check whether system tray exists
bool TrayIcon::isSystemTrayAvailable()
{
int timeout = 10; // 30 sec * 10 = 5 minutes, thus we timeout after 5 minutes
int iteration = 0;
bool trayFound = false;
while (iteration < timeout)
{
// Check we can find the system tray.
if (!QSystemTrayIcon::isSystemTrayAvailable())
{
// Wait for 30 seconds.
wait(3000);
trayFound = false;
}
else
{
trayFound = true;
break;
}
iteration++;
}
return trayFound;
}
// Make application wait for msec milliseconds
void TrayIcon::wait(int msec)
{
QMutex mutex;
QWaitCondition wc;
mutex.lock();
wc.wait(&mutex, msec);
mutex.unlock();
}
// Create the tray icon
void TrayIcon::createTrayIcon()
{
@@ -135,116 +72,21 @@ void TrayIcon::createTrayIcon()
setWindowIcon(icon);
}
// Create the menu actions
void TrayIcon::createActions()
{
m_newAction = new QAction(QString(tr("&New %1 window...")).arg(PGA_APP_NAME), this);
connect(m_newAction, SIGNAL(triggered()), this, SLOT(onNew()));
connect(m_newAction, SIGNAL(triggered()), m_menuActions, SLOT(onNew()));
m_configAction = new QAction(tr("&Configure..."), this);
connect(m_configAction, SIGNAL(triggered()), this, SLOT(onConfig()));
connect(m_configAction, SIGNAL(triggered()), m_menuActions, SLOT(onConfig()));
m_logAction = new QAction(tr("&View log..."), this);
connect(m_logAction, SIGNAL(triggered()), this, SLOT(onLog()));
connect(m_logAction, SIGNAL(triggered()), m_menuActions, SLOT(onLog()));
m_quitAction = new QAction(tr("&Shut down server"), this);
m_quitAction->setEnabled(false);
connect(m_quitAction, SIGNAL(triggered()), this, SLOT(onQuit()));
}
// Create a new application browser window on user request
void TrayIcon::onNew()
{
QSettings settings;
QString cmd = settings.value("BrowserCommand").toString();
if (!cmd.isEmpty())
{
cmd.replace("%URL%", m_appServerUrl);
QProcess::startDetached(cmd);
}
else
{
if (!QDesktopServices::openUrl(m_appServerUrl))
{
QString error(QWidget::tr("Failed to open the system default web browser. Is one installed?."));
QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
exit(1);
}
}
}
// Show the config dialogue
void TrayIcon::onConfig()
{
QSettings settings;
bool ok;
ConfigWindow *dlg = new ConfigWindow();
dlg->setWindowTitle(QString(tr("%1 Configuration")).arg(PGA_APP_NAME));
dlg->setBrowserCommand(settings.value("BrowserCommand").toString());
dlg->setPythonPath(settings.value("PythonPath").toString());
dlg->setApplicationPath(settings.value("ApplicationPath").toString());
dlg->setModal(true);
ok = dlg->exec();
QString browsercommand = dlg->getBrowserCommand();
QString pythonpath = dlg->getPythonPath();
QString applicationpath = dlg->getApplicationPath();
if (ok)
{
bool needRestart = (settings.value("PythonPath").toString() != pythonpath ||
settings.value("ApplicationPath").toString() != applicationpath);
settings.setValue("BrowserCommand", browsercommand);
settings.setValue("PythonPath", pythonpath);
settings.setValue("ApplicationPath", applicationpath);
if (needRestart)
{
if (QMessageBox::Yes == QMessageBox::question(this, tr("Shut down server?"), QString(tr("The %1 server must be restarted for changes to take effect. Do you want to shut down the server now?")).arg(PGA_APP_NAME), QMessageBox::Yes | QMessageBox::No))
{
exit(0);
}
}
}
}
// Show the log window
void TrayIcon::onLog()
{
QSettings settings;
if (!m_logWindow)
{
m_logWindow = new LogWindow(NULL, m_logFile);
m_logWindow->setWindowTitle(QString(tr("%1 Log")).arg(PGA_APP_NAME));
}
m_logWindow->show();
m_logWindow->raise();
m_logWindow->activateWindow();
QCoreApplication::processEvents( QEventLoop::AllEvents, 100 );
m_logWindow->ReadLog();
}
// Exit
void TrayIcon::onQuit()
{
if (QMessageBox::Yes == QMessageBox::question(this, tr("Shut down server?"), QString(tr("Are you sure you want to shut down the %1 server?")).arg(PGA_APP_NAME), QMessageBox::Yes | QMessageBox::No))
{
// Emit the signal to shut down the python server.
emit shutdownSignal(m_appServerUrl);
exit(0);
}
connect(m_quitAction, SIGNAL(triggered()), m_menuActions, SLOT(onQuit()));
}
void TrayIcon::enableShutdownMenu()
@@ -254,3 +96,8 @@ void TrayIcon::enableShutdownMenu()
m_quitAction->setEnabled(true);
}
}
void TrayIcon::setMenuActions(MenuActions * menuActions)
{
m_menuActions = menuActions;
}