mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2024-11-27 19:20:21 -06:00
0056a94115
This allows the Query Tool, Debugger and web browser tabs to be moved to different monitors as desired. Fixes #1344
1262 lines
46 KiB
C++
1262 lines
46 KiB
C++
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// pgAdmin 4 - PostgreSQL Tools
|
|
//
|
|
// Copyright (C) 2013 - 2017, The pgAdmin Development Team
|
|
// This software is released under the PostgreSQL Licence
|
|
//
|
|
// BrowserWindow.cpp - Implementation of the main window class
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "pgAdmin4.h"
|
|
|
|
#if QT_VERSION >= 0x050000
|
|
#include <QtWidgets>
|
|
#ifdef PGADMIN4_USE_WEBENGINE
|
|
#include <QtWebEngineWidgets>
|
|
#else
|
|
#include <QtWebKitWidgets>
|
|
#include <QtWebKit>
|
|
#endif
|
|
#else
|
|
|
|
#include <QAction>
|
|
#include <QMenu>
|
|
#include <QMenuBar>
|
|
#include <QMessageBox>
|
|
#include <QInputDialog>
|
|
#include <QLineEdit>
|
|
#endif
|
|
#include <QNetworkRequest>
|
|
#include <QNetworkReply>
|
|
// App headers
|
|
#include "BrowserWindow.h"
|
|
#include "ConfigWindow.h"
|
|
|
|
// Constructor
|
|
BrowserWindow::BrowserWindow(QString url)
|
|
{
|
|
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;
|
|
m_downloadStarted = 0;
|
|
m_downloadCancelled = 0;
|
|
m_file = NULL;
|
|
m_downloadFilename = "";
|
|
m_defaultFilename = "";
|
|
m_progressDialog = NULL;
|
|
m_last_open_folder_path = "";
|
|
m_dir = "";
|
|
m_reply = NULL;
|
|
#ifdef PGADMIN4_USE_WEBENGINE
|
|
m_download = NULL;
|
|
#endif
|
|
|
|
m_appServerUrl = url;
|
|
|
|
// Setup the shortcuts
|
|
createActions();
|
|
|
|
m_tabWidget = new DockTabWidget(this);
|
|
m_tabWidget->tabBar()->setVisible(false);
|
|
|
|
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);
|
|
|
|
#ifdef PGADMIN4_USE_WEBENGINE
|
|
m_mainWebView->setPage(new WebEnginePage());
|
|
#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);
|
|
#endif
|
|
|
|
#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.
|
|
#ifdef PGADMIN4_USE_WEBENGINE
|
|
// 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
|
|
QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef __APPLE__
|
|
m_mainWebView->setStyle(QStyleFactory::create("Fusion"));
|
|
#endif
|
|
|
|
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);
|
|
|
|
#ifdef PGADMIN4_USE_WEBENGINE
|
|
// Register the slot when click on the URL link for QWebEnginePage
|
|
connect(m_mainWebView->page(), SIGNAL(createTabWindow(QWebEnginePage * &)),SLOT(createNewTabWindow(QWebEnginePage * &)));
|
|
#else
|
|
// Register the slot when click on the URL link form main menu bar
|
|
connect(m_mainWebView, SIGNAL(linkClicked(const QUrl &)),SLOT(urlLinkClicked(const QUrl &)));
|
|
// Register the slot when click on the URL link for QWebPage
|
|
connect(m_mainWebView->page(), SIGNAL(createTabWindowKit(QWebPage * &)),SLOT(createNewTabWindowKit(QWebPage * &)));
|
|
#endif
|
|
|
|
// Register the slot on tab index change
|
|
connect(m_tabWidget,SIGNAL(currentChanged(int )), m_tabWidget,SLOT(tabIndexChanged(int )));
|
|
|
|
// Listen for download file request from the web page
|
|
#ifdef PGADMIN4_USE_WEBENGINE
|
|
// 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
|
|
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*)));
|
|
m_mainWebView->page()->setForwardUnsupportedContent(true);
|
|
m_mainWebView->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
|
|
#endif
|
|
|
|
// Restore the geometry, or set a nice default
|
|
QSettings settings;
|
|
|
|
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());
|
|
restoreState(settings.value("Browser/WindowState").toByteArray());
|
|
|
|
// Set the initial zoom
|
|
qreal zoom = settings.value("Browser/Zoom", m_mainWebView->zoomFactor()).toReal();
|
|
m_mainWebView->setZoomFactor(zoom);
|
|
|
|
// The last save location
|
|
m_last_open_folder_path = settings.value("Browser/LastSaveLocation", QDir::homePath()).toString();
|
|
|
|
// Display the app
|
|
m_mainWebView->setUrl(m_appServerUrl);
|
|
}
|
|
|
|
// Destructor
|
|
BrowserWindow::~BrowserWindow()
|
|
{
|
|
if (m_tabWidget)
|
|
delete m_tabWidget;
|
|
}
|
|
|
|
// Save the window geometry on close
|
|
void BrowserWindow::closeEvent(QCloseEvent *event)
|
|
{
|
|
QSettings settings;
|
|
settings.setValue("Browser/Geometry", saveGeometry());
|
|
settings.setValue("Browser/WindowState", saveState());
|
|
QMainWindow::closeEvent(event);
|
|
}
|
|
|
|
|
|
// Create the actions for the window
|
|
void BrowserWindow::createActions()
|
|
{
|
|
// Open an arbitrary URL
|
|
openUrlShortcut = new QShortcut(QKeySequence(Qt::ALT + Qt::SHIFT + Qt::Key_U), this);
|
|
openUrlShortcut->setContext(Qt::ApplicationShortcut);
|
|
connect(openUrlShortcut, SIGNAL(activated()), this, SLOT(openUrl()));
|
|
|
|
// Set the Python Path
|
|
preferencesShortcut = new QShortcut(QKeySequence(Qt::ALT + Qt::SHIFT + Qt::Key_P), this);
|
|
preferencesShortcut->setContext(Qt::ApplicationShortcut);
|
|
connect(preferencesShortcut, SIGNAL(activated()), this, SLOT(preferences()));
|
|
|
|
// Exit the app
|
|
exitShortcut = new QShortcut(QKeySequence::Quit, this);
|
|
exitShortcut->setContext(Qt::ApplicationShortcut);
|
|
connect(exitShortcut, SIGNAL(activated()), this, SLOT(close()));
|
|
|
|
signalMapper = new QSignalMapper(this);
|
|
|
|
// About box
|
|
aboutShortcut = new QShortcut(QKeySequence(Qt::ALT + Qt::SHIFT + Qt::Key_A), this);
|
|
aboutShortcut->setContext(Qt::ApplicationShortcut);
|
|
connect(aboutShortcut, SIGNAL(activated()), this, SLOT(about()));
|
|
|
|
// Zoom in
|
|
zoomInShortcut = new QShortcut(QKeySequence(QKeySequence::ZoomIn), this);
|
|
zoomInShortcut->setContext(Qt::ApplicationShortcut);
|
|
signalMapper->setMapping(zoomInShortcut, 1);
|
|
connect(zoomInShortcut, SIGNAL(activated()), signalMapper, SLOT(map()));
|
|
|
|
// Zoom out
|
|
zoomOutShortcut = new QShortcut(QKeySequence(QKeySequence::ZoomOut), this);
|
|
zoomOutShortcut->setContext(Qt::ApplicationShortcut);
|
|
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)));
|
|
|
|
|
|
#ifdef __APPLE__
|
|
#ifdef PGADMIN4_USE_WEBENGINE
|
|
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
|
|
|
|
}
|
|
|
|
#ifdef __APPLE__
|
|
#ifdef PGADMIN4_USE_WEBENGINE
|
|
// 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
|
|
|
|
// Check if Tab is already open with given URL name
|
|
int BrowserWindow::findURLTab(const QUrl &name)
|
|
{
|
|
int tabCount = 0;
|
|
WebViewWindow *webviewPtr = NULL;
|
|
|
|
for (tabCount = 1; tabCount < m_tabWidget->count(); tabCount++)
|
|
{
|
|
QWidget *tab = m_tabWidget->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 && !QString::compare(webviewPtr->getFirstLoadURL(),name.host(), Qt::CaseInsensitive))
|
|
{
|
|
m_tabWidget->setCurrentIndex(tabCount);
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#ifdef PGADMIN4_USE_WEBENGINE
|
|
// 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
|
|
|
|
// 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, "");
|
|
|
|
// 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)
|
|
{
|
|
#ifdef PGADMIN4_USE_WEBENGINE
|
|
WebEnginePage *sender_web_page = dynamic_cast<WebEnginePage*>(obj_web_page);
|
|
#else
|
|
QWebPage *sender_web_page = dynamic_cast<QWebPage*>(obj_web_page);
|
|
#endif
|
|
if (sender_web_page != NULL)
|
|
{
|
|
#ifdef PGADMIN4_USE_WEBKIT
|
|
QNetworkAccessManager *networkManager = sender_web_page->networkAccessManager();
|
|
QNetworkReply *reply = networkManager->get(newRequest);
|
|
if (reply != NULL)
|
|
{
|
|
m_downloadStarted = 1;
|
|
m_downloadCancelled = 0;
|
|
|
|
// Connect the signals for downloadProgress and downloadFinished
|
|
connect( reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadFileProgress(qint64, qint64)) );
|
|
connect( reply, SIGNAL(finished()), this, SLOT(downloadFinished()));
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef PGADMIN4_USE_WEBENGINE
|
|
// 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
|
|
|
|
// Below slot will be called when file download is in progress
|
|
void BrowserWindow::downloadFileProgress(qint64 readData, qint64 totalData)
|
|
{
|
|
QNetworkReply *reply = ((QNetworkReply*)sender());
|
|
QNetworkRequest request = reply->request();
|
|
QVariant v = request.attribute(QNetworkRequest::User);
|
|
|
|
// When download is canceled by user then no need to write data to file
|
|
if (m_downloadCancelled)
|
|
return;
|
|
|
|
if(reply != NULL && reply->error() != QNetworkReply::NoError)
|
|
{
|
|
qDebug() << "Network error occurred whilst downloading: " << m_defaultFilename;
|
|
return;
|
|
}
|
|
|
|
// Download is started so open the file
|
|
if (!m_file)
|
|
{
|
|
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", readData, 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()));
|
|
m_reply = reply;
|
|
|
|
// Show downloading progress bar
|
|
m_progressDialog->show();
|
|
}
|
|
|
|
if (m_file)
|
|
{
|
|
// Write data to file
|
|
m_file->write(reply->read(readData));
|
|
m_progressDialog->setValue(readData);
|
|
|
|
// As read data and totalData difference is zero means downloading is finished.
|
|
if ((totalData - readData) == 0 ||
|
|
(readData != 0 && totalData == -1))
|
|
{
|
|
// As downloading is finished so remove progress bar dialog
|
|
if (m_progressDialog)
|
|
{
|
|
m_progressDialog->deleteLater();
|
|
m_progressDialog = NULL;
|
|
}
|
|
|
|
m_downloadStarted = 0;
|
|
m_downloadFilename.clear();
|
|
m_defaultFilename.clear();
|
|
m_downloadCancelled = 0;
|
|
|
|
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 cancel the downloading file which is in progress.
|
|
void BrowserWindow::progressCanceled()
|
|
{
|
|
m_downloadCancelled = 1;
|
|
|
|
if (m_progressDialog)
|
|
{
|
|
m_progressDialog->deleteLater();
|
|
m_progressDialog = NULL;
|
|
}
|
|
|
|
#ifdef PGADMIN4_USE_WEBKIT
|
|
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;
|
|
}
|
|
#else
|
|
m_download->cancel();
|
|
#endif
|
|
|
|
m_downloadFilename.clear();
|
|
m_defaultFilename.clear();
|
|
m_downloadStarted = 0;
|
|
}
|
|
|
|
#ifdef PGADMIN4_USE_WEBENGINE
|
|
// Below slot will called when file download is finished (Only for QWebEngine)
|
|
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;
|
|
}
|
|
|
|
m_downloadFilename.clear();
|
|
m_defaultFilename.clear();
|
|
m_downloadStarted = 0;
|
|
m_downloadCancelled = 0;
|
|
}
|
|
#endif
|
|
|
|
// Below slot will called when file download is finished
|
|
void BrowserWindow::downloadFinished()
|
|
{
|
|
if (m_progressDialog)
|
|
{
|
|
m_progressDialog->deleteLater();
|
|
m_progressDialog = NULL;
|
|
}
|
|
|
|
m_downloadFilename.clear();
|
|
m_defaultFilename.clear();
|
|
m_downloadStarted = 0;
|
|
m_downloadCancelled = 0;
|
|
|
|
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)
|
|
{
|
|
#if QT_VERSION >= 0x050000
|
|
// 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");
|
|
#else
|
|
QUrl url(reply->url());
|
|
QString file_name = url.queryItemValue("filename");
|
|
QString query = url.queryItemValue("query");
|
|
#endif
|
|
|
|
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(reply->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 (reply != NULL)
|
|
{
|
|
m_downloadStarted = 1;
|
|
m_downloadCancelled = 0;
|
|
connect( reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadFileProgress(qint64, qint64)));
|
|
connect( reply, SIGNAL(finished()), this, SLOT(downloadFinished()));
|
|
}
|
|
}
|
|
}
|
|
|
|
// Slot: set the title of tab when the new tab created or existing tab contents changed
|
|
void BrowserWindow::tabTitleChanged(const QString &str)
|
|
{
|
|
WebViewWindow *nextWebViewPtr = NULL;
|
|
bool flagTabText = false;
|
|
QToolButton *backToolButton = NULL;
|
|
QToolButton *forwardToolButton = NULL;
|
|
|
|
if (!str.isEmpty())
|
|
{
|
|
QObject *senderPtr = QObject::sender();
|
|
WebViewWindow *webViewPtr = NULL;
|
|
if (senderPtr != NULL)
|
|
{
|
|
webViewPtr = dynamic_cast<WebViewWindow*>(senderPtr);
|
|
if (webViewPtr != NULL)
|
|
{
|
|
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());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void BrowserWindow::current_dir_path(const QString &dir)
|
|
{
|
|
m_dir = dir;
|
|
m_last_open_folder_path = dir;
|
|
|
|
QSettings settings;
|
|
settings.setValue("Browser/LastSaveLocation", m_last_open_folder_path);
|
|
}
|
|
|
|
#ifndef PGADMIN4_USE_WEBENGINE
|
|
void BrowserWindow::createNewTabWindowKit(QWebPage * &p)
|
|
{
|
|
m_addNewTab = new QWidget(m_tabWidget);
|
|
|
|
m_addNewGridLayout = new QGridLayout(m_addNewTab);
|
|
m_addNewGridLayout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
m_addNewWebView = new WebViewWindow(m_addNewTab);
|
|
m_addNewWebView->setPage(new WebViewPage());
|
|
m_addNewWebView->setZoomFactor(m_mainWebView->zoomFactor());
|
|
|
|
// 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);
|
|
|
|
m_addNewWebView->settings()->setAttribute(QWebSettings::JavascriptEnabled, true);
|
|
m_addNewWebView->settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, true);
|
|
|
|
m_widget = new QWidget(m_addNewTab);
|
|
|
|
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"));
|
|
m_toolBtnBack->hide();
|
|
|
|
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"));
|
|
m_toolBtnForward->hide();
|
|
|
|
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"));
|
|
|
|
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 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
|
|
connect(m_toolBtnBack, SIGNAL(clicked()), m_tabWidget, SLOT(dockGoBackPage()));
|
|
|
|
// Register the slot on toolbutton to show the next history of web
|
|
connect(m_toolBtnForward, SIGNAL(clicked()), m_tabWidget, SLOT(dockGoForwardPage()));
|
|
|
|
// Register the slot on close button , added manually
|
|
connect(m_btnClose, SIGNAL(clicked()), m_tabWidget, SLOT(dockClosetabs()));
|
|
|
|
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
|
|
|
|
#ifdef PGADMIN4_USE_WEBENGINE
|
|
// 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);
|
|
|
|
m_addNewGridLayout = new QGridLayout(m_addNewTab);
|
|
m_addNewGridLayout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
m_addNewWebView = new WebViewWindow();
|
|
m_addNewWebView->setPage(new WebEnginePage());
|
|
m_addNewWebView->setZoomFactor(m_mainWebView->zoomFactor());
|
|
|
|
m_widget = new QWidget(m_addNewTab);
|
|
|
|
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"));
|
|
m_toolBtnBack->hide();
|
|
|
|
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"));
|
|
m_toolBtnForward->hide();
|
|
|
|
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"));
|
|
|
|
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 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
|
|
connect(m_toolBtnBack, SIGNAL(clicked()), m_tabWidget, SLOT(dockGoBackPage()));
|
|
|
|
// Register the slot on toolbutton to show the next history of web
|
|
connect(m_toolBtnForward, SIGNAL(clicked()), m_tabWidget, SLOT(dockGoForwardPage()));
|
|
|
|
// Register the slot on close button , added manually
|
|
connect(m_toolBtnClose, SIGNAL(clicked()), m_tabWidget, SLOT(dockClosetabs()));
|
|
|
|
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_toolBtnClose);
|
|
|
|
m_addNewWebView->setTabIndex((m_tabWidget->count() - 1));
|
|
p = m_addNewWebView->page();
|
|
}
|
|
#endif
|
|
|
|
// Slot: Link is open from pgAdmin mainwindow
|
|
void BrowserWindow::urlLinkClicked(const QUrl &name)
|
|
{
|
|
// Check that request contains the data download at client side
|
|
QNetworkRequest request;
|
|
|
|
// 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);
|
|
|
|
m_addNewGridLayout = new QGridLayout(m_addNewTab);
|
|
m_addNewGridLayout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
m_addNewWebView = new WebViewWindow();
|
|
m_addNewWebView->setZoomFactor(m_mainWebView->zoomFactor());
|
|
|
|
// Listen for the download request from the web page
|
|
#ifdef PGADMIN4_USE_WEBENGINE
|
|
m_addNewWebView->setPage(new WebEnginePage());
|
|
connect(m_addNewWebView->page()->profile(),SIGNAL(downloadRequested(QWebEngineDownloadItem*)),this,SLOT(downloadRequested(QWebEngineDownloadItem*)));
|
|
#else
|
|
m_addNewWebView->setPage(new WebViewPage());
|
|
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*)));
|
|
|
|
// 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);
|
|
#endif
|
|
|
|
m_widget = new QWidget(m_addNewTab);
|
|
|
|
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"));
|
|
m_toolBtnBack->hide();
|
|
|
|
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"));
|
|
m_toolBtnForward->hide();
|
|
|
|
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"));
|
|
|
|
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 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
|
|
connect(m_toolBtnBack, SIGNAL(clicked()), m_tabWidget, SLOT(dockGoBackPage()));
|
|
|
|
// Register the slot on toolbutton to show the next history of web
|
|
connect(m_toolBtnForward, SIGNAL(clicked()), m_tabWidget, SLOT(dockGoForwardPage()));
|
|
|
|
// Register the slot on close button , added manually
|
|
connect(m_toolBtnClose, SIGNAL(clicked()), m_tabWidget, SLOT(dockClosetabs()));
|
|
|
|
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_toolBtnClose);
|
|
|
|
m_addNewWebView->setFirstLoadURL(name.host());
|
|
m_addNewWebView->setTabIndex((m_tabWidget->count() - 1));
|
|
m_addNewWebView->setUrl(name);
|
|
}
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
|
|
// Display the about box
|
|
void BrowserWindow::about()
|
|
{
|
|
QMessageBox::about(this, tr("About %1").arg(PGA_APP_NAME), tr("%1 - PostgreSQL Tools").arg(PGA_APP_NAME));
|
|
}
|
|
|
|
|
|
// Set Zoom Level
|
|
void BrowserWindow::setZoomLevel(int zoomFlag)
|
|
{
|
|
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)
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Set the zoom value for the next time
|
|
QSettings settings;
|
|
settings.setValue("Browser/Zoom", m_mainWebView->zoomFactor());
|
|
|
|
}
|
|
|
|
// Open an arbitrary URL
|
|
void BrowserWindow::openUrl()
|
|
{
|
|
bool ok;
|
|
|
|
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();
|
|
|
|
if (ok && !url.isEmpty())
|
|
urlLinkClicked(QUrl(url));
|
|
}
|
|
|
|
// Edit the app configuration
|
|
void BrowserWindow::preferences()
|
|
{
|
|
QSettings settings;
|
|
bool ok;
|
|
|
|
ConfigWindow *dlg = new ConfigWindow();
|
|
dlg->setWindowTitle(QWidget::tr("Configuration"));
|
|
dlg->setPythonPath(settings.value("PythonPath").toString());
|
|
dlg->setApplicationPath(settings.value("ApplicationPath").toString());
|
|
dlg->setModal(true);
|
|
ok = dlg->exec();
|
|
|
|
QString pythonpath = dlg->getPythonPath();
|
|
QString applicationpath = dlg->getApplicationPath();
|
|
|
|
if (ok)
|
|
{
|
|
settings.setValue("PythonPath", pythonpath);
|
|
settings.setValue("ApplicationPath", applicationpath);
|
|
}
|
|
}
|
|
|