Add support for detachable tabs to the runtime.

This allows the Query Tool, Debugger and web browser tabs to be moved to different monitors as desired.

Fixes #1344
This commit is contained in:
Neel Patel 2017-06-16 09:57:19 +01:00 committed by Dave Page
parent 900ccebb50
commit 0056a94115
12 changed files with 937 additions and 226 deletions

View File

@ -66,7 +66,9 @@ BrowserWindow::BrowserWindow(QString url)
// Setup the shortcuts
createActions();
m_tabWidget = new TabWindow(this);
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);
@ -121,7 +123,7 @@ BrowserWindow::BrowserWindow(QString url)
#endif
// Register the slot on tab index change
connect(m_tabWidget,SIGNAL(currentChanged(int )),this,SLOT(tabIndexChanged(int )));
connect(m_tabWidget,SIGNAL(currentChanged(int )), m_tabWidget,SLOT(tabIndexChanged(int )));
// Listen for download file request from the web page
#ifdef PGADMIN4_USE_WEBENGINE
@ -796,151 +798,14 @@ void BrowserWindow::unsupportedContent(QNetworkReply * reply)
}
}
// Slot: When the tab index change, hide/show the toolbutton displayed on tab
void BrowserWindow::tabIndexChanged(int index)
{
int tabCount = 1;
for (tabCount = 1; tabCount < m_tabWidget->count(); tabCount++)
{
if (tabCount != index)
m_tabWidget->showHideToolButton(tabCount, 0);
else
m_tabWidget->showHideToolButton(tabCount, 1);
}
}
// Close the tab and remove the memory of the given index tab
void BrowserWindow::closetabs()
{
int loopCount = 0;
int index = 0;
QPushButton *btn = NULL;
int totalTabs = m_tabWidget->count();
// If QTabWidget contains only one tab then hide the TabBar window
if ((totalTabs - 1) < 2)
m_tabWidget->tabBar()->setVisible(false);
else
m_tabWidget->tabBar()->setVisible(true);
QObject *senderPtr = QObject::sender();
if (senderPtr != NULL)
{
btn = dynamic_cast<QPushButton*>(senderPtr);
index = m_tabWidget->getButtonIndex(btn);
}
if (index != 0)
{
QWidget *tab = m_tabWidget->widget(index);
WebViewWindow *webviewPtr = NULL;
loopCount = 0;
// free the allocated memory when the tab is closed
if (tab != NULL)
{
QList<QWidget*> widgetList = tab->findChildren<QWidget*>();
foreach (QWidget* widgetPtr, widgetList)
{
if (widgetPtr != NULL)
{
webviewPtr = dynamic_cast<WebViewWindow*>(widgetPtr);
if (webviewPtr != NULL)
{
/* Trigger the action for tab window close so unload event will be called and
* resources will be freed properly.
* Trigger 'RequestClose' action from Qt5 onwards. Here we have triggerred the action
* 'ToggleVideoFullscreen + 1' because we do not know from which webkit
* version 'RequestClose' action was added so increment with previous enum value so that
* it will be backward webkit version compatible.
*/
#if QT_VERSION >= 0x050000
#ifndef PGADMIN4_USE_WEBENGINE
webviewPtr->page()->triggerAction(static_cast<QWebPage::WebAction>(QWebPage::ToggleVideoFullscreen + 1));
#endif
#endif
}
}
}
delete tab;
}
// Adjust the tab index value if the tab is closed in between
for (loopCount = 1; loopCount < totalTabs; loopCount++)
{
if (index > loopCount)
continue;
QWidget *tab = m_tabWidget->widget(loopCount);
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->setTabIndex((webviewPtr->getTabIndex() - 1));
}
}
}
}
}
}
// Slot: go back to page and enable/disable toolbutton
void BrowserWindow::goBackPage()
{
WebViewWindow *webviewPtr = NULL;
QWidget *tab = m_tabWidget->widget(m_tabWidget->currentIndex());
if (tab != NULL)
{
QList<QWidget*> widgetList = tab->findChildren<QWidget*>();
foreach( QWidget* widgetPtr, widgetList )
{
if (widgetPtr != NULL)
{
webviewPtr = dynamic_cast<WebViewWindow*>(widgetPtr);
if (webviewPtr != NULL)
{
webviewPtr->back();
m_tabWidget->enableDisableToolButton(m_tabWidget->currentIndex());
}
}
}
}
}
// Slot: go forward to page and enable/disable toolbutton
void BrowserWindow::goForwardPage()
{
WebViewWindow *webviewPtr = NULL;
QWidget *tab = m_tabWidget->widget(m_tabWidget->currentIndex());
if (tab != NULL)
{
QList<QWidget*> widgetList = tab->findChildren<QWidget*>();
foreach( QWidget* widgetPtr, widgetList )
{
if (widgetPtr != NULL)
{
webviewPtr = dynamic_cast<WebViewWindow*>(widgetPtr);
if (webviewPtr != NULL)
{
webviewPtr->forward();
m_tabWidget->enableDisableToolButton(m_tabWidget->currentIndex());
}
}
}
}
}
// 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();
@ -950,16 +815,92 @@ void BrowserWindow::tabTitleChanged(const QString &str)
webViewPtr = dynamic_cast<WebViewWindow*>(senderPtr);
if (webViewPtr != NULL)
{
m_tabWidget->setTabText(webViewPtr->getTabIndex(), str);
m_tabWidget->setTabToolTipText(webViewPtr->getTabIndex(), str);
m_tabWidget->enableDisableToolButton(webViewPtr->getTabIndex());
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());
}
}
}
}
else
{
m_tabWidget->setTabText(m_tabWidget->currentIndex(), str);
m_tabWidget->setTabToolTipText(m_tabWidget->currentIndex(), str);
}
}
}
@ -977,37 +918,51 @@ void BrowserWindow::current_dir_path(const QString &dir)
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->setDisabled(true);
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->setDisabled(true);
m_toolBtnForward->hide();
QPushButton *m_btnClose = new QPushButton(m_widget);
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);
@ -1017,13 +972,14 @@ void BrowserWindow::createNewTabWindowKit(QWebPage * &p)
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()), this, SLOT(goBackPage()));
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()), this, SLOT(goForwardPage()));
connect(m_toolBtnForward, SIGNAL(clicked()), m_tabWidget, SLOT(dockGoForwardPage()));
// Register the slot on close button , added manually
connect(m_btnClose, SIGNAL(clicked()), SLOT(closetabs()));
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);
@ -1044,34 +1000,38 @@ void BrowserWindow::createNewTabWindowKit(QWebPage * &p)
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_addNewTab);
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->setDisabled(true);
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->setDisabled(true);
m_toolBtnForward->hide();
QPushButton *m_btnClose = new QPushButton(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_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);
@ -1081,13 +1041,13 @@ void BrowserWindow::createNewTabWindow(QWebEnginePage * &p)
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()), this, SLOT(goBackPage()));
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()), this, SLOT(goForwardPage()));
connect(m_toolBtnForward, SIGNAL(clicked()), m_tabWidget, SLOT(dockGoForwardPage()));
// Register the slot on close button , added manually
connect(m_btnClose, SIGNAL(clicked()), SLOT(closetabs()));
connect(m_toolBtnClose, SIGNAL(clicked()), m_tabWidget, SLOT(dockClosetabs()));
m_addNewGridLayout->addWidget(m_addNewWebView, 0, 0, 1, 1);
m_tabWidget->addTab(m_addNewTab, QString());
@ -1096,7 +1056,7 @@ void BrowserWindow::createNewTabWindow(QWebEnginePage * &p)
// 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_tabWidget->tabBar()->setTabButton((m_tabWidget->count() - 1), QTabBar::RightSide, m_toolBtnClose);
m_addNewWebView->setTabIndex((m_tabWidget->count() - 1));
p = m_addNewWebView->page();
@ -1115,42 +1075,55 @@ void BrowserWindow::urlLinkClicked(const QUrl &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_addNewTab);
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->setDisabled(true);
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->setDisabled(true);
m_toolBtnForward->hide();
QPushButton *m_btnClose = new QPushButton(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_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);
@ -1160,13 +1133,13 @@ void BrowserWindow::urlLinkClicked(const QUrl &name)
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()), this, SLOT(goBackPage()));
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()), this, SLOT(goForwardPage()));
connect(m_toolBtnForward, SIGNAL(clicked()), m_tabWidget, SLOT(dockGoForwardPage()));
// Register the slot on close button , added manually
connect(m_btnClose, SIGNAL(clicked()), SLOT(closetabs()));
connect(m_toolBtnClose, SIGNAL(clicked()), m_tabWidget, SLOT(dockClosetabs()));
m_addNewGridLayout->addWidget(m_addNewWebView, 0, 0, 1, 1);
m_tabWidget->addTab(m_addNewTab, QString());
@ -1175,7 +1148,7 @@ void BrowserWindow::urlLinkClicked(const QUrl &name)
// 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_tabWidget->tabBar()->setTabButton((m_tabWidget->count() - 1), QTabBar::RightSide, m_toolBtnClose);
m_addNewWebView->setFirstLoadURL(name.host());
m_addNewWebView->setTabIndex((m_tabWidget->count() - 1));

View File

@ -38,6 +38,12 @@
#endif
#endif
#ifdef PGADMIN4_USE_WEBENGINE
#include <QWebEngineHistory>
#else
#include <QWebHistory>
#endif
QT_BEGIN_NAMESPACE
class QAction;
class QMenu;
@ -56,7 +62,6 @@ protected:
protected slots:
void urlLinkClicked(const QUrl &);
void closetabs();
void tabTitleChanged(const QString &);
#ifdef __APPLE__
#ifdef PGADMIN4_USE_WEBENGINE
@ -76,9 +81,6 @@ private slots:
#endif
public slots:
void tabIndexChanged(int index);
void goBackPage();
void goForwardPage();
void download(const QNetworkRequest &request);
void unsupportedContent(QNetworkReply * reply);
void downloadFinished();
@ -108,16 +110,18 @@ private:
QGridLayout *m_tabGridLayout;
QGridLayout *m_mainGridLayout;
TabWindow *m_tabWidget;
DockTabWidget *m_tabWidget;
QWidget *m_pgAdminMainTab;
QWidget *m_addNewTab;
QGridLayout *m_addNewGridLayout;
WebViewWindow *m_addNewWebView;
QHBoxLayout *m_horizontalLayout;
QWidget *m_widget;
QToolButton *m_toolBtnBack;
QToolButton *m_toolBtnForward;
QToolButton *m_toolBtnClose;
QString m_downloadFilename;
int m_downloadStarted;
@ -139,6 +143,7 @@ private:
void createActions();
void pause(int seconds = 1);
int findURLTab(const QUrl &name);
void enableDisableToolButtons(WebViewWindow *webViewPtr);
#ifdef __APPLE__
#ifdef PGADMIN4_USE_WEBENGINE

View File

@ -20,13 +20,20 @@
#include <QWebHistory>
#endif
TabWindow::TabWindow(QWidget *parent) :
DockTabWidget *DockTabWidget::mainTabWidget = NULL;
DockTabWidget::DockTabWidget(QWidget *parent) :
QTabWidget(parent)
{
setParent(parent);
setTabsClosable(false);
setElideMode(Qt::ElideRight);
// set custom tab bar in tab widget to receive events for docking.
setTabBar(new DockTabBar(this));
setDocumentMode(true);
setAcceptDrops(true);
// Get the system colours we need
QPalette palette = QApplication::palette("QPushButton");
QColor activebg = palette.color(QPalette::Button);
@ -45,11 +52,7 @@ TabWindow::TabWindow(QWidget *parent) :
"margin-top: 1px; "
#ifndef __APPLE__
"width: 15em; "
#ifdef _WIN32
"height: 1.5em; "
#else
"height: 1em; "
#endif
#endif
"} "
"QTabBar::tab:selected { "
@ -64,17 +67,318 @@ TabWindow::TabWindow(QWidget *parent) :
"alignment: left; "
"}"
);
#ifdef __APPLE__
m_testTabBar = new TabBar();
setTabBar(m_testTabBar);
#endif
// Hide the default tab
tabBar()->setVisible(false);
if (mainTabWidget == NULL)
mainTabWidget = this;
}
DockTabWidget::DockTabWidget(DockTabWidget *other, QWidget *parent) :
DockTabWidget(parent)
{
setFloatingBaseWidget(other->floatingBaseWidget());
setFloatingEnabled(other->isFloatingEnabled());
resize(other->size());
}
void DockTabWidget::setFloatingBaseWidget(QWidget *widget)
{
floatingWidget = widget;
if (floatingEnabled && parentWidget() == 0)
setParent(widget);
}
void DockTabWidget::setFloatingEnabled(bool x)
{
floatingEnabled = x;
if (parent() == 0)
{
if (x)
setWindowFlags(Qt::Tool);
else
setWindowFlags(Qt::Window);
}
}
// Slot: go back to page and enable/disable toolbutton
void DockTabWidget::dockGoBackPage()
{
WebViewWindow *webviewPtr = NULL;
QWidget *tab = this->widget(this->currentIndex());
if (tab != NULL)
{
QList<QWidget*> widgetList = tab->findChildren<QWidget*>();
foreach( QWidget* widgetPtr, widgetList )
{
if (widgetPtr != NULL)
{
webviewPtr = dynamic_cast<WebViewWindow*>(widgetPtr);
if (webviewPtr != NULL)
webviewPtr->back();
}
}
}
}
// Slot: go forward to page and enable/disable toolbutton
void DockTabWidget::dockGoForwardPage()
{
WebViewWindow *webviewPtr = NULL;
QWidget *tab = this->widget(this->currentIndex());
if (tab != NULL)
{
QList<QWidget*> widgetList = tab->findChildren<QWidget*>();
foreach( QWidget* widgetPtr, widgetList )
{
if (widgetPtr != NULL)
{
webviewPtr = dynamic_cast<WebViewWindow*>(widgetPtr);
if (webviewPtr != NULL)
webviewPtr->forward();
}
}
}
}
// Close the tab and remove the memory of the given index tab
void DockTabWidget::dockClosetabs()
{
int totalTabs = 0;
QToolButton *btn = NULL;
QWidget *tab = NULL;
DockTabWidget *l_tab_widget = NULL;
QObject *senderPtr = QObject::sender();
if (senderPtr != NULL)
{
btn = dynamic_cast<QToolButton*>(senderPtr);
if (btn != NULL)
{
l_tab_widget = dynamic_cast<DockTabWidget*>(btn->parent()->parent());
int current_tab_index = 0;
if (l_tab_widget != NULL)
{
totalTabs = l_tab_widget->count();
for (int loopCount = l_tab_widget->count();loopCount >= 0;loopCount--)
{
QWidget *l_tab = l_tab_widget->tabBar()->tabButton(loopCount, QTabBar::RightSide);
if (l_tab != NULL)
{
QToolButton *nextBtnPtr = dynamic_cast<QToolButton*>(l_tab);
if (nextBtnPtr != NULL && btn != NULL && nextBtnPtr == btn)
current_tab_index = loopCount;
}
}
QList<QWidget*> widgetList = l_tab_widget->tabBar()->findChildren<QWidget*>();
foreach(QWidget* widgetPtr, widgetList)
{
if (widgetPtr != NULL)
{
QToolButton *toolBtnPtr = dynamic_cast<QToolButton*>(widgetPtr);
if (toolBtnPtr != NULL && toolBtnPtr == btn)
{
tab = l_tab_widget->widget(current_tab_index);
break;
}
}
}
}
if (tab != NULL)
tab->deleteLater();
// If user close the last tab then close the parent tab widget also.
if (totalTabs == 1 && l_tab_widget != NULL)
l_tab_widget->deleteLater();
}
}
if (tab != NULL)
{
WebViewWindow *webviewPtr = NULL;
QList<QWidget*> widgetList = tab->findChildren<QWidget*>();
foreach (QWidget* widgetPtr, widgetList)
{
if (widgetPtr != NULL)
{
webviewPtr = dynamic_cast<WebViewWindow*>(widgetPtr);
if (webviewPtr != NULL)
{
/* Trigger the action for tab window close so unload event will be called and
* resources will be freed properly.
* Trigger 'RequestClose' action from Qt5 onwards. Here we have triggerred the action
* 'ToggleVideoFullscreen + 1' because we do not know from which webkit
* version 'RequestClose' action was added so increment with previous enum value so that
* it will be backward webkit version compatible.
*/
#if QT_VERSION >= 0x050000
#ifndef PGADMIN4_USE_WEBENGINE
webviewPtr->page()->triggerAction(static_cast<QWebPage::WebAction>(QWebPage::ToggleVideoFullscreen + 1));
#endif
#endif
}
}
}
}
// Check if main pgAdmin4 application has only one tab then close tab bar.
// Here - check for count 2 because tab will be deleted later.
DockTabWidget *mainTab = DockTabWidget::getMainTabWidget();
if (mainTab != NULL && mainTab->count() == 2)
mainTab->tabBar()->setVisible(false);
}
// This function is used to set back/forward/close buttons on new tabbar.
void DockTabWidget::setButtonsNewTabbar(int index)
{
QWidget *m_widget = new QWidget();
QToolButton *m_toolBtnBack = new QToolButton(m_widget);
m_toolBtnBack->setFixedHeight(PGA_BTN_SIZE);
m_toolBtnBack->setFixedWidth(PGA_BTN_SIZE);
m_toolBtnBack->setIcon(QIcon(":/back.png"));
m_toolBtnBack->setToolTip(tr("Go back"));
QToolButton *m_toolBtnForward = new QToolButton(m_widget);
m_toolBtnForward->setFixedHeight(PGA_BTN_SIZE);
m_toolBtnForward->setFixedWidth(PGA_BTN_SIZE);
m_toolBtnForward->setIcon(QIcon(":/forward.png"));
m_toolBtnForward->setToolTip(tr("Go forward"));
QToolButton *m_btnClose = new QToolButton(m_widget);
m_btnClose->setFixedHeight(PGA_BTN_SIZE);
m_btnClose->setFixedWidth(PGA_BTN_SIZE);
m_btnClose->setIcon(QIcon(":/close.png"));
m_btnClose->setToolTip(tr("Close tab"));
QHBoxLayout *m_horizontalLayout = new QHBoxLayout(m_widget);
m_horizontalLayout->setContentsMargins(0,1,0,0);
m_horizontalLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
m_horizontalLayout->setSpacing(1);
m_horizontalLayout->addWidget(m_toolBtnBack);
m_horizontalLayout->addWidget(m_toolBtnForward);
// Register the slot on toolbutton to show the previous history of web
connect(m_toolBtnBack, SIGNAL(clicked()), this, SLOT(dockGoBackPage()));
// Register the slot on toolbutton to show the next history of web
connect(m_toolBtnForward, SIGNAL(clicked()), this, SLOT(dockGoForwardPage()));
// Register the slot on close button , added manually
connect(m_btnClose, SIGNAL(clicked()), SLOT(dockClosetabs()));
// Register the slot on tab index change
connect(this, SIGNAL(currentChanged(int )), this,SLOT(tabIndexChanged(int )));
// Set the back and forward button on tab
this->tabBar()->setTabButton(index, QTabBar::LeftSide, m_widget);
this->tabBar()->setTabButton(index, QTabBar::RightSide, m_btnClose);
// find the webview and hide/show button depending on flag set with web view.
QWidget *tab = this->widget(index);
if (tab != NULL)
{
QList<QWidget*> widgetList = tab->findChildren<QWidget*>();
foreach( QWidget* widgetPtr, widgetList )
{
if (widgetPtr != NULL)
{
WebViewWindow *webViewPtr = dynamic_cast<WebViewWindow*>(widgetPtr);
if (webViewPtr != NULL)
{
// If user open any file in query tool then "Query -" name will not appear
// but it is still query tool so hide the tool button.
if (!webViewPtr->getBackForwardButtonHidden())
{
m_toolBtnBack->show();
m_toolBtnForward->show();
}
else
{
m_toolBtnBack->hide();
m_toolBtnForward->hide();
}
break;
}
}
}
}
}
// This function is used to move to old tab widget to new tab widget.
void DockTabWidget::moveTab(DockTabWidget *source, int sourceIndex, DockTabWidget *dest, int destIndex)
{
if (source == dest && sourceIndex < destIndex)
destIndex--;
QWidget *widget = source->widget(sourceIndex);
QString text = source->tabText(sourceIndex);
source->removeTab(sourceIndex);
dest->insertTab(destIndex, widget, text);
dest->setCurrentIndex(destIndex);
}
// This function is used to decode actual drop event on tab widget.
void DockTabWidget::decodeTabDropEvent(QDropEvent *event, DockTabWidget **p_tabWidget, int *p_index)
{
DockTabBar *tabBar = qobject_cast<DockTabBar *>(event->source());
if (!tabBar)
{
*p_tabWidget = NULL;
*p_index = 0;
return;
}
QByteArray data = event->mimeData()->data(MIMETYPE_TABINDEX);
QDataStream stream(&data, QIODevice::ReadOnly);
int index;
stream >> index;
*p_tabWidget = tabBar->tabWidget();
*p_index = index;
}
// This function is used to check event is actually drop event or not.
bool DockTabWidget::eventIsTabDrag(QDragEnterEvent *event)
{
return event->mimeData()->hasFormat(MIMETYPE_TABINDEX) && qobject_cast<DockTabBar *>(event->source());
}
// This function is used to delete tab widget when there is no tab inside.
void DockTabWidget::deleteIfEmpty()
{
if (count() == 0)
{
emit willBeAutomaticallyDeleted(this);
deleteLater();
}
}
// This is function is used to create another tab widget from parent window.
DockTabWidget *DockTabWidget::createAnotherTabWidget(QWidget *parent)
{
DockTabWidget *tab_widget = new DockTabWidget(this, parent);
tab_widget->tabBar()->setVisible(true);
return tab_widget;
}
// Check wether tab is insertable or not.
bool DockTabWidget::isInsertable(QWidget *widget)
{
Q_UNUSED(widget)
return true;
}
// Hide the close button of given index displayed on right side of tab
void TabWindow::enableDisableToolButton(const int &index)
void DockTabWidget::enableDisableToolButton(const int &index)
{
QToolButton *toolBtnPtr = NULL;
WebViewWindow *tmpwebviewPtr = NULL;
@ -127,31 +431,52 @@ void TabWindow::enableDisableToolButton(const int &index)
}
}
// Get the index of the pushbutton which is requested by user to close the tab
int TabWindow::getButtonIndex(QPushButton *btn)
// Slot: When the tab index change, hide/show the toolbutton displayed on tab
void DockTabWidget::tabIndexChanged(int index)
{
QPushButton *nextBtnPtr = NULL;
int loopCount = 0;
int totalTabs = this->count();
int tabCount = 0;
WebViewWindow *webViewPtr = NULL;
for (loopCount = 1;loopCount < totalTabs;loopCount++)
for (tabCount = 0; tabCount < this->count(); tabCount++)
{
QWidget *tab = tabBar()->tabButton(loopCount, QTabBar::RightSide);
// if main pgAdmin4 application tab then do nothing.
if (!QString::compare(this->tabText(tabCount), tr("pgAdmin 4"), Qt::CaseInsensitive))
continue;
QWidget *tab = this->widget(tabCount);
if (tab != NULL)
{
nextBtnPtr = dynamic_cast<QPushButton*>(tab);
if (nextBtnPtr != NULL && btn != NULL && nextBtnPtr == btn)
return loopCount;
QList<QWidget*> widgetList = tab->findChildren<QWidget*>();
foreach( QWidget* widgetPtr, widgetList )
{
if (widgetPtr != NULL)
{
webViewPtr = dynamic_cast<WebViewWindow*>(widgetPtr);
if (webViewPtr != NULL)
break;
}
}
}
if (tabCount != index)
this->showHideToolButton(tabCount, 0);
else
{
if (!webViewPtr->getBackForwardButtonHidden())
this->showHideToolButton(tabCount, 1);
else
this->showHideToolButton(tabCount, 0);
}
}
return 0;
// paint the tab text again as index of the tab widget changed.
this->tabBar()->update();
}
// Show and Hide the toolbutton once the tab is deselected depending on the option
// option 0: Hide the toolButton
// option 1: Show the toolButton
void TabWindow::showHideToolButton(const int &index, const int &option)
void DockTabWidget::showHideToolButton(const int &index, const int &option)
{
QToolButton *toolBtnPtr = NULL;
@ -177,7 +502,174 @@ void TabWindow::showHideToolButton(const int &index, const int &option)
}
// Set the tab tool tip text
void TabWindow::setTabToolTipText(const int &index, const QString &toolTipString)
void DockTabWidget::setTabToolTipText(const int &index, const QString &toolTipString)
{
tabBar()->setTabToolTip(index, toolTipString);
}
// Implementation of custom tab bar for docking window.
DockTabBar::DockTabBar(DockTabWidget *tabWidget, QWidget *parent) :
QTabBar(parent),
tab_widget(tabWidget)
{
setAcceptDrops(true);
}
// Insert new tab at specified index.
int DockTabBar::insertionIndexAt(const QPoint &pos)
{
#ifndef __APPLE__
this->setStyleSheet("background-color: #E8E8E8");
#endif
int index = count();
for (int i = 0; i < count(); ++i)
{
QRect rect = tabRect(i);
QRect rect1(rect.x(), rect.y(), rect.width() / 2, rect.height());
QRect rect2(rect.x() + rect1.width(), rect.y(), rect.width() - rect1.width(), rect.height());
if (rect1.contains(pos))
{
index = i;
break;
}
if (rect2.contains(pos))
{
index = i + 1;
break;
}
}
return index;
}
// Mouse press event handler for tab drag.
void DockTabBar::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
dragStartPos = event->pos();
isStartingDrag = true;
}
QTabBar::mousePressEvent(event);
}
// Mouse move event handler for tab drag.
void DockTabBar::mouseMoveEvent(QMouseEvent *event)
{
if (!isStartingDrag)
return;
if ((!event->buttons()) && Qt::LeftButton)
return;
if ((event->pos() - dragStartPos).manhattanLength() < QApplication::startDragDistance())
return;
int index = tabAt(event->pos());
if (index < 0)
return;
// Don't allow to drag the pgAdmin4 main tab.
if (!QString::compare(tab_widget->tabText(index), tr("pgAdmin 4"), Qt::CaseInsensitive))
{
return;
}
// create data
QMimeData *mimeData = new QMimeData;
QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly);
stream << index;
mimeData->setData(MIMETYPE_TABINDEX, data);
// create pixmap
QRect rect = tabRect(index);
QPixmap pixmap(rect.size());
render(&pixmap, QPoint(), QRegion(rect));
// exec drag
QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->setPixmap(pixmap);
QPoint offset = dragStartPos - rect.topLeft();
drag->setHotSpot(offset);
Qt::DropAction dropAction = drag->exec(Qt::MoveAction | Qt::IgnoreAction);
if (dropAction != Qt::MoveAction)
{
DockTabWidget *newTabWidget = tab_widget->createAnotherTabWidget();
if (!newTabWidget->isInsertable(tab_widget, index))
{
newTabWidget->deleteLater();
return;
}
DockTabWidget::moveTab(tab_widget, index, newTabWidget, 0);
newTabWidget->setButtonsNewTabbar(0);
newTabWidget->enableDisableToolButton(0);
QRect newGeometry = newTabWidget->geometry();
newGeometry.moveTopLeft(QCursor::pos() - offset);
newTabWidget->setGeometry(newGeometry);
newTabWidget->show();
// Check if main pgAdmin4 application has only one tab then close tab bar.
// Here - check for count 2 because tab will be deleted later.
DockTabWidget *mainTab = DockTabWidget::getMainTabWidget();
if (mainTab != NULL && tab_widget != NULL && tab_widget == mainTab && mainTab->count() == 1)
mainTab->tabBar()->setVisible(false);
}
tab_widget->deleteIfEmpty();
isStartingDrag = false;
}
// Actual tab drag started.
void DockTabBar::dragEnterEvent(QDragEnterEvent *event)
{
#ifndef __APPLE__
this->setStyleSheet("background-color: #84ACDD");
#endif
if (DockTabWidget::eventIsTabDrag(event))
event->acceptProposedAction();
}
// Drag event leave the actual area.
void DockTabBar::dragLeaveEvent(QDragLeaveEvent * event)
{
Q_UNUSED(event)
#ifndef __APPLE__
this->setStyleSheet("background-color: #E8E8E8");
#endif
}
// Drop event handler for tabbar.
void DockTabBar::dropEvent(QDropEvent *event)
{
DockTabWidget *oldTabWidget = NULL;
int oldIndex;
DockTabWidget::decodeTabDropEvent(event, &oldTabWidget, &oldIndex);
if (oldTabWidget && tab_widget && tab_widget->isInsertable(oldTabWidget, oldIndex))
{
int newIndex = insertionIndexAt(event->pos());
DockTabWidget::moveTab(oldTabWidget, oldIndex, tab_widget, newIndex);
// create new back/forward/close buttons and register its events.
tab_widget->setButtonsNewTabbar(newIndex);
tab_widget->enableDisableToolButton(newIndex);
// Check if main pgAdmin4 application has only one tab then close tab bar.
// Here - check for count 2 because tab will be deleted later.
DockTabWidget *mainTab = DockTabWidget::getMainTabWidget();
if (mainTab != NULL && oldTabWidget != NULL && oldTabWidget == mainTab && mainTab->count() == 1)
mainTab->tabBar()->setVisible(false);
event->acceptProposedAction();
}
}

View File

@ -22,26 +22,53 @@ const int PGA_BTN_SIZE = 18;
const int PGA_BTN_SIZE = 16;
#endif
class TabBar : public QTabBar
#include <QTabBar>
#include <QTabWidget>
#define MIMETYPE_TABINDEX "x-paintfield-tabindex"
class DockTabBar;
class DockTabWidget : public QTabWidget
{
Q_OBJECT
friend class DockTabBar;
public:
TabBar(QWidget* parent=0) : QTabBar(parent)
explicit DockTabWidget(QWidget *parent = 0);
DockTabWidget(DockTabWidget *other, QWidget *parent = 0);
// Drop event handlers of parent tab widget.
static void moveTab(DockTabWidget *source, int sourceIndex, DockTabWidget *dest, int destIndex);
static void decodeTabDropEvent(QDropEvent *event, DockTabWidget **p_tabWidget, int *p_index);
static bool eventIsTabDrag(QDragEnterEvent *event);
void setButtonsNewTabbar(int index);
static DockTabWidget *mainTabWidget;
static DockTabWidget* getMainTabWidget()
{
return mainTabWidget;
}
protected:
QSize tabSizeHint(int) const
void setFloatingBaseWidget(QWidget *widget);
QWidget *floatingBaseWidget()
{
return QSize(250, 24);
return floatingWidget;
}
};
class TabWindow : public QTabWidget
{
Q_OBJECT
public:
TabWindow(QWidget *parent = 0);
void setFloatingEnabled(bool x);
bool isFloatingEnabled() const
{
return floatingEnabled;
}
virtual bool isInsertable(QWidget *widget);
bool isInsertable(DockTabWidget *other, int index)
{
return isInsertable(other->widget(index));
}
virtual DockTabWidget *createAnotherTabWidget(QWidget *parent = 0);
int getButtonIndex(QPushButton *btn);
void showHideToolButton(const int &index,const int &option);
@ -52,8 +79,108 @@ public:
return QTabWidget::tabBar();
}
signals:
void willBeAutomaticallyDeleted(DockTabWidget *widget);
public slots:
void deleteIfEmpty();
void dockClosetabs();
void dockGoBackPage();
void dockGoForwardPage();
void tabIndexChanged(int index);
private:
TabBar *m_testTabBar;
QWidget *floatingWidget = 0;
bool floatingEnabled = false;
};
class DockTabBar : public QTabBar
{
Q_OBJECT
public:
DockTabBar(DockTabWidget *tabWidget, QWidget *parent = 0);
// return tab widget of respective tab bar widget.
DockTabWidget *tabWidget()
{
return tab_widget;
}
protected:
// re-implemnted mouse event to detect tab drag started or not.
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
// re-implemnted drag-drop event for docking of tabs.
void dragEnterEvent(QDragEnterEvent *event);
void dropEvent(QDropEvent *event);
void dragLeaveEvent(QDragLeaveEvent * event);
void paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
bool isToolBtnVisible = false;
DockTabWidget *l_tab_widget = dynamic_cast<DockTabWidget*>(this->parent());
if (l_tab_widget != NULL)
{
int current_index = l_tab_widget->currentIndex();
QStylePainter painter(this);
for(int i = 0; i < l_tab_widget->count(); ++i)
{
QString str = l_tab_widget->tabText(i);
if (!str.startsWith("pgAdmin 4") && !str.startsWith("Query -") && !str.startsWith("Debugger"))
isToolBtnVisible = true;
QStyleOptionTab option;
initStyleOption(&option, i);
QString tempText = this->tabText(i);
if (tempText.length() > 28)
{
tempText = tempText.mid(0,27);
tempText += QString("...");
}
QRect rect(option.rect);
// If toolButton is visible then only draw text after tool button pixel area.
if (isToolBtnVisible)
{
if ((current_index != -1) && i == current_index)
{
if (str.startsWith("Query -") || str.startsWith("Debugger"))
rect.setX(option.rect.x() + 5);
else
rect.setX(option.rect.x() + 45);
}
else
rect.setX(option.rect.x() + 5);
}
else
rect.setX(option.rect.x() + 5);
rect.setY(option.rect.y() + 7);
option.text = QString();
painter.drawControl(QStyle::CE_TabBarTab, option);
painter.drawItemText(rect, 0, palette(), 1, tempText);
}
}
}
#ifdef __APPLE__
QSize tabSizeHint(int) const
{
return QSize(250, 26);
}
#endif
private:
int insertionIndexAt(const QPoint &pos);
DockTabWidget *tab_widget = 0;
bool isStartingDrag = false;
QPoint dragStartPos;
};
#endif // TABWINDOW_H

View File

@ -13,12 +13,15 @@
// App headers
#include "WebViewWindow.h"
#include "TabWindow.h"
#ifndef PGADMIN4_USE_WEBENGINE
#include <QWebPage>
#include <QNetworkRequest>
#endif
WebViewWindow *WebViewWindow::mainWebViewWindow = NULL;
// Override QWebEnginePage to handle link delegation
#ifdef PGADMIN4_USE_WEBENGINE
bool WebEnginePage::acceptNavigationRequest(const QUrl & url, NavigationType type, bool isMainFrame)
@ -51,6 +54,85 @@ WebViewWindow::WebViewWindow(QWidget *parent) :
{
m_url = QString("");
m_tabIndex = 0;
m_backForwardBtnHide = false;
// Accept drop event for only main pgAdmin4 application window.
if (mainWebViewWindow == NULL)
mainWebViewWindow = this;
setAcceptDrops(true);
}
// Actual tab drag started.
void WebViewWindow::dragEnterEvent(QDragEnterEvent *event)
{
//DockTabWidget *mainTabWidget = DockTabWidget::getMainTabWidget();
//if (this->parent()->parent()->parent() == mainTabWidget)
event->accept();
}
void WebViewWindow::dragMoveEvent(QDragMoveEvent *event)
{
event->acceptProposedAction();
}
// Drop event handler for tabbar.
void WebViewWindow::dropEvent(QDropEvent *event)
{
DockTabWidget *oldTabWidget;
int oldIndex;
DockTabWidget::decodeTabDropEvent(event, &oldTabWidget, &oldIndex);
//DockTabWidget *mainTabWidget = DockTabWidget::getMainTabWidget();
DockTabWidget *mainTabWidget = dynamic_cast<DockTabWidget*>(this->parent()->parent()->parent());
if (oldTabWidget && mainTabWidget && oldTabWidget != mainTabWidget)
//if (oldTabWidget && mainTabWidget)
{
mainTabWidget->tabBar()->setVisible(true);
QPoint pos = event->pos();
int index = mainTabWidget->tabBar()->count();
for (int i = 0; i < mainTabWidget->tabBar()->count(); ++i)
{
QRect rect = mainTabWidget->tabBar()->tabRect(i);
QRect rect1(rect.x(), rect.y(), rect.width() / 2, rect.height());
QRect rect2(rect.x() + rect1.width(), rect.y(), rect.width() - rect1.width(), rect.height());
if (rect1.contains(pos))
{
index = i;
break;
}
if (rect2.contains(pos))
{
index = i + 1;
break;
}
}
DockTabWidget::moveTab(oldTabWidget, oldIndex, mainTabWidget, index);
// create new back/forward/close buttons and register its events.
mainTabWidget->setButtonsNewTabbar(index);
mainTabWidget->enableDisableToolButton(index);
// Check if main pgAdmin4 application has only one tab then close tab bar.
// Here - check for count 2 because tab will be deleted later.
DockTabWidget *mainTab = DockTabWidget::getMainTabWidget();
if (mainTab != NULL && oldTabWidget != NULL && oldTabWidget == mainTab && mainTab->count() == 1)
mainTab->tabBar()->setVisible(false);
event->acceptProposedAction();
}
}
void WebViewWindow::setBackForwardButtonHidden(const bool hideButton)
{
m_backForwardBtnHide = hideButton;
}
bool WebViewWindow::getBackForwardButtonHidden() const
{
return m_backForwardBtnHide;
}
void WebViewWindow::setFirstLoadURL(const QString &url)

View File

@ -51,11 +51,26 @@ public:
QString getFirstLoadURL() const;
void setTabIndex(const int &tabIndex);
int getTabIndex() const;
void setBackForwardButtonHidden(const bool hideButton);
bool getBackForwardButtonHidden() const;
// Store main webview window of pgAdmin4 application.
static WebViewWindow *mainWebViewWindow;
static WebViewWindow* getMainWebViewWindow()
{
return mainWebViewWindow;
}
protected:
// re-implemnted drag-drop event for docking of tabs.
void dragEnterEvent(QDragEnterEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent *event);
private:
QString m_url;
int m_tabIndex;
bool m_backForwardBtnHide;
};
#ifndef PGADMIN4_USE_WEBENGINE

BIN
runtime/back.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 448 B

After

Width:  |  Height:  |  Size: 290 B

BIN
runtime/close.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 587 B

After

Width:  |  Height:  |  Size: 346 B

BIN
runtime/forward.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 445 B

After

Width:  |  Height:  |  Size: 270 B

View File

@ -183,6 +183,9 @@ int main(int argc, char * argv[])
QCoreApplication::setOrganizationDomain("pgadmin.org");
QCoreApplication::setApplicationName(PGA_APP_NAME.toLower().replace(" ", ""));
// Set high DPI pixmap to display icons clear on Qt widget.
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
/* In windows and linux, it is required to set application level proxy
* becuase socket bind logic to find free port gives socket creation error
* when system proxy is configured. We are also setting
@ -351,7 +354,7 @@ int main(int argc, char * argv[])
exit(1);
}
delay(100);
delay(200);
}
// Create & show the main window
@ -362,6 +365,16 @@ int main(int argc, char * argv[])
// Go!
splash->finish(NULL);
// Set global application stylesheet.
QFile file(":/qss/pgadmin4.qss");
if(file.open(QFile::ReadOnly))
{
QString StyleSheet = QLatin1String(file.readAll());
qApp->setStyleSheet(StyleSheet);
file.close();
}
return app.exec();
}

View File

@ -5,5 +5,6 @@
<file>forward.png</file>
<file>close.png</file>
<file>splash.png</file>
<file>qss/pgadmin4.qss</file>
</qresource>
</RCC>

3
runtime/qss/pgadmin4.qss Normal file
View File

@ -0,0 +1,3 @@
QTabBar::tab {
background-color: #E8E8E8;
}