mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
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:
parent
900ccebb50
commit
0056a94115
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
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
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
BIN
runtime/forward.png
Normal file → Executable file
Binary file not shown.
Before Width: | Height: | Size: 445 B After Width: | Height: | Size: 270 B |
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
3
runtime/qss/pgadmin4.qss
Normal file
@ -0,0 +1,3 @@
|
||||
QTabBar::tab {
|
||||
background-color: #E8E8E8;
|
||||
}
|
Loading…
Reference in New Issue
Block a user