ginebra2/ContentViews/BrowserWindow.cpp
changeset 16 3c88a81ff781
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ginebra2/ContentViews/BrowserWindow.cpp	Fri Oct 15 17:30:59 2010 -0400
@@ -0,0 +1,375 @@
+#include "BrowserWindow.h"
+#include "WindowsView.h"
+#include "ChromeLayout.h"
+#include "ChromeWidget.h"
+#include "ChromeView.h"
+#include "ChromeDOM.h" //Get rid of this dependency
+#include "GWebContentView.h"
+#include <QGraphicsWidget>
+#include <QGraphicsScene>
+#include <QGraphicsTextItem>
+#include <QVBoxLayout>
+#include "webpagecontroller.h"
+#include "ViewStack.h"
+#ifdef Q_WS_MAEMO_5
+#include <QtGui/QX11Info>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#endif
+
+namespace GVA {
+
+  bool BrowserWindow::m_preventDisconnectPageTitleChanged = false; // workaraound for multiple windows crash
+  bool BrowserWindow::m_preventConnectPageTitleChanged = false;    // workaround for multiple windows crash
+
+  BrowserWindow::BrowserWindow(ChromeWidget * chrome, WindowsView * windows, QWidget * parent, Qt::WindowFlags flags)
+    : QMainWindow(parent, flags),
+      m_page(0),
+      m_specialPage(0),
+      m_decorated(false),
+      m_chrome(chrome),
+      m_scene(new QGraphicsScene()),
+      m_snapshot(0),
+      m_windows(windows),
+      m_state(menuEnabled),   
+      m_slidedUp(false),   
+      m_viewName("WebView"),
+      m_changingMode(false)
+  {
+    m_view = new ChromeView(m_scene, m_chrome, this);
+    setCentralWidget(m_view);
+    show();
+    ViewController *controller = viewController();
+    if(controller) {
+        connect(controller, SIGNAL(currentViewChanged(ControllableViewBase *)), this, SLOT(onViewChanged(ControllableViewBase *)));
+    }
+    slideViewIfRequired(100); // display UrlSearchBar for every new window
+  }
+
+  void BrowserWindow::setPage(WRT::WrtBrowserContainer * page)
+  { 
+    m_page = page;
+    connectPageTitleChanged();
+  }
+
+	// hide or show UrlSearchBar if required
+	// This is a workaround for the problem that created by the fact that
+	// multiple instances of BrowserWindow use same instance of m_chrome and m_chrome->layout()
+	// 
+  void BrowserWindow::slideViewIfRequired(int value)
+  {
+      if(value > 0) { // slide up to display UrlSearchBar
+           m_chrome->layout()->slideView(value);
+           m_slidedUp = true;
+           return;
+      }
+
+      if((m_slidedUp == true) && (value < 0)) { // slide down UrlSearchBar
+           m_chrome->layout()->slideView(value);
+           m_slidedUp = false;
+           return;
+      }
+  }
+  
+  void BrowserWindow::toggleDecoration() 
+  { 
+    m_decorated = !m_decorated;
+    if(m_decorated) {
+      showDecoration();
+    } 
+    else {
+      hideDecoration();
+    }
+  }
+
+  void BrowserWindow::showDecoration()
+  {
+    m_state |= active;
+    if(m_page)       
+      WebPageController::getSingleton()->setCurrentPage(m_page);
+    m_windows->deactivate(this);
+    if(m_snapshot)
+      m_snapshot->hide();
+    if(m_chrome){
+      m_chrome->layout()->setPos(0,0);
+      m_scene->addItem(m_chrome->layout());
+      m_chrome->layout()->show();
+      // Ensure that the layout size is in-synch with the window size.
+      m_chrome->layout()->resize(size());
+    }
+  }
+
+  void BrowserWindow::hideDecoration()
+  {
+    m_state &= ~active;
+
+    m_windows->activate(this);
+    if(m_chrome)
+      m_scene->removeItem(m_chrome->layout());
+
+    if(m_page){
+      m_page->triggerAction(QWebPage::Stop);
+      //QImage image = WebPageController::getSingleton()->pageThumbnail(m_page);
+      //	if(image.isNull()){
+      //QImage image =  m_page->pageThumbnail(1,1);
+      //
+      
+      QImage image;
+      //This is really a bit hackish: the page controller should be able
+      //to figure this out;
+      //if(m_windows->contentView()->currentPageIsSuperPage()){
+	//m_specialPage = static_cast<WRT::WrtBrowserContainer*>(m_windows->contentView()->wrtPage());
+        //m_windows->contentView()->updateWebPage(m_page);
+	//image = m_windows->contentView()->pageThumbnail(1,1);
+      //}
+      //else
+        QSize s(800,464);
+        image = m_page->thumbnail(s);
+      if(m_snapshot){
+	m_scene->removeItem(m_snapshot);
+	delete m_snapshot;
+      }
+      m_snapshot = new QGraphicsPixmapItem(QPixmap::fromImage(image));
+      m_scene->addItem(m_snapshot);
+      m_snapshot->show();
+    } else {
+      qDebug() << "BrowserWindow::hideDecoration: page not set";
+    }
+  }
+  
+  void BrowserWindow::closeWindow()
+  {
+    //Tell the page controler to close this page.
+    //The controller emits pageClosed. WindowsView
+    //handles this and deletes this browser window
+    // Don't delete if only 1 window open..causes crash on exit
+    if (WebPageController::getSingleton()->pageCount() > 1)
+      WebPageController::getSingleton()->closePage(m_page);
+  }
+
+  //Handle window events
+  bool BrowserWindow::event(QEvent * event) 
+  {
+    //qDebug() << "=====================BrowserWindow:event: " << event->type();
+    switch (event->type()) {
+    case QEvent::WindowBlocked:
+      m_state |= blocked;
+      break;
+    case QEvent::WindowUnblocked:
+      m_state &= ~blocked;
+      break;
+    case QEvent::WindowActivate: //Newly shown window or window maximized
+      handleWindowActivate();
+      m_chrome->windowStateChange(windowState());
+      break;
+    case QEvent::WindowDeactivate:
+      handleWindowDeactivate();
+      m_chrome->windowStateChange(windowState());
+      break;
+    case QEvent::Close:
+      m_state |= blocked; 
+      closeWindow();
+      break;    
+    default:
+      break;
+    }
+    return QMainWindow::event(event);
+  }
+
+ void BrowserWindow::changeEvent(QEvent * event) {
+    switch (event->type()) {
+      case QEvent::WindowStateChange:
+        m_chrome->windowStateChange(windowState());
+        break;
+      default:
+        break;
+    }
+    QMainWindow::changeEvent(event);
+  }
+
+  void BrowserWindow::handleWindowActivate() {
+      if(m_changingMode) {
+          // Ignore if in the process of changing from fullscreen to normal.  We get a deactivate followed by
+          // an activate call when this is done.  Clear the flag for the next time activate or deactivate is
+          // called for some other reason.
+          m_changingMode = false;
+          return;
+      }
+#ifdef Q_WS_MAEMO_5
+      grabZoomKeys(true);
+#endif
+      showDecoration();
+      if(m_chrome) {
+          connect(m_chrome, SIGNAL(requestToggleNormalFullScreen()), this, SLOT(toggleNormalFullScreen()));
+      }
+  }
+
+  void BrowserWindow::handleWindowDeactivate() {
+      if(m_changingMode) {
+          // Ignore if in the process of changing from fullscreen to normal.
+          return;
+      }
+#ifdef Q_WS_MAEMO_5
+      grabZoomKeys(false);
+#endif
+      if(!((m_state & blocked) == blocked))
+        hideDecoration();
+      slideViewIfRequired(-100); // hide UrlSearchBar if required
+      if(m_chrome) {
+          disconnect(m_chrome, SIGNAL(requestToggleNormalFullScreen()), this, SLOT(toggleNormalFullScreen()));
+      }
+  }
+
+  void BrowserWindow::setMenuEnabled(bool enabled)
+  {
+    if(enabled)
+      m_state |= menuEnabled;
+    else
+      m_state &= ~menuEnabled;
+
+    fixupWindowTitle();
+  }
+
+  void BrowserWindow::setTitle(const QString &title)
+  {
+    if(title.isEmpty()) {
+        setWindowTitle(QApplication::applicationName());
+    }
+    else {
+        setWindowTitle(title);
+    }
+
+    fixupWindowTitle();
+  }
+
+  /// Hack to hide the menu bar arrow when the menu is disabled.
+  void BrowserWindow::fixupWindowTitle() {
+      QString title = windowTitle();
+      title = title.trimmed();
+      if(!m_windows->isMenuEnabled()) {
+          // The menu is disabled, add some spaces to the title to push the down arrow out of view.
+          title += QString(60, ' ');
+      }
+      setWindowTitle(title);
+  }
+
+  void BrowserWindow::onPageTitleChanged(const QString &title)
+  {
+      setTitle(title);
+  }
+
+  void BrowserWindow::onViewChanged(ControllableViewBase *newView) {
+      Q_ASSERT(newView);
+
+      if(m_windows->contentView()->currentPageIsSuperPage()) {
+          if(!m_preventDisconnectPageTitleChanged)
+            disconnectPageTitleChanged();
+          m_preventDisconnectPageTitleChanged = true;
+          m_preventConnectPageTitleChanged = false;
+      }
+      else {
+          if(!m_preventConnectPageTitleChanged)
+            connectPageTitleChanged();
+          m_preventDisconnectPageTitleChanged = false;
+          m_preventConnectPageTitleChanged = true;
+      }
+      if(m_state & active) {
+          setTitle(newView->title());
+      }
+  }
+
+  ViewController *BrowserWindow::viewController() {
+    ViewStack *viewStack = ViewStack::getSingleton();
+    if(viewStack) {
+        return viewStack->getViewController();
+    }
+
+    return 0;
+  }
+
+  void BrowserWindow::connectPageTitleChanged() {
+      connect(m_page->mainFrame(), SIGNAL(titleChanged(const QString &)),
+              this, SLOT(onPageTitleChanged(const QString &)));
+  }
+
+  void BrowserWindow::disconnectPageTitleChanged() {
+      disconnect(m_page->mainFrame(), SIGNAL(titleChanged(const QString &)),
+              this, SLOT(onPageTitleChanged(const QString &)));
+  }
+  
+  
+   void BrowserWindow::toggleNormalFullScreen() {
+      m_changingMode = true;
+
+      // Block paint updates while switching modes.  This avoids ugly flicker in toolbar.
+      setUpdatesEnabled(false);
+
+      if(isFullScreen())
+          showNormal();
+      else {
+          // Show full screen unless it's showing a super page: bookmarks, histroy etc. should always
+          // be in normal mode.
+          if(!m_windows->contentView()->currentPageIsSuperPage()) {
+              showFullScreen();
+          }
+      }
+      // Un-block updates.
+      setUpdatesEnabled(true);
+  }
+  
+  #ifdef Q_WS_MAEMO_5
+  // Tell the system we want to handle volume key events (or not).
+  void BrowserWindow::grabZoomKeys(bool grab)
+  {
+      if (!winId()) {
+          qWarning("Can't grab keys unless we have a window id");
+          return;
+      }
+
+      unsigned long val = (grab) ? 1 : 0;
+      Atom atom = XInternAtom(QX11Info::display(), "_HILDON_ZOOM_KEY_ATOM", False);
+      if (!atom) {
+          qWarning("Unable to obtain _HILDON_ZOOM_KEY_ATOM. This example will only work "
+                   "on a Maemo 5 device!");
+          return;
+      }
+
+      XChangeProperty (QX11Info::display(),
+              winId(),
+              atom,
+              XA_INTEGER,
+              32,
+              PropModeReplace,
+              reinterpret_cast<unsigned char *>(&val),
+              1);
+  }
+
+  void BrowserWindow::keyPressEvent(QKeyEvent* event)
+  {
+      switch (event->key()) {
+      case Qt::Key_F7:
+          {
+              // Handle "volume down" key by triggering zoom-in.
+              ControllableViewBase *view = m_chrome->getView("WebView");
+              if(view) {
+                  view->triggerAction("ZoomIn");
+              }
+              event->accept();
+          }
+          break;
+
+      case Qt::Key_F8:
+          {
+              // Handle "volume up" key by triggering zoom-out.
+              ControllableViewBase *view = m_chrome->getView("WebView");
+              if(view) {
+                  view->triggerAction("ZoomOut");
+              }
+              event->accept();
+          }
+          break;
+      }
+      QWidget::keyPressEvent(event);
+  }
+#endif
+};