mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -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 #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 #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 #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 #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.
|
| `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.cache
|
||||||
.qmake.stash
|
.qmake.stash
|
||||||
Makefile
|
Makefile
|
||||||
moc_predefs.h
|
moc_*.cpp
|
||||||
moc_BrowserWindow.cpp
|
moc_*.h
|
||||||
moc_ConfigWindow.cpp
|
|
||||||
moc_LogWindow.cpp
|
|
||||||
moc_Server.cpp
|
|
||||||
moc_TabWindow.cpp
|
|
||||||
moc_WebViewWindow.cpp
|
|
||||||
pgAdmin4
|
pgAdmin4
|
||||||
pgAdmin4.app/
|
pgAdmin4.app/
|
||||||
pgAdmin4.pro.user*
|
pgAdmin4.pro.user*
|
||||||
qrc_pgAdmin4.cpp
|
qrc_pgAdmin4.cpp
|
||||||
ui_BrowserWindow.h
|
ui_*.h
|
||||||
ui_ConfigWindow.h
|
|
||||||
ui_LogWindow.h
|
|
||||||
object_script.*
|
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
|
// App headers
|
||||||
#include "ConfigWindow.h"
|
|
||||||
#include "LogWindow.h"
|
|
||||||
#include "TrayIcon.h"
|
#include "TrayIcon.h"
|
||||||
|
|
||||||
|
TrayIcon::TrayIcon()
|
||||||
TrayIcon::TrayIcon(QString logFile) :
|
|
||||||
m_logFile(logFile)
|
|
||||||
{
|
{
|
||||||
m_logWindow = NULL;
|
|
||||||
|
|
||||||
m_trayIcon = NULL;
|
m_trayIcon = NULL;
|
||||||
m_trayIconMenu = NULL;
|
m_trayIconMenu = NULL;
|
||||||
|
|
||||||
@ -32,74 +21,22 @@ TrayIcon::TrayIcon(QString logFile) :
|
|||||||
m_configAction = NULL;
|
m_configAction = NULL;
|
||||||
m_logAction = NULL;
|
m_logAction = NULL;
|
||||||
m_quitAction = NULL;
|
m_quitAction = NULL;
|
||||||
|
m_menuActions = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TrayIcon::~TrayIcon()
|
TrayIcon::~TrayIcon()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TrayIcon::Init()
|
||||||
bool TrayIcon::Init()
|
|
||||||
{
|
{
|
||||||
if (! isSystemTrayAvailable())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
createTrayIcon();
|
createTrayIcon();
|
||||||
|
|
||||||
if (m_trayIcon)
|
if (m_trayIcon)
|
||||||
m_trayIcon->show();
|
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
|
// Create the tray icon
|
||||||
void TrayIcon::createTrayIcon()
|
void TrayIcon::createTrayIcon()
|
||||||
{
|
{
|
||||||
@ -135,116 +72,21 @@ void TrayIcon::createTrayIcon()
|
|||||||
setWindowIcon(icon);
|
setWindowIcon(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Create the menu actions
|
// Create the menu actions
|
||||||
void TrayIcon::createActions()
|
void TrayIcon::createActions()
|
||||||
{
|
{
|
||||||
m_newAction = new QAction(QString(tr("&New %1 window...")).arg(PGA_APP_NAME), this);
|
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);
|
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);
|
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 = new QAction(tr("&Shut down server"), this);
|
||||||
m_quitAction->setEnabled(false);
|
m_quitAction->setEnabled(false);
|
||||||
connect(m_quitAction, SIGNAL(triggered()), this, SLOT(onQuit()));
|
connect(m_quitAction, SIGNAL(triggered()), m_menuActions, 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrayIcon::enableShutdownMenu()
|
void TrayIcon::enableShutdownMenu()
|
||||||
@ -254,3 +96,8 @@ void TrayIcon::enableShutdownMenu()
|
|||||||
m_quitAction->setEnabled(true);
|
m_quitAction->setEnabled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TrayIcon::setMenuActions(MenuActions * menuActions)
|
||||||
|
{
|
||||||
|
m_menuActions = menuActions;
|
||||||
|
}
|
||||||
|
@ -16,30 +16,24 @@
|
|||||||
|
|
||||||
// QT headers
|
// QT headers
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QMessageBox>
|
#include "MenuActions.h"
|
||||||
|
|
||||||
// App headers
|
|
||||||
#include "LogWindow.h"
|
|
||||||
|
|
||||||
class TrayIcon : public QWidget
|
class TrayIcon : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TrayIcon(QString logFile);
|
TrayIcon();
|
||||||
~TrayIcon();
|
~TrayIcon();
|
||||||
|
|
||||||
bool Init();
|
void Init();
|
||||||
void setAppServerUrl(QString appServerUrl);
|
|
||||||
void enableShutdownMenu();
|
void enableShutdownMenu();
|
||||||
|
void setMenuActions(MenuActions * menuActions);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createTrayIcon();
|
void createTrayIcon();
|
||||||
bool isSystemTrayAvailable();
|
|
||||||
void createActions();
|
void createActions();
|
||||||
|
|
||||||
void wait(int msec);
|
|
||||||
|
|
||||||
QAction *m_newAction;
|
QAction *m_newAction;
|
||||||
QAction *m_configAction;
|
QAction *m_configAction;
|
||||||
QAction *m_logAction;
|
QAction *m_logAction;
|
||||||
@ -48,18 +42,7 @@ private:
|
|||||||
QSystemTrayIcon *m_trayIcon;
|
QSystemTrayIcon *m_trayIcon;
|
||||||
QMenu *m_trayIconMenu;
|
QMenu *m_trayIconMenu;
|
||||||
|
|
||||||
QString m_appServerUrl, m_logFile;
|
MenuActions *m_menuActions;
|
||||||
|
|
||||||
LogWindow *m_logWindow;
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onNew();
|
|
||||||
void onConfig();
|
|
||||||
void onLog();
|
|
||||||
void onQuit();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void shutdownSignal(QUrl);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TRAYICON_H
|
#endif // TRAYICON_H
|
||||||
|
@ -34,6 +34,8 @@
|
|||||||
#include "ConfigWindow.h"
|
#include "ConfigWindow.h"
|
||||||
#include "Server.h"
|
#include "Server.h"
|
||||||
#include "TrayIcon.h"
|
#include "TrayIcon.h"
|
||||||
|
#include "MenuActions.h"
|
||||||
|
#include "FloatingWindow.h"
|
||||||
|
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
|
|
||||||
@ -172,6 +174,7 @@ int main(int argc, char * argv[])
|
|||||||
// Display the spash screen
|
// Display the spash screen
|
||||||
QSplashScreen *splash = new QSplashScreen();
|
QSplashScreen *splash = new QSplashScreen();
|
||||||
splash->setPixmap(QPixmap(":/splash.png"));
|
splash->setPixmap(QPixmap(":/splash.png"));
|
||||||
|
splash->setWindowFlags(splash->windowFlags() | Qt::WindowStaysOnTopHint);
|
||||||
splash->show();
|
splash->show();
|
||||||
app.processEvents(QEventLoop::AllEvents);
|
app.processEvents(QEventLoop::AllEvents);
|
||||||
|
|
||||||
@ -205,15 +208,43 @@ int main(int argc, char * argv[])
|
|||||||
// Generate the filename for the log
|
// Generate the filename for the log
|
||||||
logFileName = homeDir + (QString("/.%1.%2.log").arg(PGA_APP_NAME).arg(exeHash)).remove(" ");
|
logFileName = homeDir + (QString("/.%1.%2.log").arg(PGA_APP_NAME).arg(exeHash)).remove(" ");
|
||||||
|
|
||||||
// Start the tray service
|
// Create Menu Actions
|
||||||
TrayIcon *trayicon = new TrayIcon(logFileName);
|
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"));
|
// Start the tray service
|
||||||
QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
|
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
|
// Fire up the webserver
|
||||||
@ -221,6 +252,7 @@ int main(int argc, char * argv[])
|
|||||||
|
|
||||||
bool done = false;
|
bool done = false;
|
||||||
|
|
||||||
|
splash->showMessage(QString(QWidget::tr("Starting pgAdmin4 server...")), Qt::AlignBottom | Qt::AlignCenter);
|
||||||
while (done != true)
|
while (done != true)
|
||||||
{
|
{
|
||||||
server = new Server(port, key, logFileName);
|
server = new Server(port, key, logFileName);
|
||||||
@ -335,9 +367,13 @@ int main(int argc, char * argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Go!
|
// Go!
|
||||||
trayicon->setAppServerUrl(appServerUrl);
|
menuActions->setAppServerUrl(appServerUrl);
|
||||||
|
|
||||||
// Enable the shutdown server menu as server started successfully.
|
// 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();
|
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);
|
splash->finish(NULL);
|
||||||
|
|
||||||
|
if (floatingWindow != NULL)
|
||||||
|
floatingWindow->show();
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,19 +87,23 @@ else {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Source code
|
# Source code
|
||||||
HEADERS = \
|
HEADERS = Server.h \
|
||||||
Server.h \
|
|
||||||
pgAdmin4.h \
|
pgAdmin4.h \
|
||||||
ConfigWindow.h \
|
ConfigWindow.h \
|
||||||
TrayIcon.h \
|
TrayIcon.h \
|
||||||
LogWindow.h
|
LogWindow.h \
|
||||||
|
MenuActions.h \
|
||||||
|
FloatingWindow.h
|
||||||
SOURCES = pgAdmin4.cpp \
|
SOURCES = pgAdmin4.cpp \
|
||||||
Server.cpp \
|
Server.cpp \
|
||||||
ConfigWindow.cpp \
|
ConfigWindow.cpp \
|
||||||
TrayIcon.cpp \
|
TrayIcon.cpp \
|
||||||
LogWindow.cpp
|
LogWindow.cpp \
|
||||||
|
MenuActions.cpp \
|
||||||
|
FloatingWindow.cpp
|
||||||
FORMS = ConfigWindow.ui \
|
FORMS = ConfigWindow.ui \
|
||||||
LogWindow.ui
|
LogWindow.ui \
|
||||||
|
FloatingWindow.ui
|
||||||
ICON = pgAdmin4.icns
|
ICON = pgAdmin4.icns
|
||||||
QMAKE_INFO_PLIST = Info.plist
|
QMAKE_INFO_PLIST = Info.plist
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user