mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2024-11-21 16:27:39 -06:00
Support running on systems without a system tray. Fixes #3316
This commit is contained in:
parent
0137cfaee3
commit
765a88addf
@ -18,6 +18,7 @@ Bug fixes
|
||||
|
||||
| `Bug #3294 <https://redmine.postgresql.org/issues/3294>`_ - Infrastructure (and changes to the Query Tool) for realtime preference handling.
|
||||
| `Bug #3309 <https://redmine.postgresql.org/issues/3309>`_ - Fix Directory format support for backups.
|
||||
| `Bug #3316 <https://redmine.postgresql.org/issues/3316>`_ - Support running on systems without a system tray.
|
||||
| `Bug #3319 <https://redmine.postgresql.org/issues/3319>`_ - Cleanup and fix handling of Query Tool Cancel button status.
|
||||
| `Bug #3363 <https://redmine.postgresql.org/issues/3363>`_ - Fix restoring of restore options for sections.
|
||||
| `Bug #3371 <https://redmine.postgresql.org/issues/3371>`_ - Don't create a session when the /misc/ping test endpoint is called.
|
||||
|
13
runtime/.gitignore
vendored
13
runtime/.gitignore
vendored
@ -1,18 +1,11 @@
|
||||
.qmake.cache
|
||||
.qmake.stash
|
||||
Makefile
|
||||
moc_predefs.h
|
||||
moc_BrowserWindow.cpp
|
||||
moc_ConfigWindow.cpp
|
||||
moc_LogWindow.cpp
|
||||
moc_Server.cpp
|
||||
moc_TabWindow.cpp
|
||||
moc_WebViewWindow.cpp
|
||||
moc_*.cpp
|
||||
moc_*.h
|
||||
pgAdmin4
|
||||
pgAdmin4.app/
|
||||
pgAdmin4.pro.user*
|
||||
qrc_pgAdmin4.cpp
|
||||
ui_BrowserWindow.h
|
||||
ui_ConfigWindow.h
|
||||
ui_LogWindow.h
|
||||
ui_*.h
|
||||
object_script.*
|
||||
|
103
runtime/FloatingWindow.cpp
Normal file
103
runtime/FloatingWindow.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
// FloatingWindow.cpp - For GNOME 3.26 and above floating window will be used.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "FloatingWindow.h"
|
||||
#include "ui_FloatingWindow.h"
|
||||
|
||||
FloatingWindow::FloatingWindow(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::FloatingWindow)
|
||||
{
|
||||
m_newAction = NULL;
|
||||
m_configAction = NULL;
|
||||
m_logAction = NULL;
|
||||
m_quitAction = NULL;
|
||||
m_menuActions = NULL;
|
||||
m_floatingWindowMenu = NULL;
|
||||
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
FloatingWindow::~FloatingWindow()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
bool FloatingWindow::Init()
|
||||
{
|
||||
// Creating Menu
|
||||
createMenu();
|
||||
|
||||
// Setup the icon itself. For convenience, we'll also use it for the dialogue.
|
||||
#ifdef Q_OS_MAC
|
||||
QIcon icon(":pgAdmin4-mac.png");
|
||||
#else
|
||||
QIcon icon(":pgAdmin4.png");
|
||||
#endif
|
||||
|
||||
setWindowIcon(icon);
|
||||
setWindowTitle(tr("pgAdmin"));
|
||||
setFixedSize(300, 230);
|
||||
setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::WindowMinimizeButtonHint);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Create the menu
|
||||
void FloatingWindow::createMenu()
|
||||
{
|
||||
createActions();
|
||||
|
||||
m_floatingWindowMenu = menuBar()->addMenu(QString(tr("%1")).arg(PGA_APP_NAME));
|
||||
m_floatingWindowMenu->addAction(m_newAction);
|
||||
m_floatingWindowMenu->addSeparator();
|
||||
m_floatingWindowMenu->addAction(m_configAction);
|
||||
m_floatingWindowMenu->addAction(m_logAction);
|
||||
m_floatingWindowMenu->addSeparator();
|
||||
m_floatingWindowMenu->addAction(m_quitAction);
|
||||
}
|
||||
|
||||
// Create the menu actions
|
||||
void FloatingWindow::createActions()
|
||||
{
|
||||
m_newAction = new QAction(QString(tr("&New %1 window...")).arg(PGA_APP_NAME), this);
|
||||
connect(m_newAction, SIGNAL(triggered()), m_menuActions, SLOT(onNew()));
|
||||
|
||||
m_configAction = new QAction(tr("&Configure..."), this);
|
||||
connect(m_configAction, SIGNAL(triggered()), m_menuActions, SLOT(onConfig()));
|
||||
|
||||
m_logAction = new QAction(tr("&View log..."), this);
|
||||
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()), m_menuActions, SLOT(onQuit()));
|
||||
}
|
||||
|
||||
void FloatingWindow::enableShutdownMenu()
|
||||
{
|
||||
if (m_quitAction != NULL)
|
||||
{
|
||||
m_quitAction->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void FloatingWindow::setMenuActions(MenuActions * menuActions)
|
||||
{
|
||||
m_menuActions = menuActions;
|
||||
}
|
||||
|
||||
void FloatingWindow::closeEvent(QCloseEvent * event)
|
||||
{
|
||||
// Emit the signal to shut down the python server.
|
||||
emit shutdownSignal(m_menuActions->getAppServerUrl());
|
||||
event->accept();
|
||||
exit(0);
|
||||
}
|
56
runtime/FloatingWindow.h
Normal file
56
runtime/FloatingWindow.h
Normal file
@ -0,0 +1,56 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
// FloatingWindow.h - For GNOME 3.26 and above floating window will be used.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#ifndef FLOATINGWINDOW_H
|
||||
#define FLOATINGWINDOW_H
|
||||
|
||||
#include "pgAdmin4.h"
|
||||
#include "MenuActions.h"
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
namespace Ui {
|
||||
class FloatingWindow;
|
||||
}
|
||||
|
||||
class FloatingWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FloatingWindow(QWidget *parent = 0);
|
||||
~FloatingWindow();
|
||||
|
||||
bool Init();
|
||||
void enableShutdownMenu();
|
||||
void setMenuActions(MenuActions * menuActions);
|
||||
|
||||
private:
|
||||
Ui::FloatingWindow *ui;
|
||||
|
||||
void createMenu();
|
||||
void createActions();
|
||||
void closeEvent(QCloseEvent * event);
|
||||
|
||||
QAction *m_newAction;
|
||||
QAction *m_configAction;
|
||||
QAction *m_logAction;
|
||||
QAction *m_quitAction;
|
||||
|
||||
QMenu *m_floatingWindowMenu;
|
||||
MenuActions *m_menuActions;
|
||||
|
||||
signals:
|
||||
void shutdownSignal(QUrl);
|
||||
};
|
||||
|
||||
#endif // FLOATINGWINDOW_H
|
155
runtime/FloatingWindow.ui
Normal file
155
runtime/FloatingWindow.ui
Normal file
@ -0,0 +1,155 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>FloatingWindow</class>
|
||||
<widget class="QMainWindow" name="FloatingWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>300</width>
|
||||
<height>230</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<widget class="QWidget" name="verticalLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>281</width>
|
||||
<height>201</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">border-image:url(":pgAdmin4.png");</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::LeftToRight</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Note: Installing a system tray plugin will prevent this window being shown.</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::AutoText</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
129
runtime/MenuActions.cpp
Normal file
129
runtime/MenuActions.cpp
Normal file
@ -0,0 +1,129 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
// MenuActions.cpp - Common file for menu actions.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "MenuActions.h"
|
||||
|
||||
// QT headers
|
||||
#include <QMessageBox>
|
||||
|
||||
MenuActions::MenuActions()
|
||||
{
|
||||
m_logWindow = NULL;
|
||||
m_logFile = "";
|
||||
m_appServerUrl = "";
|
||||
}
|
||||
|
||||
MenuActions::~MenuActions()
|
||||
{
|
||||
}
|
||||
|
||||
void MenuActions::setAppServerUrl(QString appServerUrl)
|
||||
{
|
||||
m_appServerUrl = appServerUrl;
|
||||
}
|
||||
|
||||
void MenuActions::setLogFile(QString logFile)
|
||||
{
|
||||
m_logFile = logFile;
|
||||
}
|
||||
|
||||
// Create a new application browser window on user request
|
||||
void MenuActions::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 MenuActions::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(NULL, 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 MenuActions::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 MenuActions::onQuit()
|
||||
{
|
||||
if (QMessageBox::Yes == QMessageBox::question(NULL, 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);
|
||||
}
|
||||
}
|
46
runtime/MenuActions.h
Normal file
46
runtime/MenuActions.h
Normal file
@ -0,0 +1,46 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
// MenuActions.h - Common file for menu actions.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef MENUACTIONS_H
|
||||
#define MENUACTIONS_H
|
||||
|
||||
#include "pgAdmin4.h"
|
||||
|
||||
// App headers
|
||||
#include "LogWindow.h"
|
||||
#include "ConfigWindow.h"
|
||||
|
||||
class MenuActions: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MenuActions();
|
||||
~MenuActions();
|
||||
|
||||
void setAppServerUrl(QString appServerUrl);
|
||||
void setLogFile(QString logFile);
|
||||
QString getAppServerUrl() { return m_appServerUrl; }
|
||||
|
||||
private:
|
||||
QString m_appServerUrl, m_logFile;
|
||||
LogWindow *m_logWindow;
|
||||
|
||||
protected slots:
|
||||
void onNew();
|
||||
void onConfig();
|
||||
void onLog();
|
||||
void onQuit();
|
||||
|
||||
signals:
|
||||
void shutdownSignal(QUrl);
|
||||
};
|
||||
|
||||
#endif // MENUACTIONS_H
|
@ -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;
|
||||
}
|
||||
|
@ -16,30 +16,24 @@
|
||||
|
||||
// QT headers
|
||||
#include <QWidget>
|
||||
#include <QMessageBox>
|
||||
|
||||
// App headers
|
||||
#include "LogWindow.h"
|
||||
#include "MenuActions.h"
|
||||
|
||||
class TrayIcon : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TrayIcon(QString logFile);
|
||||
TrayIcon();
|
||||
~TrayIcon();
|
||||
|
||||
bool Init();
|
||||
void setAppServerUrl(QString appServerUrl);
|
||||
void Init();
|
||||
void enableShutdownMenu();
|
||||
void setMenuActions(MenuActions * menuActions);
|
||||
|
||||
private:
|
||||
void createTrayIcon();
|
||||
bool isSystemTrayAvailable();
|
||||
void createActions();
|
||||
|
||||
void wait(int msec);
|
||||
|
||||
QAction *m_newAction;
|
||||
QAction *m_configAction;
|
||||
QAction *m_logAction;
|
||||
@ -48,18 +42,7 @@ private:
|
||||
QSystemTrayIcon *m_trayIcon;
|
||||
QMenu *m_trayIconMenu;
|
||||
|
||||
QString m_appServerUrl, m_logFile;
|
||||
|
||||
LogWindow *m_logWindow;
|
||||
|
||||
private slots:
|
||||
void onNew();
|
||||
void onConfig();
|
||||
void onLog();
|
||||
void onQuit();
|
||||
|
||||
signals:
|
||||
void shutdownSignal(QUrl);
|
||||
MenuActions *m_menuActions;
|
||||
};
|
||||
|
||||
#endif // TRAYICON_H
|
||||
|
@ -34,6 +34,8 @@
|
||||
#include "ConfigWindow.h"
|
||||
#include "Server.h"
|
||||
#include "TrayIcon.h"
|
||||
#include "MenuActions.h"
|
||||
#include "FloatingWindow.h"
|
||||
|
||||
#include <QTime>
|
||||
|
||||
@ -172,6 +174,7 @@ int main(int argc, char * argv[])
|
||||
// Display the spash screen
|
||||
QSplashScreen *splash = new QSplashScreen();
|
||||
splash->setPixmap(QPixmap(":/splash.png"));
|
||||
splash->setWindowFlags(splash->windowFlags() | Qt::WindowStaysOnTopHint);
|
||||
splash->show();
|
||||
app.processEvents(QEventLoop::AllEvents);
|
||||
|
||||
@ -205,15 +208,43 @@ int main(int argc, char * argv[])
|
||||
// Generate the filename for the log
|
||||
logFileName = homeDir + (QString("/.%1.%2.log").arg(PGA_APP_NAME).arg(exeHash)).remove(" ");
|
||||
|
||||
// Start the tray service
|
||||
TrayIcon *trayicon = new TrayIcon(logFileName);
|
||||
// Create Menu Actions
|
||||
MenuActions *menuActions = new MenuActions();
|
||||
if(menuActions != NULL)
|
||||
menuActions->setLogFile(logFileName);
|
||||
|
||||
if (!trayicon->Init())
|
||||
splash->showMessage(QString(QWidget::tr("Checking for system tray...")), Qt::AlignBottom | Qt::AlignCenter);
|
||||
|
||||
// Check system tray is available or not. If not then create one floating window.
|
||||
FloatingWindow *floatingWindow = NULL;
|
||||
TrayIcon *trayicon = NULL;
|
||||
if (QSystemTrayIcon::isSystemTrayAvailable())
|
||||
{
|
||||
QString error = QString(QWidget::tr("An error occurred initialising the tray icon"));
|
||||
QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
|
||||
// Start the tray service
|
||||
trayicon = new TrayIcon();
|
||||
|
||||
exit(1);
|
||||
// Set the MenuActions object to connect to slot
|
||||
if (trayicon != NULL)
|
||||
trayicon->setMenuActions(menuActions);
|
||||
|
||||
trayicon->Init();
|
||||
}
|
||||
else
|
||||
{
|
||||
splash->showMessage(QString(QWidget::tr("System tray not found, creating floating window...")), Qt::AlignBottom | Qt::AlignCenter);
|
||||
// Unable to find tray icon, so creating floting window
|
||||
floatingWindow = new FloatingWindow();
|
||||
if (floatingWindow == NULL)
|
||||
{
|
||||
QString error = QString(QWidget::tr("Unable to initialize either a tray icon or control window."));
|
||||
QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Set the MenuActions object to connect to slot
|
||||
floatingWindow->setMenuActions(menuActions);
|
||||
floatingWindow->Init();
|
||||
}
|
||||
|
||||
// Fire up the webserver
|
||||
@ -221,6 +252,7 @@ int main(int argc, char * argv[])
|
||||
|
||||
bool done = false;
|
||||
|
||||
splash->showMessage(QString(QWidget::tr("Starting pgAdmin4 server...")), Qt::AlignBottom | Qt::AlignCenter);
|
||||
while (done != true)
|
||||
{
|
||||
server = new Server(port, key, logFileName);
|
||||
@ -335,9 +367,13 @@ int main(int argc, char * argv[])
|
||||
}
|
||||
|
||||
// Go!
|
||||
trayicon->setAppServerUrl(appServerUrl);
|
||||
menuActions->setAppServerUrl(appServerUrl);
|
||||
|
||||
// Enable the shutdown server menu as server started successfully.
|
||||
trayicon->enableShutdownMenu();
|
||||
if (trayicon != NULL)
|
||||
trayicon->enableShutdownMenu();
|
||||
if (floatingWindow != NULL)
|
||||
floatingWindow->enableShutdownMenu();
|
||||
|
||||
QString cmd = settings.value("BrowserCommand").toString();
|
||||
|
||||
@ -357,10 +393,12 @@ int main(int argc, char * argv[])
|
||||
}
|
||||
}
|
||||
|
||||
QObject::connect(trayicon, SIGNAL(shutdownSignal(QUrl)), server, SLOT(shutdown(QUrl)));
|
||||
|
||||
QObject::connect(menuActions, SIGNAL(shutdownSignal(QUrl)), server, SLOT(shutdown(QUrl)));
|
||||
splash->finish(NULL);
|
||||
|
||||
if (floatingWindow != NULL)
|
||||
floatingWindow->show();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
|
@ -87,19 +87,23 @@ else {
|
||||
}
|
||||
|
||||
# Source code
|
||||
HEADERS = \
|
||||
Server.h \
|
||||
HEADERS = Server.h \
|
||||
pgAdmin4.h \
|
||||
ConfigWindow.h \
|
||||
TrayIcon.h \
|
||||
LogWindow.h
|
||||
LogWindow.h \
|
||||
MenuActions.h \
|
||||
FloatingWindow.h
|
||||
SOURCES = pgAdmin4.cpp \
|
||||
Server.cpp \
|
||||
ConfigWindow.cpp \
|
||||
TrayIcon.cpp \
|
||||
LogWindow.cpp
|
||||
LogWindow.cpp \
|
||||
MenuActions.cpp \
|
||||
FloatingWindow.cpp
|
||||
FORMS = ConfigWindow.ui \
|
||||
LogWindow.ui
|
||||
LogWindow.ui \
|
||||
FloatingWindow.ui
|
||||
ICON = pgAdmin4.icns
|
||||
QMAKE_INFO_PLIST = Info.plist
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user