Rewrite the runtime as a tray-based server which can launch a web browser. Fixes #3086
parent
25647c16ba
commit
7192a2b675
|
@ -28,7 +28,7 @@ runtime/.qmake.stash
|
||||||
runtime/Makefile
|
runtime/Makefile
|
||||||
runtime/Makefile.Debug
|
runtime/Makefile.Debug
|
||||||
runtime/Makefile.Release
|
runtime/Makefile.Release
|
||||||
runtime/moc_BrowserWindow.cpp
|
runtime/moc_TrayIcon.cpp
|
||||||
runtime/moc_Server.cpp
|
runtime/moc_Server.cpp
|
||||||
runtime/pgAdmin4.app/
|
runtime/pgAdmin4.app/
|
||||||
runtime/pgAdmin4.pro.user*
|
runtime/pgAdmin4.pro.user*
|
||||||
|
|
497
Make-MinGW.bat
497
Make-MinGW.bat
|
@ -1,497 +0,0 @@
|
||||||
@ECHO off
|
|
||||||
SETLOCAL
|
|
||||||
REM
|
|
||||||
REM ****************************************************************
|
|
||||||
SET WD=%CD%
|
|
||||||
SET "PGBUILDPATH=%WD%\win-build"
|
|
||||||
SET CMDOPTION=""
|
|
||||||
IF "%1" == "clean" SET CMDOPTION="VALID"
|
|
||||||
IF "%1" == "x86" SET CMDOPTION="VALID"
|
|
||||||
|
|
||||||
IF NOT %CMDOPTION%=="VALID" ( GOTO USAGE )
|
|
||||||
SET ARCHITECTURE=%1
|
|
||||||
|
|
||||||
IF "%ARCHITECTURE%"=="clean" (
|
|
||||||
GOTO CLEAN_RELEASE
|
|
||||||
GOTO EXIT
|
|
||||||
)
|
|
||||||
|
|
||||||
REM Main Functions
|
|
||||||
|
|
||||||
CALL :SET_PGADMIN4_ENVIRONMENT
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
CALL :VALIDATE_ENVIRONMENT
|
|
||||||
|
|
||||||
CALL :CLEAN_RELEASE
|
|
||||||
|
|
||||||
CALL :CREATE_VIRTUAL_ENV
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
CALL :CREATE_RUNTIME_ENV
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
CALL :CREATE_PYTHON_ENV
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
CALL :CLEANUP_ENV
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
CALL :CREATE_INSTALLER
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
CALL :SIGN_INSTALLER
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
CD %WD%
|
|
||||||
GOTO EXIT
|
|
||||||
REM Main function Ends
|
|
||||||
|
|
||||||
:CLEAN_RELEASE
|
|
||||||
ECHO Calling clean target...
|
|
||||||
IF EXIST "%PGBUILDPATH%" rd "%PGBUILDPATH%" /S /Q
|
|
||||||
|
|
||||||
FOR /R "%WD%" %%f in (*.pyc *.pyo) do DEL /q "%%f" > nul
|
|
||||||
IF EXIST "%WD%\pkg\win32\Output" rd "%WD%\pkg\win32\Output" /S /Q
|
|
||||||
IF EXIST DEL /q "%WD%\pkg\win32\installer.iss" > nul
|
|
||||||
CD %WD%
|
|
||||||
GOTO:eof
|
|
||||||
|
|
||||||
:SET_PGADMIN4_ENVIRONMENT
|
|
||||||
IF "%PYTHON_HOME%" == "" SET "PYTHON_HOME=C:\Python27"
|
|
||||||
IF "%PYTHON_DLL%" == "" SET "PYTHON_DLL=C:\Windows\SysWOW64\python27.dll"
|
|
||||||
IF "%QTDIR%" == "" SET "QTDIR=C:\Qt\5.9.1\mingw53_32"
|
|
||||||
IF "%PGDIR%" == "" SET "PGDIR=C:\Program Files (x86)\PostgreSQL\9.6"
|
|
||||||
IF "%INNOTOOL%" == "" SET "INNOTOOL=C:\Program Files (x86)\Inno Setup 5"
|
|
||||||
IF "%YARNDIR%" == "" SET "YARNDIR=C:\Program Files\Yarn"
|
|
||||||
IF "%NODEJSDIR%" == "" SET "NODEJSDIR=C:\Program Files\nodejs"
|
|
||||||
IF "%VCDIR%" == "" SET "VCDIR=C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC"
|
|
||||||
IF "%VCREDIST%" == "" SET "VCREDIST=C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\redist\1033\vcredist_x86.exe"
|
|
||||||
IF "%SIGNTOOL%" == "" SET "SIGNTOOL=C:\Program Files\Microsoft SDKs\Windows\v7.1A\Bin\signtool.exe"
|
|
||||||
SET "VCREDISTNAME=vcredist_x86.exe"
|
|
||||||
|
|
||||||
GOTO:eof
|
|
||||||
|
|
||||||
:VALIDATE_ENVIRONMENT
|
|
||||||
REM SET the variables IF not availalbe in windows environment
|
|
||||||
SET "QMAKE=%QTDIR%\bin\qmake.exe"
|
|
||||||
SET "VIRTUALENV=venv"
|
|
||||||
SET "TARGETINSTALLER=%WD%\dist"
|
|
||||||
SET "VCREDIST=%VCDIR%\redist\1033\%VCREDISTNAME%"
|
|
||||||
|
|
||||||
FOR /F "tokens=3" %%a IN ('findstr /C:"APP_RELEASE =" %WD%\web\config.py') DO SET APP_RELEASE=%%a
|
|
||||||
FOR /F "tokens=3" %%a IN ('findstr /C:"APP_REVISION =" %WD%\web\config.py') DO SET APP_REVISION_VERSION=%%a
|
|
||||||
FOR /F "tokens=3" %%a IN ('findstr /C:"APP_SUFFIX =" %WD%\web\config.py') DO SET APP_SUFFIX_VERSION=%%a
|
|
||||||
REM remove single quote from the string
|
|
||||||
SET APP_SUFFIX_VERSION=%APP_SUFFIX_VERSION:'=%
|
|
||||||
SET APP_NAME=""
|
|
||||||
FOR /F "tokens=2* DELims='" %%a IN ('findstr /C:"APP_NAME =" web\config.py') DO SET APP_NAME=%%a
|
|
||||||
FOR /f "tokens=1 DELims=." %%G IN ('%PYTHON_HOME%/python.exe -c "print('%APP_NAME%'.lower().replace(' ', ''))"') DO SET APP_SHORTNAME=%%G
|
|
||||||
FOR /F "tokens=4,5 delims=. " %%a IN ('%QMAKE% -v ^| findstr /B /C:"Using Qt version "') DO SET QT_VERSION=%%a.%%b
|
|
||||||
|
|
||||||
SET INSTALLERNAME=%APP_SHORTNAME%-%APP_RELEASE%.%APP_REVISION_VERSION%-%APP_SUFFIX_VERSION%-%ARCHITECTURE%.exe
|
|
||||||
IF "%APP_SUFFIX_VERSION%" == "" SET INSTALLERNAME=%APP_SHORTNAME%-%APP_RELEASE%.%APP_REVISION_VERSION%-%ARCHITECTURE%.exe
|
|
||||||
|
|
||||||
SET PGADMIN4_VERSION=v%APP_RELEASE%
|
|
||||||
SET PGADMIN4_APP_VERSION=%APP_RELEASE%.%APP_REVISION_VERSION%
|
|
||||||
|
|
||||||
ECHO ****************************************************************
|
|
||||||
ECHO S U M M A R Y
|
|
||||||
ECHO ****************************************************************
|
|
||||||
ECHO Target mode = x86
|
|
||||||
ECHO INNOTOOL = %INNOTOOL%
|
|
||||||
ECHO VCDIR = %VCDIR%
|
|
||||||
ECHO VCDIST = %VCREDIST%
|
|
||||||
ECHO SIGNTOOL = %SIGNTOOL%
|
|
||||||
ECHO QTDIR = %QTDIR%
|
|
||||||
ECHO QMAKE = %QMAKE%
|
|
||||||
ECHO QT_VERSION = %QT_VERSION%
|
|
||||||
ECHO YARNDIR = %YARNDIR%
|
|
||||||
ECHO NODEJSDIR = %NODEJSDIR%
|
|
||||||
ECHO BROWSER = QtWebKit
|
|
||||||
ECHO PYTHON_HOME = %PYTHON_HOME%
|
|
||||||
ECHO PYTHON_DLL = %PYTHON_DLL%
|
|
||||||
ECHO PGDIR = %PGDIR%
|
|
||||||
ECHO ****************************************************************
|
|
||||||
|
|
||||||
REM Check IF path SET in enviroments really exist or not ?
|
|
||||||
IF NOT EXIST "%INNOTOOL%" GOTO err_handle_inno
|
|
||||||
IF NOT EXIST "%VCDIR%" GOTO err_handle_visualstudio
|
|
||||||
IF NOT EXIST "%VCREDIST%" GOTO err_handle_visualstudio_dist
|
|
||||||
IF NOT EXIST "%QTDIR%" GOTO err_handle_qt
|
|
||||||
IF NOT EXIST "%QMAKE%" GOTO err_handle_qt
|
|
||||||
IF NOT EXIST "%PYTHON_HOME%" GOTO err_handle_python
|
|
||||||
IF NOT EXIST "%PYTHON_DLL%" GOTO err_handle_python
|
|
||||||
IF NOT EXIST "%PGDIR%" GOTO err_handle_pg
|
|
||||||
IF NOT EXIST "%YARNDIR%" GOTO err_handle_yarn
|
|
||||||
IF NOT EXIST "%NODEJSDIR%" GOTO err_handle_nodejs
|
|
||||||
|
|
||||||
REM get Python version ex. 2.7.1 will get as 27
|
|
||||||
FOR /f "tokens=1 DELims=." %%G IN ('%PYTHON_HOME%/python.exe -c "import sys; print(sys.version.split(' ')[0])"') DO SET PYTHON_MAJOR=%%G
|
|
||||||
FOR /f "tokens=2 DELims=." %%G IN ('%PYTHON_HOME%/python.exe -c "import sys; print(sys.version.split(' ')[0])"') DO SET PYTHON_MINOR=%%G
|
|
||||||
SET "PYTHON_VERSION=%PYTHON_MAJOR%%PYTHON_MINOR%"
|
|
||||||
|
|
||||||
IF NOT EXIST "%PYTHON_HOME%\Scripts\virtualenv.exe" GOTO err_handle_pythonvirtualenv
|
|
||||||
|
|
||||||
SET PATH=%PGDIR%;%PGDIR%\bin;%QTDIR%\..\..\Tools\mingw530_32\bin;%NODEJSDIR%;%YARNDIR%\bin;%PATH%;
|
|
||||||
GOTO:eof
|
|
||||||
|
|
||||||
:CREATE_VIRTUAL_ENV
|
|
||||||
ECHO Creating Virtual Enviroment...
|
|
||||||
IF NOT EXIST "%PGBUILDPATH%" MKDIR "%PGBUILDPATH%"
|
|
||||||
|
|
||||||
CD "%PGBUILDPATH%"
|
|
||||||
"%PYTHON_HOME%\Scripts\virtualenv.exe" "%VIRTUALENV%"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
ECHO Activating Virtual Enviroment - %PGBUILDPATH%\%VIRTUALENV%\Scripts\activate...
|
|
||||||
CALL "%PGBUILDPATH%\%VIRTUALENV%\Scripts\activate"
|
|
||||||
SET PATH=%PGDIR%\bin;%PATH%
|
|
||||||
|
|
||||||
ECHO Installing dependencies...
|
|
||||||
pip install -r "%WD%\requirements.txt"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
pip install sphinx
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
ECHO Virtual Environment created successfully.
|
|
||||||
|
|
||||||
ECHO Deactivating Virtual Enviroment - %PGBUILDPATH%\%VIRTUALENV%\Scripts\deactivate...
|
|
||||||
CALL "%PGBUILDPATH%\%VIRTUALENV%\Scripts\deactivate"
|
|
||||||
|
|
||||||
CD %WD%
|
|
||||||
GOTO:eof
|
|
||||||
|
|
||||||
:CREATE_RUNTIME_ENV
|
|
||||||
ECHO Compiling source code...
|
|
||||||
MKDIR "%PGBUILDPATH%\runtime" > nul
|
|
||||||
|
|
||||||
REM --- Processing WEB ---
|
|
||||||
CD "%WD%\web"
|
|
||||||
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
ECHO Install Javascript dependencies
|
|
||||||
call yarn install
|
|
||||||
ECHO Bundle all Javascript
|
|
||||||
call yarn run bundle
|
|
||||||
|
|
||||||
XCOPY /S /I /E /H /Y "%WD%\web" "%PGBUILDPATH%\web" > nul
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
REM Clean up .pyc, .pyo, pgadmin4.db, config_local.py
|
|
||||||
ECHO Cleaning up unnecessary files...
|
|
||||||
FOR /R "%PGBUILDPATH%\web" %%f in (*.pyc *.pyo) do DEL /q "%%f"
|
|
||||||
FOR /R "%PGBUILDPATH%\web" %%f in (tests feature_tests __pycache__ node_modules) do RD /Q /S "%%f"
|
|
||||||
RD /Q /S "%PGBUILDPATH%\web\regression"
|
|
||||||
RD /Q /S "%PGBUILDPATH%\web\tools"
|
|
||||||
DEL /q "%PGBUILDPATH%\web\pgadmin4.db"
|
|
||||||
DEL /q "%PGBUILDPATH%\web\config_local.py"
|
|
||||||
|
|
||||||
ECHO Creating config_distro.py
|
|
||||||
ECHO SERVER_MODE = False > "%PGBUILDPATH%\web\config_distro.py"
|
|
||||||
ECHO HELP_PATH = '../../../docs/en_US/html/' >> "%PGBUILDPATH%\web\config_distro.py"
|
|
||||||
ECHO DEFAULT_BINARY_PATHS = { >> "%PGBUILDPATH%\web\config_distro.py"
|
|
||||||
ECHO 'pg': '$DIR/../runtime', >> "%PGBUILDPATH%\web\config_distro.py"
|
|
||||||
ECHO 'ppas': '' >> "%PGBUILDPATH%\web\config_distro.py"
|
|
||||||
ECHO } >> "%PGBUILDPATH%\web\config_distro.py"
|
|
||||||
|
|
||||||
ECHO Activating Virtual Enviroment - %PGBUILDPATH%\%VIRTUALENV%\Scripts\activate...
|
|
||||||
CALL "%PGBUILDPATH%\%VIRTUALENV%\Scripts\activate"
|
|
||||||
|
|
||||||
ECHO Building docs...
|
|
||||||
MKDIR "%PGBUILDPATH%\docs\en_US\html"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
CD "%WD%\docs\en_US"
|
|
||||||
"%PGBUILDPATH%\%VIRTUALENV%\Scripts\python.exe" build_code_snippet.py
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
"%PGBUILDPATH%\%VIRTUALENV%\Scripts\sphinx-build.exe" "%WD%\docs\en_US" "%PGBUILDPATH%\docs\en_US\html"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
ECHO Removing Sphinx
|
|
||||||
pip uninstall -y sphinx Pygments alabaster colorama docutils imagesize requests snowballstemmer
|
|
||||||
|
|
||||||
ECHO Fixing backports.csv - adding missing __init__.py
|
|
||||||
type nul >> "%PGBUILDPATH%\%VIRTUALENV%\Lib\site-packages\backports\__init__.py"
|
|
||||||
|
|
||||||
ECHO Assembling runtime environment...
|
|
||||||
CD "%WD%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
CALL "%QMAKE%" "DEFINES+=PGADMIN4_USE_WEBKIT"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
CALL mingw32-make.exe clean
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
CALL mingw32-make.exe
|
|
||||||
IF ERRORLEVEL 1 GOTO ERR_HANDLER
|
|
||||||
|
|
||||||
REM Copy binary to Release Folder
|
|
||||||
copy "%WD%\runtime\release\pgAdmin4.exe" "%PGBUILDPATH%\runtime"
|
|
||||||
IF ERRORLEVEL 1 GOTO ERR_HANDLER
|
|
||||||
|
|
||||||
REM Copy QT dependences
|
|
||||||
copy "%QTDIR%\bin\Qt5Core.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5Sql.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5Gui.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5Qml.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5OpenGL.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5Quick.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5Sensors.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5Widgets.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5Network.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5Multimedia.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5WebChannel.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5Positioning.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5PrintSupport.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5MultimediaWidgets.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
IF %QT_VERSION% GEQ 5.9 (
|
|
||||||
copy "%QTDIR%\bin\Qt5WebKit.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5WebKitWidgets.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
) ELSE (
|
|
||||||
copy "%QTDIR%\bin\libQt5WebKit.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\libQt5WebKitWidgets.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
)
|
|
||||||
|
|
||||||
copy "%QTDIR%\bin\icudt57.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\icuin57.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\icuuc57.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\libgcc_s_dw2-1.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\libstdc++-6.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\libwinpthread-1.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\libxml2-2.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\libxslt-1.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
MKDIR "%PGBUILDPATH%\runtime\platforms"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\plugins\platforms\qwindows.dll" "%PGBUILDPATH%\runtime\platforms" > nul
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
ECHO [Paths] > "%PGBUILDPATH%\runtime\qt.conf"
|
|
||||||
ECHO Plugins=plugins >> "%PGBUILDPATH%\runtime\qt.conf"
|
|
||||||
|
|
||||||
copy "%PGDIR%\bin\libpq.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%PGDIR%\bin\ssleay32.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%PGDIR%\bin\libeay32.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%PGDIR%\bin\libintl-*.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%PGDIR%\bin\libiconv-*.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%PGDIR%\bin\zlib1.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%PGDIR%\bin\pg_dump.exe" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%PGDIR%\bin\pg_dumpall.exe" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%PGDIR%\bin\pg_restore.exe" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%PGDIR%\bin\psql.exe" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
MKDIR "%PGBUILDPATH%\installer"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%VCREDIST%" "%PGBUILDPATH%\installer" > nul
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
ECHO Runtime built successfully.
|
|
||||||
|
|
||||||
CD %WD%
|
|
||||||
GOTO:eof
|
|
||||||
|
|
||||||
:CREATE_PYTHON_ENV
|
|
||||||
copy %PYTHON_DLL% "%PGBUILDPATH%\runtime" > nul
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
REM Copy Python interpretor as it's needed to run background processes
|
|
||||||
copy %PYTHON_HOME%\python.exe "%PGBUILDPATH%\runtime" > nul
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy %PYTHON_HOME%\pythonw.exe "%PGBUILDPATH%\runtime" > nul
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
XCOPY /S /I /E /H /Y "%PYTHON_HOME%\DLLs" "%PGBUILDPATH%\%VIRTUALENV%\DLLs" > nul
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
XCOPY /S /I /E /H /Y "%PYTHON_HOME%\Lib" "%PGBUILDPATH%\%VIRTUALENV%\Lib" > nul
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
ECHO Cleaning up unnecessary files...
|
|
||||||
FOR /R "%PGBUILDPATH%\%VIRTUALENV%" %%f in (*.pyc *.pyo) do DEL /q "%%f"
|
|
||||||
FOR /R "%PGBUILDPATH%\%VIRTUALENV%\Lib" %%f in (test tests) do RD /Q /S "%%f"
|
|
||||||
RD /Q /S "%PGBUILDPATH%\%VIRTUALENV%\tcl"
|
|
||||||
|
|
||||||
CD %WD%
|
|
||||||
GOTO:eof
|
|
||||||
|
|
||||||
:CREATE_INSTALLER
|
|
||||||
ECHO Preparing for creation of windows installer...
|
|
||||||
IF NOT EXIST "%TARGETINSTALLER%" MKDIR "%TARGETINSTALLER%"
|
|
||||||
|
|
||||||
copy "%WD%\pkg\win32\Resources\pgAdmin4.ico" "%PGBUILDPATH%"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
CD "%WD%"
|
|
||||||
CD pkg
|
|
||||||
CD win32
|
|
||||||
|
|
||||||
"%PYTHON_HOME%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in" "-o" "%WD%\pkg\win32\installer.iss.in_stage1" "-s" MYAPP_NAME -r """%APP_NAME%"""
|
|
||||||
"%PYTHON_HOME%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in_stage1" "-o" "%WD%\pkg\win32\installer.iss.in_stage2" "-s" MYAPP_FULLVERSION -r """%PGADMIN4_APP_VERSION%"""
|
|
||||||
"%PYTHON_HOME%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in_stage2" "-o" "%WD%\pkg\win32\installer.iss.in_stage3" "-s" MYAPP_VERSION -r """%PGADMIN4_VERSION%"""
|
|
||||||
|
|
||||||
set ARCMODE=
|
|
||||||
IF "%ARCHITECTURE%"=="amd64" (
|
|
||||||
set ARCMODE="x64"
|
|
||||||
)
|
|
||||||
"%PYTHON_HOME%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in_stage3" "-o" "%WD%\pkg\win32\installer.iss.in_stage4" "-s" MYAPP_ARCHITECTURESMODE -r """%ARCMODE%"""
|
|
||||||
"%PYTHON_HOME%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in_stage4" "-o" "%WD%\pkg\win32\installer.iss" "-s" MYAPP_VCDIST -r """%VCREDISTNAME%"""
|
|
||||||
|
|
||||||
|
|
||||||
DEL /s "%WD%\pkg\win32\installer.iss.in_stage*" > nul
|
|
||||||
ECHO Creating windows installer... using INNO tool
|
|
||||||
|
|
||||||
CALL "%INNOTOOL%\ISCC.exe" /q "%WD%\pkg\win32\installer.iss"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
MOVE "%WD%\pkg\win32\Output\Setup.exe" "%TARGETINSTALLER%\%INSTALLERNAME%"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
ECHO "Location - %TARGETINSTALLER%\%INSTALLERNAME%"
|
|
||||||
ECHO Installer generated successfully.
|
|
||||||
|
|
||||||
CD %WD%
|
|
||||||
GOTO:eof
|
|
||||||
|
|
||||||
:SIGN_INSTALLER
|
|
||||||
ECHO Attempting to sign the installer...
|
|
||||||
"%SIGNTOOL%" sign /t http://timestamp.verisign.com/scripts/timstamp.dll "%TARGETINSTALLER%\%INSTALLERNAME%"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 (
|
|
||||||
ECHO
|
|
||||||
ECHO ************************************************************
|
|
||||||
ECHO * Failed to sign the installer
|
|
||||||
ECHO ************************************************************
|
|
||||||
PAUSE
|
|
||||||
)
|
|
||||||
|
|
||||||
CD %WD%
|
|
||||||
GOTO:eof
|
|
||||||
|
|
||||||
:CLEANUP_ENV
|
|
||||||
ECHO Cleaning up private environment...
|
|
||||||
rd "%PGBUILDPATH%\%VIRTUALENV%\Include" /S /Q
|
|
||||||
DEL /s "%PGBUILDPATH%\%VIRTUALENV%\pip-selfcheck.json"
|
|
||||||
|
|
||||||
ECHO Cleaned up private environment successfully.
|
|
||||||
CD %WD%
|
|
||||||
GOTO:eof
|
|
||||||
|
|
||||||
:err_handle_inno
|
|
||||||
ECHO %INNOTOOL% does not exist
|
|
||||||
ECHO Please Install Innotool and SET INNOTOOL enviroment Variable.
|
|
||||||
ECHO SET "INNOTOOL=<PATH>"
|
|
||||||
exit /B 1
|
|
||||||
GOTO EXIT
|
|
||||||
|
|
||||||
:err_handle_visualstudio
|
|
||||||
ECHO %VCDIR% does not exist
|
|
||||||
ECHO Please Install Microsoft Visual studio and SET the VCDIR enviroment Variable.
|
|
||||||
ECHO SET "VCDIR=<PATH>"
|
|
||||||
exit /B 1
|
|
||||||
GOTO EXIT
|
|
||||||
|
|
||||||
:err_handle_visualstudio_dist
|
|
||||||
ECHO %VCREDIST% does not exist
|
|
||||||
ECHO Please Install Microsoft Visual studio and SET the VCDIST enviroment Variable.
|
|
||||||
ECHO SET "VCDIST=<PATH>"
|
|
||||||
exit /B 1
|
|
||||||
GOTO EXIT
|
|
||||||
|
|
||||||
|
|
||||||
:err_handle_python
|
|
||||||
ECHO %PYTHON_HOME% does not exist, or
|
|
||||||
ECHO PYTHON_VERSION is not SET, or
|
|
||||||
ECHO %PYTHON_DLL% does not exist.
|
|
||||||
ECHO Please install Python and SET the PYTHON_HOME enviroment Variable.
|
|
||||||
ECHO SET "PYTHON_VERSION=<VERSION NUMBER>"
|
|
||||||
ECHO SET "PYTHON_HOME=<PATH>"
|
|
||||||
ECHO SET "PYTHON_DLL=<PATH>"
|
|
||||||
exit /B 1
|
|
||||||
GOTO EXIT
|
|
||||||
|
|
||||||
:err_handle_qt
|
|
||||||
ECHO %QTDIR% does not exist.
|
|
||||||
ECHO Please Install QT SDK and SET the QTDIR enviroment variable.
|
|
||||||
ECHO SET "QTDIR=<PATH>"
|
|
||||||
exit /B 1
|
|
||||||
GOTO EXIT
|
|
||||||
|
|
||||||
:err_handle_yarn
|
|
||||||
ECHO %YARNDIR% does not exist.
|
|
||||||
ECHO Please Install YARN and SET the YARNDIR enviroment variable.
|
|
||||||
ECHO SET "YARNDIR=<YARN PATH>"
|
|
||||||
exit /B 1
|
|
||||||
GOTO EXIT
|
|
||||||
|
|
||||||
:err_handle_nodejs
|
|
||||||
ECHO %NODEJSDIR% does not exist.
|
|
||||||
ECHO Please Install NodeJs and SET the NODEJSDIR enviroment variable.
|
|
||||||
ECHO SET "NODEJSDIR=<NODEJS PATH>"
|
|
||||||
exit /B 1
|
|
||||||
GOTO EXIT
|
|
||||||
|
|
||||||
:err_handle_pg
|
|
||||||
ECHO %PGDIR% does not exist.
|
|
||||||
ECHO Please Install Postgres and SET enviroment Variable
|
|
||||||
ECHO SET "PGDIR=<PATH>"
|
|
||||||
exit /B 1
|
|
||||||
GOTO EXIT
|
|
||||||
|
|
||||||
:err_handle_pythonvirtualenv
|
|
||||||
ECHO Python virtualenv is missing @ location - %PYTHON_HOME%\Scripts\virtualenv.exe
|
|
||||||
exit /B 1
|
|
||||||
GOTO EXIT
|
|
||||||
|
|
||||||
:ERR_HANDLER
|
|
||||||
ECHO.
|
|
||||||
ECHO Aborting build!
|
|
||||||
CD %WD%
|
|
||||||
exit /B 1
|
|
||||||
GOTO EXIT
|
|
||||||
|
|
||||||
:USAGE
|
|
||||||
ECHO Invalid command line options....
|
|
||||||
ECHO Usage: "Make.bat <x86 | clean>"
|
|
||||||
ECHO.
|
|
||||||
exit /B 1
|
|
||||||
GOTO EXIT
|
|
||||||
|
|
||||||
:EXIT
|
|
||||||
|
|
241
Make.bat
241
Make.bat
|
@ -7,7 +7,6 @@ SET "PGBUILDPATH=%WD%\win-build"
|
||||||
SET CMDOPTION=""
|
SET CMDOPTION=""
|
||||||
IF "%1" == "clean" SET CMDOPTION="VALID"
|
IF "%1" == "clean" SET CMDOPTION="VALID"
|
||||||
IF "%1" == "x86" SET CMDOPTION="VALID"
|
IF "%1" == "x86" SET CMDOPTION="VALID"
|
||||||
IF "%1" == "amd64" SET CMDOPTION="VALID"
|
|
||||||
|
|
||||||
IF NOT %CMDOPTION%=="VALID" ( GOTO USAGE )
|
IF NOT %CMDOPTION%=="VALID" ( GOTO USAGE )
|
||||||
SET ARCHITECTURE=%1
|
SET ARCHITECTURE=%1
|
||||||
|
@ -59,65 +58,22 @@ REM Main function Ends
|
||||||
GOTO:eof
|
GOTO:eof
|
||||||
|
|
||||||
:SET_PGADMIN4_ENVIRONMENT
|
:SET_PGADMIN4_ENVIRONMENT
|
||||||
REM Check os architecture x86 or amd64
|
IF "%PYTHON_HOME%" == "" SET "PYTHON_HOME=C:\Python27"
|
||||||
SET RegQry=HKLM\Hardware\Description\System\CentralProcessor\0
|
IF "%PYTHON_DLL%" == "" SET "PYTHON_DLL=C:\Windows\SysWOW64\python27.dll"
|
||||||
REG.exe Query %RegQry% > checkOS.txt
|
IF "%QTDIR%" == "" SET "QTDIR=C:\Qt\5.9.1\mingw53_32"
|
||||||
Find /i "x86" < CheckOS.txt > StringCheck.txt
|
IF "%PGDIR%" == "" SET "PGDIR=C:\Program Files (x86)\PostgreSQL\10"
|
||||||
SET OSTYPE=""
|
IF "%INNOTOOL%" == "" SET "INNOTOOL=C:\Program Files (x86)\Inno Setup 5"
|
||||||
IF %ERRORLEVEL% == 0 (
|
IF "%YARNDIR%" == "" SET "YARNDIR=C:\Program Files\Yarn"
|
||||||
SET OSTYPE=x86
|
IF "%NODEJSDIR%" == "" SET "NODEJSDIR=C:\Program Files\nodejs"
|
||||||
) else (
|
IF "%VCDIR%" == "" SET "VCDIR=C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC"
|
||||||
SET OSTYPE=amd64
|
IF "%VCREDIST%" == "" SET "VCREDIST=C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\redist\1033\vcredist_x86.exe"
|
||||||
)
|
IF "%SIGNTOOL%" == "" SET "SIGNTOOL=C:\Program Files\Microsoft SDKs\Windows\v7.1A\Bin\signtool.exe"
|
||||||
DEL CheckOS.txt StringCheck.txt
|
SET "VCREDISTNAME=vcredist_x86.exe"
|
||||||
SET OSVALUE=""
|
|
||||||
IF "%OSTYPE%"=="x86" (
|
|
||||||
IF "%ARCHITECTURE%"=="amd64" (
|
|
||||||
ECHO ARCHITECTURE - %ARCHITECTURE% cannot be run on 32 bit machine
|
|
||||||
GOTO EXIT
|
|
||||||
)
|
|
||||||
SET OSVALUE=%OSTYPE%
|
|
||||||
)
|
|
||||||
|
|
||||||
REM Check IF its is windows 32 bit machine and selected architecture is x86
|
|
||||||
IF %OSVALUE%=="x86" (
|
|
||||||
IF "%PYTHON_HOME%" == "" SET "PYTHON_HOME=C:\Python27"
|
|
||||||
IF "%PYTHON_DLL%" == "" SET "PYTHON_DLL=C:\Windows\System32\python27.dll"
|
|
||||||
IF "%QTDIR%" == "" SET "QTDIR=C:\Qt\5.7\msvc2013"
|
|
||||||
IF "%PGDIR%" == "" SET "PGDIR=C:\Program Files\PostgreSQL\9.6"
|
|
||||||
IF "%INNOTOOL%" == "" SET "INNOTOOL=C:\Program Files\Inno Setup 5"
|
|
||||||
IF "%VCDIR%" == "" SET "VCDIR=C:\Program Files\Microsoft Visual Studio 12.0\VC"
|
|
||||||
SET "VCREDISTNAME=vcredist_x86.exe"
|
|
||||||
)
|
|
||||||
|
|
||||||
REM Check IF its is windows 64 bit machine and selected architecture is x86 or amd64
|
|
||||||
IF "%ARCHITECTURE%"=="x86" (
|
|
||||||
IF "%PYTHON_HOME%" == "" SET "PYTHON_HOME=C:\Python27"
|
|
||||||
IF "%PYTHON_DLL%" == "" SET "PYTHON_DLL=C:\Windows\SysWOW64\python27.dll"
|
|
||||||
IF "%QTDIR%" == "" SET "QTDIR=C:\Qt\5.7\msvc2013"
|
|
||||||
IF "%PGDIR%" == "" SET "PGDIR=C:\Program Files (x86)\PostgreSQL\9.6"
|
|
||||||
IF "%INNOTOOL%" == "" SET "INNOTOOL=C:\Program Files (x86)\Inno Setup 5"
|
|
||||||
IF "%VCDIR%" == "" SET "VCDIR=C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC"
|
|
||||||
IF "%VCREDIST%" == "" SET "VCREDIST=C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\redist\1033\vcredist_x86.exe"
|
|
||||||
SET "VCREDISTNAME=vcredist_x86.exe"
|
|
||||||
)
|
|
||||||
|
|
||||||
IF "%ARCHITECTURE%"=="amd64" (
|
|
||||||
IF "%PYTHON_HOME%" == "" SET "PYTHON_HOME=C:\Python27-x64"
|
|
||||||
IF "%PYTHON_DLL%" == "" SET "PYTHON_DLL=C:\Windows\System32\python27.dll"
|
|
||||||
IF "%QTDIR%" == "" SET "QTDIR=C:\Qt\5.7\msvc2013"
|
|
||||||
IF "%PGDIR%" == "" SET "PGDIR=C:\Program Files\PostgreSQL\9.6"
|
|
||||||
IF "%INNOTOOL%" == "" SET "INNOTOOL=C:\Program Files\Inno Setup 5"
|
|
||||||
IF "%VCDIR%" == "" SET "VCDIR=C:\Program Files\Microsoft Visual Studio 12.0\VC"
|
|
||||||
IF "%VCREDIST%" == "" SET "VCREDIST=C:\Program Files\Microsoft Visual Studio 12.0\VC\redist\1033\vcredist_x64.exe"
|
|
||||||
SET "VCREDISTNAME=vcredist_x64.exe"
|
|
||||||
)
|
|
||||||
GOTO:eof
|
GOTO:eof
|
||||||
|
|
||||||
:VALIDATE_ENVIRONMENT
|
:VALIDATE_ENVIRONMENT
|
||||||
REM SET the variables IF not availalbe in windows environment
|
REM SET the variables IF not available in windows environment
|
||||||
SET "VCVAR=%VCDIR%\vcvarsall.bat"
|
|
||||||
SET "VCNMAKE=%VCDIR%\bin\nmake.exe"
|
|
||||||
SET "QMAKE=%QTDIR%\bin\qmake.exe"
|
SET "QMAKE=%QTDIR%\bin\qmake.exe"
|
||||||
SET "VIRTUALENV=venv"
|
SET "VIRTUALENV=venv"
|
||||||
SET "TARGETINSTALLER=%WD%\dist"
|
SET "TARGETINSTALLER=%WD%\dist"
|
||||||
|
@ -142,19 +98,16 @@ REM Main function Ends
|
||||||
ECHO ****************************************************************
|
ECHO ****************************************************************
|
||||||
ECHO S U M M A R Y
|
ECHO S U M M A R Y
|
||||||
ECHO ****************************************************************
|
ECHO ****************************************************************
|
||||||
ECHO Target mode = %ARCHITECTURE%
|
ECHO Target mode = x86
|
||||||
ECHO INNOTOOL = %INNOTOOL%
|
ECHO INNOTOOL = %INNOTOOL%
|
||||||
ECHO VCDIR = %VCDIR%
|
ECHO VCDIR = %VCDIR%
|
||||||
ECHO VCDIST = %VCREDIST%
|
ECHO VCDIST = %VCREDIST%
|
||||||
ECHO NMAKE = %VCNMAKE%
|
ECHO SIGNTOOL = %SIGNTOOL%
|
||||||
ECHO QTDIR = %QTDIR%
|
ECHO QTDIR = %QTDIR%
|
||||||
ECHO QMAKE = %QMAKE%
|
ECHO QMAKE = %QMAKE%
|
||||||
ECHO QT_VERSION = %QT_VERSION%
|
ECHO QT_VERSION = %QT_VERSION%
|
||||||
IF %QT_VERSION% GEQ 5.5 (
|
ECHO YARNDIR = %YARNDIR%
|
||||||
ECHO BROWSER = QtWebEngine
|
ECHO NODEJSDIR = %NODEJSDIR%
|
||||||
) ELSE (
|
|
||||||
ECHO BROWSER = QtWebKit
|
|
||||||
)
|
|
||||||
ECHO PYTHON_HOME = %PYTHON_HOME%
|
ECHO PYTHON_HOME = %PYTHON_HOME%
|
||||||
ECHO PYTHON_DLL = %PYTHON_DLL%
|
ECHO PYTHON_DLL = %PYTHON_DLL%
|
||||||
ECHO PGDIR = %PGDIR%
|
ECHO PGDIR = %PGDIR%
|
||||||
|
@ -164,35 +117,13 @@ REM Main function Ends
|
||||||
IF NOT EXIST "%INNOTOOL%" GOTO err_handle_inno
|
IF NOT EXIST "%INNOTOOL%" GOTO err_handle_inno
|
||||||
IF NOT EXIST "%VCDIR%" GOTO err_handle_visualstudio
|
IF NOT EXIST "%VCDIR%" GOTO err_handle_visualstudio
|
||||||
IF NOT EXIST "%VCREDIST%" GOTO err_handle_visualstudio_dist
|
IF NOT EXIST "%VCREDIST%" GOTO err_handle_visualstudio_dist
|
||||||
IF NOT EXIST "%VCVAR%" GOTO err_handle_visualstudio
|
|
||||||
IF NOT EXIST "%VCNMAKE%" GOTO err_handle_visualstudio
|
|
||||||
IF NOT EXIST "%QTDIR%" GOTO err_handle_qt
|
IF NOT EXIST "%QTDIR%" GOTO err_handle_qt
|
||||||
IF NOT EXIST "%QMAKE%" GOTO err_handle_qt
|
IF NOT EXIST "%QMAKE%" GOTO err_handle_qt
|
||||||
IF NOT EXIST "%PYTHON_HOME%" GOTO err_handle_python
|
IF NOT EXIST "%PYTHON_HOME%" GOTO err_handle_python
|
||||||
IF NOT EXIST "%PYTHON_DLL%" GOTO err_handle_python
|
IF NOT EXIST "%PYTHON_DLL%" GOTO err_handle_python
|
||||||
IF NOT EXIST "%PGDIR%" GOTO err_handle_pg
|
IF NOT EXIST "%PGDIR%" GOTO err_handle_pg
|
||||||
|
IF NOT EXIST "%YARNDIR%" GOTO err_handle_yarn
|
||||||
REM Check for QT and VC dependences
|
IF NOT EXIST "%NODEJSDIR%" GOTO err_handle_nodejs
|
||||||
FOR /L %%G IN (15,1,19) DO "%VCDIR%\bin\cl.exe" /? 2>&1 | findstr /C:"Version %%G" > nul && SET MSVC_MAJOR_VERSION=%%G
|
|
||||||
|
|
||||||
IF %MSVC_MAJOR_VERSION%==19 SET QT_MSVC_PATH=msvc2015
|
|
||||||
IF %MSVC_MAJOR_VERSION%==18 SET QT_MSVC_PATH=msvc2013
|
|
||||||
IF %MSVC_MAJOR_VERSION%==17 SET QT_MSVC_PATH=msvc2012
|
|
||||||
IF %MSVC_MAJOR_VERSION%==16 SET QT_MSVC_PATH=msvc2010
|
|
||||||
IF %MSVC_MAJOR_VERSION%==15 SET QT_MSVC_PATH=msvc2008
|
|
||||||
|
|
||||||
REM on 64 bit machine if x86 is selected and QTDIR is set to 64 bit is should not allow
|
|
||||||
IF "%OSTYPE%"=="amd64" (
|
|
||||||
IF "%ARCHITECTURE%"=="x86" (
|
|
||||||
echo "%QTDIR%" | findstr /C:"_64" > nul && ( GOTO err_handle_qt_compactissue )
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
IF "%ARCHITECTURE%"=="amd64" (
|
|
||||||
SET QT_MSVC_PATH=%QT_MSVC_PATH%_64
|
|
||||||
)
|
|
||||||
|
|
||||||
IF NOT EXIST "%QTDIR%\..\%QT_MSVC_PATH%" GOTO err_handle_qt_mismatch
|
|
||||||
|
|
||||||
REM get Python version ex. 2.7.1 will get as 27
|
REM get Python version ex. 2.7.1 will get as 27
|
||||||
FOR /f "tokens=1 DELims=." %%G IN ('%PYTHON_HOME%/python.exe -c "import sys; print(sys.version.split(' ')[0])"') DO SET PYTHON_MAJOR=%%G
|
FOR /f "tokens=1 DELims=." %%G IN ('%PYTHON_HOME%/python.exe -c "import sys; print(sys.version.split(' ')[0])"') DO SET PYTHON_MAJOR=%%G
|
||||||
|
@ -201,8 +132,7 @@ REM Main function Ends
|
||||||
|
|
||||||
IF NOT EXIST "%PYTHON_HOME%\Scripts\virtualenv.exe" GOTO err_handle_pythonvirtualenv
|
IF NOT EXIST "%PYTHON_HOME%\Scripts\virtualenv.exe" GOTO err_handle_pythonvirtualenv
|
||||||
|
|
||||||
SET PATH=%PGDIR%;%PGDIR%\bin;%PATH%
|
SET PATH=%PGDIR%;%PGDIR%\bin;%QTDIR%\..\..\Tools\mingw530_32\bin;%NODEJSDIR%;%YARNDIR%\bin;%PATH%;
|
||||||
|
|
||||||
GOTO:eof
|
GOTO:eof
|
||||||
|
|
||||||
:CREATE_VIRTUAL_ENV
|
:CREATE_VIRTUAL_ENV
|
||||||
|
@ -244,6 +174,9 @@ REM Main function Ends
|
||||||
ECHO Bundle all Javascript
|
ECHO Bundle all Javascript
|
||||||
call yarn run bundle
|
call yarn run bundle
|
||||||
|
|
||||||
|
REM Remove any cache
|
||||||
|
RD /Q /S "%WD%\web\pgadmin\static\js\generated\.cache"
|
||||||
|
|
||||||
XCOPY /S /I /E /H /Y "%WD%\web" "%PGBUILDPATH%\web" > nul
|
XCOPY /S /I /E /H /Y "%WD%\web" "%PGBUILDPATH%\web" > nul
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
||||||
|
|
||||||
|
@ -288,17 +221,15 @@ REM Main function Ends
|
||||||
CD "%WD%\runtime"
|
CD "%WD%\runtime"
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
||||||
|
|
||||||
CALL "%VCVAR%" %ARCHITECTURE%
|
CALL "%QMAKE%" "DEFINES+=PGADMIN4_USE_WEBKIT"
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
||||||
|
|
||||||
CALL "%QMAKE%"
|
CALL mingw32-make.exe clean
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
||||||
|
|
||||||
CALL "%VCNMAKE%" clean
|
CALL mingw32-make.exe
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
CALL "%VCNMAKE%"
|
|
||||||
IF ERRORLEVEL 1 GOTO ERR_HANDLER
|
IF ERRORLEVEL 1 GOTO ERR_HANDLER
|
||||||
|
|
||||||
REM Copy binary to Release Folder
|
REM Copy binary to Release Folder
|
||||||
copy "%WD%\runtime\release\pgAdmin4.exe" "%PGBUILDPATH%\runtime"
|
copy "%WD%\runtime\release\pgAdmin4.exe" "%PGBUILDPATH%\runtime"
|
||||||
IF ERRORLEVEL 1 GOTO ERR_HANDLER
|
IF ERRORLEVEL 1 GOTO ERR_HANDLER
|
||||||
|
@ -306,97 +237,24 @@ REM Main function Ends
|
||||||
REM Copy QT dependences
|
REM Copy QT dependences
|
||||||
copy "%QTDIR%\bin\Qt5Core.dll" "%PGBUILDPATH%\runtime"
|
copy "%QTDIR%\bin\Qt5Core.dll" "%PGBUILDPATH%\runtime"
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
||||||
copy "%QTDIR%\bin\Qt5Sql.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5Gui.dll" "%PGBUILDPATH%\runtime"
|
copy "%QTDIR%\bin\Qt5Gui.dll" "%PGBUILDPATH%\runtime"
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
||||||
copy "%QTDIR%\bin\Qt5Qml.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5OpenGL.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5Quick.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5Sensors.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5Widgets.dll" "%PGBUILDPATH%\runtime"
|
copy "%QTDIR%\bin\Qt5Widgets.dll" "%PGBUILDPATH%\runtime"
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
||||||
copy "%QTDIR%\bin\Qt5Network.dll" "%PGBUILDPATH%\runtime"
|
copy "%QTDIR%\bin\Qt5Network.dll" "%PGBUILDPATH%\runtime"
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
||||||
copy "%QTDIR%\bin\Qt5Multimedia.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5WebChannel.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5Positioning.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5PrintSupport.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5MultimediaWidgets.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
|
|
||||||
REM Install the appropriate browser components. We use QtWebEngine with Qt 5.5+
|
|
||||||
IF %QT_VERSION% GEQ 5.7 (
|
|
||||||
copy "%QTDIR%\bin\Qt5QuickWidgets.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
)
|
|
||||||
|
|
||||||
IF %QT_VERSION% GEQ 5.7 (
|
|
||||||
copy "%QTDIR%\resources\icudtl.dat" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\resources\qtwebengine_resources.pak" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\resources\qtwebengine_devtools_resources.pak" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\resources\qtwebengine_resources_100p.pak" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\resources\qtwebengine_resources_200p.pak" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5WebEngine.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5WebEngineCore.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5WebEngineWidgets.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\QtWebEngineProcess.exe" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\opengl32sw.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
) ELSE (
|
|
||||||
IF %QT_VERSION% GEQ 5.5 (
|
|
||||||
copy "%QTDIR%\bin\icudt54.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\icuin54.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\icuuc54.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\icudtl.dat" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\qtwebengine_resources.pak" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\qtwebengine_resources_100p.pak" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\qtwebengine_resources_200p.pak" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5WebEngine.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5WebEngineCore.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5WebEngineWidgets.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\QtWebEngineProcess.exe" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
) ELSE (
|
|
||||||
copy "%QTDIR%\bin\Qt5WebKit.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
copy "%QTDIR%\bin\Qt5WebKitWidgets.dll" "%PGBUILDPATH%\runtime"
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
copy "%QTDIR%\bin\libgcc_s_dw2-1.dll" "%PGBUILDPATH%\runtime"
|
||||||
|
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
||||||
|
copy "%QTDIR%\bin\libstdc++-6.dll" "%PGBUILDPATH%\runtime"
|
||||||
|
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
||||||
|
copy "%QTDIR%\bin\libwinpthread-1.dll" "%PGBUILDPATH%\runtime"
|
||||||
|
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
||||||
MKDIR "%PGBUILDPATH%\runtime\platforms"
|
MKDIR "%PGBUILDPATH%\runtime\platforms"
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
||||||
|
|
||||||
copy "%QTDIR%\plugins\platforms\qwindows.dll" "%PGBUILDPATH%\runtime\platforms" > nul
|
copy "%QTDIR%\plugins\platforms\qwindows.dll" "%PGBUILDPATH%\runtime\platforms" > nul
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
||||||
|
|
||||||
ECHO [Paths] > "%PGBUILDPATH%\runtime\qt.conf"
|
ECHO [Paths] > "%PGBUILDPATH%\runtime\qt.conf"
|
||||||
ECHO Plugins=plugins >> "%PGBUILDPATH%\runtime\qt.conf"
|
ECHO Plugins=plugins >> "%PGBUILDPATH%\runtime\qt.conf"
|
||||||
|
|
||||||
|
@ -494,13 +352,13 @@ REM Main function Ends
|
||||||
|
|
||||||
:SIGN_INSTALLER
|
:SIGN_INSTALLER
|
||||||
ECHO Attempting to sign the installer...
|
ECHO Attempting to sign the installer...
|
||||||
signtool sign /t http://timestamp.verisign.com/scripts/timstamp.dll "%TARGETINSTALLER%\%INSTALLERNAME%"
|
"%SIGNTOOL%" sign /t http://timestamp.verisign.com/scripts/timstamp.dll "%TARGETINSTALLER%\%INSTALLERNAME%"
|
||||||
IF %ERRORLEVEL% NEQ 0 (
|
IF %ERRORLEVEL% NEQ 0 (
|
||||||
ECHO
|
ECHO
|
||||||
ECHO ************************************************************
|
ECHO ************************************************************
|
||||||
ECHO * Failed to sign the installer
|
ECHO * Failed to sign the installer
|
||||||
ECHO ************************************************************
|
ECHO ************************************************************
|
||||||
SLEEP 5
|
PAUSE
|
||||||
)
|
)
|
||||||
|
|
||||||
CD %WD%
|
CD %WD%
|
||||||
|
@ -523,20 +381,16 @@ REM Main function Ends
|
||||||
GOTO EXIT
|
GOTO EXIT
|
||||||
|
|
||||||
:err_handle_visualstudio
|
:err_handle_visualstudio
|
||||||
ECHO %VCDIR% does not exist, or
|
ECHO %VCDIR% does not exist
|
||||||
ECHO %VCVAR% does not exist, or
|
|
||||||
ECHO %VCNMAKE% does not exist.
|
|
||||||
ECHO Please Install Microsoft Visual studio and SET the VCDIR enviroment Variable.
|
ECHO Please Install Microsoft Visual studio and SET the VCDIR enviroment Variable.
|
||||||
ECHO SET "VCDIR%=<PATH>"
|
ECHO SET "VCDIR=<PATH>"
|
||||||
ECHO SET "VCVAR%=<PATH>"
|
|
||||||
ECHO SET "VCNMAKE%=<PATH>"
|
|
||||||
exit /B 1
|
exit /B 1
|
||||||
GOTO EXIT
|
GOTO EXIT
|
||||||
|
|
||||||
:err_handle_visualstudio_dist
|
:err_handle_visualstudio_dist
|
||||||
ECHO %VCREDIST% does not exist
|
ECHO %VCREDIST% does not exist
|
||||||
ECHO Please Install Microsoft Visual studio and SET the VCDIST enviroment Variable.
|
ECHO Please Install Microsoft Visual studio and SET the VCDIST enviroment Variable.
|
||||||
ECHO SET "VCDIST%=<PATH>"
|
ECHO SET "VCDIST=<PATH>"
|
||||||
exit /B 1
|
exit /B 1
|
||||||
GOTO EXIT
|
GOTO EXIT
|
||||||
|
|
||||||
|
@ -559,18 +413,17 @@ REM Main function Ends
|
||||||
exit /B 1
|
exit /B 1
|
||||||
GOTO EXIT
|
GOTO EXIT
|
||||||
|
|
||||||
:err_handle_qt_mismatch
|
:err_handle_yarn
|
||||||
ECHO %QTDIR%\..\%QT_MSVC_PATH%" does not match with your current Visual Studio, version %QT_MSVC_PATH%
|
ECHO %YARNDIR% does not exist.
|
||||||
ECHO Your current QT installation willraise a linking error with an MSVC version mismatch.
|
ECHO Please Install YARN and SET the YARNDIR enviroment variable.
|
||||||
ECHO Please use a valid QT installation with a folder %QT_MSVC_PATH%. You can use the Qt Maintenance
|
ECHO SET "YARNDIR=<YARN PATH>"
|
||||||
ECHO Tool to add or remove compiler kits.
|
|
||||||
exit /B 1
|
exit /B 1
|
||||||
GOTO EXIT
|
GOTO EXIT
|
||||||
|
|
||||||
:err_handle_qt_compactissue
|
:err_handle_nodejs
|
||||||
ECHO %QTDIR%" does support the current architecture selected %ARCHITECTURE%
|
ECHO %NODEJSDIR% does not exist.
|
||||||
ECHO Please use a valid QT installation with a folder %QT_MSVC_PATH%. You can use the Qt Maintenance
|
ECHO Please Install NodeJs and SET the NODEJSDIR enviroment variable.
|
||||||
ECHO Tool to add or remove compiler kits.
|
ECHO SET "NODEJSDIR=<NODEJS PATH>"
|
||||||
exit /B 1
|
exit /B 1
|
||||||
GOTO EXIT
|
GOTO EXIT
|
||||||
|
|
||||||
|
@ -595,7 +448,7 @@ REM Main function Ends
|
||||||
|
|
||||||
:USAGE
|
:USAGE
|
||||||
ECHO Invalid command line options....
|
ECHO Invalid command line options....
|
||||||
ECHO Usage: "Make.bat <x86 | amd64 | clean>"
|
ECHO Usage: "Make.bat <x86 | clean>"
|
||||||
ECHO.
|
ECHO.
|
||||||
exit /B 1
|
exit /B 1
|
||||||
GOTO EXIT
|
GOTO EXIT
|
||||||
|
|
3
Makefile
3
Makefile
|
@ -19,9 +19,6 @@ all: docs pip src
|
||||||
appbundle: docs
|
appbundle: docs
|
||||||
./pkg/mac/build.sh
|
./pkg/mac/build.sh
|
||||||
|
|
||||||
appbundle-webkit: docs
|
|
||||||
PGADMIN4_USE_WEBKIT=1 ./pkg/mac/build.sh
|
|
||||||
|
|
||||||
install-node:
|
install-node:
|
||||||
cd web && yarn install
|
cd web && yarn install
|
||||||
|
|
||||||
|
|
18
README
18
README
|
@ -18,18 +18,16 @@ utilised.
|
||||||
Although developed using web technologies, pgAdmin 4 can be deployed either on
|
Although developed using web technologies, pgAdmin 4 can be deployed either on
|
||||||
a web server using a browser, or standalone on a workstation. The runtime/
|
a web server using a browser, or standalone on a workstation. The runtime/
|
||||||
subdirectory contains a QT based runtime application intended to allow this -
|
subdirectory contains a QT based runtime application intended to allow this -
|
||||||
it is essentially a browser and Python interpreter in one package which is
|
it is essentially a Python application server that runs in the system tray
|
||||||
capable of hosting the Python application and presenting it to the user as a
|
and allows the user to connect to the application using their web browser.
|
||||||
desktop application.
|
|
||||||
|
|
||||||
Building the Runtime
|
Building the Runtime
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
To build the runtime, the following packages must be installed:
|
To build the runtime, the following packages must be installed:
|
||||||
|
|
||||||
- QT 4.6 or above, up to 5.5 (older versions may work, but haven't been tested,
|
- QT 4.6 or above
|
||||||
newer versions are not yet supported as Qt Webkit has been deprecated).
|
- Python 2.6, 2.7 or 3.3+ (2.7 only on Windows)
|
||||||
- Python 2.6, 2.7 or 3.3+
|
|
||||||
|
|
||||||
Assuming both qmake and python-config are in the path:
|
Assuming both qmake and python-config are in the path:
|
||||||
|
|
||||||
|
@ -230,8 +228,8 @@ a number of known locations for the pgAdmin4.py file needed to run pgAdmin
|
||||||
an alternate path if needed.
|
an alternate path if needed.
|
||||||
|
|
||||||
If either a working environment or pgAdmin4.py cannot be found at startup, the
|
If either a working environment or pgAdmin4.py cannot be found at startup, the
|
||||||
runtime will prompt for the locations. Alternatively, you can use Alt+Shift+P
|
runtime will prompt for the locations. Alternatively, you can click the try
|
||||||
to open the path configuration dialogue.
|
icon and select the Configuration option to open the configuration dialogue.
|
||||||
|
|
||||||
On a Linux/Mac system, the Python Path will typically consist of a single path
|
On a Linux/Mac system, the Python Path will typically consist of a single path
|
||||||
to the virtual environment's site-packages directory, e.g.
|
to the virtual environment's site-packages directory, e.g.
|
||||||
|
@ -308,11 +306,11 @@ Qt 5.5.1, Python 2.7 and Visual Studio 2013. The examples below are for a
|
||||||
similar 32 bit system:
|
similar 32 bit system:
|
||||||
|
|
||||||
INNOTOOL=C:\Program Files\Inno Setup 5
|
INNOTOOL=C:\Program Files\Inno Setup 5
|
||||||
PGDIR=C:\Program Files\PostgreSQL\9.6
|
PGDIR=C:\Program Files\PostgreSQL\10
|
||||||
PYTHON_DLL=C:\Windows\System32\Python27.dll
|
PYTHON_DLL=C:\Windows\System32\Python27.dll
|
||||||
PYTHON_HOME=C:\Python27
|
PYTHON_HOME=C:\Python27
|
||||||
PYTHON_VERSION=27
|
PYTHON_VERSION=27
|
||||||
QTDIR=C:\Qt\5.5\msvc2013
|
QTDIR=C:\Qt\5.9\msvc2013
|
||||||
VCDIR=C:\Program Files\Microsoft Visual Studio 12.0\VC
|
VCDIR=C:\Program Files\Microsoft Visual Studio 12.0\VC
|
||||||
|
|
||||||
To build the installer:
|
To build the installer:
|
||||||
|
|
|
@ -5,8 +5,16 @@ Desktop Deployment
|
||||||
******************
|
******************
|
||||||
|
|
||||||
pgAdmin may be deployed as a desktop application by configuring the application
|
pgAdmin may be deployed as a desktop application by configuring the application
|
||||||
to run in desktop mode and then utilising the desktop runtime to host and
|
to run in desktop mode and then utilising the desktop runtime to host the
|
||||||
display the program on a supported Windows, Mac OS X or Linux installation.
|
program on a supported Windows, Mac OS X or Linux installation.
|
||||||
|
|
||||||
|
The desktop runtime is a system-tray application that when launched, runs the
|
||||||
|
pgAdmin server and launches a web browser to render the user interface. If
|
||||||
|
additional instances of pgAdmin are launched, a new browser tab will be opened
|
||||||
|
and be served by the existing instance of the server in order to minimise system
|
||||||
|
resource utilisation. Clicking the icon in the system tray will present a menu
|
||||||
|
offering options to open a new pgAdmin window, configure the runtime, view the
|
||||||
|
server log and shutdown the server.
|
||||||
|
|
||||||
.. note:: Pre-compiled and configured installation packages are available for
|
.. note:: Pre-compiled and configured installation packages are available for
|
||||||
a number of platforms. These packages should be used by end-users whereever
|
a number of platforms. These packages should be used by end-users whereever
|
||||||
|
|
|
@ -28,11 +28,11 @@ Contents:
|
||||||
change_user_password
|
change_user_password
|
||||||
|
|
||||||
In a Desktop Deployment, the pgAdmin application is configured to use the
|
In a Desktop Deployment, the pgAdmin application is configured to use the
|
||||||
desktop runtime environment to host and display the program on a supported
|
desktop runtime environment to host the program on a supported platform.
|
||||||
platform. Typically, users will install a pre-built package to run pgAdmin
|
Typically, users will install a pre-built package to run pgAdmin in desktop
|
||||||
in desktop mode, but a manual desktop deployment can be installed and though
|
mode, but a manual desktop deployment can be installed and though it is more
|
||||||
it is more difficult to setup, it may be useful for developers interested
|
difficult to setup, it may be useful for developers interested in understanding
|
||||||
in understanding how pgAdmin works.
|
how pgAdmin works.
|
||||||
|
|
||||||
Contents:
|
Contents:
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,11 @@ pgAdmin 4
|
||||||
:align: right
|
:align: right
|
||||||
:alt: pgAdmin Logo
|
:alt: pgAdmin Logo
|
||||||
|
|
||||||
Welcome to pgAdmin 4. pgAdmin is the leading Open Source management tool for Postgres, the world's most advanced Open Source database. pgAdmin 4 is designed to meet the needs of both novice and experienced Postgres users alike, providing a powerful graphical interface that simplifies the creation, maintenance and use of database objects.
|
Welcome to pgAdmin 4. pgAdmin is the leading Open Source management tool for
|
||||||
|
Postgres, the world's most advanced Open Source database. pgAdmin 4 is designed
|
||||||
|
to meet the needs of both novice and experienced Postgres users alike, providing
|
||||||
|
a powerful graphical interface that simplifies the creation, maintenance and use
|
||||||
|
of database objects.
|
||||||
|
|
||||||
Contents:
|
Contents:
|
||||||
|
|
||||||
|
|
|
@ -2,31 +2,9 @@
|
||||||
Keyboard Shortcuts
|
Keyboard Shortcuts
|
||||||
******************
|
******************
|
||||||
|
|
||||||
Keyboard shortcuts are provided in pgAdmin to allow easy access to specific functions.
|
Keyboard shortcuts are provided in pgAdmin to allow easy access to specific
|
||||||
The shortcuts can be configured through File > Preferences dialogue as per the need.
|
functions. Alternate shortcuts can be configured through File > Preferences if
|
||||||
|
desired.
|
||||||
|
|
||||||
**Desktop Runtime**
|
|
||||||
|
|
||||||
When running in the Desktop Runtime, the following keyboard shortcuts are available:
|
|
||||||
|
|
||||||
+--------------------------+----------------+---------------------------------------+
|
|
||||||
| Shortcut (Windows/Linux) | Shortcut (Mac) | Function |
|
|
||||||
+==========================+================+=======================================+
|
|
||||||
| Alt+Shift+A | Option+Shift+A | Display the runtime's About box |
|
|
||||||
+--------------------------+----------------+---------------------------------------+
|
|
||||||
| Alt+Shift+P | Option+Shift+U | Open the runtime preferences dialogue |
|
|
||||||
+--------------------------+----------------+---------------------------------------+
|
|
||||||
| Alt+Shift+U | Option+Shift+U | Open an arbitrary URL |
|
|
||||||
+--------------------------+----------------+---------------------------------------+
|
|
||||||
| Ctrl+Q | Cmd+Q | Quit |
|
|
||||||
+--------------------------+----------------+---------------------------------------+
|
|
||||||
| Ctrl+Plus | Cmd+Plus | Zoom in |
|
|
||||||
+--------------------------+----------------+---------------------------------------+
|
|
||||||
| Ctrl+Minus | Cmd+Minus | Zoom out |
|
|
||||||
+--------------------------+----------------+---------------------------------------+
|
|
||||||
| Ctrl+0 | Cmd+0 | Reset the zoom level |
|
|
||||||
+--------------------------+----------------+---------------------------------------+
|
|
||||||
|
|
||||||
**Main Browser Window**
|
**Main Browser Window**
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,9 @@ pushd web
|
||||||
yarn install
|
yarn install
|
||||||
yarn run bundle
|
yarn run bundle
|
||||||
|
|
||||||
for FILE in `ls -d pgAdmin/static/js/generated/*`
|
rm -rf pgadmin/static/js/generated/.cache
|
||||||
|
|
||||||
|
for FILE in `ls -d pgadmin/static/js/generated/*`
|
||||||
do
|
do
|
||||||
echo Adding $FILE
|
echo Adding $FILE
|
||||||
tar cf - $FILE | (cd ../docker-build/web; tar xf -)
|
tar cf - $FILE | (cd ../docker-build/web; tar xf -)
|
||||||
|
|
|
@ -137,11 +137,7 @@ _build_runtime() {
|
||||||
_create_python_virtualenv || exit 1
|
_create_python_virtualenv || exit 1
|
||||||
cd $SOURCEDIR/runtime
|
cd $SOURCEDIR/runtime
|
||||||
make clean
|
make clean
|
||||||
if [ "$PGADMIN4_USE_WEBKIT" == "1" ]; then
|
$QMAKE || { echo qmake failed; exit 1; }
|
||||||
$QMAKE DEFINES+=PGADMIN4_USE_WEBKIT || { echo qmake failed; exit 1; }
|
|
||||||
else
|
|
||||||
$QMAKE || { echo qmake failed; exit 1; }
|
|
||||||
fi
|
|
||||||
make || { echo make failed; exit 1; }
|
make || { echo make failed; exit 1; }
|
||||||
cp -r pgAdmin4.app "$BUILDROOT/$APP_BUNDLE_NAME"
|
cp -r pgAdmin4.app "$BUILDROOT/$APP_BUNDLE_NAME"
|
||||||
}
|
}
|
||||||
|
@ -187,7 +183,7 @@ _complete_bundle() {
|
||||||
cp -r $SOURCEDIR/web "$BUILDROOT/$APP_BUNDLE_NAME/Contents/Resources/" || exit 1
|
cp -r $SOURCEDIR/web "$BUILDROOT/$APP_BUNDLE_NAME/Contents/Resources/" || exit 1
|
||||||
cd "$BUILDROOT/$APP_BUNDLE_NAME/Contents/Resources/web"
|
cd "$BUILDROOT/$APP_BUNDLE_NAME/Contents/Resources/web"
|
||||||
rm -f pgadmin4.db config_local.*
|
rm -f pgadmin4.db config_local.*
|
||||||
rm -rf karma.conf.js package.json node_modules/ regression/ tools/
|
rm -rf karma.conf.js package.json node_modules/ regression/ tools/ pgadmin/static/js/generated/.cache
|
||||||
find . -name "tests" -type d -exec rm -rf "{}" \;
|
find . -name "tests" -type d -exec rm -rf "{}" \;
|
||||||
find . -name "feature_tests" -type d -exec rm -rf "{}" \;
|
find . -name "feature_tests" -type d -exec rm -rf "{}" \;
|
||||||
find . -name ".DS_Store" -exec rm -f "{}" \;
|
find . -name ".DS_Store" -exec rm -f "{}" \;
|
||||||
|
|
|
@ -86,13 +86,6 @@ function CompleteSingleApp() {
|
||||||
test -d $lib_loc || mkdir -p $lib_loc
|
test -d $lib_loc || mkdir -p $lib_loc
|
||||||
echo Copying -R $QTDIR/lib/$qtfw_path/$lib_bn to $lib_loc/
|
echo Copying -R $QTDIR/lib/$qtfw_path/$lib_bn to $lib_loc/
|
||||||
cp $QTDIR/lib/$qtfw_path/$lib_bn $lib_loc/
|
cp $QTDIR/lib/$qtfw_path/$lib_bn $lib_loc/
|
||||||
|
|
||||||
if [ "$lib_bn" = "QtWebEngineCore" ]; then
|
|
||||||
# QtWebEngineCore has some required resources
|
|
||||||
cp -R $QTDIR/lib/$qtfw_path/Resources $lib_loc/
|
|
||||||
cp -R $QTDIR/lib/$qtfw_path/Helpers $lib_loc/
|
|
||||||
ln -s Versions/Current/Helpers "$bundle/Contents/Frameworks/QtWebEngineCore.Framework/Helpers"
|
|
||||||
fi
|
|
||||||
elif echo $lib | grep Python > /dev/null ; then
|
elif echo $lib | grep Python > /dev/null ; then
|
||||||
test -d $lib_loc || mkdir -p $lib_loc
|
test -d $lib_loc || mkdir -p $lib_loc
|
||||||
cp -R "$lib" "$lib_loc/$lib_bn"
|
cp -R "$lib" "$lib_loc/$lib_bn"
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,170 +0,0 @@
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// pgAdmin 4 - PostgreSQL Tools
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013 - 2018, 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 "pgAdmin4.h"
|
|
||||||
#include "TabWindow.h"
|
|
||||||
#include "WebViewWindow.h"
|
|
||||||
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
#include <QtWidgets>
|
|
||||||
|
|
||||||
#ifdef PGADMIN4_USE_WEBENGINE
|
|
||||||
#include <QtWebEngineWidgets>
|
|
||||||
#else
|
|
||||||
#include <QtWebKitWidgets>
|
|
||||||
#include <QNetworkCookieJar>
|
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#include <QMainWindow>
|
|
||||||
|
|
||||||
#ifdef PGADMIN4_USE_WEBENGINE
|
|
||||||
#include <QtWebEngineView>
|
|
||||||
#else
|
|
||||||
#include <QWebView>
|
|
||||||
#include <QNetworkCookieJar>
|
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PGADMIN4_USE_WEBENGINE
|
|
||||||
#include <QWebEngineHistory>
|
|
||||||
#else
|
|
||||||
#include <QWebHistory>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
|
||||||
class QAction;
|
|
||||||
class QMenu;
|
|
||||||
QT_END_NAMESPACE
|
|
||||||
|
|
||||||
class BrowserWindow : public QMainWindow
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
BrowserWindow(QString url);
|
|
||||||
~BrowserWindow();
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
void setRegistryMessage(const QString &msg);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void closeEvent(QCloseEvent *event);
|
|
||||||
|
|
||||||
protected slots:
|
|
||||||
void urlLinkClicked(const QUrl &);
|
|
||||||
void tabTitleChanged(const QString &);
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#ifdef PGADMIN4_USE_WEBENGINE
|
|
||||||
void onMacCut();
|
|
||||||
void onMacCopy();
|
|
||||||
void onMacPaste();
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void openUrl();
|
|
||||||
void preferences();
|
|
||||||
void about();
|
|
||||||
void setZoomLevel(int zoomFlag);
|
|
||||||
#ifdef PGADMIN4_USE_WEBENGINE
|
|
||||||
void downloadRequested(QWebEngineDownloadItem *download);
|
|
||||||
#endif
|
|
||||||
void urlLoadingFinished(bool);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void download(const QNetworkRequest &request);
|
|
||||||
void unsupportedContent(QNetworkReply * reply);
|
|
||||||
void downloadFinished();
|
|
||||||
void downloadFileProgress(qint64 , qint64 );
|
|
||||||
void progressCanceled();
|
|
||||||
void current_dir_path(const QString &dir);
|
|
||||||
void replyReady();
|
|
||||||
#ifdef PGADMIN4_USE_WEBENGINE
|
|
||||||
void createNewTabWindow(QWebEnginePage * &);
|
|
||||||
void downloadEngineFileProgress(qint64 , qint64 );
|
|
||||||
void downloadEngineFinished();
|
|
||||||
#else
|
|
||||||
void createNewTabWindowKit(QWebPage * &);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString m_appServerUrl;
|
|
||||||
WebViewWindow *m_mainWebView;
|
|
||||||
|
|
||||||
QShortcut *openUrlShortcut;
|
|
||||||
QShortcut *preferencesShortcut;
|
|
||||||
QShortcut *exitShortcut;
|
|
||||||
QShortcut *aboutShortcut;
|
|
||||||
QShortcut *zoomInShortcut;
|
|
||||||
QShortcut *zoomOutShortcut;
|
|
||||||
QShortcut *zoomResetShortcut;
|
|
||||||
QSignalMapper *signalMapper;
|
|
||||||
|
|
||||||
QGridLayout *m_tabGridLayout;
|
|
||||||
QGridLayout *m_mainGridLayout;
|
|
||||||
DockTabWidget *m_tabWidget;
|
|
||||||
QWidget *m_pgAdminMainTab;
|
|
||||||
|
|
||||||
QWidget *m_addNewTab;
|
|
||||||
QGridLayout *m_addNewGridLayout;
|
|
||||||
WebViewWindow *m_addNewWebView;
|
|
||||||
QHBoxLayout *m_horizontalLayout;
|
|
||||||
|
|
||||||
QWidget *m_widget;
|
|
||||||
QToolButton *m_toolBtnBack;
|
|
||||||
QToolButton *m_toolBtnForward;
|
|
||||||
QToolButton *m_toolBtnClose;
|
|
||||||
|
|
||||||
QString m_downloadFilename;
|
|
||||||
int m_downloadStarted;
|
|
||||||
int m_downloadCancelled;
|
|
||||||
QFile *m_file;
|
|
||||||
QProgressDialog *m_progressDialog;
|
|
||||||
QString m_defaultFilename;
|
|
||||||
QString m_last_open_folder_path;
|
|
||||||
QString m_dir;
|
|
||||||
QNetworkReply *m_reply;
|
|
||||||
bool is_readyReadSignaled;
|
|
||||||
qint64 m_readBytes;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
QString m_regMessage;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PGADMIN4_USE_WEBENGINE
|
|
||||||
QWebEngineDownloadItem *m_download;
|
|
||||||
#else
|
|
||||||
QNetworkCookieJar *m_cookieJar;
|
|
||||||
QNetworkAccessManager *m_netAccessMan;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void createActions();
|
|
||||||
void pause(int seconds = 1);
|
|
||||||
int findURLTab(const QUrl &name);
|
|
||||||
void enableDisableToolButtons(WebViewWindow *webViewPtr);
|
|
||||||
#ifdef _WIN32
|
|
||||||
QString getRegistryMessage();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#ifdef PGADMIN4_USE_WEBENGINE
|
|
||||||
void triggerWebViewWindowEvents(QWebEnginePage::WebAction action);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // BROWSERWINDOW_H
|
|
|
@ -1,37 +0,0 @@
|
||||||
<?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>
|
|
|
@ -34,6 +34,11 @@ void ConfigWindow::on_buttonBox_rejected()
|
||||||
this->close();
|
this->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString ConfigWindow::getBrowserCommand()
|
||||||
|
{
|
||||||
|
return ui->browserCommandLineEdit->text();
|
||||||
|
}
|
||||||
|
|
||||||
QString ConfigWindow::getPythonPath()
|
QString ConfigWindow::getPythonPath()
|
||||||
{
|
{
|
||||||
return ui->pythonPathLineEdit->text();
|
return ui->pythonPathLineEdit->text();
|
||||||
|
@ -45,6 +50,11 @@ QString ConfigWindow::getApplicationPath()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ConfigWindow::setBrowserCommand(QString command)
|
||||||
|
{
|
||||||
|
ui->browserCommandLineEdit->setText(command);
|
||||||
|
}
|
||||||
|
|
||||||
void ConfigWindow::setPythonPath(QString path)
|
void ConfigWindow::setPythonPath(QString path)
|
||||||
{
|
{
|
||||||
ui->pythonPathLineEdit->setText(path);
|
ui->pythonPathLineEdit->setText(path);
|
||||||
|
|
|
@ -26,9 +26,11 @@ public:
|
||||||
explicit ConfigWindow(QWidget *parent = 0);
|
explicit ConfigWindow(QWidget *parent = 0);
|
||||||
~ConfigWindow();
|
~ConfigWindow();
|
||||||
|
|
||||||
|
QString getBrowserCommand();
|
||||||
QString getPythonPath();
|
QString getPythonPath();
|
||||||
QString getApplicationPath();
|
QString getApplicationPath();
|
||||||
|
|
||||||
|
void setBrowserCommand(QString command);
|
||||||
void setPythonPath(QString path);
|
void setPythonPath(QString path);
|
||||||
void setApplicationPath(QString path);
|
void setApplicationPath(QString path);
|
||||||
|
|
||||||
|
@ -38,7 +40,6 @@ private slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::ConfigWindow *ui;
|
Ui::ConfigWindow *ui;
|
||||||
QString m_pythonpath, m_applicationpath;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CONFIGWINDOW_H
|
#endif // CONFIGWINDOW_H
|
||||||
|
|
|
@ -6,49 +6,211 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>608</width>
|
<width>625</width>
|
||||||
<height>118</height>
|
<height>300</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>625</width>
|
||||||
|
<height>300</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Dialog</string>
|
<string>Dialog</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QFormLayout" name="formLayout">
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
<property name="sizeConstraint">
|
<property name="currentIndex">
|
||||||
<enum>QLayout::SetDefaultConstraint</enum>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="fieldGrowthPolicy">
|
<widget class="QWidget" name="tab">
|
||||||
<enum>QFormLayout::ExpandingFieldsGrow</enum>
|
<attribute name="title">
|
||||||
</property>
|
<string>Runtime</string>
|
||||||
<item row="0" column="0">
|
</attribute>
|
||||||
<widget class="QLabel" name="pythonPathLabel">
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
<property name="text">
|
<item>
|
||||||
<string>Python Path</string>
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
</property>
|
<property name="sizeConstraint">
|
||||||
</widget>
|
<enum>QLayout::SetMaximumSize</enum>
|
||||||
</item>
|
</property>
|
||||||
<item row="0" column="1">
|
<item>
|
||||||
<widget class="QLineEdit" name="pythonPathLineEdit"/>
|
<widget class="QLabel" name="label_3">
|
||||||
</item>
|
<property name="sizePolicy">
|
||||||
<item row="1" column="0">
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
<widget class="QLabel" name="applicationPathLabel">
|
<horstretch>0</horstretch>
|
||||||
<property name="text">
|
<verstretch>0</verstretch>
|
||||||
<string>Application Path</string>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="maximumSize">
|
||||||
</item>
|
<size>
|
||||||
<item row="1" column="1">
|
<width>589</width>
|
||||||
<widget class="QLineEdit" name="applicationPathLineEdit"/>
|
<height>16777215</height>
|
||||||
</item>
|
</size>
|
||||||
</layout>
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Enter a command line to be used to start the browser. If blank, the system default browser will be used. %URL% will be replaced with the appropriate URL when executing the browser.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_4">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Fixed</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>10</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetMaximumSize</enum>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="pythonPathLabel_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Browser Command</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="browserCommandLineEdit"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tab_2">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Python</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>The options below are intended for expert users only, and may not behave as expected as they modify fixed search paths and are not alternate values. Modify with care!</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Fixed</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>10</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Enter the path to the directory containing pgAdmin.py if desired.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="pythonPathLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Python Path</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="pythonPathLineEdit"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Enter a PYTHONPATH if desired. Path elements should be semi-colon delimited.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="applicationPathLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Application Path</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLineEdit" name="applicationPathLineEdit"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
|
|
@ -29,5 +29,7 @@
|
||||||
<string>org.pgadmin.@EXECUTABLE@</string>
|
<string>org.pgadmin.@EXECUTABLE@</string>
|
||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
<string>NSApplication</string>
|
<string>NSApplication</string>
|
||||||
|
<key>LSUIElement</key>
|
||||||
|
<string>1</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// pgAdmin 4 - PostgreSQL Tools
|
||||||
|
//
|
||||||
|
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||||
|
// This software is released under the PostgreSQL Licence
|
||||||
|
//
|
||||||
|
// LogWindow.cpp - Log viewer window
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "LogWindow.h"
|
||||||
|
#include "ui_LogWindow.h"
|
||||||
|
|
||||||
|
#include <QTime>
|
||||||
|
|
||||||
|
|
||||||
|
LogWindow::LogWindow(QWidget *parent, QString logFile) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::LogWindow),
|
||||||
|
m_logFile(logFile)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LogWindow::~LogWindow()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LogWindow::reload()
|
||||||
|
{
|
||||||
|
this->ReadLog();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Read the logfile
|
||||||
|
void LogWindow::ReadLog()
|
||||||
|
{
|
||||||
|
FILE *log;
|
||||||
|
char *buffer;
|
||||||
|
long len = 0;
|
||||||
|
int i, lines = 0;
|
||||||
|
|
||||||
|
// Look busy!
|
||||||
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||||
|
ui->lblStatus->setText(tr("Loading logfile..."));
|
||||||
|
this->setDisabled(true);
|
||||||
|
QCoreApplication::processEvents( QEventLoop::AllEvents, 100 );
|
||||||
|
|
||||||
|
ui->textLog->clear();
|
||||||
|
|
||||||
|
// Attempt to open the file
|
||||||
|
log = fopen(m_logFile.toUtf8().data(), "r");
|
||||||
|
if (log == NULL)
|
||||||
|
{
|
||||||
|
ui->textLog->setPlainText(QString(tr("The log file (%1) could not be opened.")).arg(m_logFile));
|
||||||
|
this->setDisabled(false);
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the file size, and read the data
|
||||||
|
fseek(log, 0, SEEK_END);
|
||||||
|
len = ftell(log);
|
||||||
|
rewind(log);
|
||||||
|
buffer = (char *)malloc((len + 1) * sizeof(char));
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
if (fread(buffer + i, 1, 1, log) > 0)
|
||||||
|
{
|
||||||
|
if (buffer[i] == '\n')
|
||||||
|
lines++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[i] = 0;
|
||||||
|
|
||||||
|
fclose(log);
|
||||||
|
ui->textLog->setPlainText(buffer);
|
||||||
|
|
||||||
|
// And... relax
|
||||||
|
ui->lblStatus->setText(QString(tr("Loaded logfile (%1 lines).")).arg(lines));
|
||||||
|
this->setDisabled(false);
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// pgAdmin 4 - PostgreSQL Tools
|
||||||
|
//
|
||||||
|
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||||
|
// This software is released under the PostgreSQL Licence
|
||||||
|
//
|
||||||
|
// LogWindow.h - Log viewer window
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef LOGWINDOW_H
|
||||||
|
#define LOGWINDOW_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class LogWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
class LogWindow : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit LogWindow(QWidget *parent = 0, QString logFile = "");
|
||||||
|
~LogWindow();
|
||||||
|
|
||||||
|
void ReadLog();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void reload();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::LogWindow *ui;
|
||||||
|
|
||||||
|
QString m_logFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // LOGWINDOW_H
|
|
@ -0,0 +1,106 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>LogWindow</class>
|
||||||
|
<widget class="QDialog" name="LogWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>800</width>
|
||||||
|
<height>500</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Dialog</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPlainTextEdit" name="textLog">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Courier</family>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="plainText">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<property name="centerOnScroll">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btnReload">
|
||||||
|
<property name="text">
|
||||||
|
<string>Reload</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="lblStatus">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btnClose">
|
||||||
|
<property name="text">
|
||||||
|
<string>Close</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>btnReload</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>LogWindow</receiver>
|
||||||
|
<slot>reload()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>53</x>
|
||||||
|
<y>471</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>399</x>
|
||||||
|
<y>249</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>btnClose</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>LogWindow</receiver>
|
||||||
|
<slot>close()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>731</x>
|
||||||
|
<y>471</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>399</x>
|
||||||
|
<y>249</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
<slots>
|
||||||
|
<slot>reload()</slot>
|
||||||
|
</slots>
|
||||||
|
</ui>
|
|
@ -53,11 +53,12 @@ static void add_to_path(QString &python_path, QString path, bool prepend=false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Server::Server(quint16 port, QString key)
|
Server::Server(quint16 port, QString key, QString logFileName)
|
||||||
{
|
{
|
||||||
// Appserver port etc
|
// Appserver port etc
|
||||||
m_port = port;
|
m_port = port;
|
||||||
m_key = key;
|
m_key = key;
|
||||||
|
m_logFileName = logFileName;
|
||||||
m_wcAppName = NULL;
|
m_wcAppName = NULL;
|
||||||
m_wcPythonHome = NULL;
|
m_wcPythonHome = NULL;
|
||||||
|
|
||||||
|
@ -206,6 +207,11 @@ Server::Server(quint16 port, QString key)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Redirect stderr
|
||||||
|
PyObject *sys = PyImport_ImportModule("sys");
|
||||||
|
PyObject *err = PyFile_FromString(m_logFileName.toUtf8().data(), (char *)"w");
|
||||||
|
PyObject_SetAttrString(sys, "stderr", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
Server::~Server()
|
Server::~Server()
|
||||||
|
@ -315,3 +321,4 @@ void Server::run()
|
||||||
|
|
||||||
fclose(cp);
|
fclose(cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,26 +23,29 @@ class Server : public QThread
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Server(quint16 port, QString key);
|
Server(quint16 port, QString key, QString logFileName);
|
||||||
~Server();
|
~Server();
|
||||||
|
|
||||||
bool Init();
|
bool Init();
|
||||||
QString getError() { return m_error; };
|
QString getError() { return m_error; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setError(QString error) { m_error = error; };
|
void setError(QString error) { m_error = error; }
|
||||||
|
|
||||||
QString m_appfile;
|
QString m_appfile;
|
||||||
QString m_error;
|
QString m_error;
|
||||||
|
|
||||||
quint16 m_port;
|
quint16 m_port;
|
||||||
QString m_key;
|
QString m_key;
|
||||||
|
QString m_logFileName;
|
||||||
|
|
||||||
// Application name in UTF-8 for Python
|
// Application name in UTF-8 for Python
|
||||||
wchar_t *m_wcAppName;
|
wchar_t *m_wcAppName;
|
||||||
QByteArray PGA_APP_NAME_UTF8;
|
QByteArray PGA_APP_NAME_UTF8;
|
||||||
|
|
||||||
// PythonHome for Python
|
// PythonHome for Python
|
||||||
wchar_t *m_wcPythonHome;
|
wchar_t *m_wcPythonHome;
|
||||||
QByteArray pythonHome_utf8;
|
QByteArray pythonHome_utf8;
|
||||||
|
|
|
@ -1,713 +0,0 @@
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// pgAdmin 4 - PostgreSQL Tools
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
|
||||||
// This software is released under the PostgreSQL Licence
|
|
||||||
//
|
|
||||||
// TabWindow.cpp - Implementation of the custom tab widget
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "pgAdmin4.h"
|
|
||||||
|
|
||||||
// App headers
|
|
||||||
#include "TabWindow.h"
|
|
||||||
|
|
||||||
#ifdef PGADMIN4_USE_WEBENGINE
|
|
||||||
#include <QWebEngineHistory>
|
|
||||||
#else
|
|
||||||
#include <QWebHistory>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DockTabWidget *DockTabWidget::mainTabWidget = NULL;
|
|
||||||
|
|
||||||
DockTabWidget::DockTabWidget(QWidget *parent) :
|
|
||||||
QTabWidget(parent)
|
|
||||||
{
|
|
||||||
floatingWidget = NULL;
|
|
||||||
floatingEnabled = false;
|
|
||||||
|
|
||||||
setParent(parent);
|
|
||||||
setTabsClosable(false);
|
|
||||||
setElideMode(Qt::ElideRight);
|
|
||||||
|
|
||||||
// set custom tab bar in tab widget to receive events for docking.
|
|
||||||
setTabBar(new DockTabBar(this));
|
|
||||||
setDocumentMode(true);
|
|
||||||
setAcceptDrops(true);
|
|
||||||
|
|
||||||
// Get the system colours we need
|
|
||||||
QPalette palette = QApplication::palette("QPushButton");
|
|
||||||
QColor activebg = palette.color(QPalette::Button);
|
|
||||||
QColor activefg = palette.color(QPalette::ButtonText);
|
|
||||||
QColor inactivebg = palette.color(QPalette::Dark);
|
|
||||||
QColor inactivefg = palette.color(QPalette::ButtonText);
|
|
||||||
QColor border = palette.color(QPalette::Mid);
|
|
||||||
|
|
||||||
setStyleSheet(
|
|
||||||
"QTabBar::tab { "
|
|
||||||
"background-color: " + inactivebg.name() + "; "
|
|
||||||
"color: " + inactivefg.name() + "; "
|
|
||||||
"border: 1px solid " + border.name() + "; "
|
|
||||||
"padding: 1px 0px; "
|
|
||||||
"margin-left: 0px; "
|
|
||||||
"margin-top: 1px; "
|
|
||||||
#ifndef __APPLE__
|
|
||||||
"width: 15em; "
|
|
||||||
"height: 1.5em; "
|
|
||||||
#endif
|
|
||||||
"} "
|
|
||||||
"QTabBar::tab:selected { "
|
|
||||||
"background-color: " + activebg.name() + "; "
|
|
||||||
"color: " + activefg.name() + "; "
|
|
||||||
"border-bottom-style: none; "
|
|
||||||
"} "
|
|
||||||
"QTabWidget::pane { "
|
|
||||||
"border: 0; "
|
|
||||||
"} "
|
|
||||||
"QTabWidget::tab-bar {"
|
|
||||||
"alignment: left; "
|
|
||||||
"}"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (mainTabWidget == NULL)
|
|
||||||
mainTabWidget = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
DockTabWidget::DockTabWidget(DockTabWidget *other, QWidget *parent) :
|
|
||||||
QTabWidget(parent)
|
|
||||||
{
|
|
||||||
setFloatingBaseWidget(other->floatingBaseWidget());
|
|
||||||
setFloatingEnabled(other->isFloatingEnabled());
|
|
||||||
resize(other->size());
|
|
||||||
|
|
||||||
// set custom tab bar in tab widget to receive events for docking.
|
|
||||||
setTabBar(new DockTabBar(this));
|
|
||||||
setDocumentMode(true);
|
|
||||||
setAcceptDrops(true);
|
|
||||||
|
|
||||||
// Get the system colours we need
|
|
||||||
QPalette palette = QApplication::palette("QPushButton");
|
|
||||||
QColor activebg = palette.color(QPalette::Button);
|
|
||||||
QColor activefg = palette.color(QPalette::ButtonText);
|
|
||||||
QColor inactivebg = palette.color(QPalette::Dark);
|
|
||||||
QColor inactivefg = palette.color(QPalette::ButtonText);
|
|
||||||
QColor border = palette.color(QPalette::Mid);
|
|
||||||
|
|
||||||
setStyleSheet(
|
|
||||||
"QTabBar::tab { "
|
|
||||||
"background-color: " + inactivebg.name() + "; "
|
|
||||||
"color: " + inactivefg.name() + "; "
|
|
||||||
"border: 1px solid " + border.name() + "; "
|
|
||||||
"padding: 1px 0px; "
|
|
||||||
"margin-left: 0px; "
|
|
||||||
"margin-top: 1px; "
|
|
||||||
#ifndef __APPLE__
|
|
||||||
"width: 15em; "
|
|
||||||
"height: 1.5em; "
|
|
||||||
#else
|
|
||||||
"font: 11pt; "
|
|
||||||
"width: 19em; "
|
|
||||||
"height: 1.5em; "
|
|
||||||
#endif
|
|
||||||
"} "
|
|
||||||
"QTabBar::tab:selected { "
|
|
||||||
"background-color: " + activebg.name() + "; "
|
|
||||||
"color: " + activefg.name() + "; "
|
|
||||||
"border-bottom-style: none; "
|
|
||||||
"} "
|
|
||||||
"QTabWidget::pane { "
|
|
||||||
"border: 0; "
|
|
||||||
"} "
|
|
||||||
"QTabWidget::tab-bar {"
|
|
||||||
"alignment: left; "
|
|
||||||
"}"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DockTabWidget::setFloatingBaseWidget(QWidget *widget)
|
|
||||||
{
|
|
||||||
floatingWidget = widget;
|
|
||||||
if (floatingEnabled && parentWidget() == 0)
|
|
||||||
setParent(widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DockTabWidget::setFloatingEnabled(bool x)
|
|
||||||
{
|
|
||||||
floatingEnabled = x;
|
|
||||||
|
|
||||||
if (parent() == 0)
|
|
||||||
{
|
|
||||||
if (x)
|
|
||||||
setWindowFlags(Qt::Tool);
|
|
||||||
else
|
|
||||||
setWindowFlags(Qt::Window);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Slot: go back to page and enable/disable toolbutton
|
|
||||||
void DockTabWidget::dockGoBackPage()
|
|
||||||
{
|
|
||||||
WebViewWindow *webviewPtr = NULL;
|
|
||||||
|
|
||||||
QWidget *tab = this->widget(this->currentIndex());
|
|
||||||
if (tab != NULL)
|
|
||||||
{
|
|
||||||
QList<QWidget*> widgetList = tab->findChildren<QWidget*>();
|
|
||||||
foreach( QWidget* widgetPtr, widgetList )
|
|
||||||
{
|
|
||||||
if (widgetPtr != NULL)
|
|
||||||
{
|
|
||||||
webviewPtr = dynamic_cast<WebViewWindow*>(widgetPtr);
|
|
||||||
if (webviewPtr != NULL)
|
|
||||||
webviewPtr->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Slot: go forward to page and enable/disable toolbutton
|
|
||||||
void DockTabWidget::dockGoForwardPage()
|
|
||||||
{
|
|
||||||
WebViewWindow *webviewPtr = NULL;
|
|
||||||
|
|
||||||
QWidget *tab = this->widget(this->currentIndex());
|
|
||||||
if (tab != NULL)
|
|
||||||
{
|
|
||||||
QList<QWidget*> widgetList = tab->findChildren<QWidget*>();
|
|
||||||
foreach( QWidget* widgetPtr, widgetList )
|
|
||||||
{
|
|
||||||
if (widgetPtr != NULL)
|
|
||||||
{
|
|
||||||
webviewPtr = dynamic_cast<WebViewWindow*>(widgetPtr);
|
|
||||||
if (webviewPtr != NULL)
|
|
||||||
webviewPtr->forward();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close the tab and remove the memory of the given index tab
|
|
||||||
void DockTabWidget::dockClosetabs()
|
|
||||||
{
|
|
||||||
int totalTabs = 0;
|
|
||||||
QToolButton *btn = NULL;
|
|
||||||
QWidget *tab = NULL;
|
|
||||||
DockTabWidget *l_tab_widget = NULL;
|
|
||||||
|
|
||||||
QObject *senderPtr = QObject::sender();
|
|
||||||
if (senderPtr != NULL)
|
|
||||||
{
|
|
||||||
btn = dynamic_cast<QToolButton*>(senderPtr);
|
|
||||||
if (btn != NULL)
|
|
||||||
{
|
|
||||||
l_tab_widget = dynamic_cast<DockTabWidget*>(btn->parent()->parent());
|
|
||||||
int current_tab_index = 0;
|
|
||||||
|
|
||||||
if (l_tab_widget != NULL)
|
|
||||||
{
|
|
||||||
totalTabs = l_tab_widget->count();
|
|
||||||
for (int loopCount = l_tab_widget->count();loopCount >= 0;loopCount--)
|
|
||||||
{
|
|
||||||
QWidget *l_tab = l_tab_widget->tabBar()->tabButton(loopCount, QTabBar::RightSide);
|
|
||||||
if (l_tab != NULL)
|
|
||||||
{
|
|
||||||
QToolButton *nextBtnPtr = dynamic_cast<QToolButton*>(l_tab);
|
|
||||||
if (nextBtnPtr != NULL && btn != NULL && nextBtnPtr == btn)
|
|
||||||
current_tab_index = loopCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<QWidget*> widgetList = l_tab_widget->tabBar()->findChildren<QWidget*>();
|
|
||||||
foreach(QWidget* widgetPtr, widgetList)
|
|
||||||
{
|
|
||||||
if (widgetPtr != NULL)
|
|
||||||
{
|
|
||||||
QToolButton *toolBtnPtr = dynamic_cast<QToolButton*>(widgetPtr);
|
|
||||||
if (toolBtnPtr != NULL && toolBtnPtr == btn)
|
|
||||||
{
|
|
||||||
tab = l_tab_widget->widget(current_tab_index);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tab != NULL)
|
|
||||||
tab->deleteLater();
|
|
||||||
|
|
||||||
// If user close the last tab then close the parent tab widget also.
|
|
||||||
if (totalTabs == 1 && l_tab_widget != NULL)
|
|
||||||
l_tab_widget->deleteLater();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tab != NULL)
|
|
||||||
{
|
|
||||||
WebViewWindow *webviewPtr = NULL;
|
|
||||||
|
|
||||||
QList<QWidget*> widgetList = tab->findChildren<QWidget*>();
|
|
||||||
foreach (QWidget* widgetPtr, widgetList)
|
|
||||||
{
|
|
||||||
if (widgetPtr != NULL)
|
|
||||||
{
|
|
||||||
webviewPtr = dynamic_cast<WebViewWindow*>(widgetPtr);
|
|
||||||
if (webviewPtr != NULL)
|
|
||||||
{
|
|
||||||
/* Trigger the action for tab window close so unload event will be called and
|
|
||||||
* resources will be freed properly.
|
|
||||||
* Trigger 'RequestClose' action from Qt5 onwards. Here we have triggerred the action
|
|
||||||
* 'ToggleVideoFullscreen + 1' because we do not know from which webkit
|
|
||||||
* version 'RequestClose' action was added so increment with previous enum value so that
|
|
||||||
* it will be backward webkit version compatible.
|
|
||||||
*/
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
#ifndef PGADMIN4_USE_WEBENGINE
|
|
||||||
webviewPtr->page()->triggerAction(static_cast<QWebPage::WebAction>(QWebPage::ToggleVideoFullscreen + 1));
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if main pgAdmin4 application has only one tab then close tab bar.
|
|
||||||
// Here - check for count 2 because tab will be deleted later.
|
|
||||||
DockTabWidget *mainTab = DockTabWidget::getMainTabWidget();
|
|
||||||
if (mainTab != NULL && l_tab_widget != NULL && l_tab_widget == mainTab && mainTab->count() == 2)
|
|
||||||
mainTab->tabBar()->setVisible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function is used to set back/forward/close buttons on new tabbar.
|
|
||||||
void DockTabWidget::setButtonsNewTabbar(int index)
|
|
||||||
{
|
|
||||||
QWidget *m_widget = new QWidget();
|
|
||||||
|
|
||||||
QToolButton *m_toolBtnBack = new QToolButton(m_widget);
|
|
||||||
m_toolBtnBack->setFixedHeight(PGA_BTN_SIZE);
|
|
||||||
m_toolBtnBack->setFixedWidth(PGA_BTN_SIZE);
|
|
||||||
m_toolBtnBack->setIcon(QIcon(":/back.png"));
|
|
||||||
m_toolBtnBack->setToolTip(tr("Go back"));
|
|
||||||
|
|
||||||
QToolButton *m_toolBtnForward = new QToolButton(m_widget);
|
|
||||||
m_toolBtnForward->setFixedHeight(PGA_BTN_SIZE);
|
|
||||||
m_toolBtnForward->setFixedWidth(PGA_BTN_SIZE);
|
|
||||||
m_toolBtnForward->setIcon(QIcon(":/forward.png"));
|
|
||||||
m_toolBtnForward->setToolTip(tr("Go forward"));
|
|
||||||
|
|
||||||
QToolButton *m_btnClose = new QToolButton(m_widget);
|
|
||||||
m_btnClose->setFixedHeight(PGA_BTN_SIZE);
|
|
||||||
m_btnClose->setFixedWidth(PGA_BTN_SIZE);
|
|
||||||
m_btnClose->setIcon(QIcon(":/close.png"));
|
|
||||||
m_btnClose->setToolTip(tr("Close tab"));
|
|
||||||
|
|
||||||
QHBoxLayout *m_horizontalLayout = new QHBoxLayout(m_widget);
|
|
||||||
m_horizontalLayout->setContentsMargins(0,1,0,0);
|
|
||||||
m_horizontalLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
|
|
||||||
m_horizontalLayout->setSpacing(1);
|
|
||||||
m_horizontalLayout->addWidget(m_toolBtnBack);
|
|
||||||
m_horizontalLayout->addWidget(m_toolBtnForward);
|
|
||||||
|
|
||||||
// Register the slot on toolbutton to show the previous history of web
|
|
||||||
connect(m_toolBtnBack, SIGNAL(clicked()), this, SLOT(dockGoBackPage()));
|
|
||||||
|
|
||||||
// Register the slot on toolbutton to show the next history of web
|
|
||||||
connect(m_toolBtnForward, SIGNAL(clicked()), this, SLOT(dockGoForwardPage()));
|
|
||||||
|
|
||||||
// Register the slot on close button , added manually
|
|
||||||
connect(m_btnClose, SIGNAL(clicked()), SLOT(dockClosetabs()));
|
|
||||||
|
|
||||||
// Register the slot on tab index change
|
|
||||||
connect(this, SIGNAL(currentChanged(int )), this,SLOT(tabIndexChanged(int )));
|
|
||||||
|
|
||||||
// Set the back and forward button on tab
|
|
||||||
this->tabBar()->setTabButton(index, QTabBar::LeftSide, m_widget);
|
|
||||||
this->tabBar()->setTabButton(index, QTabBar::RightSide, m_btnClose);
|
|
||||||
|
|
||||||
// find the webview and hide/show button depending on flag set with web view.
|
|
||||||
QWidget *tab = this->widget(index);
|
|
||||||
if (tab != NULL)
|
|
||||||
{
|
|
||||||
QList<QWidget*> widgetList = tab->findChildren<QWidget*>();
|
|
||||||
foreach( QWidget* widgetPtr, widgetList )
|
|
||||||
{
|
|
||||||
if (widgetPtr != NULL)
|
|
||||||
{
|
|
||||||
WebViewWindow *webViewPtr = dynamic_cast<WebViewWindow*>(widgetPtr);
|
|
||||||
if (webViewPtr != NULL)
|
|
||||||
{
|
|
||||||
// If user open any file in query tool then "Query -" name will not appear
|
|
||||||
// but it is still query tool so hide the tool button.
|
|
||||||
if (!webViewPtr->getBackForwardButtonHidden())
|
|
||||||
{
|
|
||||||
m_toolBtnBack->show();
|
|
||||||
m_toolBtnForward->show();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_toolBtnBack->hide();
|
|
||||||
m_toolBtnForward->hide();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function is used to move to old tab widget to new tab widget.
|
|
||||||
void DockTabWidget::moveTab(DockTabWidget *source, int sourceIndex, DockTabWidget *dest, int destIndex)
|
|
||||||
{
|
|
||||||
if (source == dest && sourceIndex < destIndex)
|
|
||||||
destIndex--;
|
|
||||||
|
|
||||||
QWidget *widget = source->widget(sourceIndex);
|
|
||||||
QString text = source->tabText(sourceIndex);
|
|
||||||
|
|
||||||
source->removeTab(sourceIndex);
|
|
||||||
|
|
||||||
dest->insertTab(destIndex, widget, text);
|
|
||||||
dest->setCurrentIndex(destIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function is used to decode actual drop event on tab widget.
|
|
||||||
void DockTabWidget::decodeTabDropEvent(QDropEvent *event, DockTabWidget **p_tabWidget, int *p_index)
|
|
||||||
{
|
|
||||||
DockTabBar *tabBar = qobject_cast<DockTabBar *>(event->source());
|
|
||||||
if (!tabBar)
|
|
||||||
{
|
|
||||||
*p_tabWidget = NULL;
|
|
||||||
*p_index = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray data = event->mimeData()->data(MIMETYPE_TABINDEX);
|
|
||||||
QDataStream stream(&data, QIODevice::ReadOnly);
|
|
||||||
|
|
||||||
int index;
|
|
||||||
stream >> index;
|
|
||||||
|
|
||||||
*p_tabWidget = tabBar->tabWidget();
|
|
||||||
*p_index = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function is used to check event is actually drop event or not.
|
|
||||||
bool DockTabWidget::eventIsTabDrag(QDragEnterEvent *event)
|
|
||||||
{
|
|
||||||
return event->mimeData()->hasFormat(MIMETYPE_TABINDEX) && qobject_cast<DockTabBar *>(event->source());
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function is used to delete tab widget when there is no tab inside.
|
|
||||||
void DockTabWidget::deleteIfEmpty()
|
|
||||||
{
|
|
||||||
if (count() == 0)
|
|
||||||
{
|
|
||||||
emit willBeAutomaticallyDeleted(this);
|
|
||||||
deleteLater();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is function is used to create another tab widget from parent window.
|
|
||||||
DockTabWidget *DockTabWidget::createAnotherTabWidget(QWidget *parent)
|
|
||||||
{
|
|
||||||
DockTabWidget *tab_widget = new DockTabWidget(this, parent);
|
|
||||||
tab_widget->tabBar()->setVisible(true);
|
|
||||||
return tab_widget;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check wether tab is insertable or not.
|
|
||||||
bool DockTabWidget::isInsertable(QWidget *widget)
|
|
||||||
{
|
|
||||||
Q_UNUSED(widget)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide the close button of given index displayed on right side of tab
|
|
||||||
void DockTabWidget::enableDisableToolButton(const int &index)
|
|
||||||
{
|
|
||||||
QToolButton *toolBtnPtr = NULL;
|
|
||||||
WebViewWindow *tmpwebviewPtr = NULL;
|
|
||||||
WebViewWindow *webviewPtr = NULL;
|
|
||||||
|
|
||||||
// Enable/disable the toolbutton based on the history
|
|
||||||
QWidget *tab1 = this->widget(index);
|
|
||||||
if (tab1 != NULL)
|
|
||||||
{
|
|
||||||
QList<QWidget*> widgetList = tab1->findChildren<QWidget*>();
|
|
||||||
foreach( QWidget* widgetPtr, widgetList )
|
|
||||||
{
|
|
||||||
if (widgetPtr != NULL)
|
|
||||||
tmpwebviewPtr = dynamic_cast<WebViewWindow*>(widgetPtr);
|
|
||||||
|
|
||||||
if (tmpwebviewPtr != NULL)
|
|
||||||
webviewPtr = tmpwebviewPtr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QWidget *tab = tabBar()->tabButton(index, QTabBar::LeftSide);
|
|
||||||
if (tab != NULL)
|
|
||||||
{
|
|
||||||
QList<QWidget*> widgetList = tab->findChildren<QWidget*>();
|
|
||||||
foreach( QWidget* widgetPtr, widgetList )
|
|
||||||
{
|
|
||||||
if (widgetPtr != NULL)
|
|
||||||
{
|
|
||||||
toolBtnPtr = dynamic_cast<QToolButton*>(widgetPtr);
|
|
||||||
if (webviewPtr != NULL && toolBtnPtr != NULL)
|
|
||||||
{
|
|
||||||
if (!QString::compare(toolBtnPtr->toolTip(), tr("Go back"), Qt::CaseInsensitive))
|
|
||||||
{
|
|
||||||
if (webviewPtr->page()->history()->canGoBack())
|
|
||||||
toolBtnPtr->setDisabled(false);
|
|
||||||
else
|
|
||||||
toolBtnPtr->setDisabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!QString::compare(toolBtnPtr->toolTip(), tr("Go forward"), Qt::CaseInsensitive))
|
|
||||||
{
|
|
||||||
if (webviewPtr->page()->history()->canGoForward())
|
|
||||||
toolBtnPtr->setDisabled(false);
|
|
||||||
else
|
|
||||||
toolBtnPtr->setDisabled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Slot: When the tab index change, hide/show the toolbutton displayed on tab
|
|
||||||
void DockTabWidget::tabIndexChanged(int index)
|
|
||||||
{
|
|
||||||
int tabCount = 0;
|
|
||||||
WebViewWindow *webViewPtr = NULL;
|
|
||||||
|
|
||||||
for (tabCount = 0; tabCount < this->count(); tabCount++)
|
|
||||||
{
|
|
||||||
// if main pgAdmin4 application tab then do nothing.
|
|
||||||
if (!QString::compare(this->tabText(tabCount), tr("pgAdmin 4"), Qt::CaseInsensitive))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
QWidget *tab = this->widget(tabCount);
|
|
||||||
if (tab != NULL)
|
|
||||||
{
|
|
||||||
QList<QWidget*> widgetList = tab->findChildren<QWidget*>();
|
|
||||||
foreach( QWidget* widgetPtr, widgetList )
|
|
||||||
{
|
|
||||||
if (widgetPtr != NULL)
|
|
||||||
{
|
|
||||||
webViewPtr = dynamic_cast<WebViewWindow*>(widgetPtr);
|
|
||||||
if (webViewPtr != NULL)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tabCount != index)
|
|
||||||
this->showHideToolButton(tabCount, 0);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!webViewPtr->getBackForwardButtonHidden())
|
|
||||||
this->showHideToolButton(tabCount, 1);
|
|
||||||
else
|
|
||||||
this->showHideToolButton(tabCount, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// paint the tab text again as index of the tab widget changed.
|
|
||||||
this->tabBar()->update();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show and Hide the toolbutton once the tab is deselected depending on the option
|
|
||||||
// option 0: Hide the toolButton
|
|
||||||
// option 1: Show the toolButton
|
|
||||||
void DockTabWidget::showHideToolButton(const int &index, const int &option)
|
|
||||||
{
|
|
||||||
QToolButton *toolBtnPtr = NULL;
|
|
||||||
|
|
||||||
QWidget *tab = tabBar()->tabButton(index, QTabBar::LeftSide);
|
|
||||||
if (tab != NULL)
|
|
||||||
{
|
|
||||||
QList<QWidget*> widgetList = tab->findChildren<QWidget*>();
|
|
||||||
foreach( QWidget* widgetPtr, widgetList )
|
|
||||||
{
|
|
||||||
if (widgetPtr != NULL)
|
|
||||||
{
|
|
||||||
toolBtnPtr = dynamic_cast<QToolButton*>(widgetPtr);
|
|
||||||
if (toolBtnPtr != NULL)
|
|
||||||
{
|
|
||||||
if (!option)
|
|
||||||
toolBtnPtr->hide();
|
|
||||||
else
|
|
||||||
toolBtnPtr->show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the tab tool tip text
|
|
||||||
void DockTabWidget::setTabToolTipText(const int &index, const QString &toolTipString)
|
|
||||||
{
|
|
||||||
tabBar()->setTabToolTip(index, toolTipString);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implementation of custom tab bar for docking window.
|
|
||||||
DockTabBar::DockTabBar(DockTabWidget *tabWidget, QWidget *parent) :
|
|
||||||
QTabBar(parent),
|
|
||||||
tab_widget(tabWidget)
|
|
||||||
{
|
|
||||||
isStartingDrag = false;
|
|
||||||
setAcceptDrops(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert new tab at specified index.
|
|
||||||
int DockTabBar::insertionIndexAt(const QPoint &pos)
|
|
||||||
{
|
|
||||||
int index = count();
|
|
||||||
for (int i = 0; i < count(); ++i)
|
|
||||||
{
|
|
||||||
QRect rect = tabRect(i);
|
|
||||||
QRect rect1(rect.x(), rect.y(), rect.width() / 2, rect.height());
|
|
||||||
QRect rect2(rect.x() + rect1.width(), rect.y(), rect.width() - rect1.width(), rect.height());
|
|
||||||
if (rect1.contains(pos))
|
|
||||||
{
|
|
||||||
index = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (rect2.contains(pos))
|
|
||||||
{
|
|
||||||
index = i + 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mouse press event handler for tab drag.
|
|
||||||
void DockTabBar::mousePressEvent(QMouseEvent *event)
|
|
||||||
{
|
|
||||||
if (event->button() == Qt::LeftButton)
|
|
||||||
{
|
|
||||||
dragStartPos = event->pos();
|
|
||||||
isStartingDrag = true;
|
|
||||||
}
|
|
||||||
QTabBar::mousePressEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mouse move event handler for tab drag.
|
|
||||||
void DockTabBar::mouseMoveEvent(QMouseEvent *event)
|
|
||||||
{
|
|
||||||
if (!isStartingDrag)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ((!event->buttons()) && Qt::LeftButton)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ((event->pos() - dragStartPos).manhattanLength() < QApplication::startDragDistance())
|
|
||||||
return;
|
|
||||||
|
|
||||||
int index = tabAt(event->pos());
|
|
||||||
|
|
||||||
if (index < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Don't allow to drag the pgAdmin4 main tab.
|
|
||||||
if (!QString::compare(tab_widget->tabText(index), tr("pgAdmin 4"), Qt::CaseInsensitive))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create data
|
|
||||||
QMimeData *mimeData = new QMimeData;
|
|
||||||
|
|
||||||
QByteArray data;
|
|
||||||
QDataStream stream(&data, QIODevice::WriteOnly);
|
|
||||||
stream << index;
|
|
||||||
|
|
||||||
mimeData->setData(MIMETYPE_TABINDEX, data);
|
|
||||||
|
|
||||||
// create pixmap
|
|
||||||
QRect rect = tabRect(index);
|
|
||||||
QPixmap pixmap(rect.size());
|
|
||||||
|
|
||||||
render(&pixmap, QPoint(), QRegion(rect));
|
|
||||||
|
|
||||||
// exec drag
|
|
||||||
QDrag *drag = new QDrag(this);
|
|
||||||
drag->setMimeData(mimeData);
|
|
||||||
drag->setPixmap(pixmap);
|
|
||||||
QPoint offset = dragStartPos - rect.topLeft();
|
|
||||||
drag->setHotSpot(offset);
|
|
||||||
Qt::DropAction dropAction = drag->exec(Qt::MoveAction | Qt::IgnoreAction);
|
|
||||||
|
|
||||||
if (dropAction != Qt::MoveAction)
|
|
||||||
{
|
|
||||||
DockTabWidget *newTabWidget = tab_widget->createAnotherTabWidget();
|
|
||||||
if (!newTabWidget->isInsertable(tab_widget, index))
|
|
||||||
{
|
|
||||||
newTabWidget->deleteLater();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DockTabWidget::moveTab(tab_widget, index, newTabWidget, 0);
|
|
||||||
|
|
||||||
newTabWidget->setButtonsNewTabbar(0);
|
|
||||||
newTabWidget->enableDisableToolButton(0);
|
|
||||||
|
|
||||||
QRect newGeometry = newTabWidget->geometry();
|
|
||||||
newGeometry.moveTopLeft(QCursor::pos() - offset);
|
|
||||||
newTabWidget->setGeometry(newGeometry);
|
|
||||||
newTabWidget->show();
|
|
||||||
|
|
||||||
// Check if main pgAdmin4 application has only one tab then close tab bar.
|
|
||||||
// Here - check for count 2 because tab will be deleted later.
|
|
||||||
DockTabWidget *mainTab = DockTabWidget::getMainTabWidget();
|
|
||||||
if (mainTab != NULL && tab_widget != NULL && tab_widget == mainTab && mainTab->count() == 1)
|
|
||||||
mainTab->tabBar()->setVisible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
tab_widget->deleteIfEmpty();
|
|
||||||
isStartingDrag = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actual tab drag started.
|
|
||||||
void DockTabBar::dragEnterEvent(QDragEnterEvent *event)
|
|
||||||
{
|
|
||||||
if (DockTabWidget::eventIsTabDrag(event))
|
|
||||||
event->acceptProposedAction();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Drag event leave the actual area.
|
|
||||||
void DockTabBar::dragLeaveEvent(QDragLeaveEvent * event)
|
|
||||||
{
|
|
||||||
Q_UNUSED(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Drop event handler for tabbar.
|
|
||||||
void DockTabBar::dropEvent(QDropEvent *event)
|
|
||||||
{
|
|
||||||
DockTabWidget *oldTabWidget = NULL;
|
|
||||||
int oldIndex;
|
|
||||||
DockTabWidget::decodeTabDropEvent(event, &oldTabWidget, &oldIndex);
|
|
||||||
|
|
||||||
if (oldTabWidget && tab_widget && tab_widget->isInsertable(oldTabWidget, oldIndex))
|
|
||||||
{
|
|
||||||
|
|
||||||
int newIndex = insertionIndexAt(event->pos());
|
|
||||||
DockTabWidget::moveTab(oldTabWidget, oldIndex, tab_widget, newIndex);
|
|
||||||
|
|
||||||
// create new back/forward/close buttons and register its events.
|
|
||||||
tab_widget->setButtonsNewTabbar(newIndex);
|
|
||||||
tab_widget->enableDisableToolButton(newIndex);
|
|
||||||
|
|
||||||
// Check if main pgAdmin4 application has only one tab then close tab bar.
|
|
||||||
// Here - check for count 2 because tab will be deleted later.
|
|
||||||
DockTabWidget *mainTab = DockTabWidget::getMainTabWidget();
|
|
||||||
if (mainTab != NULL && oldTabWidget != NULL && oldTabWidget == mainTab && mainTab->count() == 1)
|
|
||||||
mainTab->tabBar()->setVisible(false);
|
|
||||||
|
|
||||||
event->acceptProposedAction();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,188 +0,0 @@
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// pgAdmin 4 - PostgreSQL Tools
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
|
||||||
// This software is released under the PostgreSQL Licence
|
|
||||||
//
|
|
||||||
// TabWindow.h - Declaration of the custom tab widget
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef TABWINDOW_H
|
|
||||||
#define TABWINDOW_H
|
|
||||||
|
|
||||||
#include "pgAdmin4.h"
|
|
||||||
#include "WebViewWindow.h"
|
|
||||||
|
|
||||||
// Define button sizes
|
|
||||||
#ifdef _WIN32
|
|
||||||
const int PGA_BTN_SIZE = 18;
|
|
||||||
#else
|
|
||||||
const int PGA_BTN_SIZE = 16;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <QTabBar>
|
|
||||||
#include <QTabWidget>
|
|
||||||
|
|
||||||
#define MIMETYPE_TABINDEX "x-paintfield-tabindex"
|
|
||||||
|
|
||||||
class DockTabBar;
|
|
||||||
|
|
||||||
class DockTabWidget : public QTabWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
friend class DockTabBar;
|
|
||||||
public:
|
|
||||||
|
|
||||||
explicit DockTabWidget(QWidget *parent = 0);
|
|
||||||
|
|
||||||
DockTabWidget(DockTabWidget *other, QWidget *parent = 0);
|
|
||||||
|
|
||||||
// Drop event handlers of parent tab widget.
|
|
||||||
static void moveTab(DockTabWidget *source, int sourceIndex, DockTabWidget *dest, int destIndex);
|
|
||||||
static void decodeTabDropEvent(QDropEvent *event, DockTabWidget **p_tabWidget, int *p_index);
|
|
||||||
static bool eventIsTabDrag(QDragEnterEvent *event);
|
|
||||||
void setButtonsNewTabbar(int index);
|
|
||||||
|
|
||||||
static DockTabWidget *mainTabWidget;
|
|
||||||
static DockTabWidget* getMainTabWidget()
|
|
||||||
{
|
|
||||||
return mainTabWidget;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setFloatingBaseWidget(QWidget *widget);
|
|
||||||
QWidget *floatingBaseWidget()
|
|
||||||
{
|
|
||||||
return floatingWidget;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setFloatingEnabled(bool x);
|
|
||||||
bool isFloatingEnabled() const
|
|
||||||
{
|
|
||||||
return floatingEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool isInsertable(QWidget *widget);
|
|
||||||
bool isInsertable(DockTabWidget *other, int index)
|
|
||||||
{
|
|
||||||
return isInsertable(other->widget(index));
|
|
||||||
}
|
|
||||||
virtual DockTabWidget *createAnotherTabWidget(QWidget *parent = 0);
|
|
||||||
|
|
||||||
int getButtonIndex(QPushButton *btn);
|
|
||||||
void showHideToolButton(const int &index,const int &option);
|
|
||||||
void enableDisableToolButton(const int &index);
|
|
||||||
void setTabToolTipText(const int &index, const QString &toolTipString);
|
|
||||||
QTabBar *tabBar() const
|
|
||||||
{
|
|
||||||
return QTabWidget::tabBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void willBeAutomaticallyDeleted(DockTabWidget *widget);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void deleteIfEmpty();
|
|
||||||
void dockClosetabs();
|
|
||||||
void dockGoBackPage();
|
|
||||||
void dockGoForwardPage();
|
|
||||||
void tabIndexChanged(int index);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QWidget *floatingWidget;
|
|
||||||
bool floatingEnabled;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DockTabBar : public QTabBar
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
DockTabBar(DockTabWidget *tabWidget, QWidget *parent = 0);
|
|
||||||
// return tab widget of respective tab bar widget.
|
|
||||||
DockTabWidget *tabWidget()
|
|
||||||
{
|
|
||||||
return tab_widget;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// re-implemnted mouse event to detect tab drag started or not.
|
|
||||||
void mousePressEvent(QMouseEvent *event);
|
|
||||||
void mouseMoveEvent(QMouseEvent *event);
|
|
||||||
|
|
||||||
// re-implemnted drag-drop event for docking of tabs.
|
|
||||||
void dragEnterEvent(QDragEnterEvent *event);
|
|
||||||
void dropEvent(QDropEvent *event);
|
|
||||||
void dragLeaveEvent(QDragLeaveEvent * event);
|
|
||||||
|
|
||||||
// re-implemented paint event to draw the text on tab bar of tab widget control.
|
|
||||||
void paintEvent(QPaintEvent *event)
|
|
||||||
{
|
|
||||||
Q_UNUSED(event);
|
|
||||||
bool isToolBtnVisible = false;
|
|
||||||
|
|
||||||
DockTabWidget *l_tab_widget = dynamic_cast<DockTabWidget*>(this->parent());
|
|
||||||
|
|
||||||
if (l_tab_widget != NULL)
|
|
||||||
{
|
|
||||||
int current_index = l_tab_widget->currentIndex();
|
|
||||||
QStylePainter painter(this);
|
|
||||||
for(int i = 0; i < l_tab_widget->count(); ++i)
|
|
||||||
{
|
|
||||||
QString str = l_tab_widget->tabText(i);
|
|
||||||
if (!str.startsWith("pgAdmin 4") && !str.startsWith("Query -") && !str.startsWith("Debugger"))
|
|
||||||
isToolBtnVisible = true;
|
|
||||||
|
|
||||||
QStyleOptionTab option;
|
|
||||||
initStyleOption(&option, i);
|
|
||||||
QString tempText = this->tabText(i);
|
|
||||||
if (tempText.length() > 28)
|
|
||||||
{
|
|
||||||
tempText = tempText.mid(0,27);
|
|
||||||
tempText += QString("...");
|
|
||||||
}
|
|
||||||
|
|
||||||
QRect rect(option.rect);
|
|
||||||
|
|
||||||
// If toolButton is visible then only draw text after tool button pixel area.
|
|
||||||
// If tool button is not visible - draw the text after margin of 10px.
|
|
||||||
if (isToolBtnVisible)
|
|
||||||
{
|
|
||||||
if ((current_index != -1) && i == current_index)
|
|
||||||
{
|
|
||||||
if (str.startsWith("Query -") || str.startsWith("Debugger"))
|
|
||||||
rect.setX(option.rect.x() + 10);
|
|
||||||
else
|
|
||||||
rect.setX(option.rect.x() + 45);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
rect.setX(option.rect.x() + 10);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
rect.setX(option.rect.x() + 10);
|
|
||||||
|
|
||||||
rect.setY(option.rect.y() + 7);
|
|
||||||
|
|
||||||
option.text = QString();
|
|
||||||
|
|
||||||
painter.drawControl(QStyle::CE_TabBarTab, option);
|
|
||||||
painter.drawItemText(rect, 0, palette(), 1, tempText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
QSize tabSizeHint(int) const
|
|
||||||
{
|
|
||||||
return QSize(250, 26);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
|
||||||
int insertionIndexAt(const QPoint &pos);
|
|
||||||
DockTabWidget *tab_widget;
|
|
||||||
bool isStartingDrag;
|
|
||||||
QPoint dragStartPos;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // TABWINDOW_H
|
|
|
@ -0,0 +1,244 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// pgAdmin 4 - PostgreSQL Tools
|
||||||
|
//
|
||||||
|
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||||
|
// This software is released under the PostgreSQL Licence
|
||||||
|
//
|
||||||
|
// TrayIcon.cpp - Manages the tray icon
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#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)
|
||||||
|
{
|
||||||
|
m_logWindow = NULL;
|
||||||
|
|
||||||
|
m_trayIcon = NULL;
|
||||||
|
m_trayIconMenu = NULL;
|
||||||
|
|
||||||
|
m_newAction = NULL;
|
||||||
|
m_configAction = NULL;
|
||||||
|
m_logAction = NULL;
|
||||||
|
m_quitAction = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TrayIcon::~TrayIcon()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool 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()
|
||||||
|
{
|
||||||
|
createActions();
|
||||||
|
|
||||||
|
if (m_trayIconMenu)
|
||||||
|
{
|
||||||
|
delete m_trayIconMenu;
|
||||||
|
m_trayIconMenu = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_trayIconMenu = new QMenu(this);
|
||||||
|
m_trayIconMenu->addAction(m_newAction);
|
||||||
|
m_trayIconMenu->addSeparator();
|
||||||
|
m_trayIconMenu->addAction(m_configAction);
|
||||||
|
m_trayIconMenu->addAction(m_logAction);
|
||||||
|
m_trayIconMenu->addSeparator();
|
||||||
|
m_trayIconMenu->addAction(m_quitAction);
|
||||||
|
|
||||||
|
if (!m_trayIcon)
|
||||||
|
m_trayIcon = new QSystemTrayIcon(this);
|
||||||
|
m_trayIcon->setContextMenu(m_trayIconMenu);
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
m_trayIcon->setIcon(icon);
|
||||||
|
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()));
|
||||||
|
|
||||||
|
m_configAction = new QAction(tr("&Configure..."), this);
|
||||||
|
connect(m_configAction, SIGNAL(triggered()), this, SLOT(onConfig()));
|
||||||
|
|
||||||
|
m_logAction = new QAction(tr("&View log..."), this);
|
||||||
|
connect(m_logAction, SIGNAL(triggered()), this, SLOT(onLog()));
|
||||||
|
|
||||||
|
m_quitAction = new QAction(tr("&Shutdown server"), this);
|
||||||
|
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("Shutdown server?"), QString(tr("The %1 server must be restarted for changes to take effect. Do you want to shutdown 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("Shutdown server?"), QString(tr("Are you sure you want to shutdown the %1 server?")).arg(PGA_APP_NAME), QMessageBox::Yes | QMessageBox::No))
|
||||||
|
{
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// pgAdmin 4 - PostgreSQL Tools
|
||||||
|
//
|
||||||
|
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||||
|
// This software is released under the PostgreSQL Licence
|
||||||
|
//
|
||||||
|
// TrayIcon.h - Manages the tray icon
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef TRAYICON_H
|
||||||
|
#define TRAYICON_H
|
||||||
|
|
||||||
|
#include "pgAdmin4.h"
|
||||||
|
|
||||||
|
// QT headers
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
|
// App headers
|
||||||
|
#include "LogWindow.h"
|
||||||
|
|
||||||
|
class TrayIcon : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
TrayIcon(QString logFile);
|
||||||
|
~TrayIcon();
|
||||||
|
|
||||||
|
bool Init();
|
||||||
|
void setAppServerUrl(QString appServerUrl);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void createTrayIcon();
|
||||||
|
bool isSystemTrayAvailable();
|
||||||
|
void createActions();
|
||||||
|
|
||||||
|
void wait(int msec);
|
||||||
|
|
||||||
|
QAction *m_newAction;
|
||||||
|
QAction *m_configAction;
|
||||||
|
QAction *m_logAction;
|
||||||
|
QAction *m_quitAction;
|
||||||
|
|
||||||
|
QSystemTrayIcon *m_trayIcon;
|
||||||
|
QMenu *m_trayIconMenu;
|
||||||
|
|
||||||
|
QString m_appServerUrl, m_logFile;
|
||||||
|
|
||||||
|
LogWindow *m_logWindow;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onNew();
|
||||||
|
void onConfig();
|
||||||
|
void onLog();
|
||||||
|
void onQuit();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TRAYICON_H
|
|
@ -1,195 +0,0 @@
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// pgAdmin 4 - PostgreSQL Tools
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
|
||||||
// This software is released under the PostgreSQL Licence
|
|
||||||
//
|
|
||||||
// WebViewWindow.cpp - Implementation of the custom web view widget
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "pgAdmin4.h"
|
|
||||||
|
|
||||||
// App headers
|
|
||||||
#include "WebViewWindow.h"
|
|
||||||
#include "TabWindow.h"
|
|
||||||
|
|
||||||
#ifndef PGADMIN4_USE_WEBENGINE
|
|
||||||
#include <QWebPage>
|
|
||||||
#include <QNetworkRequest>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
WebViewWindow *WebViewWindow::mainWebViewWindow = NULL;
|
|
||||||
|
|
||||||
// Override QWebEnginePage to handle link delegation
|
|
||||||
#ifdef PGADMIN4_USE_WEBENGINE
|
|
||||||
bool WebEnginePage::acceptNavigationRequest(const QUrl & url, NavigationType type, bool isMainFrame)
|
|
||||||
{
|
|
||||||
Q_UNUSED(type);
|
|
||||||
Q_UNUSED(url);
|
|
||||||
Q_UNUSED(isMainFrame);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QWebEnginePage *WebEnginePage::createWindow(QWebEnginePage::WebWindowType type)
|
|
||||||
{
|
|
||||||
if (type == QWebEnginePage::WebBrowserTab)
|
|
||||||
{
|
|
||||||
QWebEnginePage *_page = NULL;
|
|
||||||
emit createTabWindow(_page);
|
|
||||||
return _page;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
WebViewWindow::WebViewWindow(QWidget *parent) :
|
|
||||||
#ifdef PGADMIN4_USE_WEBENGINE
|
|
||||||
QWebEngineView(parent)
|
|
||||||
#else
|
|
||||||
QWebView(parent)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
m_url = QString("");
|
|
||||||
m_tabIndex = 0;
|
|
||||||
m_backForwardBtnHide = false;
|
|
||||||
|
|
||||||
// Accept drop event for only main pgAdmin4 application window.
|
|
||||||
if (mainWebViewWindow == NULL)
|
|
||||||
mainWebViewWindow = this;
|
|
||||||
|
|
||||||
setAcceptDrops(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actual tab drag started.
|
|
||||||
void WebViewWindow::dragEnterEvent(QDragEnterEvent *event)
|
|
||||||
{
|
|
||||||
//DockTabWidget *mainTabWidget = DockTabWidget::getMainTabWidget();
|
|
||||||
//if (this->parent()->parent()->parent() == mainTabWidget)
|
|
||||||
event->accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebViewWindow::dragMoveEvent(QDragMoveEvent *event)
|
|
||||||
{
|
|
||||||
event->acceptProposedAction();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Drop event handler for tabbar.
|
|
||||||
void WebViewWindow::dropEvent(QDropEvent *event)
|
|
||||||
{
|
|
||||||
DockTabWidget *oldTabWidget;
|
|
||||||
int oldIndex;
|
|
||||||
DockTabWidget::decodeTabDropEvent(event, &oldTabWidget, &oldIndex);
|
|
||||||
|
|
||||||
//DockTabWidget *mainTabWidget = DockTabWidget::getMainTabWidget();
|
|
||||||
DockTabWidget *mainTabWidget = dynamic_cast<DockTabWidget*>(this->parent()->parent()->parent());
|
|
||||||
|
|
||||||
if (oldTabWidget && mainTabWidget && oldTabWidget != mainTabWidget)
|
|
||||||
//if (oldTabWidget && mainTabWidget)
|
|
||||||
{
|
|
||||||
mainTabWidget->tabBar()->setVisible(true);
|
|
||||||
QPoint pos = event->pos();
|
|
||||||
int index = mainTabWidget->tabBar()->count();
|
|
||||||
for (int i = 0; i < mainTabWidget->tabBar()->count(); ++i)
|
|
||||||
{
|
|
||||||
QRect rect = mainTabWidget->tabBar()->tabRect(i);
|
|
||||||
QRect rect1(rect.x(), rect.y(), rect.width() / 2, rect.height());
|
|
||||||
QRect rect2(rect.x() + rect1.width(), rect.y(), rect.width() - rect1.width(), rect.height());
|
|
||||||
if (rect1.contains(pos))
|
|
||||||
{
|
|
||||||
index = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (rect2.contains(pos))
|
|
||||||
{
|
|
||||||
index = i + 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DockTabWidget::moveTab(oldTabWidget, oldIndex, mainTabWidget, index);
|
|
||||||
|
|
||||||
// create new back/forward/close buttons and register its events.
|
|
||||||
mainTabWidget->setButtonsNewTabbar(index);
|
|
||||||
mainTabWidget->enableDisableToolButton(index);
|
|
||||||
|
|
||||||
// Check if main pgAdmin4 application has only one tab then close tab bar.
|
|
||||||
// Here - check for count 2 because tab will be deleted later.
|
|
||||||
DockTabWidget *mainTab = DockTabWidget::getMainTabWidget();
|
|
||||||
if (mainTab != NULL && oldTabWidget != NULL && oldTabWidget == mainTab && mainTab->count() == 1)
|
|
||||||
mainTab->tabBar()->setVisible(false);
|
|
||||||
|
|
||||||
event->acceptProposedAction();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebViewWindow::setBackForwardButtonHidden(const bool hideButton)
|
|
||||||
{
|
|
||||||
m_backForwardBtnHide = hideButton;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WebViewWindow::getBackForwardButtonHidden() const
|
|
||||||
{
|
|
||||||
return m_backForwardBtnHide;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebViewWindow::setFirstLoadURL(const QString &url)
|
|
||||||
{
|
|
||||||
m_url = url;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString WebViewWindow::getFirstLoadURL() const
|
|
||||||
{
|
|
||||||
return m_url;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebViewWindow::setTabIndex(const int &tabIndex)
|
|
||||||
{
|
|
||||||
m_tabIndex = tabIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
int WebViewWindow::getTabIndex() const
|
|
||||||
{
|
|
||||||
return m_tabIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef PGADMIN4_USE_WEBENGINE
|
|
||||||
WebViewPage::WebViewPage(QObject *parent)
|
|
||||||
: QWebPage(parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WebViewPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type)
|
|
||||||
{
|
|
||||||
Q_UNUSED(type);
|
|
||||||
Q_UNUSED(request);
|
|
||||||
Q_UNUSED(frame);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QWebPage *WebViewPage::createWindow(QWebPage::WebWindowType type)
|
|
||||||
{
|
|
||||||
if (type == QWebPage::WebBrowserWindow)
|
|
||||||
{
|
|
||||||
QWebPage *_page = NULL;
|
|
||||||
emit createTabWindowKit(_page);
|
|
||||||
return _page;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WebViewPage::javaScriptConfirm(QWebFrame * frame, const QString & msg)
|
|
||||||
{
|
|
||||||
// If required, override the QDialog to give custom confirmation message to user.
|
|
||||||
Q_UNUSED(frame);
|
|
||||||
Q_UNUSED(msg);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
WebViewPage::~WebViewPage()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,95 +0,0 @@
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// pgAdmin 4 - PostgreSQL Tools
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
|
||||||
// This software is released under the PostgreSQL Licence
|
|
||||||
//
|
|
||||||
// WebViewWindow.h - Declaration of the custom web view widget
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef WEBVIEWWINDOW_H
|
|
||||||
#define WEBVIEWWINDOW_H
|
|
||||||
|
|
||||||
#include "pgAdmin4.h"
|
|
||||||
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
#ifdef PGADMIN4_USE_WEBENGINE
|
|
||||||
#include <QtWebEngineWidgets>
|
|
||||||
#else
|
|
||||||
#include <QtWebKitWidgets>
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#include <QWebView>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Override QWebEnginePage to handle link delegation
|
|
||||||
#ifdef PGADMIN4_USE_WEBENGINE
|
|
||||||
class WebEnginePage : public QWebEnginePage
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
protected:
|
|
||||||
virtual bool acceptNavigationRequest(const QUrl & url, NavigationType type, bool isMainFrame);
|
|
||||||
QWebEnginePage *createWindow(QWebEnginePage::WebWindowType type);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void createTabWindow(QWebEnginePage * &);
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PGADMIN4_USE_WEBENGINE
|
|
||||||
class WebViewWindow : public QWebEngineView
|
|
||||||
#else
|
|
||||||
class WebViewWindow : public QWebView
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
WebViewWindow(QWidget *parent = NULL);
|
|
||||||
void setFirstLoadURL(const QString &url);
|
|
||||||
QString getFirstLoadURL() const;
|
|
||||||
void setTabIndex(const int &tabIndex);
|
|
||||||
int getTabIndex() const;
|
|
||||||
void setBackForwardButtonHidden(const bool hideButton);
|
|
||||||
bool getBackForwardButtonHidden() const;
|
|
||||||
|
|
||||||
// Store main webview window of pgAdmin4 application.
|
|
||||||
static WebViewWindow *mainWebViewWindow;
|
|
||||||
static WebViewWindow* getMainWebViewWindow()
|
|
||||||
{
|
|
||||||
return mainWebViewWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// re-implemnted drag-drop event for docking of tabs.
|
|
||||||
void dragEnterEvent(QDragEnterEvent *event);
|
|
||||||
void dragMoveEvent(QDragMoveEvent *event);
|
|
||||||
void dropEvent(QDropEvent *event);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString m_url;
|
|
||||||
int m_tabIndex;
|
|
||||||
bool m_backForwardBtnHide;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifndef PGADMIN4_USE_WEBENGINE
|
|
||||||
class WebViewPage : public QWebPage
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
WebViewPage(QObject *parent = 0);
|
|
||||||
~WebViewPage();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual bool acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type);
|
|
||||||
QWebPage *createWindow(QWebPage::WebWindowType type);
|
|
||||||
bool javaScriptConfirm(QWebFrame * frame, const QString & msg);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void createTabWindowKit(QWebPage * &);
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // WEBVIEWWINDOW_H
|
|
Binary file not shown.
After Width: | Height: | Size: 80 KiB |
|
@ -28,153 +28,22 @@
|
||||||
#include <QSplashScreen>
|
#include <QSplashScreen>
|
||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
#include <QNetworkProxyFactory>
|
#include <QNetworkProxyFactory>
|
||||||
#include <QSslConfiguration>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// App headers
|
// App headers
|
||||||
#include "BrowserWindow.h"
|
|
||||||
#include "ConfigWindow.h"
|
#include "ConfigWindow.h"
|
||||||
#include "Server.h"
|
#include "Server.h"
|
||||||
|
#include "TrayIcon.h"
|
||||||
|
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
|
|
||||||
// Implement support for system proxies for Qt 4.x on Linux
|
QString logFileName;
|
||||||
#if defined (Q_OS_LINUX) && QT_VERSION < 0x050000
|
QString addrFileName;
|
||||||
|
|
||||||
#include "qnetworkproxy.h"
|
|
||||||
|
|
||||||
#include <QtCore/QByteArray>
|
|
||||||
#include <QtCore/QUrl>
|
|
||||||
|
|
||||||
#ifndef QT_NO_NETWORKPROXY
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
static bool ignoreProxyFor(const QNetworkProxyQuery &query)
|
|
||||||
{
|
|
||||||
const QByteArray noProxy = qgetenv("no_proxy").trimmed();
|
|
||||||
if (noProxy.isEmpty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const QList<QByteArray> noProxyTokens = noProxy.split(',');
|
|
||||||
|
|
||||||
foreach (const QByteArray &rawToken, noProxyTokens) {
|
|
||||||
QByteArray token = rawToken.trimmed();
|
|
||||||
QString peerHostName = query.peerHostName();
|
|
||||||
|
|
||||||
// Since we use suffix matching, "*" is our 'default' behaviour
|
|
||||||
if (token.startsWith("*"))
|
|
||||||
token = token.mid(1);
|
|
||||||
|
|
||||||
// Harmonize trailing dot notation
|
|
||||||
if (token.endsWith('.') && !peerHostName.endsWith('.'))
|
|
||||||
token = token.left(token.length()-1);
|
|
||||||
|
|
||||||
// We prepend a dot to both values, so that when we do a suffix match,
|
|
||||||
// we don't match "donotmatch.com" with "match.com"
|
|
||||||
if (!token.startsWith('.'))
|
|
||||||
token.prepend('.');
|
|
||||||
|
|
||||||
if (!peerHostName.startsWith('.'))
|
|
||||||
peerHostName.prepend('.');
|
|
||||||
|
|
||||||
if (peerHostName.endsWith(QString::fromLatin1(token)))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QList<QNetworkProxy> pgAdminSystemProxyForQuery(const QNetworkProxyQuery &query)
|
|
||||||
{
|
|
||||||
QList<QNetworkProxy> proxyList;
|
|
||||||
|
|
||||||
if (ignoreProxyFor(query))
|
|
||||||
return proxyList << QNetworkProxy::NoProxy;
|
|
||||||
|
|
||||||
// No need to care about casing here, QUrl lowercases values already
|
|
||||||
const QString queryProtocol = query.protocolTag();
|
|
||||||
QByteArray proxy_env;
|
|
||||||
|
|
||||||
if (queryProtocol == QLatin1String("http"))
|
|
||||||
proxy_env = qgetenv("http_proxy");
|
|
||||||
else if (queryProtocol == QLatin1String("https"))
|
|
||||||
proxy_env = qgetenv("https_proxy");
|
|
||||||
else if (queryProtocol == QLatin1String("ftp"))
|
|
||||||
proxy_env = qgetenv("ftp_proxy");
|
|
||||||
else
|
|
||||||
proxy_env = qgetenv("all_proxy");
|
|
||||||
|
|
||||||
// Fallback to http_proxy is no protocol specific proxy was found
|
|
||||||
if (proxy_env.isEmpty())
|
|
||||||
proxy_env = qgetenv("http_proxy");
|
|
||||||
|
|
||||||
if (!proxy_env.isEmpty())
|
|
||||||
{
|
|
||||||
QUrl url = QUrl(QString::fromLocal8Bit(proxy_env));
|
|
||||||
if (url.scheme() == QLatin1String("socks5"))
|
|
||||||
{
|
|
||||||
QNetworkProxy proxy(QNetworkProxy::Socks5Proxy, url.host(),
|
|
||||||
url.port() ? url.port() : 1080, url.userName(), url.password());
|
|
||||||
proxyList << proxy;
|
|
||||||
} else if (url.scheme() == QLatin1String("socks5h"))
|
|
||||||
{
|
|
||||||
QNetworkProxy proxy(QNetworkProxy::Socks5Proxy, url.host(),
|
|
||||||
url.port() ? url.port() : 1080, url.userName(), url.password());
|
|
||||||
proxy.setCapabilities(QNetworkProxy::HostNameLookupCapability);
|
|
||||||
proxyList << proxy;
|
|
||||||
} else if ((url.scheme() == QLatin1String("http") || url.scheme() == QLatin1String("https") || url.scheme().isEmpty())
|
|
||||||
&& query.queryType() != QNetworkProxyQuery::UdpSocket
|
|
||||||
&& query.queryType() != QNetworkProxyQuery::TcpServer)
|
|
||||||
{
|
|
||||||
QNetworkProxy proxy(QNetworkProxy::HttpProxy, url.host(),
|
|
||||||
url.port() ? url.port() : 8080, url.userName(), url.password());
|
|
||||||
proxyList << proxy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (proxyList.isEmpty())
|
|
||||||
proxyList << QNetworkProxy::NoProxy;
|
|
||||||
|
|
||||||
return proxyList;
|
|
||||||
}
|
|
||||||
|
|
||||||
class pgAdminSystemConfigurationProxyFactory : public QNetworkProxyFactory
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
pgAdminSystemConfigurationProxyFactory() : QNetworkProxyFactory() {}
|
|
||||||
|
|
||||||
virtual QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery& query)
|
|
||||||
{
|
|
||||||
QList<QNetworkProxy> proxies = pgAdminSystemProxyForQuery(query);
|
|
||||||
|
|
||||||
// Make sure NoProxy is in the list, so that QTcpServer can work:
|
|
||||||
// it searches for the first proxy that can has the ListeningCapability capability
|
|
||||||
// if none have (as is the case with HTTP proxies), it fails to bind.
|
|
||||||
// NoProxy allows it to fallback to the 'no proxy' case and bind.
|
|
||||||
proxies.append(QNetworkProxy::NoProxy);
|
|
||||||
|
|
||||||
return proxies;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
|
||||||
|
|
||||||
#endif // QT_NO_NETWORKINTERFACE
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void delay( int milliseconds )
|
|
||||||
{
|
|
||||||
QTime endTime = QTime::currentTime().addMSecs( milliseconds );
|
|
||||||
while( QTime::currentTime() < endTime )
|
|
||||||
{
|
|
||||||
QCoreApplication::processEvents( QEventLoop::AllEvents, 100 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char * argv[])
|
int main(int argc, char * argv[])
|
||||||
{
|
{
|
||||||
|
QSettings settings;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Before starting main application, need to set 'QT_X11_NO_MITSHM=1'
|
* Before starting main application, need to set 'QT_X11_NO_MITSHM=1'
|
||||||
* to make the runtime work with IBM PPC machine.
|
* to make the runtime work with IBM PPC machine.
|
||||||
|
@ -186,6 +55,7 @@ int main(int argc, char * argv[])
|
||||||
|
|
||||||
// Create the QT application
|
// Create the QT application
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
app.setQuitOnLastWindowClosed(false);
|
||||||
|
|
||||||
// Setup the settings management
|
// Setup the settings management
|
||||||
QCoreApplication::setOrganizationName("pgadmin");
|
QCoreApplication::setOrganizationName("pgadmin");
|
||||||
|
@ -197,36 +67,84 @@ int main(int argc, char * argv[])
|
||||||
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
// Create a hash of the executable path so we can run copies side-by-side
|
||||||
// Set registry "HKEY_CLASSES_ROOT\.css\Content Type" to value "text/css" to avoid rendering issue in windows OS.
|
QString homeDir = QDir::homePath();
|
||||||
QString infoMsgStr("");
|
unsigned long exeHash = sdbm((unsigned char *)argv[0]);
|
||||||
QSettings css_keys("HKEY_CLASSES_ROOT", QSettings::NativeFormat);
|
|
||||||
|
|
||||||
// If key already exists then check for existing value and it differs then only change it.
|
// Create the address file, that will be used to store the appserver URL for this instance
|
||||||
if (css_keys.childGroups().contains(".css", Qt::CaseInsensitive))
|
addrFileName = homeDir + QString("/.%1.%2.addr").arg(PGA_APP_NAME).arg(exeHash);
|
||||||
{
|
addrFileName.remove(" ");
|
||||||
QSettings set("HKEY_CLASSES_ROOT\\.css", QSettings::NativeFormat);
|
QFile addrFile(addrFileName);
|
||||||
if (set.value("Content Type").toString() != "text/css")
|
|
||||||
{
|
// Create a system-wide semaphore keyed by app name, exe hash and the username
|
||||||
set.setValue("Content Type", "text/css");
|
// to ensure instances are unique to the user and path
|
||||||
// If error while setting registry then it should be issue with permissions.
|
QString userName = qgetenv("USER"); // *nix
|
||||||
if (set.status() == QSettings::NoError)
|
if (userName.isEmpty())
|
||||||
infoMsgStr = "pgAdmin 4 application has reset the registry key 'HKEY_CLASSES_ROOT\\css\\Content Type' to 'text/css' to fix a system misconfiguration that can lead to rendering problems.";
|
userName = qgetenv("USERNAME"); // Windows
|
||||||
else
|
|
||||||
infoMsgStr = "Failed to reset the registry key 'HKEY_CLASSES_ROOT\\css\\Content Type' to 'text/css'. Try to run with Administrator privileges.";
|
QString semaName = QString("%1-%2-%3-sema").arg(PGA_APP_NAME).arg(userName).arg(exeHash);
|
||||||
}
|
QString shmemName = QString("%1-%2-%3-shmem").arg(PGA_APP_NAME).arg(userName).arg(exeHash);
|
||||||
}
|
|
||||||
|
QSystemSemaphore sema(semaName, 1);
|
||||||
|
sema.acquire();
|
||||||
|
|
||||||
|
#ifndef Q_OS_WIN32
|
||||||
|
// We may need to clean up stale shmem segments on *nix. Attaching and detaching
|
||||||
|
// should remove the segment if it is orphaned.
|
||||||
|
QSharedMemory stale_shmem(shmemName);
|
||||||
|
if (stale_shmem.attach())
|
||||||
|
stale_shmem.detach();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* In windows and linux, it is required to set application level proxy
|
QSharedMemory shmem(shmemName);
|
||||||
* becuase socket bind logic to find free port gives socket creation error
|
bool is_running;
|
||||||
* when system proxy is configured. We are also setting
|
if (shmem.attach())
|
||||||
* "setUseSystemConfiguration"=true to use the system proxy which will
|
{
|
||||||
* override this application level proxy. As this bug is fixed in Qt 5.9 so
|
is_running = true;
|
||||||
* need to set application proxy for Qt version < 5.9.
|
}
|
||||||
*/
|
else
|
||||||
#ifndef PGADMIN4_USE_WEBENGINE
|
{
|
||||||
#if defined (Q_OS_WIN) && QT_VERSION <= 0x050800
|
shmem.create(1);
|
||||||
|
is_running = false;
|
||||||
|
}
|
||||||
|
sema.release();
|
||||||
|
|
||||||
|
if (is_running){
|
||||||
|
addrFile.open(QIODevice::ReadOnly | QIODevice::Text);
|
||||||
|
QTextStream in(&addrFile);
|
||||||
|
QString addr = in.readLine();
|
||||||
|
|
||||||
|
QString cmd = settings.value("BrowserCommand").toString();
|
||||||
|
|
||||||
|
if (!cmd.isEmpty())
|
||||||
|
{
|
||||||
|
cmd.replace("%URL%", addr);
|
||||||
|
QProcess::startDetached(cmd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!QDesktopServices::openUrl(addr))
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
atexit(cleanup);
|
||||||
|
|
||||||
|
// In windows and linux, it is required to set application level proxy
|
||||||
|
// because socket bind logic to find free port gives socket creation error
|
||||||
|
// when system proxy is configured. We are also setting
|
||||||
|
// "setUseSystemConfiguration"=true to use the system proxy which will
|
||||||
|
// override this application level proxy. As this bug is fixed in Qt 5.9 so
|
||||||
|
// need to set application proxy for Qt version < 5.9.
|
||||||
|
//
|
||||||
|
#if defined (Q_OS_WIN) && QT_VERSION <= 0x050800
|
||||||
// Give dummy URL required to find proxy server configured in windows.
|
// Give dummy URL required to find proxy server configured in windows.
|
||||||
QNetworkProxyQuery proxyQuery(QUrl("https://www.pgadmin.org"));
|
QNetworkProxyQuery proxyQuery(QUrl("https://www.pgadmin.org"));
|
||||||
QNetworkProxy l_proxy;
|
QNetworkProxy l_proxy;
|
||||||
|
@ -241,18 +159,15 @@ int main(int argc, char * argv[])
|
||||||
QNetworkProxy::setApplicationProxy(QNetworkProxy());
|
QNetworkProxy::setApplicationProxy(QNetworkProxy());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PGADMIN4_USE_WEBENGINE
|
#if defined (Q_OS_LINUX) && QT_VERSION <= 0x050800
|
||||||
#if defined (Q_OS_LINUX) && QT_VERSION <= 0x050800
|
|
||||||
QByteArray proxy_env;
|
QByteArray proxy_env;
|
||||||
proxy_env = qgetenv("http_proxy");
|
proxy_env = qgetenv("http_proxy");
|
||||||
// If http_proxy environment is defined in linux then proxy server is configured.
|
// If http_proxy environment is defined in linux then proxy server is configured.
|
||||||
if (!proxy_env.isEmpty()) {
|
if (!proxy_env.isEmpty()) {
|
||||||
QNetworkProxy::setApplicationProxy(QNetworkProxy());
|
QNetworkProxy::setApplicationProxy(QNetworkProxy());
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Display the spash screen
|
// Display the spash screen
|
||||||
|
@ -288,19 +203,20 @@ int main(int argc, char * argv[])
|
||||||
QString key = QUuid::createUuid().toString();
|
QString key = QUuid::createUuid().toString();
|
||||||
key = key.mid(1, key.length() - 2);
|
key = key.mid(1, key.length() - 2);
|
||||||
|
|
||||||
#if defined (Q_OS_LINUX) && QT_VERSION < 0x050000
|
// Generate the filename for the log
|
||||||
QNetworkProxyFactory::setApplicationProxyFactory(new pgAdminSystemConfigurationProxyFactory);
|
logFileName = homeDir + QString("/.%1.%2.log").arg(PGA_APP_NAME).arg(exeHash);
|
||||||
QSslConfiguration sslCfg = QSslConfiguration::defaultConfiguration();
|
logFileName.remove(" ");
|
||||||
QList<QSslCertificate> ca_list = sslCfg.caCertificates();
|
|
||||||
QList<QSslCertificate> ca_new = QSslCertificate::fromData("CaCertificates");
|
|
||||||
ca_list += ca_new;
|
|
||||||
|
|
||||||
sslCfg.setCaCertificates(ca_list);
|
// Start the tray service
|
||||||
sslCfg.setProtocol(QSsl::AnyProtocol);
|
TrayIcon *trayicon = new TrayIcon(logFileName);
|
||||||
QSslConfiguration::setDefaultConfiguration(sslCfg);
|
|
||||||
#else
|
if (!trayicon->Init())
|
||||||
QNetworkProxyFactory::setUseSystemConfiguration(true);
|
{
|
||||||
#endif
|
QString error = QString(QWidget::tr("An error occurred initialising the tray icon"));
|
||||||
|
QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
// Fire up the webserver
|
// Fire up the webserver
|
||||||
Server *server;
|
Server *server;
|
||||||
|
@ -309,7 +225,7 @@ int main(int argc, char * argv[])
|
||||||
|
|
||||||
while (done != true)
|
while (done != true)
|
||||||
{
|
{
|
||||||
server = new Server(port, key);
|
server = new Server(port, key, logFileName);
|
||||||
|
|
||||||
if (!server->Init())
|
if (!server->Init())
|
||||||
{
|
{
|
||||||
|
@ -325,6 +241,13 @@ int main(int argc, char * argv[])
|
||||||
|
|
||||||
server->start();
|
server->start();
|
||||||
|
|
||||||
|
// This is a hack to give the server a chance to start and potentially fail. As
|
||||||
|
// the Python interpreter is a synchronous call, we can't check for proper startup
|
||||||
|
// easily in a more robust way - we have to rely on a clean startup not returning.
|
||||||
|
// It should always fail pretty quickly, and take longer to start if it succeeds, so
|
||||||
|
// we don't really get a visible delay here.
|
||||||
|
delay(1000);
|
||||||
|
|
||||||
// Any errors?
|
// Any errors?
|
||||||
if (server->isFinished() || server->getError().length() > 0)
|
if (server->isFinished() || server->getError().length() > 0)
|
||||||
{
|
{
|
||||||
|
@ -341,16 +264,19 @@ int main(int argc, char * argv[])
|
||||||
|
|
||||||
ConfigWindow *dlg = new ConfigWindow();
|
ConfigWindow *dlg = new ConfigWindow();
|
||||||
dlg->setWindowTitle(QWidget::tr("Configuration"));
|
dlg->setWindowTitle(QWidget::tr("Configuration"));
|
||||||
|
dlg->setBrowserCommand(settings.value("BrowserCommand").toString());
|
||||||
dlg->setPythonPath(settings.value("PythonPath").toString());
|
dlg->setPythonPath(settings.value("PythonPath").toString());
|
||||||
dlg->setApplicationPath(settings.value("ApplicationPath").toString());
|
dlg->setApplicationPath(settings.value("ApplicationPath").toString());
|
||||||
dlg->setModal(true);
|
dlg->setModal(true);
|
||||||
ok = dlg->exec();
|
ok = dlg->exec();
|
||||||
|
|
||||||
|
QString browsercommand = dlg->getBrowserCommand();
|
||||||
QString pythonpath = dlg->getPythonPath();
|
QString pythonpath = dlg->getPythonPath();
|
||||||
QString applicationpath = dlg->getApplicationPath();
|
QString applicationpath = dlg->getApplicationPath();
|
||||||
|
|
||||||
if (ok)
|
if (ok)
|
||||||
{
|
{
|
||||||
|
settings.setValue("BrowserCommand", browsercommand);
|
||||||
settings.setValue("PythonPath", pythonpath);
|
settings.setValue("PythonPath", pythonpath);
|
||||||
settings.setValue("ApplicationPath", applicationpath);
|
settings.setValue("ApplicationPath", applicationpath);
|
||||||
settings.sync();
|
settings.sync();
|
||||||
|
@ -371,7 +297,6 @@ int main(int argc, char * argv[])
|
||||||
QString appServerUrl = QString("http://127.0.0.1:%1/?key=%2").arg(port).arg(key);
|
QString appServerUrl = QString("http://127.0.0.1:%1/?key=%2").arg(port).arg(key);
|
||||||
|
|
||||||
// Read the server connection timeout from the registry or set the default timeout.
|
// Read the server connection timeout from the registry or set the default timeout.
|
||||||
QSettings settings;
|
|
||||||
int timeout = settings.value("ConnectionTimeout", 30).toInt();
|
int timeout = settings.value("ConnectionTimeout", 30).toInt();
|
||||||
|
|
||||||
// Now the server should be up, we'll attempt to connect and get a response.
|
// Now the server should be up, we'll attempt to connect and get a response.
|
||||||
|
@ -393,7 +318,7 @@ int main(int argc, char * argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to connect one more time in case of a long network timeout while looping
|
// Attempt to connect one more time in case of a long network timeout while looping
|
||||||
if(!alive && !PingServer(QUrl(appServerUrl)))
|
if (!alive && !PingServer(QUrl(appServerUrl)))
|
||||||
{
|
{
|
||||||
splash->finish(NULL);
|
splash->finish(NULL);
|
||||||
QString error(QWidget::tr("The application server could not be contacted."));
|
QString error(QWidget::tr("The application server could not be contacted."));
|
||||||
|
@ -402,26 +327,35 @@ int main(int argc, char * argv[])
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create & show the main window
|
// Stash the URL for any duplicate processes to open
|
||||||
BrowserWindow browserWindow(appServerUrl);
|
if (addrFile.open(QIODevice::WriteOnly))
|
||||||
browserWindow.setWindowTitle(PGA_APP_NAME);
|
{
|
||||||
browserWindow.setWindowIcon(QIcon(":/pgAdmin4.ico"));
|
QTextStream out(&addrFile);
|
||||||
#ifdef _WIN32
|
out << appServerUrl << endl;
|
||||||
browserWindow.setRegistryMessage(infoMsgStr);
|
}
|
||||||
#endif
|
|
||||||
browserWindow.show();
|
|
||||||
|
|
||||||
// Go!
|
// Go!
|
||||||
splash->finish(NULL);
|
trayicon->setAppServerUrl(appServerUrl);
|
||||||
|
|
||||||
// Set global application stylesheet.
|
QString cmd = settings.value("BrowserCommand").toString();
|
||||||
QFile file(":/qss/pgadmin4.qss");
|
|
||||||
if(file.open(QFile::ReadOnly))
|
if (!cmd.isEmpty())
|
||||||
{
|
{
|
||||||
QString StyleSheet = QLatin1String(file.readAll());
|
cmd.replace("%URL%", appServerUrl);
|
||||||
qApp->setStyleSheet(StyleSheet);
|
QProcess::startDetached(cmd);
|
||||||
file.close();
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!QDesktopServices::openUrl(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
splash->finish(NULL);
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
@ -468,3 +402,36 @@ bool PingServer(QUrl url)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void delay(int milliseconds)
|
||||||
|
{
|
||||||
|
QTime endTime = QTime::currentTime().addMSecs(milliseconds);
|
||||||
|
while(QTime::currentTime() < endTime)
|
||||||
|
{
|
||||||
|
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void cleanup()
|
||||||
|
{
|
||||||
|
// Remove the address file
|
||||||
|
QFile addrFile(addrFileName);
|
||||||
|
addrFile.remove();
|
||||||
|
|
||||||
|
// Remove the log file
|
||||||
|
QFile logFile(logFileName);
|
||||||
|
logFile.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned long sdbm(unsigned char *str)
|
||||||
|
{
|
||||||
|
unsigned long hash = 0;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
while ((c = *str++))
|
||||||
|
hash = c + (hash << 6) + (hash << 16) - hash;
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
|
@ -36,5 +36,8 @@ const QString PGA_APP_NAME = QString("pgAdmin 4");
|
||||||
// Global function prototypes
|
// Global function prototypes
|
||||||
int main(int argc, char * argv[]);
|
int main(int argc, char * argv[]);
|
||||||
bool PingServer(QUrl url);
|
bool PingServer(QUrl url);
|
||||||
|
void delay(int milliseconds);
|
||||||
|
void cleanup();
|
||||||
|
unsigned long sdbm(unsigned char *str);
|
||||||
|
|
||||||
#endif // PGADMIN4_H
|
#endif // PGADMIN4_H
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 97 KiB |
|
@ -1,4 +1,4 @@
|
||||||
VERSION = 2.1.0.0
|
VERSION = 3.0.0.0
|
||||||
QMAKE_TARGET_COMPANY = "The pgAdmin Development Team"
|
QMAKE_TARGET_COMPANY = "The pgAdmin Development Team"
|
||||||
QMAKE_TARGET_PRODUCT = "pgAdmin 4"
|
QMAKE_TARGET_PRODUCT = "pgAdmin 4"
|
||||||
QMAKE_TARGET_DESCRIPTION = "pgAdmin 4 Desktop Runtime"
|
QMAKE_TARGET_DESCRIPTION = "pgAdmin 4 Desktop Runtime"
|
||||||
|
@ -7,52 +7,17 @@ QMAKE_TARGET_COPYRIGHT = "Copyright 2013 - 2018, The pgAdmin Development Team"
|
||||||
# Configure QT modules for the appropriate version of QT
|
# Configure QT modules for the appropriate version of QT
|
||||||
greaterThan(QT_MAJOR_VERSION, 4) {
|
greaterThan(QT_MAJOR_VERSION, 4) {
|
||||||
message(Building for QT5+...)
|
message(Building for QT5+...)
|
||||||
|
message()
|
||||||
# Users can force the use of WebKit in Qt5, e.g. qmake "DEFINES += PGADMIN4_USE_WEBKIT"
|
QT += network widgets
|
||||||
contains(DEFINES, PGADMIN4_USE_WEBKIT) {
|
|
||||||
message(Forcing use of QWebKit...)
|
|
||||||
message()
|
|
||||||
message(************************************** WARNING **************************************)
|
|
||||||
message(* It is strongly advised that Qt 5.5.0 or later is used to build the pgAdmin runtime.)
|
|
||||||
message(*************************************************************************************)
|
|
||||||
message()
|
|
||||||
QT += webkitwidgets network widgets
|
|
||||||
} else {
|
|
||||||
greaterThan(QT_MINOR_VERSION, 4) {
|
|
||||||
message(Using QWebEngine...)
|
|
||||||
DEFINES += PGADMIN4_USE_WEBENGINE
|
|
||||||
QT += webenginewidgets network widgets
|
|
||||||
} else {
|
|
||||||
message(Using QWebKit...)
|
|
||||||
message()
|
|
||||||
message(************************************** WARNING **************************************)
|
|
||||||
message(* It is strongly advised that Qt 5.5.0 or later is used to build the pgAdmin runtime.)
|
|
||||||
message(*************************************************************************************)
|
|
||||||
message()
|
|
||||||
DEFINES *= PGADMIN4_USE_WEBKIT
|
|
||||||
QT += webkitwidgets network widgets
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
message(Building for QT4...)
|
message(Building for QT4...)
|
||||||
message(Using QWebKit...)
|
|
||||||
message()
|
message()
|
||||||
message(************************************** WARNING **************************************)
|
QT += network
|
||||||
message(* It is strongly advised that Qt 5.5.0 or later is used to build the pgAdmin runtime.)
|
|
||||||
message(*************************************************************************************)
|
|
||||||
message()
|
|
||||||
DEFINES += PGADMIN4_USE_WEBKIT
|
|
||||||
QT += webkit network
|
|
||||||
}
|
}
|
||||||
win32 {
|
win32 {
|
||||||
RC_ICONS += pgAdmin4.ico
|
RC_ICONS += pgAdmin4.ico
|
||||||
}
|
}
|
||||||
|
|
||||||
CONFIG(debug, debug|release) {
|
|
||||||
DEFINES += PGADMIN4_DEBUG
|
|
||||||
message(Configure pgAdmin4 to run in debug mode...)
|
|
||||||
}
|
|
||||||
|
|
||||||
# Environment settings for the build
|
# Environment settings for the build
|
||||||
QMAKE_CFLAGS += $$(PGADMIN_CFLAGS)
|
QMAKE_CFLAGS += $$(PGADMIN_CFLAGS)
|
||||||
QMAKE_CXXFLAGS += $$(PGADMIN_CXXFLAGS)
|
QMAKE_CXXFLAGS += $$(PGADMIN_CXXFLAGS)
|
||||||
|
@ -122,23 +87,21 @@ else {
|
||||||
}
|
}
|
||||||
|
|
||||||
# Source code
|
# Source code
|
||||||
HEADERS = BrowserWindow.h \
|
HEADERS = \
|
||||||
Server.h \
|
Server.h \
|
||||||
pgAdmin4.h \
|
pgAdmin4.h \
|
||||||
TabWindow.h \
|
ConfigWindow.h \
|
||||||
WebViewWindow.h \
|
TrayIcon.h \
|
||||||
ConfigWindow.h
|
LogWindow.h
|
||||||
SOURCES = pgAdmin4.cpp \
|
SOURCES = pgAdmin4.cpp \
|
||||||
BrowserWindow.cpp \
|
|
||||||
Server.cpp \
|
Server.cpp \
|
||||||
TabWindow.cpp \
|
ConfigWindow.cpp \
|
||||||
WebViewWindow.cpp \
|
TrayIcon.cpp \
|
||||||
ConfigWindow.cpp
|
LogWindow.cpp
|
||||||
FORMS = BrowserWindow.ui \
|
FORMS = ConfigWindow.ui \
|
||||||
ConfigWindow.ui
|
LogWindow.ui
|
||||||
ICON = pgAdmin4.icns
|
ICON = pgAdmin4.icns
|
||||||
QMAKE_INFO_PLIST = Info.plist
|
QMAKE_INFO_PLIST = Info.plist
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += pgadmin4.qrc
|
||||||
pgadmin4.qrc
|
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
<file>forward.png</file>
|
<file>forward.png</file>
|
||||||
<file>close.png</file>
|
<file>close.png</file>
|
||||||
<file>splash.png</file>
|
<file>splash.png</file>
|
||||||
<file>qss/pgadmin4.qss</file>
|
<file>pgAdmin4.png</file>
|
||||||
|
<file>pgAdmin4-mac.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
QTabBar::tab {
|
|
||||||
background-color: #E8E8E8;
|
|
||||||
}
|
|
Loading…
Reference in New Issue