public inbox for [email protected]  
help / color / mirror / Atom feed
[pgAdmin4] - Desktop runtime patch
3+ messages / 2 participants
[nested] [flat]

* [pgAdmin4] - Desktop runtime patch
@ 2016-01-15 14:06  Neel Patel <[email protected]>
  0 siblings, 1 reply; 3+ messages in thread

From: Neel Patel @ 2016-01-15 14:06 UTC (permalink / raw)
  To: pgadmin-hackers; +Cc: [email protected]

Hi,

Please find the attached patch file for the below fix when pgAdmin 4 run in
desktop mode.

Added functionality to open different website link and load the website
data to different tab. To achieve this, new customized QTabWidget and
QWebView are added to render the data to WebView widget. All the widgets
(New Tab, WebViewWinodw, and QToolButton) are added dynamically.
QToolButton is used to traverse back and forward to web document opened in
WebViewWindow.

Introduced the New class called WebViewWindow which is derived from
QWebView. Each tab of the QTabWidget contains the instance of WebViewWindow
class. WebViewWindow class is useful to display the web document.

Introduced New class called TabWindow which is derived from QTabWidget. This
class is useful to achieve following functionality.
  - Customize the close button of tabbar so that it can only be visible other
then main pgAdmin 4 window.
  - Enable/Disable the toolbutton added left side of tabbar  depending on
the web history traversed by the user in WebViewWindow.
  - Set the tooltip text of the tabbar depending on the title change event
of WebViewWindow class.

Modified the Qt project file to support the both the version of python 2
and python 3.

Qt5 is recommended to test pgAdmin4 in dektop mode.

Attached patch is applied and tested on Linux, do let us know for any
comments/issues.

Thanks,
Neel Patel


-- 
Sent via pgadmin-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers


Attachments:

  [application/octet-stream] pgAdmin4_runtime_new.patch (27.8K, 3-pgAdmin4_runtime_new.patch)
  download | inline diff:
diff --git a/runtime/BrowserWindow.cpp b/runtime/BrowserWindow.cpp
index 023a264..89d963c 100644
--- a/runtime/BrowserWindow.cpp
+++ b/runtime/BrowserWindow.cpp
@@ -2,7 +2,7 @@
 //
 // pgAdmin 4 - PostgreSQL Tools
 //
-// Copyright (C) 2013, The pgAdmin Development Team
+// Copyright (C) 2016, The pgAdmin Development Team
 // This software is released under the PostgreSQL Licence
 //
 // BrowserWindow.cpp - Implementation of the main window class
@@ -11,9 +11,6 @@
 
 #include "pgAdmin4.h"
 
-// QT headers
-#include <QtGlobal>
-
 #if QT_VERSION >= 0x050000
 #include <QtWidgets>
 #include <QtWebKitWidgets>
@@ -30,20 +27,54 @@
 // App headers
 #include "BrowserWindow.h"
 
-
 // Constructor
 BrowserWindow::BrowserWindow(QString url)
 {
+    m_tabGridLayout = NULL;
+    m_mainGridLayout = NULL;;
+    m_tabWidget = NULL;
+    m_pgAdminMainTab = NULL;
+    m_addNewTab = NULL;
+    m_addNewGridLayout = NULL;
+    m_addNewWebView = NULL;
+    m_horizontalLayout = NULL;
+    m_widget = NULL;
+    m_toolBtnBack = NULL;
+    m_toolBtnForward = NULL;
+
     m_appServerUrl = url;
 
     // Setup the UI
     createActions();
     createMenus();
 
-    // Create the WebKit control
-    webView = new QWebView(this);
-    setCentralWidget(webView);
-    connect(webView, SIGNAL(loadFinished(bool)), SLOT(finishLoading(bool)));
+    m_tabWidget = new TabWindow(this);
+    m_mainGridLayout = new QGridLayout(m_tabWidget);
+    m_mainGridLayout->setContentsMargins(0, 0, 0, 0);
+    m_pgAdminMainTab = new QWidget(m_tabWidget);
+    m_tabGridLayout = new QGridLayout(m_pgAdminMainTab);
+    m_tabGridLayout->setContentsMargins(0, 0, 0, 0);
+    m_mainWebView = new WebViewWindow(m_pgAdminMainTab);
+
+    m_tabGridLayout->addWidget(m_mainWebView, 0, 0, 1, 1);
+    m_tabWidget->addTab(m_pgAdminMainTab, QString());
+    m_tabWidget->setCurrentIndex(0);
+    m_tabWidget->setTabText(0, "pgAdmin4");
+    m_tabWidget->setTabToolTipText(0, QString("pgAdmin4"));
+
+#ifndef __APPLE__
+    m_tabWidget->setStyleSheet("QTabBar::tab{max-height:32px;max-width:250px;}");
+#endif
+
+    setCentralWidget(m_tabWidget);
+
+    connect(m_mainWebView, SIGNAL(loadFinished(bool)), SLOT(finishLoading(bool)));
+    //Register the slot when click on the URL link form main pgAmdin menu bar
+    connect(m_mainWebView,SIGNAL(linkClicked(const QUrl &)),SLOT(urlLinkClicked(const QUrl &)));
+    //Register the slot on tab index change
+    connect(m_tabWidget,SIGNAL(currentChanged(int )),this,SLOT(tabIndexChanged(int )));
+
+    m_mainWebView->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
 
     // Restore the geometry
     QSettings settings;
@@ -53,10 +84,9 @@ BrowserWindow::BrowserWindow(QString url)
     // Display the app
     m_initialLoad = true;
     m_loadAttempt = 1;
-    webView->setUrl(m_appServerUrl);
+    m_mainWebView->setUrl(m_appServerUrl);
 }
 
-
 // Save the window geometry on close
 void BrowserWindow::closeEvent(QCloseEvent *event)
 {
@@ -125,16 +155,16 @@ void BrowserWindow::finishLoading(bool ok)
             if (m_loadAttempt > 1)
             {
                 qDebug() << "Initial connection failed. Retrying in" << m_loadAttempt << "seconds.";
-                webView->setHtml(QString(tr("<p>Failed to connect to the pgAdmin application server. Retrying in %1 seconds, ") +
+                m_mainWebView->setHtml(QString(tr("<p>Failed to connect to the pgAdmin application server. Retrying in %1 seconds, ") +
                                          tr("or click <a href=\"%2\">here</a> to try again now.</p>")).arg(m_loadAttempt).arg(m_appServerUrl));
             }
             else
             {
-               webView->setHtml(QString(tr("<p>Connecting to the application server...</p>")));
+               m_mainWebView->setHtml(QString(tr("<p>Connecting to the application server...</p>")));
             }
 
             pause(m_loadAttempt);
-            webView->setUrl(m_appServerUrl);
+            m_mainWebView->setUrl(m_appServerUrl);
             m_loadAttempt++;
 
             return;
@@ -142,7 +172,7 @@ void BrowserWindow::finishLoading(bool ok)
         else
         {
             qDebug() << "Initial connection failed after multiple attempts. Aborting.";
-            webView->setHtml(QString(tr("<p>Failed to connect to the pgAdmin application server. ") +
+            m_mainWebView->setHtml(QString(tr("<p>Failed to connect to the pgAdmin application server. ") +
                                      tr("Click <a href=\"%1\">here</a> to try again.</p>")).arg(m_appServerUrl));
         }
     }
@@ -150,6 +180,228 @@ void BrowserWindow::finishLoading(bool ok)
     m_initialLoad = false;
 }
 
+// Check if Tab is already open with given URL name
+int BrowserWindow::findURLTab(const QUrl &name)
+{
+    int tabCount = 0;
+    WebViewWindow *webviewPtr = NULL;
+
+    for (tabCount = 1;tabCount < m_tabWidget->count();tabCount++)
+    {
+        QWidget *tab = m_tabWidget->widget(tabCount);
+        if (tab != NULL)
+        {
+            QList<QWidget*> widgetList = tab->findChildren<QWidget*>();
+            foreach( QWidget* widgetPtr, widgetList )
+            {
+                if (widgetPtr != NULL)
+                {
+	            webviewPtr = dynamic_cast<WebViewWindow*>(widgetPtr);
+
+	            if (webviewPtr != NULL && !QString::compare(webviewPtr->getFirstLoadURL(),name.url(), Qt::CaseInsensitive))
+	            {
+		        m_tabWidget->setCurrentIndex(tabCount);
+		        return 1;
+                    }
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
+// 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();
+
+    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)
+            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)
+{
+    if (!str.isEmpty())
+    {
+        QObject *senderPtr = QObject::sender();
+        WebViewWindow *webViewPtr = NULL;
+        if (senderPtr != NULL)
+        {
+            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());
+            }
+        }
+        else
+        {
+            m_tabWidget->setTabText(m_tabWidget->currentIndex(), str);
+            m_tabWidget->setTabToolTipText(m_tabWidget->currentIndex(), str);
+        }
+    }
+}
+
+// Slot: Link is open from pgAdmin mainwindow
+void BrowserWindow::urlLinkClicked(const QUrl &name)
+{
+    // First check is there any tab opened with same URL then open it again.
+    int tabFound = findURLTab(name);
+
+    if (!tabFound)
+    {
+        m_addNewTab = new QWidget(m_tabWidget);
+        m_addNewGridLayout = new QGridLayout(m_addNewTab);
+        m_addNewGridLayout->setContentsMargins(0, 0, 0, 0);
+        m_addNewWebView = new WebViewWindow(m_addNewTab);
+
+        m_widget = new QWidget(m_addNewTab);
+        m_toolBtnBack = new QToolButton(m_widget);
+        m_toolBtnBack->setFixedHeight(20);
+        m_toolBtnBack->setFixedWidth(20);
+        m_toolBtnBack->setText("<");
+        m_toolBtnForward = new QToolButton(m_widget);
+        m_toolBtnForward->setFixedHeight(20);
+        m_toolBtnForward->setFixedWidth(20);
+        m_toolBtnForward->setText(">");
+        m_toolBtnBack->setDisabled(true);
+        m_toolBtnForward->setDisabled(true);
+
+        QPushButton *m_pushBtn = new QPushButton(m_widget);
+        m_pushBtn->setText(QString("x"));
+        m_pushBtn->setFixedHeight(20);
+        m_pushBtn->setFixedWidth(20);
+
+        m_horizontalLayout = new QHBoxLayout(m_widget);
+        m_horizontalLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
+        m_horizontalLayout->addWidget(m_toolBtnBack);
+        m_horizontalLayout->addWidget(m_toolBtnForward);
+
+        //Register the slot on titleChange so set the tab text accordingly
+        connect(m_addNewWebView,SIGNAL(titleChanged(const QString &)),SLOT(tabTitleChanged(const QString &)));
+        //Register the slot on toolbutton to show the previous history of web
+        connect(m_toolBtnBack,SIGNAL(clicked()),this,SLOT(goBackPage()));
+        //Register the slot on toolbutton to show the next history of web
+        connect(m_toolBtnForward,SIGNAL(clicked()),this,SLOT(goForwardPage()));
+        //Register the slot on close button , added manually
+        connect(m_pushBtn,SIGNAL(clicked()),SLOT(closetabs()));
+
+        m_addNewGridLayout->addWidget(m_addNewWebView, 0, 0, 1, 1);
+        m_tabWidget->addTab(m_addNewTab, QString());
+        m_tabWidget->setCurrentIndex((m_tabWidget->count() - 1));
+        // Set the back and forward button on tab
+        m_tabWidget->tabBar()->setTabButton((m_tabWidget->count() - 1), QTabBar::LeftSide, m_widget);
+        m_tabWidget->tabBar()->setTabButton((m_tabWidget->count() - 1), QTabBar::RightSide, m_pushBtn);
+
+        m_addNewWebView->setFirstLoadURL(name.url());
+        m_addNewWebView->setTabIndex((m_tabWidget->count() - 1));
+        m_addNewWebView->setUrl(name);
+    }
+}
 
 // Pause for n seconds, without freezing the UI.
 void BrowserWindow::pause(int seconds)
@@ -160,14 +412,12 @@ void BrowserWindow::pause(int seconds)
         QCoreApplication::processEvents(QEventLoop::AllEvents, 100);    
 }
 
-
 // Display the about box
 void BrowserWindow::about()
 {
     QMessageBox::about(this, tr("About pgAdmin 4"), tr("pgAdmin 4 - PostgreSQL Tools"));
 }
 
-
 // Open an arbitrary URL
 void BrowserWindow::openUrl()
 {
@@ -175,7 +425,7 @@ void BrowserWindow::openUrl()
     QString url = QInputDialog::getText(this, tr("Open URL"), tr("Enter a URL"), QLineEdit::Normal, "http://", &ok);
 
     if (ok && !url.isEmpty())
-        webView->setUrl(url);
+        m_mainWebView->setUrl(url);
 }
 
 // Open an arbitrary URL
diff --git a/runtime/BrowserWindow.h b/runtime/BrowserWindow.h
index e580d8b..fc45173 100644
--- a/runtime/BrowserWindow.h
+++ b/runtime/BrowserWindow.h
@@ -2,7 +2,7 @@
 //
 // pgAdmin 4 - PostgreSQL Tools
 //
-// Copyright (C) 2013, The pgAdmin Development Team
+// Copyright (C) 2016, The pgAdmin Development Team
 // This software is released under the PostgreSQL Licence
 //
 // BrowserWindow.h - Declaration of the main window class
@@ -13,8 +13,8 @@
 #define BROWSERWINDOW_H
 
 #include "pgAdmin4.h"
-
-#include <QtGlobal>
+#include "TabWindow.h"
+#include "WebViewWindow.h"
 
 #if QT_VERSION >= 0x050000
 #include <QtWidgets>
@@ -41,15 +41,23 @@ protected:
 
 protected slots:
     void finishLoading(bool);
+    void urlLinkClicked(const QUrl &);
+    void closetabs();
+    void tabTitleChanged(const QString &);
 
 private slots:
     void openUrl();
     void pythonPath();
     void about();
 
+public slots:
+    void tabIndexChanged(int index);
+    void goBackPage();
+    void goForwardPage();
+
 private:
     QString m_appServerUrl;
-    QWebView *webView;
+    WebViewWindow *m_mainWebView;
     QMenu *fileMenu;
     QMenu *helpMenu;
     QAction *openUrlAction;
@@ -57,12 +65,26 @@ private:
     QAction *exitAction;
     QAction *aboutAction;
 
+    QGridLayout  *m_tabGridLayout;
+    QGridLayout  *m_mainGridLayout;
+    TabWindow    *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;
+
     bool m_initialLoad;
     int m_loadAttempt;
 
     void createActions();
     void createMenus();
     void pause(int seconds = 1);
+    int  findURLTab(const QUrl &name);
 };
 
 #endif // BROWSERWINDOW_H
diff --git a/runtime/Server.cpp b/runtime/Server.cpp
index b47ece3..42b636d 100644
--- a/runtime/Server.cpp
+++ b/runtime/Server.cpp
@@ -2,7 +2,7 @@
 //
 // pgAdmin 4 - PostgreSQL Tools
 //
-// Copyright (C) 2013, The pgAdmin Development Team
+// Copyright (C) 2016, The pgAdmin Development Team
 // This software is released under the PostgreSQL Licence
 //
 // Server.cpp - Thread in which the web server will run.
@@ -26,9 +26,21 @@ Server::Server(quint16 port)
 {    
     // Appserver port
     m_port = port;
+    m_wcAppName = NULL;
 
     // Initialise Python
+    // As Python3 require to convert char  * to wchar_t * type so below condition is required for
+    // Python2 and Python3
+#ifdef PYTHON2
     Py_SetProgramName(PGA_APP_NAME.toUtf8().data());
+#else
+    char *appName = PGA_APP_NAME.toUtf8().data();
+    const size_t cSize = strlen(appName)+1;
+    m_wcAppName = new wchar_t[cSize];
+    mbstowcs (m_wcAppName, appName, cSize);
+    Py_SetProgramName(m_wcAppName);
+#endif
+
     Py_Initialize();
 
     // Setup the search path
@@ -45,12 +57,21 @@ Server::Server(quint16 port)
 
         // Add new additional path elements
         for (int i = 0; i < path_list.size(); ++i)
+        {
+            #ifdef PYTHON2
             PyList_Append(sysPath, PyString_FromString(path_list.at(i).toUtf8().data()));
+            #else
+            PyList_Append(sysPath, PyBytes_FromString(path_list.at(i).toUtf8().data()));
+            #endif
+        }
     }
 }
 
 Server::~Server()
 {
+    if (m_wcAppName)
+        delete m_wcAppName;
+
     // Shutdown Python
     Py_Finalize();
 }
diff --git a/runtime/Server.h b/runtime/Server.h
index 73c06b7..1cc2fcb 100644
--- a/runtime/Server.h
+++ b/runtime/Server.h
@@ -2,7 +2,7 @@
 //
 // pgAdmin 4 - PostgreSQL Tools
 //
-// Copyright (C) 2013, The pgAdmin Development Team
+// Copyright (C) 2016, The pgAdmin Development Team
 // This software is released under the PostgreSQL Licence
 //
 // Server.h - Thread in which the web server will run.
@@ -38,7 +38,8 @@ private:
     QString m_appfile;
     QString m_error;
 
-    quint16 m_port;
+    quint16  m_port;
+    wchar_t *m_wcAppName;
 };
 
 #endif // SERVER_H
diff --git a/runtime/TabWindow.cpp b/runtime/TabWindow.cpp
new file mode 100644
index 0000000..de9670c
--- /dev/null
+++ b/runtime/TabWindow.cpp
@@ -0,0 +1,134 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2016, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+// TabWindow.cpp - Implementation of the custom tab widget
+//
+//////////////////////////////////////////////////////////////////////////
+
+#include "pgAdmin4.h"
+
+// App headers
+#include "TabWindow.h"
+
+
+TabWindow::TabWindow(QWidget *parent) :
+    QTabWidget(parent)
+{
+    setParent(parent);
+    setTabsClosable(false);
+    setElideMode(Qt::ElideRight);
+#ifdef __APPLE__
+    m_testTabBar = new TabBar();
+    setTabBar(m_testTabBar);
+#endif
+
+}
+
+// hide the close button of given index displayed on right side of tab
+void TabWindow::enableDisableToolButton(const int &index)
+{
+    QToolButton *toolBtnPtr = NULL;
+    WebViewWindow *webviewPtr = NULL;
+
+    // Code to enable/disable the toolbutton based on the history
+    QWidget *tab1 = this->widget(index);
+    if (tab1 != NULL)
+    {
+        QList<QWidget*> widgetList = tab1->findChildren<QWidget*>();
+        foreach( QWidget* widgetPtr, widgetList )
+        {
+            if (widgetPtr != NULL)
+                webviewPtr = dynamic_cast<WebViewWindow*>(widgetPtr);
+        }
+    }
+
+    QWidget *tab = tabBar()->tabButton(index, QTabBar::LeftSide);
+    if (tab != NULL)
+    {
+        QList<QWidget*> widgetList = tab->findChildren<QWidget*>();
+        foreach( QWidget* widgetPtr, widgetList )
+        {
+            if (widgetPtr != NULL)
+            {
+                toolBtnPtr = dynamic_cast<QToolButton*>(widgetPtr);
+                if (webviewPtr != NULL && toolBtnPtr != NULL)
+                {
+		    if (!QString::compare(toolBtnPtr->text(),QString("<"), Qt::CaseInsensitive))
+                    {
+			if (webviewPtr->page()->history()->canGoBack())
+			    toolBtnPtr->setDisabled(false);
+		        else
+			    toolBtnPtr->setDisabled(true);
+                    }
+
+		    if (!QString::compare(toolBtnPtr->text(),QString(">"), Qt::CaseInsensitive))
+                    {
+			if (webviewPtr->page()->history()->canGoForward())
+			    toolBtnPtr->setDisabled(false);
+		        else
+			    toolBtnPtr->setDisabled(true);
+		    }
+		}
+            }
+        }
+    }
+}
+
+// get the index of the pushbutton which is requested by user to close the tab
+int TabWindow::getButtonIndex(QPushButton *btn)
+{
+    QPushButton *nextBtnPtr = NULL;
+    int loopCount = 0;
+    int totalTabs = this->count();
+
+    for (loopCount = 1;loopCount < totalTabs;loopCount++)
+    {
+        QWidget *tab = tabBar()->tabButton(loopCount, QTabBar::RightSide);
+        if (tab != NULL)
+        {
+            nextBtnPtr = dynamic_cast<QPushButton*>(tab);
+            if (nextBtnPtr != NULL && btn != NULL && nextBtnPtr == btn)
+                return loopCount;
+        }
+    }
+
+    return 0;
+}
+
+// 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)
+{
+    QToolButton *toolBtnPtr = NULL;
+
+    QWidget *tab = tabBar()->tabButton(index, QTabBar::LeftSide);
+    if (tab != NULL)
+    {
+        QList<QWidget*> widgetList = tab->findChildren<QWidget*>();
+        foreach( QWidget* widgetPtr, widgetList )
+        {
+            if (widgetPtr != NULL)
+            {
+                toolBtnPtr = dynamic_cast<QToolButton*>(widgetPtr);
+                if (toolBtnPtr != NULL)
+		{
+		    if (!option)
+                        toolBtnPtr->hide();
+		    else
+                        toolBtnPtr->show();
+		}
+            }
+        }
+    }
+}
+
+// Set the tab tool tip text
+void TabWindow::setTabToolTipText(const int &index, const QString &toolTipString)
+{
+    tabBar()->setTabToolTip(index, toolTipString);
+}
diff --git a/runtime/TabWindow.h b/runtime/TabWindow.h
new file mode 100644
index 0000000..67e59ad
--- /dev/null
+++ b/runtime/TabWindow.h
@@ -0,0 +1,52 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2016, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+// TabWindow.h - Declaration of the custom tab widget
+//
+//////////////////////////////////////////////////////////////////////////
+
+#ifndef TABWINDOW_H
+#define TABWINDOW_H
+
+#include "pgAdmin4.h"
+#include "WebViewWindow.h"
+
+class TabBar : public QTabBar
+{
+    Q_OBJECT
+public:
+    TabBar(QWidget* parent=0) : QTabBar(parent)
+    {
+    }
+
+protected:
+    QSize tabSizeHint(int) const
+    {
+        return QSize(250, 32);
+    }
+};
+
+class TabWindow : public QTabWidget
+{
+    Q_OBJECT
+public:
+    TabWindow(QWidget *parent = 0);
+
+    int getButtonIndex(QPushButton *btn);
+    void showHideToolButton(const int &index,const int &option);
+    void enableDisableToolButton(const int &index);
+    void setTabToolTipText(const int &index, const QString &toolTipString);
+    QTabBar *tabBar() const
+    {
+        return QTabWidget::tabBar();
+    }
+
+private:
+    TabBar *m_testTabBar;
+};
+
+#endif // TABWINDOW_H
diff --git a/runtime/WebViewWindow.cpp b/runtime/WebViewWindow.cpp
new file mode 100644
index 0000000..0e6e738
--- /dev/null
+++ b/runtime/WebViewWindow.cpp
@@ -0,0 +1,42 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2016, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+// WebViewWindow.cpp - Implementation of the custom web view widget
+//
+//////////////////////////////////////////////////////////////////////////
+
+#include "pgAdmin4.h"
+
+// App headers
+#include "WebViewWindow.h"
+
+WebViewWindow::WebViewWindow(QWidget *parent) :
+    QWebView(parent)
+{
+    m_url = QString("");
+    m_tabIndex = 0;
+}
+
+void WebViewWindow::setFirstLoadURL(const QString &url)
+{
+    m_url = url;
+}
+
+QString WebViewWindow::getFirstLoadURL() const
+{
+    return m_url;
+}
+
+void WebViewWindow::setTabIndex(const int &tabIndex)
+{
+    m_tabIndex = tabIndex;
+}
+
+int WebViewWindow::getTabIndex() const
+{
+    return m_tabIndex;
+}
diff --git a/runtime/WebViewWindow.h b/runtime/WebViewWindow.h
new file mode 100644
index 0000000..b988e48
--- /dev/null
+++ b/runtime/WebViewWindow.h
@@ -0,0 +1,35 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2016, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+// WebViewWindow.h - Declaration of the custom web view widget
+//
+//////////////////////////////////////////////////////////////////////////
+
+#ifndef WEBVIEWWINDOW_H
+#define WEBVIEWWINDOW_H
+
+#include "pgAdmin4.h"
+
+#include <QtWebKitWidgets>
+
+class WebViewWindow : public QWebView
+{
+    Q_OBJECT
+public:
+   WebViewWindow(QWidget *parent = NULL);
+   void setFirstLoadURL(const QString &url);
+   QString getFirstLoadURL() const;
+   void setTabIndex(const int &tabIndex);
+   int getTabIndex() const;
+
+private:
+    QString m_url;
+    int m_tabIndex;
+
+};
+
+#endif //WEBVIEWWINDOW_H
diff --git a/runtime/pgAdmin4.cpp b/runtime/pgAdmin4.cpp
index 6546eb2..1dbfb73 100644
--- a/runtime/pgAdmin4.cpp
+++ b/runtime/pgAdmin4.cpp
@@ -2,7 +2,7 @@
 //
 // pgAdmin 4 - PostgreSQL Tools
 //
-// Copyright (C) 2013, The pgAdmin Development Team
+// Copyright (C) 2016, The pgAdmin Development Team
 // This software is released under the PostgreSQL Licence
 //
 // pgAdmin4.cpp - Main application entry point
@@ -14,14 +14,14 @@
 // Must be before QT
 #include <Python.h>
 
-// QT headers
-#include <QtGlobal>
-
 #if QT_VERSION >= 0x050000
 #include <QtWidgets>
 #else
 #include <QApplication>
 #include <QDebug>
+#include <QtNetwork>
+#include <QLineEdit>
+#include <QInputDialog>
 #endif
 
 // App headers
@@ -38,11 +38,18 @@ int main(int argc, char * argv[])
     QCoreApplication::setOrganizationDomain("pgadmin.org");
     QCoreApplication::setApplicationName(PGA_APP_NAME);
 
+    quint16 port = 0L;
+
     // Find an unused port number. Essentially, we're just reserving one
     // here that Flask will use when we start up the server.
-    QTcpSocket socket;
-    socket.bind(0, QAbstractSocket::DontShareAddress);
-    quint16 port = socket.localPort();
+    // In order to use the socket, we need to free this socket ASAP.
+    // Hence - putting this code in a code block, so that - the scope of socket
+    // variable goes out of scope to make that socket available.
+    {
+        QTcpSocket socket;
+        socket.bind(0, QAbstractSocket::DontShareAddress);
+        port = socket.localPort();
+    }
 
     // Fire up the webserver
     Server *server = new Server(port);
diff --git a/runtime/pgAdmin4.h b/runtime/pgAdmin4.h
index a6b251f..0f7dd24 100644
--- a/runtime/pgAdmin4.h
+++ b/runtime/pgAdmin4.h
@@ -2,7 +2,7 @@
 //
 // pgAdmin 4 - PostgreSQL Tools
 //
-// Copyright (C) 2013, The pgAdmin Development Team
+// Copyright (C) 2016, The pgAdmin Development Team
 // This software is released under the PostgreSQL Licence
 //
 // pgAdmin4.h - Main application header
@@ -23,6 +23,7 @@
 #include <QtWidgets>
 #else
 #include <QApplication>
+#include <Qt/qurl.h>
 #endif
 
 // Application name
diff --git a/runtime/pgAdmin4.pro b/runtime/pgAdmin4.pro
index c9dd8c2..d75b92e 100644
--- a/runtime/pgAdmin4.pro
+++ b/runtime/pgAdmin4.pro
@@ -7,20 +7,32 @@ greaterThan(QT_MAJOR_VERSION, 4) {
     QT += webkit network 
 }
 
+PYTHON_CONFIG=python3-config
+
 # Find and configure Python
-!system(which python-config > /dev/null 2>&1) {
-    error(The python-config executable could not be found. Ensure Python is installed and in the system path.)
+!system(which python3-config > /dev/null 2>&1) {
+    !system(which python-config > /dev/null 2>&1) {
+        error(The python-config executable could not be found. Ensure Python is installed and in the system path.)
+    } else {
+	PYTHON_CONFIG=python-config
+	DEFINES += PYTHON2
+    }
 }
-QMAKE_CXXFLAGS += $$system(python-config --includes)
-QMAKE_LFLAGS += $$system(python-config --ldflags)
+
+QMAKE_CXXFLAGS += $$system($$PYTHON_CONFIG --includes)
+QMAKE_LFLAGS += $$system($$PYTHON_CONFIG --ldflags)
 
 # Source code
 HEADERS     =   BrowserWindow.h \
                 Server.h \
-                pgAdmin4.h
+                pgAdmin4.h \
+                TabWindow.h \
+                WebViewWindow.h
 SOURCES     =   pgAdmin4.cpp \
                 BrowserWindow.cpp \
-                Server.cpp
+                Server.cpp \
+                TabWindow.cpp \
+                WebViewWindow.cpp
 FORMS       =   BrowserWindow.ui
 ICON        =   pgAdmin4.icns
 QMAKE_INFO_PLIST = Info.plist


^ permalink  raw  reply  [nested|flat] 3+ messages in thread

* Re: [pgadmin-support] [pgAdmin4] - Desktop runtime patch
@ 2016-01-18 14:37  Dave Page <[email protected]>
  parent: Neel Patel <[email protected]>
  0 siblings, 1 reply; 3+ messages in thread

From: Dave Page @ 2016-01-18 14:37 UTC (permalink / raw)
  To: Neel Patel <[email protected]>; +Cc: pgadmin-hackers; pgAdmin Support <[email protected]>

Thanks Neel. I've committed this with various minor tweaks, mostly
around the tab button text and sizing.

Please test on Windows and Linux to ensure I didn't inadvertently
break anything. Mac seems fine here.

On Fri, Jan 15, 2016 at 2:06 PM, Neel Patel <[email protected]> wrote:
> Hi,
>
> Please find the attached patch file for the below fix when pgAdmin 4 run in
> desktop mode.
>
> Added functionality to open different website link and load the website data
> to different tab. To achieve this, new customized QTabWidget and QWebView
> are added to render the data to WebView widget. All the widgets (New Tab,
> WebViewWinodw, and QToolButton) are added dynamically. QToolButton is used
> to traverse back and forward to web document opened in WebViewWindow.
>
> Introduced the New class called WebViewWindow which is derived from
> QWebView. Each tab of the QTabWidget contains the instance of WebViewWindow
> class. WebViewWindow class is useful to display the web document.
>
> Introduced New class called TabWindow which is derived from QTabWidget. This
> class is useful to achieve following functionality.
>   - Customize the close button of tabbar so that it can only be visible
> other then main pgAdmin 4 window.
>   - Enable/Disable the toolbutton added left side of tabbar  depending on
> the web history traversed by the user in WebViewWindow.
>   - Set the tooltip text of the tabbar depending on the title change event
> of WebViewWindow class.
>
> Modified the Qt project file to support the both the version of python 2 and
> python 3.
>
> Qt5 is recommended to test pgAdmin4 in dektop mode.
>
> Attached patch is applied and tested on Linux, do let us know for any
> comments/issues.
>
> Thanks,
> Neel Patel
>
>
> --
> Sent via pgadmin-support mailing list ([email protected])
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgadmin-support
>



-- 
Dave Page
Blog: http://pgsnake.blogspot.com
Twitter: @pgsnake

EnterpriseDB UK: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


-- 
Sent via pgadmin-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers



^ permalink  raw  reply  [nested|flat] 3+ messages in thread

* Re: [pgAdmin4] - Desktop runtime patch
@ 2016-01-18 16:47  Neel Patel <[email protected]>
  parent: Dave Page <[email protected]>
  0 siblings, 0 replies; 3+ messages in thread

From: Neel Patel @ 2016-01-18 16:47 UTC (permalink / raw)
  To: Dave Page <[email protected]>; +Cc: pgadmin-hackers; pgAdmin Support <[email protected]>

Thanks Dave.
I will test on Windows and Linux and keep you updated.

Thanks,
Neel Patel

On Mon, Jan 18, 2016 at 8:07 PM, Dave Page <[email protected]> wrote:

> Thanks Neel. I've committed this with various minor tweaks, mostly
> around the tab button text and sizing.
>
> Please test on Windows and Linux to ensure I didn't inadvertently
> break anything. Mac seems fine here.
>
> On Fri, Jan 15, 2016 at 2:06 PM, Neel Patel <[email protected]>
> wrote:
> > Hi,
> >
> > Please find the attached patch file for the below fix when pgAdmin 4 run
> in
> > desktop mode.
> >
> > Added functionality to open different website link and load the website
> data
> > to different tab. To achieve this, new customized QTabWidget and QWebView
> > are added to render the data to WebView widget. All the widgets (New Tab,
> > WebViewWinodw, and QToolButton) are added dynamically. QToolButton is
> used
> > to traverse back and forward to web document opened in WebViewWindow.
> >
> > Introduced the New class called WebViewWindow which is derived from
> > QWebView. Each tab of the QTabWidget contains the instance of
> WebViewWindow
> > class. WebViewWindow class is useful to display the web document.
> >
> > Introduced New class called TabWindow which is derived from QTabWidget.
> This
> > class is useful to achieve following functionality.
> >   - Customize the close button of tabbar so that it can only be visible
> > other then main pgAdmin 4 window.
> >   - Enable/Disable the toolbutton added left side of tabbar  depending on
> > the web history traversed by the user in WebViewWindow.
> >   - Set the tooltip text of the tabbar depending on the title change
> event
> > of WebViewWindow class.
> >
> > Modified the Qt project file to support the both the version of python 2
> and
> > python 3.
> >
> > Qt5 is recommended to test pgAdmin4 in dektop mode.
> >
> > Attached patch is applied and tested on Linux, do let us know for any
> > comments/issues.
> >
> > Thanks,
> > Neel Patel
> >
> >
> > --
> > Sent via pgadmin-support mailing list ([email protected])
> > To make changes to your subscription:
> > http://www.postgresql.org/mailpref/pgadmin-support
> >
>
>
>
> --
> Dave Page
> Blog: http://pgsnake.blogspot.com
> Twitter: @pgsnake
>
> EnterpriseDB UK: http://www.enterprisedb.com
> The Enterprise PostgreSQL Company
>


^ permalink  raw  reply  [nested|flat] 3+ messages in thread


end of thread, other threads:[~2016-01-18 16:47 UTC | newest]

Thread overview: 3+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2016-01-15 14:06 [pgAdmin4] - Desktop runtime patch Neel Patel <[email protected]>
2016-01-18 14:37 ` Dave Page <[email protected]>
2016-01-18 16:47   ` Neel Patel <[email protected]>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox