Add a very experimental QT based runtime for pgAdmin 4.
This runtime implements a brower control with embedded Python interpretor. The Python interpretor runs a simple script at startup to generate some HTML that is displayed in the browser. Arbitrary URLs can be opened from the "Open URL" option on the File menu.pull/3/head
parent
192cddef0e
commit
38ff104cb9
|
|
@ -0,0 +1,71 @@
|
||||||
|
pgAdmin 4
|
||||||
|
=========
|
||||||
|
|
||||||
|
pgAdmin 4 is a rewrite of the popular pgAdmin3 management tool for the
|
||||||
|
PostgreSQL (http://www.postgresql.org) database.
|
||||||
|
|
||||||
|
At present, it is an experimental/proof of concept project. Use at your own
|
||||||
|
risk, and don't blame us if it breaks anything!
|
||||||
|
|
||||||
|
Architecture
|
||||||
|
------------
|
||||||
|
|
||||||
|
pgAdmin 4 is being written as a web application in Python, using jQuery for the
|
||||||
|
client side processing and UI. On the server side, CherryPy and Backbone are
|
||||||
|
being considered.
|
||||||
|
|
||||||
|
Although developed using web technologies, we intend for pgAdmin 4 to be usable
|
||||||
|
either on a web server using a browser, or standalone on a workstation. The
|
||||||
|
runtime/ subdirectory contains a QT based runtime application intended to allow
|
||||||
|
this - it is essentially a browser and Python interpretor in one package which
|
||||||
|
will be capable of hosting the Python application and presenting it to the user
|
||||||
|
as a desktop application.
|
||||||
|
|
||||||
|
Building
|
||||||
|
--------
|
||||||
|
|
||||||
|
To build the runtime, the following packages must be installed:
|
||||||
|
|
||||||
|
- QT 4.6 or above (older versions may work, but haven't been tested).
|
||||||
|
- Python 2.6 or above.
|
||||||
|
|
||||||
|
Assuming both qmake and python-config are in the path:
|
||||||
|
|
||||||
|
$ cd $PGADMIN4_SRC/runtime
|
||||||
|
$ qmake
|
||||||
|
Project MESSAGE: Building for QT5+...
|
||||||
|
$ make
|
||||||
|
...
|
||||||
|
|
||||||
|
On Linux, an executable called 'pgAdmin4' will be built, and on Mac OS X, an
|
||||||
|
app bundle called pgAdmin4.app will be created.
|
||||||
|
|
||||||
|
At the time of writing, no attempt has been made to build the runtime on a
|
||||||
|
Windows system, though in theory it should work.
|
||||||
|
|
||||||
|
Support
|
||||||
|
-------
|
||||||
|
|
||||||
|
pgAdmin 4 is completely experiemental and unsupported!
|
||||||
|
|
||||||
|
Project info
|
||||||
|
------------
|
||||||
|
|
||||||
|
The source code repository can be found here:
|
||||||
|
|
||||||
|
http://git.postgresql.org/gitweb/?p=pgadmin4.git;a=summary
|
||||||
|
|
||||||
|
A Redmine project for pgAdmin 4 can be found at the address below. A PostgreSQL
|
||||||
|
community account is required to access this site. Please note that at present
|
||||||
|
only project developers can log bug and feature requests:
|
||||||
|
|
||||||
|
https://redmine.postgresql.org/projects/pgadmin4
|
||||||
|
|
||||||
|
If you wish to discuss pgAdmin 4, or contribute to the project, please use the
|
||||||
|
pgAdmin Hackers mailing list:
|
||||||
|
|
||||||
|
pgadmin-hackers@postgresql.org
|
||||||
|
|
||||||
|
--
|
||||||
|
Dave Page
|
||||||
|
pgAdmin Project Lead
|
||||||
|
|
@ -0,0 +1,131 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// pgAdmin 4 - PostgreSQL Tools
|
||||||
|
//
|
||||||
|
// Copyright (C) 2013, The pgAdmin Development Team
|
||||||
|
// This software is released under the PostgreSQL Licence
|
||||||
|
//
|
||||||
|
// BrowserWindow.cpp - Implementation of the main window class
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Must be before QT
|
||||||
|
#include <Python.h>
|
||||||
|
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
#if QT_VERSION >= 0x050000
|
||||||
|
#include <QtWidgets>
|
||||||
|
#include <QtWebKitWidgets>
|
||||||
|
#else
|
||||||
|
#include <QtWebKit>
|
||||||
|
#include <QAction>
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QMenuBar>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QInputDialog>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "BrowserWindow.h"
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
BrowserWindow::BrowserWindow()
|
||||||
|
{
|
||||||
|
createActions();
|
||||||
|
createMenus();
|
||||||
|
|
||||||
|
// Create the WebKit control
|
||||||
|
webView = new QWebView(this);
|
||||||
|
setCentralWidget(webView);
|
||||||
|
|
||||||
|
// Execute some python and set the web text
|
||||||
|
QString data = execPython(tr("from time import time,ctime\n"
|
||||||
|
"print 'Today is <b>%s</b><br /><i>This is python-generated HTML.</i>' % ctime(time())\n"));
|
||||||
|
|
||||||
|
webView->setHtml(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the actions for the window
|
||||||
|
void BrowserWindow::createActions()
|
||||||
|
{
|
||||||
|
// Open an arbitrary URL
|
||||||
|
openUrlAction = new QAction(tr("&Open URL..."), this);
|
||||||
|
openUrlAction->setShortcut(tr("Ctrl+U"));
|
||||||
|
openUrlAction->setStatusTip(tr("Open a URL"));
|
||||||
|
connect(openUrlAction, SIGNAL(triggered()), this, SLOT(openUrl()));
|
||||||
|
|
||||||
|
// Exit the app
|
||||||
|
exitAction = new QAction(tr("E&xit"), this);
|
||||||
|
exitAction->setStatusTip(tr("Exit the application"));
|
||||||
|
exitAction->setShortcuts(QKeySequence::Quit);
|
||||||
|
connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));
|
||||||
|
|
||||||
|
// About box
|
||||||
|
aboutAction = new QAction(tr("&About"), this);
|
||||||
|
aboutAction->setStatusTip(tr("Show the application's About box"));
|
||||||
|
connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the application menus
|
||||||
|
void BrowserWindow::createMenus()
|
||||||
|
{
|
||||||
|
// File
|
||||||
|
fileMenu = menuBar()->addMenu(tr("&File"));
|
||||||
|
fileMenu->addAction(openUrlAction);
|
||||||
|
fileMenu->addSeparator();
|
||||||
|
fileMenu->addAction(exitAction);
|
||||||
|
|
||||||
|
menuBar()->addSeparator();
|
||||||
|
|
||||||
|
// Help
|
||||||
|
helpMenu = menuBar()->addMenu(tr("&Help"));
|
||||||
|
helpMenu->addAction(aboutAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display the about box
|
||||||
|
void BrowserWindow::about()
|
||||||
|
{
|
||||||
|
QMessageBox::about(this, tr("About pgAdmin 4"), tr("pgAdmin 4 - PostgreSQL Tools"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open an arbitrary URL
|
||||||
|
void BrowserWindow::openUrl()
|
||||||
|
{
|
||||||
|
bool ok;
|
||||||
|
QString url = QInputDialog::getText(this, tr("Enter a URL"), tr("URL:"), QLineEdit::Normal, "http://", &ok);
|
||||||
|
|
||||||
|
if (ok && !url.isEmpty())
|
||||||
|
webView->setUrl(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString BrowserWindow::execPython(QString script)
|
||||||
|
{
|
||||||
|
// This python script allows us to capture stdout/stderr
|
||||||
|
QString stdOutErr =
|
||||||
|
tr("import sys\n\
|
||||||
|
class CatchStdoutStderr:\n\
|
||||||
|
def __init__(self):\n\
|
||||||
|
self.op = ''\n\
|
||||||
|
def write(self, txt):\n\
|
||||||
|
self.op += txt\n\
|
||||||
|
catchStdoutStderr = CatchStdoutStderr()\n\
|
||||||
|
sys.stdout = catchStdoutStderr\n\
|
||||||
|
sys.stderr = catchStdoutStderr\n\
|
||||||
|
");
|
||||||
|
|
||||||
|
// Create the main module, and call the redirect code.
|
||||||
|
PyObject *pModule = PyImport_AddModule("__main__");
|
||||||
|
PyRun_SimpleString(stdOutErr.toUtf8().constData());
|
||||||
|
|
||||||
|
// Now execute the actual script
|
||||||
|
PyRun_SimpleString(script.toUtf8().constData());
|
||||||
|
|
||||||
|
// Get the catcher object
|
||||||
|
PyObject *catcher = PyObject_GetAttrString(pModule,"catchStdoutStderr");
|
||||||
|
PyErr_Print();
|
||||||
|
|
||||||
|
PyObject *output = PyObject_GetAttrString(catcher,"op");
|
||||||
|
|
||||||
|
return QString(PyString_AsString(output));
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// pgAdmin 4 - PostgreSQL Tools
|
||||||
|
//
|
||||||
|
// Copyright (C) 2013, The pgAdmin Development Team
|
||||||
|
// This software is released under the PostgreSQL Licence
|
||||||
|
//
|
||||||
|
// BrowserWindow.h - Declaration of the main window class
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef BROWSERWINDOW_H
|
||||||
|
#define BROWSERWINDOW_H
|
||||||
|
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
#if QT_VERSION >= 0x050000
|
||||||
|
#include <QtWidgets>
|
||||||
|
#include <QtWebKitWidgets>
|
||||||
|
#else
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QWebView>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QAction;
|
||||||
|
class QMenu;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
class BrowserWindow : public QMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
BrowserWindow();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void openUrl();
|
||||||
|
void about();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QWebView *webView;
|
||||||
|
QMenu *fileMenu;
|
||||||
|
QMenu *helpMenu;
|
||||||
|
QAction *openUrlAction;
|
||||||
|
QAction *exitAction;
|
||||||
|
QAction *aboutAction;
|
||||||
|
|
||||||
|
void createActions();
|
||||||
|
void createMenus();
|
||||||
|
QString execPython(QString script);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Form</class>
|
||||||
|
<widget class="QWidget" name="Form">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>911</width>
|
||||||
|
<height>688</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QWebView" name="webView">
|
||||||
|
<property name="url">
|
||||||
|
<url>
|
||||||
|
<string>about:blank</string>
|
||||||
|
</url>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>QWebView</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>QtWebKitWidgets/QWebView</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
|
||||||
|
<plist version="0.9">
|
||||||
|
<dict>
|
||||||
|
<!-- start of standard entries -->
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string>@ICON@</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleGetInfoString</key>
|
||||||
|
<string>pgAdmin 4 - PostgreSQL Tools</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>@TYPEINFO@</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>@EXECUTABLE@</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>org.pgadmin.@EXECUTABLE@</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// pgAdmin 4 - PostgreSQL Tools
|
||||||
|
//
|
||||||
|
// Copyright (C) 2013, The pgAdmin Development Team
|
||||||
|
// This software is released under the PostgreSQL Licence
|
||||||
|
//
|
||||||
|
// pgAdmin4.cpp - Main application entry point
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Must be before QT
|
||||||
|
#include <Python.h>
|
||||||
|
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
#if QT_VERSION >= 0x050000
|
||||||
|
#include <QtWidgets>
|
||||||
|
#else
|
||||||
|
#include <QApplication>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "BrowserWindow.h"
|
||||||
|
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
// Create the QT application
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
|
// Initialise Python
|
||||||
|
Py_SetProgramName(argv[0]);
|
||||||
|
Py_Initialize();
|
||||||
|
|
||||||
|
// Create & show the main window
|
||||||
|
BrowserWindow browserWindow;
|
||||||
|
browserWindow.show();
|
||||||
|
|
||||||
|
// Go!
|
||||||
|
return app.exec();
|
||||||
|
|
||||||
|
// Shutdown Python
|
||||||
|
Py_Finalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,24 @@
|
||||||
|
# Configure QT modules for the appropriate version of QT
|
||||||
|
greaterThan(QT_MAJOR_VERSION, 4) {
|
||||||
|
message(Building for QT5+...)
|
||||||
|
QT += webkitwidgets network widgets
|
||||||
|
} else {
|
||||||
|
message(Building for QT4...)
|
||||||
|
QT += webkit network
|
||||||
|
}
|
||||||
|
|
||||||
|
# Find and configure Python
|
||||||
|
!system(which python-config > /dev/null 2>&1) {
|
||||||
|
error(The python-config executable could not be found. Ensure Python is installed and in the system path.)
|
||||||
|
}
|
||||||
|
QMAKE_CXXFLAGS += $$system(python-config --includes)
|
||||||
|
QMAKE_LFLAGS += $$system(python-config --ldflags)
|
||||||
|
|
||||||
|
# Source code
|
||||||
|
HEADERS = BrowserWindow.h
|
||||||
|
SOURCES = pgAdmin4.cpp \
|
||||||
|
BrowserWindow.cpp
|
||||||
|
FORMS = BrowserWindow.ui
|
||||||
|
ICON = pgAdmin4.icns
|
||||||
|
QMAKE_INFO_PLIST = Info.plist
|
||||||
|
|
||||||
Loading…
Reference in New Issue