2013-06-16 14:17:46 +01:00
//////////////////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
2018-01-05 10:42:49 +00:00
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
2013-06-16 14:17:46 +01:00
// This software is released under the PostgreSQL Licence
//
// BrowserWindow.cpp - Implementation of the main window class
//
//////////////////////////////////////////////////////////////////////////
2013-06-21 23:21:11 +01:00
#include "pgAdmin4.h"
2013-06-16 14:17:46 +01:00
#if QT_VERSION >= 0x050000
#include <QtWidgets>
2017-02-13 11:44:53 +00:00
#ifdef PGADMIN4_USE_WEBENGINE
2016-11-08 10:54:34 +00:00
#include <QtWebEngineWidgets>
2013-06-16 14:17:46 +01:00
#else
2016-11-08 10:54:34 +00:00
#include <QtWebKitWidgets>
2013-06-16 14:17:46 +01:00
#include <QtWebKit>
2016-11-08 10:54:34 +00:00
#endif
#else
2013-06-16 14:17:46 +01:00
#include <QAction>
#include <QMenu>
#include <QMenuBar>
#include <QMessageBox>
#include <QInputDialog>
#include <QLineEdit>
#endif
2016-07-25 12:39:57 +01:00
#include <QNetworkRequest>
#include <QNetworkReply>
2013-06-21 23:21:11 +01:00
// App headers
2013-06-16 14:17:46 +01:00
#include "BrowserWindow.h"
2016-01-19 10:26:01 +00:00
#include "ConfigWindow.h"
2013-06-16 14:17:46 +01:00
// Constructor
2013-10-04 18:16:31 +01:00
BrowserWindow :: BrowserWindow ( QString url )
2013-06-16 14:17:46 +01:00
{
2016-01-18 14:33:28 +00:00
m_tabGridLayout = NULL ;
m_mainGridLayout = NULL ;;
m_tabWidget = NULL ;
m_pgAdminMainTab = NULL ;
m_addNewTab = NULL ;
m_addNewGridLayout = NULL ;
m_addNewWebView = NULL ;
m_horizontalLayout = NULL ;
m_widget = NULL ;
m_toolBtnBack = NULL ;
m_toolBtnForward = NULL ;
2016-07-13 12:26:24 +01:00
m_downloadStarted = 0 ;
m_downloadCancelled = 0 ;
m_file = NULL ;
m_downloadFilename = "" ;
m_defaultFilename = "" ;
m_progressDialog = NULL ;
2016-07-18 15:28:20 +01:00
m_last_open_folder_path = "" ;
2016-07-13 12:26:24 +01:00
m_dir = "" ;
m_reply = NULL ;
2017-11-20 14:43:34 +00:00
is_readyReadSignaled = false ;
m_readBytes = 0 ;
2017-02-13 11:44:53 +00:00
#ifdef PGADMIN4_USE_WEBENGINE
2016-11-08 10:54:34 +00:00
m_download = NULL ;
#endif
2016-01-18 14:33:28 +00:00
2013-10-04 18:16:31 +01:00
m_appServerUrl = url ;
2013-10-04 17:12:10 +01:00
2017-11-15 16:33:24 +00:00
#ifdef _WIN32
m_regMessage = "" ;
#endif
2016-06-17 11:31:52 +01:00
// Setup the shortcuts
2013-06-16 14:17:46 +01:00
createActions ();
2017-06-16 09:57:19 +01:00
m_tabWidget = new DockTabWidget ( this );
m_tabWidget -> tabBar () -> setVisible ( false );
2016-01-18 14:33:28 +00:00
m_mainGridLayout = new QGridLayout ( m_tabWidget );
m_mainGridLayout -> setContentsMargins ( 0 , 0 , 0 , 0 );
m_pgAdminMainTab = new QWidget ( m_tabWidget );
m_tabGridLayout = new QGridLayout ( m_pgAdminMainTab );
m_tabGridLayout -> setContentsMargins ( 0 , 0 , 0 , 0 );
m_mainWebView = new WebViewWindow ( m_pgAdminMainTab );
2017-05-09 13:03:44 +05:30
2017-02-13 11:44:53 +00:00
#ifdef PGADMIN4_USE_WEBENGINE
2016-11-08 10:54:34 +00:00
m_mainWebView -> setPage ( new WebEnginePage ());
2017-05-09 13:03:44 +05:30
#else
m_cookieJar = new QNetworkCookieJar ();
m_netAccessMan = new QNetworkAccessManager ();
m_netAccessMan -> setCookieJar ( m_cookieJar );
m_mainWebView -> setPage ( new WebViewPage ());
m_mainWebView -> page () -> setNetworkAccessManager ( m_netAccessMan );
m_mainWebView -> settings () -> setAttribute ( QWebSettings :: JavascriptEnabled , true );
m_mainWebView -> settings () -> setAttribute ( QWebSettings :: JavascriptCanOpenWindows , true );
2016-11-08 10:54:34 +00:00
#endif
2016-01-18 14:33:28 +00:00
2016-05-19 09:33:00 -04:00
#ifdef PGADMIN4_DEBUG
// If pgAdmin4 is run in debug mode, then we should enable the
// "Inspect" option, when the user right clicks on QWebView widget.
// This option is useful to debug the pgAdmin4 desktop application and open the developer tools.
2017-02-13 11:44:53 +00:00
#ifdef PGADMIN4_USE_WEBENGINE
2016-11-08 10:54:34 +00:00
// With QWebEngine, run with QTWEBENGINE_REMOTE_DEBUGGING=<port> and then point Google
// Chrome at 127.0.0.1:<port> to debug the runtime's web engine
#else
2016-05-19 09:33:00 -04:00
QWebSettings :: globalSettings () -> setAttribute ( QWebSettings :: DeveloperExtrasEnabled , true );
#endif
2016-11-08 10:54:34 +00:00
#endif
2016-05-19 09:33:00 -04:00
2016-06-02 15:15:53 +05:30
#ifdef __APPLE__
m_mainWebView -> setStyle ( QStyleFactory :: create ( "Fusion" ));
#endif
2016-01-18 14:33:28 +00:00
m_tabGridLayout -> addWidget ( m_mainWebView , 0 , 0 , 1 , 1 );
m_tabWidget -> addTab ( m_pgAdminMainTab , QString ());
m_tabWidget -> setCurrentIndex ( 0 );
m_tabWidget -> setTabText ( 0 , PGA_APP_NAME );
m_tabWidget -> setTabToolTipText ( 0 , PGA_APP_NAME ) ;
setCentralWidget ( m_tabWidget );
2017-02-13 11:44:53 +00:00
#ifdef PGADMIN4_USE_WEBENGINE
2016-11-08 10:54:34 +00:00
// Register the slot when click on the URL link for QWebEnginePage
connect ( m_mainWebView -> page (), SIGNAL ( createTabWindow ( QWebEnginePage * & )), SLOT ( createNewTabWindow ( QWebEnginePage * & )));
#else
2016-01-18 14:33:28 +00:00
// Register the slot when click on the URL link form main menu bar
2016-01-19 10:26:01 +00:00
connect ( m_mainWebView , SIGNAL ( linkClicked ( const QUrl & )), SLOT ( urlLinkClicked ( const QUrl & )));
2017-05-09 13:03:44 +05:30
// Register the slot when click on the URL link for QWebPage
connect ( m_mainWebView -> page (), SIGNAL ( createTabWindowKit ( QWebPage * & )), SLOT ( createNewTabWindowKit ( QWebPage * & )));
2016-11-08 10:54:34 +00:00
#endif
2016-01-18 14:33:28 +00:00
// Register the slot on tab index change
2017-06-16 09:57:19 +01:00
connect ( m_tabWidget , SIGNAL ( currentChanged ( int )), m_tabWidget , SLOT ( tabIndexChanged ( int )));
2016-01-18 14:33:28 +00:00
2016-07-13 12:26:24 +01:00
// Listen for download file request from the web page
2017-02-13 11:44:53 +00:00
#ifdef PGADMIN4_USE_WEBENGINE
2016-11-08 10:54:34 +00:00
// Register downloadRequested signal of QWenEngineProfile to start download file to client side.
connect ( m_mainWebView -> page () -> profile (), SIGNAL ( downloadRequested ( QWebEngineDownloadItem * )), this , SLOT ( downloadRequested ( QWebEngineDownloadItem * )));
#else
2016-07-13 12:26:24 +01:00
m_mainWebView -> page () -> setForwardUnsupportedContent ( true );
connect ( m_mainWebView -> page (), SIGNAL ( downloadRequested ( const QNetworkRequest & )), this , SLOT ( download ( const QNetworkRequest & )));
connect ( m_mainWebView -> page (), SIGNAL ( unsupportedContent ( QNetworkReply * )), this , SLOT ( unsupportedContent ( QNetworkReply * )));
2017-05-09 13:03:44 +05:30
m_mainWebView -> page () -> setForwardUnsupportedContent ( true );
2016-01-18 14:33:28 +00:00
m_mainWebView -> page () -> setLinkDelegationPolicy ( QWebPage :: DelegateAllLinks );
2016-11-08 10:54:34 +00:00
#endif
2013-06-16 14:17:46 +01:00
2017-11-15 16:33:24 +00:00
// Register the signal when base URL loading is finished.
connect ( m_mainWebView , SIGNAL ( loadFinished ( bool )), this , SLOT ( urlLoadingFinished ( bool )));
2016-11-08 11:37:57 +00:00
// Restore the geometry, or set a nice default
2013-10-04 10:08:18 -04:00
QSettings settings ;
2016-11-08 11:37:57 +00:00
QSize availableSize = qApp -> desktop () -> availableGeometry (). size ();
QSize defaultSize ( availableSize . width () * 0.9 , availableSize . height () * 0.9 );
QRect defaultGeometry = QStyle :: alignedRect (
Qt :: LeftToRight ,
Qt :: AlignCenter ,
defaultSize ,
qApp -> desktop () -> availableGeometry ()
);
restoreGeometry ( settings . value ( "Browser/Geometry" , defaultGeometry ). toByteArray ());
2014-12-16 12:53:09 +00:00
restoreState ( settings . value ( "Browser/WindowState" ). toByteArray ());
2013-10-04 10:08:18 -04:00
2016-09-22 12:37:38 +01:00
// Set the initial zoom
2016-09-22 14:43:32 +01:00
qreal zoom = settings . value ( "Browser/Zoom" , m_mainWebView -> zoomFactor ()). toReal ();
2016-09-22 12:37:38 +01:00
m_mainWebView -> setZoomFactor ( zoom );
2016-07-18 15:28:20 +01:00
// The last save location
m_last_open_folder_path = settings . value ( "Browser/LastSaveLocation" , QDir :: homePath ()). toString ();
2013-06-21 23:21:11 +01:00
// Display the app
2016-01-18 14:33:28 +00:00
m_mainWebView -> setUrl ( m_appServerUrl );
2013-06-16 14:17:46 +01:00
}
2017-05-09 13:03:44 +05:30
// Destructor
BrowserWindow ::~ BrowserWindow ()
{
if ( m_tabWidget )
delete m_tabWidget ;
}
2013-10-04 10:08:18 -04:00
// Save the window geometry on close
void BrowserWindow :: closeEvent ( QCloseEvent * event )
{
2017-11-07 20:10:55 -05:00
if ( QMessageBox :: Yes == QMessageBox :: question ( this , "Exit the application?" , "Are you sure you want to exit the application?" , QMessageBox :: Yes | QMessageBox :: No ))
{
QSettings settings ;
settings . setValue ( "Browser/Geometry" , saveGeometry ());
settings . setValue ( "Browser/WindowState" , saveState ());
QMainWindow :: closeEvent ( event );
event -> accept ();
}
else
{
event -> ignore ();
}
2013-10-04 10:08:18 -04:00
}
2017-11-15 16:33:24 +00:00
#ifdef _WIN32
// Set the message when change in registry value.
void BrowserWindow :: setRegistryMessage ( const QString & msg )
{
m_regMessage = msg ;
}
QString BrowserWindow :: getRegistryMessage ()
{
return m_regMessage ;
}
#endif
void BrowserWindow :: urlLoadingFinished ( bool res )
{
if ( res )
{
#ifdef _WIN32
// Check if registry value is set by application then display information message to user.
// If message is empty string means no value set by application in registry.
QString message = getRegistryMessage ();
if ( message != QString ( "" ))
QMessageBox :: information ( this , tr ( "Registry change" ), message );
#endif
}
}
2013-06-16 14:17:46 +01:00
// Create the actions for the window
void BrowserWindow :: createActions ()
{
// Open an arbitrary URL
2016-06-29 20:31:40 +01:00
openUrlShortcut = new QShortcut ( QKeySequence ( Qt :: ALT + Qt :: SHIFT + Qt :: Key_U ), this );
2016-06-17 11:31:52 +01:00
openUrlShortcut -> setContext ( Qt :: ApplicationShortcut );
connect ( openUrlShortcut , SIGNAL ( activated ()), this , SLOT ( openUrl ()));
2013-06-16 14:17:46 +01:00
2014-12-16 12:53:09 +00:00
// Set the Python Path
2016-06-29 20:31:40 +01:00
preferencesShortcut = new QShortcut ( QKeySequence ( Qt :: ALT + Qt :: SHIFT + Qt :: Key_P ), this );
2016-06-17 11:31:52 +01:00
preferencesShortcut -> setContext ( Qt :: ApplicationShortcut );
connect ( preferencesShortcut , SIGNAL ( activated ()), this , SLOT ( preferences ()));
2014-12-16 12:53:09 +00:00
2013-06-16 14:17:46 +01:00
// Exit the app
2016-06-17 11:31:52 +01:00
exitShortcut = new QShortcut ( QKeySequence :: Quit , this );
exitShortcut -> setContext ( Qt :: ApplicationShortcut );
connect ( exitShortcut , SIGNAL ( activated ()), this , SLOT ( close ()));
2013-06-16 14:17:46 +01:00
2017-06-13 10:21:51 +01:00
signalMapper = new QSignalMapper ( this );
2013-06-16 14:17:46 +01:00
// About box
2016-06-29 20:31:40 +01:00
aboutShortcut = new QShortcut ( QKeySequence ( Qt :: ALT + Qt :: SHIFT + Qt :: Key_A ), this );
2016-06-17 11:31:52 +01:00
aboutShortcut -> setContext ( Qt :: ApplicationShortcut );
connect ( aboutShortcut , SIGNAL ( activated ()), this , SLOT ( about ()));
2016-09-22 12:37:38 +01:00
// Zoom in
zoomInShortcut = new QShortcut ( QKeySequence ( QKeySequence :: ZoomIn ), this );
zoomInShortcut -> setContext ( Qt :: ApplicationShortcut );
2017-06-13 10:21:51 +01:00
signalMapper -> setMapping ( zoomInShortcut , 1 );
connect ( zoomInShortcut , SIGNAL ( activated ()), signalMapper , SLOT ( map ()));
2016-09-22 12:37:38 +01:00
// Zoom out
zoomOutShortcut = new QShortcut ( QKeySequence ( QKeySequence :: ZoomOut ), this );
zoomOutShortcut -> setContext ( Qt :: ApplicationShortcut );
2017-06-13 10:21:51 +01:00
signalMapper -> setMapping ( zoomOutShortcut , - 1 );
connect ( zoomOutShortcut , SIGNAL ( activated ()), signalMapper , SLOT ( map ()));
// Reset Zoom
zoomResetShortcut = new QShortcut ( QKeySequence ( Qt :: CTRL + Qt :: Key_0 ), this );
zoomResetShortcut -> setContext ( Qt :: ApplicationShortcut );
signalMapper -> setMapping ( zoomResetShortcut , 0 );
connect ( zoomResetShortcut , SIGNAL ( activated ()), signalMapper , SLOT ( map ()));
connect ( signalMapper , SIGNAL ( mapped ( int )), this , SLOT ( setZoomLevel ( int )));
2016-11-29 14:18:39 +09:00
#ifdef __APPLE__
2017-02-13 11:44:53 +00:00
#ifdef PGADMIN4_USE_WEBENGINE
2016-11-29 14:18:39 +09:00
QShortcut * cut_shortcut = new QShortcut ( QKeySequence ( "Ctrl+X" ), this );
QObject :: connect ( cut_shortcut , SIGNAL ( activated ()), this , SLOT ( onMacCut ()));
QShortcut * copy_shortcut = new QShortcut ( QKeySequence ( "Ctrl+C" ), this );
QObject :: connect ( copy_shortcut , SIGNAL ( activated ()), this , SLOT ( onMacCopy ()));
QShortcut * paste_shortcut = new QShortcut ( QKeySequence ( "Ctrl+V" ), this );
QObject :: connect ( paste_shortcut , SIGNAL ( activated ()), this , SLOT ( onMacPaste ()));
#endif
#endif
2013-06-16 14:17:46 +01:00
}
2016-11-29 14:18:39 +09:00
#ifdef __APPLE__
2017-02-13 11:44:53 +00:00
#ifdef PGADMIN4_USE_WEBENGINE
2016-11-29 14:18:39 +09:00
// Find current tab widget's webview widget and trigger the respective events of web page
void BrowserWindow :: triggerWebViewWindowEvents ( QWebEnginePage :: WebAction action )
{
WebViewWindow * webviewPtr = NULL ;
// Find current selected index from the view and set the cut/copy/paste events.
int index = m_tabWidget -> currentIndex ();
// If main web view window is pgAdmin then we should return from here after triggering events
if ( index == 0 )
{
m_mainWebView -> triggerPageAction ( action );
return ;
}
// if multiple webviews are opened then trigger cut/copy/paste events to respective webviews.
QWidget * tab = m_tabWidget -> widget ( index );
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 -> triggerPageAction ( action );
}
}
}
}
// Trigger web page's cut event
void BrowserWindow :: onMacCut ()
{
triggerWebViewWindowEvents ( QWebEnginePage :: Cut );
}
// Trigger web page's copy event
void BrowserWindow :: onMacCopy ()
{
triggerWebViewWindowEvents ( QWebEnginePage :: Copy );
}
// Trigger web page's paste event
void BrowserWindow :: onMacPaste ()
{
triggerWebViewWindowEvents ( QWebEnginePage :: Paste );
}
#endif
#endif
2013-06-22 00:49:40 +01:00
2016-01-18 14:33:28 +00:00
// Check if Tab is already open with given URL name
int BrowserWindow :: findURLTab ( const QUrl & name )
{
int tabCount = 0 ;
WebViewWindow * webviewPtr = NULL ;
2016-09-22 12:37:38 +01:00
for ( tabCount = 1 ; tabCount < m_tabWidget -> count (); tabCount ++ )
2016-01-18 14:33:28 +00:00
{
QWidget * tab = m_tabWidget -> widget ( tabCount );
if ( tab != NULL )
{
QList < QWidget *> widgetList = tab -> findChildren < QWidget *> ();
foreach ( QWidget * widgetPtr , widgetList )
{
if ( widgetPtr != NULL )
{
2016-09-22 12:37:38 +01:00
webviewPtr = dynamic_cast < WebViewWindow *> ( widgetPtr );
2016-01-18 14:33:28 +00:00
2016-09-22 12:37:38 +01:00
if ( webviewPtr != NULL && ! QString :: compare ( webviewPtr -> getFirstLoadURL (), name . host (), Qt :: CaseInsensitive ))
{
m_tabWidget -> setCurrentIndex ( tabCount );
return 1 ;
2016-01-18 14:33:28 +00:00
}
}
}
}
}
return 0 ;
}
2017-02-13 11:44:53 +00:00
#ifdef PGADMIN4_USE_WEBENGINE
2016-11-08 10:54:34 +00:00
// Below slot will be called when user start download (Only for QWebEngine. Qt version >= 5.5)
void BrowserWindow :: downloadRequested ( QWebEngineDownloadItem * download )
{
// Save the web engine download item state. it require when user cancel the download.
if ( download != NULL )
m_download = download ;
// Extract filename and query from encoded URL
QUrlQuery query_data ( download -> url ());
QString file_name = query_data . queryItemValue ( "filename" );
QString query = query_data . queryItemValue ( "query" );
if ( m_downloadStarted )
{
// Inform user that download is already started
QMessageBox :: information ( this , tr ( "Download warning" ), tr ( "File download already in progress: %1" ). arg ( m_defaultFilename ));
return ;
}
// If encoded URL contains 'filename' attribute then use that filename in file dialog.
if ( file_name . isEmpty () && query . isEmpty ())
m_defaultFilename = QFileInfo ( download -> url (). toString ()). fileName ();
else
m_defaultFilename = file_name ;
QFileDialog save_dialog ( this );
save_dialog . setAcceptMode ( QFileDialog :: AcceptSave );
save_dialog . setWindowTitle ( tr ( "Save file" ));
save_dialog . setDirectory ( m_last_open_folder_path );
save_dialog . selectFile ( m_defaultFilename );
QObject :: connect ( & save_dialog , SIGNAL ( directoryEntered ( const QString & )), this , SLOT ( current_dir_path ( const QString & )));
m_dir = m_last_open_folder_path ;
QString fileName = "" ;
QString f_name = "" ;
if ( save_dialog . exec () == QDialog :: Accepted ) {
fileName = save_dialog . selectedFiles (). first ();
f_name = fileName . replace ( m_dir , "" );
// Remove the first character(/) from fiename
f_name . remove ( 0 , 1 );
m_defaultFilename = f_name ;
}
else
return ;
fileName = m_dir + fileName ;
// Clear last open folder path
m_dir . clear ();
#ifdef __APPLE__
// Check that user has given valid file name or not - forward slash is not allowed in file name
// In Mac OSX, forward slash is converted to colon(:) by Qt so we need to check for colon.
if ( f_name . indexOf ( ":" ) != - 1 )
{
QMessageBox :: information ( this , tr ( "File name error" ), tr ( "Invalid file name" ));
return ;
}
#else
// Check that user has given valid file name or not - forward slash is not allowed in file name
if ( f_name . indexOf ( "/" ) != - 1 )
{
QMessageBox :: information ( this , tr ( "File name error" ), tr ( "Invalid file name" ));
return ;
}
#endif
if ( fileName . isEmpty ())
return ;
else
{
m_downloadFilename = fileName ;
if ( download != NULL )
{
m_downloadStarted = 1 ;
m_downloadCancelled = 0 ;
connect ( download , SIGNAL ( downloadProgress ( qint64 , qint64 )), this , SLOT ( downloadEngineFileProgress ( qint64 , qint64 )));
connect ( download , SIGNAL ( finished ()), this , SLOT ( downloadEngineFinished ()));
download -> setPath ( m_downloadFilename );
download -> accept ();
}
}
}
#endif
2016-07-13 12:26:24 +01:00
// Below slot will be called when user right click on download link and select "Save Link..." option from context menu
void BrowserWindow :: download ( const QNetworkRequest & request )
{
// Check that request contains data for download at client side
QUrl name ;
if ( m_downloadStarted )
{
// Inform user that a download is already started
QMessageBox :: information ( this , tr ( "Download warning" ), tr ( "File download already in progress: %1" ). arg ( m_defaultFilename ));
return ;
}
m_defaultFilename = QFileInfo ( request . url (). toString ()). fileName ();
// Open the dialog to save file
QFileDialog save_dialog ( this );
save_dialog . setAcceptMode ( QFileDialog :: AcceptSave );
save_dialog . setWindowTitle ( tr ( "Save file" ));
save_dialog . setDirectory ( m_last_open_folder_path );
save_dialog . selectFile ( m_defaultFilename );
// Register the slot for directory travesing when file dialog is opened and save the last open directory
QObject :: connect ( & save_dialog , SIGNAL ( directoryEntered ( const QString & )), this , SLOT ( current_dir_path ( const QString & )));
m_dir = m_last_open_folder_path ;
QString fileName = "" ;
QString f_name = "" ;
if ( save_dialog . exec () == QDialog :: Accepted ) {
fileName = save_dialog . selectedFiles (). first ();
f_name = fileName . replace ( m_dir , "" );
2016-09-22 12:37:38 +01:00
2016-07-13 12:26:24 +01:00
// Remove the first character(/) from fiename
f_name . remove ( 0 , 1 );
m_defaultFilename = f_name ;
}
else
return ;
fileName = m_dir + fileName ;
// Clear the last open directory path
m_dir . clear ();
#ifdef __APPLE__
// Check that user has given valid file name or not - forward slash is not allowed in file name
// In Mac OSX, forward slash is converted to colon(:) by Qt so we need to check for colon.
if ( f_name . indexOf ( ":" ) != - 1 )
{
QMessageBox :: information ( this , tr ( "File name error" ), tr ( "Invalid file name" ));
return ;
}
#else
// Check that user has given valid file name or not - forward slash is not allowed in file name
if ( f_name . indexOf ( "/" ) != - 1 )
{
QMessageBox :: information ( this , tr ( "File name error" ), tr ( "Invalid file name" ));
return ;
}
#endif
if ( fileName . isEmpty ())
return ;
else
{
m_downloadFilename = fileName ;
QNetworkRequest newRequest = request ;
newRequest . setAttribute ( QNetworkRequest :: User , fileName );
QObject * obj_web_page = QObject :: sender ();
if ( obj_web_page != NULL )
{
2017-02-13 11:44:53 +00:00
#ifdef PGADMIN4_USE_WEBENGINE
2016-11-08 10:54:34 +00:00
WebEnginePage * sender_web_page = dynamic_cast < WebEnginePage *> ( obj_web_page );
#else
2016-07-13 12:26:24 +01:00
QWebPage * sender_web_page = dynamic_cast < QWebPage *> ( obj_web_page );
2016-11-08 10:54:34 +00:00
#endif
2016-07-13 12:26:24 +01:00
if ( sender_web_page != NULL )
{
2017-02-13 11:44:53 +00:00
#ifdef PGADMIN4_USE_WEBKIT
2016-07-13 12:26:24 +01:00
QNetworkAccessManager * networkManager = sender_web_page -> networkAccessManager ();
QNetworkReply * reply = networkManager -> get ( newRequest );
if ( reply != NULL )
{
m_downloadStarted = 1 ;
m_downloadCancelled = 0 ;
2016-09-22 12:37:38 +01:00
2017-11-20 14:43:34 +00:00
// Download is started so open the file
if ( ! m_file )
{
if ( ! m_downloadFilename . isEmpty ())
{
m_file = new QFile ( m_downloadFilename );
if ( ! m_file -> open ( QIODevice :: WriteOnly ))
{
qDebug () << "Error opening file: " << m_downloadFilename ;
m_downloadFilename . clear ();
m_defaultFilename . clear ();
m_downloadStarted = 0 ;
return ;
}
// Create progress bar dialog
m_progressDialog = new QProgressDialog ( tr ( "Downloading file: %1 " ). arg ( m_defaultFilename ), "Cancel" , 0 , 100 , this );
m_progressDialog -> setWindowModality ( Qt :: WindowModal );
m_progressDialog -> setWindowTitle ( tr ( "Download progress" ));
m_progressDialog -> setMinimumWidth ( 450 );
m_progressDialog -> setMinimumHeight ( 80 );
m_progressDialog -> setWindowFlags ( Qt :: Window | Qt :: CustomizeWindowHint | Qt :: WindowMinimizeButtonHint | Qt :: WindowCloseButtonHint );
// Register slot for file download cancel request
QObject :: connect ( m_progressDialog , SIGNAL ( canceled ()), this , SLOT ( progressCanceled ()));
m_reply = reply ;
// Show downloading progress bar
m_progressDialog -> show ();
}
}
2016-09-22 12:37:38 +01:00
// Connect the signals for downloadProgress and downloadFinished
2017-11-20 14:43:34 +00:00
connect ( reply , SIGNAL ( readyRead ()), this , SLOT ( replyReady ()));
2016-07-13 12:26:24 +01:00
connect ( reply , SIGNAL ( downloadProgress ( qint64 , qint64 )), this , SLOT ( downloadFileProgress ( qint64 , qint64 )) );
connect ( reply , SIGNAL ( finished ()), this , SLOT ( downloadFinished ()));
}
2016-11-08 10:54:34 +00:00
#endif
2016-07-13 12:26:24 +01:00
}
}
}
}
2017-02-13 11:44:53 +00:00
#ifdef PGADMIN4_USE_WEBENGINE
2016-11-08 10:54:34 +00:00
// Below slot will be called when file download is in progress ( Only for QWebEngine Qt version >= 5.5 )
void BrowserWindow :: downloadEngineFileProgress ( qint64 readData , qint64 totalData )
{
// Check if progress dialog is already opened then only update the progress bar status
if ( ! m_progressDialog )
{
// Create progress bar dialog
m_progressDialog = new QProgressDialog ( tr ( "Downloading file: %1 " ). arg ( m_defaultFilename ), "Cancel" , 0 , totalData , this );
m_progressDialog -> setWindowModality ( Qt :: WindowModal );
m_progressDialog -> setWindowTitle ( tr ( "Download progress" ));
m_progressDialog -> setMinimumWidth ( 450 );
m_progressDialog -> setMinimumHeight ( 80 );
m_progressDialog -> setWindowFlags ( Qt :: Window | Qt :: CustomizeWindowHint | Qt :: WindowMinimizeButtonHint | Qt :: WindowCloseButtonHint );
// Register slot for file download cancel request
QObject :: connect ( m_progressDialog , SIGNAL ( canceled ()), this , SLOT ( progressCanceled ()));
// Show downloading progress bar
m_progressDialog -> show ();
}
else
m_progressDialog -> setValue ( readData );
}
#endif
2017-11-20 14:43:34 +00:00
// Below slot will be called when data are available for download.
void BrowserWindow :: replyReady ()
{
is_readyReadSignaled = true ;
// When download is canceled by user then no need to write data to file
if ( m_downloadCancelled )
return ;
// Write the data received from network to file.
if ( m_reply != NULL && m_file != NULL )
{
QByteArray data = m_reply -> readAll ();
int l_size = data . size ();
m_readBytes += ( qint64 )( l_size );
m_file -> write ( data );
// Calculate size in MB to be displayed in progress bar dialog.
if ( m_progressDialog ) {
qreal k_bytes = ((( qreal ) m_readBytes ) / 1024 );
qreal m_bytes = ( k_bytes / 1024 );
QString f_str = QString :: number ( m_bytes , 'f' , 1 );
QString set_str = QString ( "Downloaded " ) + f_str + QString ( " MB" );
m_progressDialog -> setLabelText ( set_str );
}
}
}
2016-07-13 12:26:24 +01:00
// Below slot will be called when file download is in progress
void BrowserWindow :: downloadFileProgress ( qint64 readData , qint64 totalData )
{
// When download is canceled by user then no need to write data to file
if ( m_downloadCancelled )
return ;
2017-11-20 14:43:34 +00:00
if ( m_reply != NULL && m_reply -> error () != QNetworkReply :: NoError )
2016-07-13 12:26:24 +01:00
{
qDebug () << "Network error occurred whilst downloading: " << m_defaultFilename ;
return ;
}
2017-11-20 14:43:34 +00:00
if ( m_file )
2016-07-13 12:26:24 +01:00
{
2017-11-20 14:43:34 +00:00
// Only update the status in progress bar as percentage.
if ( ! is_readyReadSignaled )
2016-07-13 12:26:24 +01:00
{
2017-11-20 14:43:34 +00:00
m_progressDialog -> setRange ( 0 , totalData );
m_progressDialog -> setValue ( readData );
2016-07-13 12:26:24 +01:00
}
2017-11-20 14:43:34 +00:00
// Check if download is finished without readyRead signal then write the data.
2017-12-19 12:20:01 +00:00
if ( m_reply && m_reply -> isFinished () && ! is_readyReadSignaled )
2016-07-13 12:26:24 +01:00
{
2017-11-20 14:43:34 +00:00
// Write data to file
m_file -> write ( m_reply -> read ( readData ));
is_readyReadSignaled = false ;
2016-07-13 12:26:24 +01:00
// As downloading is finished so remove progress bar dialog
if ( m_progressDialog )
{
2016-07-25 12:39:57 +01:00
m_progressDialog -> deleteLater ();
2016-07-13 12:26:24 +01:00
m_progressDialog = NULL ;
}
m_downloadStarted = 0 ;
m_downloadFilename . clear ();
m_defaultFilename . clear ();
m_downloadCancelled = 0 ;
2016-09-22 12:37:38 +01:00
2016-07-13 12:26:24 +01:00
if ( m_file )
{
m_file -> close ();
delete m_file ;
m_file = NULL ;
}
if ( m_reply )
m_reply = NULL ;
}
2017-11-20 14:43:34 +00:00
2017-12-19 12:20:01 +00:00
if ( m_reply && m_reply -> isFinished () && readData == totalData )
2017-11-20 14:43:34 +00:00
m_readBytes = 0 ;
}
2016-07-13 12:26:24 +01:00
}
// Below slot will be called when user cancel the downloading file which is in progress.
void BrowserWindow :: progressCanceled ()
{
m_downloadCancelled = 1 ;
if ( m_progressDialog )
{
2016-07-25 12:39:57 +01:00
m_progressDialog -> deleteLater ();
2016-07-13 12:26:24 +01:00
m_progressDialog = NULL ;
}
2017-02-13 11:44:53 +00:00
#ifdef PGADMIN4_USE_WEBKIT
2016-07-13 12:26:24 +01:00
if ( m_file )
{
m_file -> close ();
// Remove the file from file system as downloading is canceled by user
m_file -> remove ();
delete m_file ;
m_file = NULL ;
}
if ( m_reply )
{
m_reply -> abort ();
m_reply = NULL ;
}
2016-11-08 10:54:34 +00:00
#else
m_download -> cancel ();
#endif
m_downloadFilename . clear ();
m_defaultFilename . clear ();
m_downloadStarted = 0 ;
2017-11-20 14:43:34 +00:00
is_readyReadSignaled = false ;
m_readBytes = 0 ;
2016-11-08 10:54:34 +00:00
}
2017-02-13 11:44:53 +00:00
#ifdef PGADMIN4_USE_WEBENGINE
// Below slot will called when file download is finished (Only for QWebEngine)
2016-11-08 10:54:34 +00:00
void BrowserWindow :: downloadEngineFinished ()
{
// Check download finished state.
if ( m_download )
{
QWebEngineDownloadItem :: DownloadState state = m_download -> state ();
switch ( state )
{
case QWebEngineDownloadItem :: DownloadRequested :
case QWebEngineDownloadItem :: DownloadInProgress :
Q_UNREACHABLE ();
break ;
case QWebEngineDownloadItem :: DownloadCompleted :
case QWebEngineDownloadItem :: DownloadCancelled :
case QWebEngineDownloadItem :: DownloadInterrupted :
m_download = NULL ;
break ;
}
}
if ( m_progressDialog )
{
m_progressDialog -> deleteLater ();
m_progressDialog = NULL ;
}
2016-07-13 12:26:24 +01:00
m_downloadFilename . clear ();
m_defaultFilename . clear ();
m_downloadStarted = 0 ;
2016-11-08 10:54:34 +00:00
m_downloadCancelled = 0 ;
2016-07-13 12:26:24 +01:00
}
2016-11-08 10:54:34 +00:00
#endif
2016-07-13 12:26:24 +01:00
// Below slot will called when file download is finished
void BrowserWindow :: downloadFinished ()
{
if ( m_progressDialog )
{
2016-07-25 12:39:57 +01:00
m_progressDialog -> deleteLater ();
2016-07-13 12:26:24 +01:00
m_progressDialog = NULL ;
}
m_downloadFilename . clear ();
m_defaultFilename . clear ();
m_downloadStarted = 0 ;
m_downloadCancelled = 0 ;
2017-11-20 14:43:34 +00:00
is_readyReadSignaled = false ;
m_readBytes = 0 ;
2016-09-22 12:37:38 +01:00
2016-07-13 12:26:24 +01:00
if ( m_file )
{
m_file -> close ();
delete m_file ;
m_file = NULL ;
}
if ( m_reply )
m_reply = NULL ;
}
// Below slot will be called when user directly click on any download link
void BrowserWindow :: unsupportedContent ( QNetworkReply * reply )
{
2016-07-25 12:39:57 +01:00
#if QT_VERSION >= 0x050000
2016-07-18 15:28:20 +01:00
// Extract filename and query from encoded URL
QUrlQuery query_data ( reply -> url ());
QString file_name = query_data . queryItemValue ( "filename" );
QString query = query_data . queryItemValue ( "query" );
2016-07-25 12:39:57 +01:00
#else
QUrl url ( reply -> url ());
QString file_name = url . queryItemValue ( "filename" );
QString query = url . queryItemValue ( "query" );
#endif
2016-07-18 15:28:20 +01:00
2016-07-13 12:26:24 +01:00
if ( m_downloadStarted )
{
// Inform user that download is already started
QMessageBox :: information ( this , tr ( "Download warning" ), tr ( "File download already in progress: %1" ). arg ( m_defaultFilename ));
return ;
}
2016-07-18 15:28:20 +01:00
// If encoded URL contains 'filename' attribute then use that filename in file dialog.
if ( file_name . isEmpty () && query . isEmpty ())
m_defaultFilename = QFileInfo ( reply -> url (). toString ()). fileName ();
else
m_defaultFilename = file_name ;
2016-07-13 12:26:24 +01:00
QFileDialog save_dialog ( this );
save_dialog . setAcceptMode ( QFileDialog :: AcceptSave );
save_dialog . setWindowTitle ( tr ( "Save file" ));
save_dialog . setDirectory ( m_last_open_folder_path );
save_dialog . selectFile ( m_defaultFilename );
QObject :: connect ( & save_dialog , SIGNAL ( directoryEntered ( const QString & )), this , SLOT ( current_dir_path ( const QString & )));
m_dir = m_last_open_folder_path ;
QString fileName = "" ;
QString f_name = "" ;
if ( save_dialog . exec () == QDialog :: Accepted ) {
fileName = save_dialog . selectedFiles (). first ();
f_name = fileName . replace ( m_dir , "" );
// Remove the first character(/) from fiename
f_name . remove ( 0 , 1 );
m_defaultFilename = f_name ;
}
else
return ;
fileName = m_dir + fileName ;
// Clear last open folder path
m_dir . clear ();
#ifdef __APPLE__
// Check that user has given valid file name or not - forward slash is not allowed in file name
// In Mac OSX, forward slash is converted to colon(:) by Qt so we need to check for colon.
if ( f_name . indexOf ( ":" ) != - 1 )
{
QMessageBox :: information ( this , tr ( "File name error" ), tr ( "Invalid file name" ));
return ;
}
#else
// Check that user has given valid file name or not - forward slash is not allowed in file name
if ( f_name . indexOf ( "/" ) != - 1 )
{
QMessageBox :: information ( this , tr ( "File name error" ), tr ( "Invalid file name" ));
return ;
}
#endif
if ( fileName . isEmpty ())
return ;
else
{
m_downloadFilename = fileName ;
if ( reply != NULL )
{
m_downloadStarted = 1 ;
m_downloadCancelled = 0 ;
2017-11-20 14:43:34 +00:00
// Download is started so open the file
if ( ! m_file )
{
if ( ! m_downloadFilename . isEmpty ())
{
m_file = new QFile ( m_downloadFilename );
if ( ! m_file -> open ( QIODevice :: WriteOnly ))
{
qDebug () << "Error opening file: " << m_downloadFilename ;
m_downloadFilename . clear ();
m_defaultFilename . clear ();
m_downloadStarted = 0 ;
return ;
}
// Create progress bar dialog
m_progressDialog = new QProgressDialog ( tr ( "Downloading file: %1 " ). arg ( m_defaultFilename ), "Cancel" , 0 , 100 , this );
m_progressDialog -> setWindowModality ( Qt :: WindowModal );
m_progressDialog -> setWindowTitle ( tr ( "Download progress" ));
m_progressDialog -> setMinimumWidth ( 450 );
m_progressDialog -> setMinimumHeight ( 80 );
m_progressDialog -> setWindowFlags ( Qt :: Window | Qt :: CustomizeWindowHint | Qt :: WindowMinimizeButtonHint | Qt :: WindowCloseButtonHint );
// Register slot for file download cancel request
QObject :: connect ( m_progressDialog , SIGNAL ( canceled ()), this , SLOT ( progressCanceled ()));
m_reply = reply ;
// Show downloading progress bar
m_progressDialog -> show ();
}
}
connect ( reply , SIGNAL ( readyRead ()), this , SLOT ( replyReady ()));
2016-07-13 12:26:24 +01:00
connect ( reply , SIGNAL ( downloadProgress ( qint64 , qint64 )), this , SLOT ( downloadFileProgress ( qint64 , qint64 )));
connect ( reply , SIGNAL ( finished ()), this , SLOT ( downloadFinished ()));
}
}
}
2016-01-18 14:33:28 +00:00
// Slot: set the title of tab when the new tab created or existing tab contents changed
void BrowserWindow :: tabTitleChanged ( const QString & str )
{
2017-06-16 09:57:19 +01:00
WebViewWindow * nextWebViewPtr = NULL ;
bool flagTabText = false ;
QToolButton * backToolButton = NULL ;
QToolButton * forwardToolButton = NULL ;
2016-01-18 14:33:28 +00:00
if ( ! str . isEmpty ())
{
QObject * senderPtr = QObject :: sender ();
WebViewWindow * webViewPtr = NULL ;
if ( senderPtr != NULL )
{
webViewPtr = dynamic_cast < WebViewWindow *> ( senderPtr );
if ( webViewPtr != NULL )
{
2017-06-16 09:57:19 +01:00
DockTabWidget * dock_tab_widget = dynamic_cast < DockTabWidget *> ( webViewPtr -> parent () -> parent () -> parent ());
if ( dock_tab_widget != NULL )
{
for ( int loopCount = dock_tab_widget -> count (); loopCount >= 0 ; loopCount -- )
{
QWidget * tab = dock_tab_widget -> widget ( loopCount );
if ( tab != NULL )
{
QList < QWidget *> widgetList = tab -> findChildren < QWidget *> ();
foreach ( QWidget * widgetPtr , widgetList )
{
if ( widgetPtr != NULL )
nextWebViewPtr = dynamic_cast < WebViewWindow *> ( widgetPtr );
if ( nextWebViewPtr != NULL && nextWebViewPtr == webViewPtr )
{
// If tab title is for Query tool then we should hide tool buttons.
QWidget * tab = dock_tab_widget -> tabBar () -> tabButton ( loopCount , QTabBar :: LeftSide );
if ( tab != NULL )
{
QList < QWidget *> widgetList = tab -> findChildren < QWidget *> ();
foreach ( QWidget * widgetPtr , widgetList )
{
if ( widgetPtr != NULL )
{
QToolButton * toolBtnPtr = dynamic_cast < QToolButton *> ( widgetPtr );
if ( toolBtnPtr != NULL )
{
if ( ! QString :: compare ( toolBtnPtr -> toolTip (), tr ( "Go back" ), Qt :: CaseInsensitive ))
backToolButton = toolBtnPtr ;
if ( ! QString :: compare ( toolBtnPtr -> toolTip (), tr ( "Go forward" ), Qt :: CaseInsensitive ))
forwardToolButton = toolBtnPtr ;
}
}
}
}
if ( backToolButton != NULL && forwardToolButton != NULL )
{
if ( ! str . startsWith ( "Query -" ))
{
if ( str . startsWith ( "Debugger" ))
{
backToolButton -> hide ();
forwardToolButton -> hide ();
webViewPtr -> setBackForwardButtonHidden ( true );
}
// 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.
else if ( ! webViewPtr -> getBackForwardButtonHidden ())
{
backToolButton -> show ();
forwardToolButton -> show ();
webViewPtr -> setBackForwardButtonHidden ( false );
}
}
else
{
backToolButton -> hide ();
forwardToolButton -> hide ();
webViewPtr -> setBackForwardButtonHidden ( true );
}
}
dock_tab_widget -> setTabText ( loopCount , str );
dock_tab_widget -> setTabToolTipText ( loopCount , str );
dock_tab_widget -> enableDisableToolButton ( loopCount );
flagTabText = true ;
break ;
}
}
}
if ( flagTabText )
break ;
}
if ( ! flagTabText )
{
dock_tab_widget -> setTabText ( dock_tab_widget -> currentIndex (), str );
dock_tab_widget -> setTabToolTipText ( dock_tab_widget -> currentIndex (), str );
dock_tab_widget -> enableDisableToolButton ( dock_tab_widget -> currentIndex ());
}
}
2016-01-18 14:33:28 +00:00
}
}
}
}
2017-05-09 13:03:44 +05:30
2016-07-13 12:26:24 +01:00
void BrowserWindow :: current_dir_path ( const QString & dir )
{
m_dir = dir ;
m_last_open_folder_path = dir ;
2016-07-18 15:28:20 +01:00
QSettings settings ;
settings . setValue ( "Browser/LastSaveLocation" , m_last_open_folder_path );
2016-07-13 12:26:24 +01:00
}
2017-05-09 13:03:44 +05:30
#ifndef PGADMIN4_USE_WEBENGINE
void BrowserWindow :: createNewTabWindowKit ( QWebPage * & p )
{
m_addNewTab = new QWidget ( m_tabWidget );
2017-06-16 09:57:19 +01:00
2017-05-09 13:03:44 +05:30
m_addNewGridLayout = new QGridLayout ( m_addNewTab );
m_addNewGridLayout -> setContentsMargins ( 0 , 0 , 0 , 0 );
2017-06-16 09:57:19 +01:00
2017-05-09 13:03:44 +05:30
m_addNewWebView = new WebViewWindow ( m_addNewTab );
m_addNewWebView -> setPage ( new WebViewPage ());
m_addNewWebView -> setZoomFactor ( m_mainWebView -> zoomFactor ());
2017-06-16 09:57:19 +01:00
// Register the slot when click on the URL link form main menu bar
connect ( m_addNewWebView , SIGNAL ( linkClicked ( const QUrl & )), SLOT ( urlLinkClicked ( const QUrl & )));
// Register the slot when click on the URL link for QWebPage
connect ( m_addNewWebView -> page (), SIGNAL ( createTabWindowKit ( QWebPage * & )), SLOT ( createNewTabWindowKit ( QWebPage * & )));
m_addNewWebView -> page () -> setForwardUnsupportedContent ( true );
connect ( m_addNewWebView -> page (), SIGNAL ( downloadRequested ( const QNetworkRequest & )), this , SLOT ( download ( const QNetworkRequest & )));
connect ( m_addNewWebView -> page (), SIGNAL ( unsupportedContent ( QNetworkReply * )), this , SLOT ( unsupportedContent ( QNetworkReply * )));
m_addNewWebView -> page () -> setLinkDelegationPolicy ( QWebPage :: DelegateAllLinks );
2017-05-09 13:03:44 +05:30
m_addNewWebView -> settings () -> setAttribute ( QWebSettings :: JavascriptEnabled , true );
m_addNewWebView -> settings () -> setAttribute ( QWebSettings :: JavascriptCanOpenWindows , true );
m_widget = new QWidget ( m_addNewTab );
2017-06-16 09:57:19 +01:00
2017-05-09 13:03:44 +05:30
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" ));
2017-06-16 09:57:19 +01:00
m_toolBtnBack -> hide ();
2017-05-09 13:03:44 +05:30
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" ));
2017-06-16 09:57:19 +01:00
m_toolBtnForward -> hide ();
2017-05-09 13:03:44 +05:30
2017-06-16 09:57:19 +01:00
QToolButton * m_btnClose = new QToolButton ( m_widget );
2017-05-09 13:03:44 +05:30
m_btnClose -> setFixedHeight ( PGA_BTN_SIZE );
m_btnClose -> setFixedWidth ( PGA_BTN_SIZE );
m_btnClose -> setIcon ( QIcon ( ":/close.png" ));
m_btnClose -> setToolTip ( tr ( "Close tab" ));
m_horizontalLayout = new QHBoxLayout ( m_widget );
2017-06-16 09:57:19 +01:00
m_horizontalLayout -> setContentsMargins ( 0 , 1 , 0 , 0 );
2017-05-09 13:03:44 +05:30
m_horizontalLayout -> setSizeConstraint ( QLayout :: SetMinAndMaxSize );
m_horizontalLayout -> setSpacing ( 1 );
m_horizontalLayout -> addWidget ( m_toolBtnBack );
m_horizontalLayout -> addWidget ( m_toolBtnForward );
// Register the slot on titleChange so set the tab text accordingly
connect ( m_addNewWebView , SIGNAL ( titleChanged ( const QString & )), SLOT ( tabTitleChanged ( const QString & )));
// Register the slot on toolbutton to show the previous history of web
2017-06-16 09:57:19 +01:00
connect ( m_toolBtnBack , SIGNAL ( clicked ()), m_tabWidget , SLOT ( dockGoBackPage ()));
2017-05-09 13:03:44 +05:30
// Register the slot on toolbutton to show the next history of web
2017-06-16 09:57:19 +01:00
connect ( m_toolBtnForward , SIGNAL ( clicked ()), m_tabWidget , SLOT ( dockGoForwardPage ()));
2017-05-09 13:03:44 +05:30
// Register the slot on close button , added manually
2017-06-16 09:57:19 +01:00
connect ( m_btnClose , SIGNAL ( clicked ()), m_tabWidget , SLOT ( dockClosetabs ()));
2017-05-09 13:03:44 +05:30
m_addNewGridLayout -> addWidget ( m_addNewWebView , 0 , 0 , 1 , 1 );
m_tabWidget -> addTab ( m_addNewTab , QString ());
m_tabWidget -> tabBar () -> setVisible ( true );
m_tabWidget -> setCurrentIndex (( m_tabWidget -> count () - 1 ));
// Set the back and forward button on tab
m_tabWidget -> tabBar () -> setTabButton (( m_tabWidget -> count () - 1 ), QTabBar :: LeftSide , m_widget );
m_tabWidget -> tabBar () -> setTabButton (( m_tabWidget -> count () - 1 ), QTabBar :: RightSide , m_btnClose );
m_addNewWebView -> setTabIndex (( m_tabWidget -> count () - 1 ));
m_addNewWebView -> page () -> setNetworkAccessManager ( m_netAccessMan );
p = m_addNewWebView -> page ();
}
#endif
2017-02-13 11:44:53 +00:00
#ifdef PGADMIN4_USE_WEBENGINE
2016-11-08 10:54:34 +00:00
// Below slot will be called when link is required to open in new tab.
void BrowserWindow :: createNewTabWindow ( QWebEnginePage * & p )
{
m_addNewTab = new QWidget ( m_tabWidget );
2017-06-16 09:57:19 +01:00
2016-11-08 10:54:34 +00:00
m_addNewGridLayout = new QGridLayout ( m_addNewTab );
m_addNewGridLayout -> setContentsMargins ( 0 , 0 , 0 , 0 );
2017-06-16 09:57:19 +01:00
m_addNewWebView = new WebViewWindow ();
2016-11-08 10:54:34 +00:00
m_addNewWebView -> setPage ( new WebEnginePage ());
m_addNewWebView -> setZoomFactor ( m_mainWebView -> zoomFactor ());
m_widget = new QWidget ( m_addNewTab );
2017-06-16 09:57:19 +01:00
2016-11-08 10:54:34 +00:00
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" ));
2017-06-16 09:57:19 +01:00
m_toolBtnBack -> hide ();
2016-11-08 10:54:34 +00:00
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" ));
2017-06-16 09:57:19 +01:00
m_toolBtnForward -> hide ();
2016-11-08 10:54:34 +00:00
2017-06-16 09:57:19 +01:00
m_toolBtnClose = new QToolButton ( m_widget );
m_toolBtnClose -> setFixedHeight ( PGA_BTN_SIZE );
m_toolBtnClose -> setFixedWidth ( PGA_BTN_SIZE );
m_toolBtnClose -> setIcon ( QIcon ( ":/close.png" ));
m_toolBtnClose -> setToolTip ( tr ( "Close tab" ));
2016-11-08 10:54:34 +00:00
m_horizontalLayout = new QHBoxLayout ( m_widget );
2017-06-16 09:57:19 +01:00
m_horizontalLayout -> setContentsMargins ( 0 , 1 , 0 , 0 );
2016-11-08 10:54:34 +00:00
m_horizontalLayout -> setSizeConstraint ( QLayout :: SetMinAndMaxSize );
m_horizontalLayout -> setSpacing ( 1 );
m_horizontalLayout -> addWidget ( m_toolBtnBack );
m_horizontalLayout -> addWidget ( m_toolBtnForward );
// Register the slot on titleChange so set the tab text accordingly
connect ( m_addNewWebView , SIGNAL ( titleChanged ( const QString & )), SLOT ( tabTitleChanged ( const QString & )));
// Register the slot on toolbutton to show the previous history of web
2017-06-16 09:57:19 +01:00
connect ( m_toolBtnBack , SIGNAL ( clicked ()), m_tabWidget , SLOT ( dockGoBackPage ()));
2016-11-08 10:54:34 +00:00
// Register the slot on toolbutton to show the next history of web
2017-06-16 09:57:19 +01:00
connect ( m_toolBtnForward , SIGNAL ( clicked ()), m_tabWidget , SLOT ( dockGoForwardPage ()));
2016-11-08 10:54:34 +00:00
// Register the slot on close button , added manually
2017-06-16 09:57:19 +01:00
connect ( m_toolBtnClose , SIGNAL ( clicked ()), m_tabWidget , SLOT ( dockClosetabs ()));
2016-11-08 10:54:34 +00:00
m_addNewGridLayout -> addWidget ( m_addNewWebView , 0 , 0 , 1 , 1 );
m_tabWidget -> addTab ( m_addNewTab , QString ());
m_tabWidget -> tabBar () -> setVisible ( true );
m_tabWidget -> setCurrentIndex (( m_tabWidget -> count () - 1 ));
// Set the back and forward button on tab
m_tabWidget -> tabBar () -> setTabButton (( m_tabWidget -> count () - 1 ), QTabBar :: LeftSide , m_widget );
2017-06-16 09:57:19 +01:00
m_tabWidget -> tabBar () -> setTabButton (( m_tabWidget -> count () - 1 ), QTabBar :: RightSide , m_toolBtnClose );
2016-11-08 10:54:34 +00:00
m_addNewWebView -> setTabIndex (( m_tabWidget -> count () - 1 ));
p = m_addNewWebView -> page ();
}
#endif
2016-01-18 14:33:28 +00:00
// Slot: Link is open from pgAdmin mainwindow
void BrowserWindow :: urlLinkClicked ( const QUrl & name )
{
2016-07-13 12:26:24 +01:00
// Check that request contains the data download at client side
QNetworkRequest request ;
2016-01-18 14:33:28 +00:00
// First check is there any tab opened with same URL then open it again.
int tabFound = findURLTab ( name );
if ( ! tabFound )
{
m_addNewTab = new QWidget ( m_tabWidget );
2017-06-16 09:57:19 +01:00
2016-01-18 14:33:28 +00:00
m_addNewGridLayout = new QGridLayout ( m_addNewTab );
m_addNewGridLayout -> setContentsMargins ( 0 , 0 , 0 , 0 );
2017-06-16 09:57:19 +01:00
m_addNewWebView = new WebViewWindow ();
2016-09-22 14:43:32 +01:00
m_addNewWebView -> setZoomFactor ( m_mainWebView -> zoomFactor ());
2016-01-18 14:33:28 +00:00
2016-09-22 12:37:38 +01:00
// Listen for the download request from the web page
2017-02-13 11:44:53 +00:00
#ifdef PGADMIN4_USE_WEBENGINE
2017-06-16 09:57:19 +01:00
m_addNewWebView -> setPage ( new WebEnginePage ());
2016-11-08 10:54:34 +00:00
connect ( m_addNewWebView -> page () -> profile (), SIGNAL ( downloadRequested ( QWebEngineDownloadItem * )), this , SLOT ( downloadRequested ( QWebEngineDownloadItem * )));
#else
2017-06-16 09:57:19 +01:00
m_addNewWebView -> setPage ( new WebViewPage ());
2016-09-22 12:37:38 +01:00
m_addNewWebView -> page () -> setForwardUnsupportedContent ( true );
2016-07-13 12:26:24 +01:00
connect ( m_addNewWebView -> page (), SIGNAL ( downloadRequested ( const QNetworkRequest & )), this , SLOT ( download ( const QNetworkRequest & )));
connect ( m_addNewWebView -> page (), SIGNAL ( unsupportedContent ( QNetworkReply * )), this , SLOT ( unsupportedContent ( QNetworkReply * )));
2017-06-16 09:57:19 +01:00
// Register the slot when click on the URL link form main menu bar
connect ( m_addNewWebView , SIGNAL ( linkClicked ( const QUrl & )), SLOT ( urlLinkClicked ( const QUrl & )));
// Register the slot when click on the URL link for QWebPage
connect ( m_addNewWebView -> page (), SIGNAL ( createTabWindowKit ( QWebPage * & )), SLOT ( createNewTabWindowKit ( QWebPage * & )));
m_addNewWebView -> page () -> setLinkDelegationPolicy ( QWebPage :: DelegateAllLinks );
2016-11-08 10:54:34 +00:00
#endif
2016-07-13 12:26:24 +01:00
2016-01-18 14:33:28 +00:00
m_widget = new QWidget ( m_addNewTab );
2017-06-16 09:57:19 +01:00
2016-01-18 14:33:28 +00:00
m_toolBtnBack = new QToolButton ( m_widget );
2016-01-22 14:21:34 +00:00
m_toolBtnBack -> setFixedHeight ( PGA_BTN_SIZE );
m_toolBtnBack -> setFixedWidth ( PGA_BTN_SIZE );
2016-01-25 17:21:00 +00:00
m_toolBtnBack -> setIcon ( QIcon ( ":/back.png" ));
m_toolBtnBack -> setToolTip ( tr ( "Go back" ));
2017-06-16 09:57:19 +01:00
m_toolBtnBack -> hide ();
2016-01-18 14:33:28 +00:00
m_toolBtnForward = new QToolButton ( m_widget );
2016-01-22 14:21:34 +00:00
m_toolBtnForward -> setFixedHeight ( PGA_BTN_SIZE );
m_toolBtnForward -> setFixedWidth ( PGA_BTN_SIZE );
2016-01-25 17:21:00 +00:00
m_toolBtnForward -> setIcon ( QIcon ( ":/forward.png" ));
m_toolBtnForward -> setToolTip ( tr ( "Go forward" ));
2017-06-16 09:57:19 +01:00
m_toolBtnForward -> hide ();
2016-01-18 14:33:28 +00:00
2017-06-16 09:57:19 +01:00
m_toolBtnClose = new QToolButton ( m_widget );
m_toolBtnClose -> setFixedHeight ( PGA_BTN_SIZE );
m_toolBtnClose -> setFixedWidth ( PGA_BTN_SIZE );
m_toolBtnClose -> setIcon ( QIcon ( ":/close.png" ));
m_toolBtnClose -> setToolTip ( tr ( "Close tab" ));
2016-01-18 14:33:28 +00:00
m_horizontalLayout = new QHBoxLayout ( m_widget );
2017-06-16 09:57:19 +01:00
m_horizontalLayout -> setContentsMargins ( 0 , 1 , 0 , 0 );
2016-01-18 14:33:28 +00:00
m_horizontalLayout -> setSizeConstraint ( QLayout :: SetMinAndMaxSize );
2016-01-22 14:21:34 +00:00
m_horizontalLayout -> setSpacing ( 1 );
2016-01-18 14:33:28 +00:00
m_horizontalLayout -> addWidget ( m_toolBtnBack );
m_horizontalLayout -> addWidget ( m_toolBtnForward );
// Register the slot on titleChange so set the tab text accordingly
connect ( m_addNewWebView , SIGNAL ( titleChanged ( const QString & )), SLOT ( tabTitleChanged ( const QString & )));
// Register the slot on toolbutton to show the previous history of web
2017-06-16 09:57:19 +01:00
connect ( m_toolBtnBack , SIGNAL ( clicked ()), m_tabWidget , SLOT ( dockGoBackPage ()));
2016-01-18 14:33:28 +00:00
// Register the slot on toolbutton to show the next history of web
2017-06-16 09:57:19 +01:00
connect ( m_toolBtnForward , SIGNAL ( clicked ()), m_tabWidget , SLOT ( dockGoForwardPage ()));
2016-01-18 14:33:28 +00:00
// Register the slot on close button , added manually
2017-06-16 09:57:19 +01:00
connect ( m_toolBtnClose , SIGNAL ( clicked ()), m_tabWidget , SLOT ( dockClosetabs ()));
2016-01-18 14:33:28 +00:00
m_addNewGridLayout -> addWidget ( m_addNewWebView , 0 , 0 , 1 , 1 );
m_tabWidget -> addTab ( m_addNewTab , QString ());
2016-01-26 10:03:15 +00:00
m_tabWidget -> tabBar () -> setVisible ( true );
2016-01-18 14:33:28 +00:00
m_tabWidget -> setCurrentIndex (( m_tabWidget -> count () - 1 ));
// Set the back and forward button on tab
m_tabWidget -> tabBar () -> setTabButton (( m_tabWidget -> count () - 1 ), QTabBar :: LeftSide , m_widget );
2017-06-16 09:57:19 +01:00
m_tabWidget -> tabBar () -> setTabButton (( m_tabWidget -> count () - 1 ), QTabBar :: RightSide , m_toolBtnClose );
2016-01-18 14:33:28 +00:00
2016-02-23 09:10:49 +00:00
m_addNewWebView -> setFirstLoadURL ( name . host ());
2016-01-18 14:33:28 +00:00
m_addNewWebView -> setTabIndex (( m_tabWidget -> count () - 1 ));
m_addNewWebView -> setUrl ( name );
}
}
2013-06-22 00:49:40 +01:00
// Pause for n seconds, without freezing the UI.
void BrowserWindow :: pause ( int seconds )
{
QTime dieTime = QTime :: currentTime (). addSecs ( seconds );
while ( QTime :: currentTime () < dieTime )
QCoreApplication :: processEvents ( QEventLoop :: AllEvents , 100 );
}
2013-06-16 14:17:46 +01:00
// Display the about box
void BrowserWindow :: about ()
{
2016-01-18 14:33:28 +00:00
QMessageBox :: about ( this , tr ( "About %1" ). arg ( PGA_APP_NAME ), tr ( "%1 - PostgreSQL Tools" ). arg ( PGA_APP_NAME ));
2013-06-16 14:17:46 +01:00
}
2016-09-22 12:37:38 +01:00
2017-06-13 10:21:51 +01:00
// Set Zoom Level
void BrowserWindow :: setZoomLevel ( int zoomFlag )
2016-09-22 12:37:38 +01:00
{
int tabCount = 0 ;
WebViewWindow * webviewPtr = NULL ;
// Loop through all the tabs
for ( tabCount = 0 ; tabCount < m_tabWidget -> count (); tabCount ++ )
{
QWidget * tab = m_tabWidget -> widget ( tabCount );
if ( tab != NULL )
{
// Find and loop through any child controls
QList < QWidget *> widgetList = tab -> findChildren < QWidget *> ();
foreach ( QWidget * widgetPtr , widgetList )
{
if ( widgetPtr != NULL )
{
// If it's a web view control, set the zoom level based on the main view
webviewPtr = dynamic_cast < WebViewWindow *> ( widgetPtr );
if ( webviewPtr != NULL )
{
2017-06-13 10:21:51 +01:00
if ( zoomFlag == 1 ) {
webviewPtr -> setZoomFactor ( m_mainWebView -> zoomFactor () + 0.1 );
}
else if ( zoomFlag == - 1 ) {
webviewPtr -> setZoomFactor ( m_mainWebView -> zoomFactor () - 0.1 );
}
else if ( zoomFlag == 0 ) {
webviewPtr -> setZoomFactor ( 1.0 );
}
2016-09-22 12:37:38 +01:00
}
}
}
}
}
2017-06-13 10:21:51 +01:00
// Set the zoom value for the next time
2016-09-22 12:37:38 +01:00
QSettings settings ;
settings . setValue ( "Browser/Zoom" , m_mainWebView -> zoomFactor ());
}
2013-06-16 14:17:46 +01:00
// Open an arbitrary URL
void BrowserWindow :: openUrl ()
{
bool ok ;
2016-01-19 10:26:01 +00:00
QInputDialog * dlg = new QInputDialog ();
dlg -> setInputMode ( QInputDialog :: TextInput );
dlg -> setWindowTitle ( QWidget :: tr ( "Open URL" ));
dlg -> setLabelText ( QWidget :: tr ( "Enter a URL" ));
dlg -> setTextValue ( "http://" );
dlg -> resize ( 600 , 100 );
ok = dlg -> exec ();
QString url = dlg -> textValue ();
2013-06-16 14:17:46 +01:00
if ( ok && ! url . isEmpty ())
2016-01-19 10:26:01 +00:00
urlLinkClicked ( QUrl ( url ));
2013-06-16 14:17:46 +01:00
}
2016-01-21 09:07:48 +00:00
// Edit the app configuration
2016-06-17 11:31:52 +01:00
void BrowserWindow :: preferences ()
2014-12-16 12:53:09 +00:00
{
QSettings settings ;
bool ok ;
2016-01-19 10:26:01 +00:00
ConfigWindow * dlg = new ConfigWindow ();
dlg -> setWindowTitle ( QWidget :: tr ( "Configuration" ));
dlg -> setPythonPath ( settings . value ( "PythonPath" ). toString ());
dlg -> setApplicationPath ( settings . value ( "ApplicationPath" ). toString ());
dlg -> setModal ( true );
2016-01-18 14:33:28 +00:00
ok = dlg -> exec ();
2016-01-19 10:26:01 +00:00
QString pythonpath = dlg -> getPythonPath ();
QString applicationpath = dlg -> getApplicationPath ();
2014-12-16 12:53:09 +00:00
if ( ok )
2016-01-19 10:26:01 +00:00
{
settings . setValue ( "PythonPath" , pythonpath );
settings . setValue ( "ApplicationPath" , applicationpath );
}
2014-12-16 12:53:09 +00:00
}