ginebra2/ContentViews/BrowserWindow.cpp
changeset 16 3c88a81ff781
equal deleted inserted replaced
14:6aeb7a756187 16:3c88a81ff781
       
     1 #include "BrowserWindow.h"
       
     2 #include "WindowsView.h"
       
     3 #include "ChromeLayout.h"
       
     4 #include "ChromeWidget.h"
       
     5 #include "ChromeView.h"
       
     6 #include "ChromeDOM.h" //Get rid of this dependency
       
     7 #include "GWebContentView.h"
       
     8 #include <QGraphicsWidget>
       
     9 #include <QGraphicsScene>
       
    10 #include <QGraphicsTextItem>
       
    11 #include <QVBoxLayout>
       
    12 #include "webpagecontroller.h"
       
    13 #include "ViewStack.h"
       
    14 #ifdef Q_WS_MAEMO_5
       
    15 #include <QtGui/QX11Info>
       
    16 #include <X11/Xlib.h>
       
    17 #include <X11/Xatom.h>
       
    18 #endif
       
    19 
       
    20 namespace GVA {
       
    21 
       
    22   bool BrowserWindow::m_preventDisconnectPageTitleChanged = false; // workaraound for multiple windows crash
       
    23   bool BrowserWindow::m_preventConnectPageTitleChanged = false;    // workaround for multiple windows crash
       
    24 
       
    25   BrowserWindow::BrowserWindow(ChromeWidget * chrome, WindowsView * windows, QWidget * parent, Qt::WindowFlags flags)
       
    26     : QMainWindow(parent, flags),
       
    27       m_page(0),
       
    28       m_specialPage(0),
       
    29       m_decorated(false),
       
    30       m_chrome(chrome),
       
    31       m_scene(new QGraphicsScene()),
       
    32       m_snapshot(0),
       
    33       m_windows(windows),
       
    34       m_state(menuEnabled),   
       
    35       m_slidedUp(false),   
       
    36       m_viewName("WebView"),
       
    37       m_changingMode(false)
       
    38   {
       
    39     m_view = new ChromeView(m_scene, m_chrome, this);
       
    40     setCentralWidget(m_view);
       
    41     show();
       
    42     ViewController *controller = viewController();
       
    43     if(controller) {
       
    44         connect(controller, SIGNAL(currentViewChanged(ControllableViewBase *)), this, SLOT(onViewChanged(ControllableViewBase *)));
       
    45     }
       
    46     slideViewIfRequired(100); // display UrlSearchBar for every new window
       
    47   }
       
    48 
       
    49   void BrowserWindow::setPage(WRT::WrtBrowserContainer * page)
       
    50   { 
       
    51     m_page = page;
       
    52     connectPageTitleChanged();
       
    53   }
       
    54 
       
    55 	// hide or show UrlSearchBar if required
       
    56 	// This is a workaround for the problem that created by the fact that
       
    57 	// multiple instances of BrowserWindow use same instance of m_chrome and m_chrome->layout()
       
    58 	// 
       
    59   void BrowserWindow::slideViewIfRequired(int value)
       
    60   {
       
    61       if(value > 0) { // slide up to display UrlSearchBar
       
    62            m_chrome->layout()->slideView(value);
       
    63            m_slidedUp = true;
       
    64            return;
       
    65       }
       
    66 
       
    67       if((m_slidedUp == true) && (value < 0)) { // slide down UrlSearchBar
       
    68            m_chrome->layout()->slideView(value);
       
    69            m_slidedUp = false;
       
    70            return;
       
    71       }
       
    72   }
       
    73   
       
    74   void BrowserWindow::toggleDecoration() 
       
    75   { 
       
    76     m_decorated = !m_decorated;
       
    77     if(m_decorated) {
       
    78       showDecoration();
       
    79     } 
       
    80     else {
       
    81       hideDecoration();
       
    82     }
       
    83   }
       
    84 
       
    85   void BrowserWindow::showDecoration()
       
    86   {
       
    87     m_state |= active;
       
    88     if(m_page)       
       
    89       WebPageController::getSingleton()->setCurrentPage(m_page);
       
    90     m_windows->deactivate(this);
       
    91     if(m_snapshot)
       
    92       m_snapshot->hide();
       
    93     if(m_chrome){
       
    94       m_chrome->layout()->setPos(0,0);
       
    95       m_scene->addItem(m_chrome->layout());
       
    96       m_chrome->layout()->show();
       
    97       // Ensure that the layout size is in-synch with the window size.
       
    98       m_chrome->layout()->resize(size());
       
    99     }
       
   100   }
       
   101 
       
   102   void BrowserWindow::hideDecoration()
       
   103   {
       
   104     m_state &= ~active;
       
   105 
       
   106     m_windows->activate(this);
       
   107     if(m_chrome)
       
   108       m_scene->removeItem(m_chrome->layout());
       
   109 
       
   110     if(m_page){
       
   111       m_page->triggerAction(QWebPage::Stop);
       
   112       //QImage image = WebPageController::getSingleton()->pageThumbnail(m_page);
       
   113       //	if(image.isNull()){
       
   114       //QImage image =  m_page->pageThumbnail(1,1);
       
   115       //
       
   116       
       
   117       QImage image;
       
   118       //This is really a bit hackish: the page controller should be able
       
   119       //to figure this out;
       
   120       //if(m_windows->contentView()->currentPageIsSuperPage()){
       
   121 	//m_specialPage = static_cast<WRT::WrtBrowserContainer*>(m_windows->contentView()->wrtPage());
       
   122         //m_windows->contentView()->updateWebPage(m_page);
       
   123 	//image = m_windows->contentView()->pageThumbnail(1,1);
       
   124       //}
       
   125       //else
       
   126         QSize s(800,464);
       
   127         image = m_page->thumbnail(s);
       
   128       if(m_snapshot){
       
   129 	m_scene->removeItem(m_snapshot);
       
   130 	delete m_snapshot;
       
   131       }
       
   132       m_snapshot = new QGraphicsPixmapItem(QPixmap::fromImage(image));
       
   133       m_scene->addItem(m_snapshot);
       
   134       m_snapshot->show();
       
   135     } else {
       
   136       qDebug() << "BrowserWindow::hideDecoration: page not set";
       
   137     }
       
   138   }
       
   139   
       
   140   void BrowserWindow::closeWindow()
       
   141   {
       
   142     //Tell the page controler to close this page.
       
   143     //The controller emits pageClosed. WindowsView
       
   144     //handles this and deletes this browser window
       
   145     // Don't delete if only 1 window open..causes crash on exit
       
   146     if (WebPageController::getSingleton()->pageCount() > 1)
       
   147       WebPageController::getSingleton()->closePage(m_page);
       
   148   }
       
   149 
       
   150   //Handle window events
       
   151   bool BrowserWindow::event(QEvent * event) 
       
   152   {
       
   153     //qDebug() << "=====================BrowserWindow:event: " << event->type();
       
   154     switch (event->type()) {
       
   155     case QEvent::WindowBlocked:
       
   156       m_state |= blocked;
       
   157       break;
       
   158     case QEvent::WindowUnblocked:
       
   159       m_state &= ~blocked;
       
   160       break;
       
   161     case QEvent::WindowActivate: //Newly shown window or window maximized
       
   162       handleWindowActivate();
       
   163       m_chrome->windowStateChange(windowState());
       
   164       break;
       
   165     case QEvent::WindowDeactivate:
       
   166       handleWindowDeactivate();
       
   167       m_chrome->windowStateChange(windowState());
       
   168       break;
       
   169     case QEvent::Close:
       
   170       m_state |= blocked; 
       
   171       closeWindow();
       
   172       break;    
       
   173     default:
       
   174       break;
       
   175     }
       
   176     return QMainWindow::event(event);
       
   177   }
       
   178 
       
   179  void BrowserWindow::changeEvent(QEvent * event) {
       
   180     switch (event->type()) {
       
   181       case QEvent::WindowStateChange:
       
   182         m_chrome->windowStateChange(windowState());
       
   183         break;
       
   184       default:
       
   185         break;
       
   186     }
       
   187     QMainWindow::changeEvent(event);
       
   188   }
       
   189 
       
   190   void BrowserWindow::handleWindowActivate() {
       
   191       if(m_changingMode) {
       
   192           // Ignore if in the process of changing from fullscreen to normal.  We get a deactivate followed by
       
   193           // an activate call when this is done.  Clear the flag for the next time activate or deactivate is
       
   194           // called for some other reason.
       
   195           m_changingMode = false;
       
   196           return;
       
   197       }
       
   198 #ifdef Q_WS_MAEMO_5
       
   199       grabZoomKeys(true);
       
   200 #endif
       
   201       showDecoration();
       
   202       if(m_chrome) {
       
   203           connect(m_chrome, SIGNAL(requestToggleNormalFullScreen()), this, SLOT(toggleNormalFullScreen()));
       
   204       }
       
   205   }
       
   206 
       
   207   void BrowserWindow::handleWindowDeactivate() {
       
   208       if(m_changingMode) {
       
   209           // Ignore if in the process of changing from fullscreen to normal.
       
   210           return;
       
   211       }
       
   212 #ifdef Q_WS_MAEMO_5
       
   213       grabZoomKeys(false);
       
   214 #endif
       
   215       if(!((m_state & blocked) == blocked))
       
   216         hideDecoration();
       
   217       slideViewIfRequired(-100); // hide UrlSearchBar if required
       
   218       if(m_chrome) {
       
   219           disconnect(m_chrome, SIGNAL(requestToggleNormalFullScreen()), this, SLOT(toggleNormalFullScreen()));
       
   220       }
       
   221   }
       
   222 
       
   223   void BrowserWindow::setMenuEnabled(bool enabled)
       
   224   {
       
   225     if(enabled)
       
   226       m_state |= menuEnabled;
       
   227     else
       
   228       m_state &= ~menuEnabled;
       
   229 
       
   230     fixupWindowTitle();
       
   231   }
       
   232 
       
   233   void BrowserWindow::setTitle(const QString &title)
       
   234   {
       
   235     if(title.isEmpty()) {
       
   236         setWindowTitle(QApplication::applicationName());
       
   237     }
       
   238     else {
       
   239         setWindowTitle(title);
       
   240     }
       
   241 
       
   242     fixupWindowTitle();
       
   243   }
       
   244 
       
   245   /// Hack to hide the menu bar arrow when the menu is disabled.
       
   246   void BrowserWindow::fixupWindowTitle() {
       
   247       QString title = windowTitle();
       
   248       title = title.trimmed();
       
   249       if(!m_windows->isMenuEnabled()) {
       
   250           // The menu is disabled, add some spaces to the title to push the down arrow out of view.
       
   251           title += QString(60, ' ');
       
   252       }
       
   253       setWindowTitle(title);
       
   254   }
       
   255 
       
   256   void BrowserWindow::onPageTitleChanged(const QString &title)
       
   257   {
       
   258       setTitle(title);
       
   259   }
       
   260 
       
   261   void BrowserWindow::onViewChanged(ControllableViewBase *newView) {
       
   262       Q_ASSERT(newView);
       
   263 
       
   264       if(m_windows->contentView()->currentPageIsSuperPage()) {
       
   265           if(!m_preventDisconnectPageTitleChanged)
       
   266             disconnectPageTitleChanged();
       
   267           m_preventDisconnectPageTitleChanged = true;
       
   268           m_preventConnectPageTitleChanged = false;
       
   269       }
       
   270       else {
       
   271           if(!m_preventConnectPageTitleChanged)
       
   272             connectPageTitleChanged();
       
   273           m_preventDisconnectPageTitleChanged = false;
       
   274           m_preventConnectPageTitleChanged = true;
       
   275       }
       
   276       if(m_state & active) {
       
   277           setTitle(newView->title());
       
   278       }
       
   279   }
       
   280 
       
   281   ViewController *BrowserWindow::viewController() {
       
   282     ViewStack *viewStack = ViewStack::getSingleton();
       
   283     if(viewStack) {
       
   284         return viewStack->getViewController();
       
   285     }
       
   286 
       
   287     return 0;
       
   288   }
       
   289 
       
   290   void BrowserWindow::connectPageTitleChanged() {
       
   291       connect(m_page->mainFrame(), SIGNAL(titleChanged(const QString &)),
       
   292               this, SLOT(onPageTitleChanged(const QString &)));
       
   293   }
       
   294 
       
   295   void BrowserWindow::disconnectPageTitleChanged() {
       
   296       disconnect(m_page->mainFrame(), SIGNAL(titleChanged(const QString &)),
       
   297               this, SLOT(onPageTitleChanged(const QString &)));
       
   298   }
       
   299   
       
   300   
       
   301    void BrowserWindow::toggleNormalFullScreen() {
       
   302       m_changingMode = true;
       
   303 
       
   304       // Block paint updates while switching modes.  This avoids ugly flicker in toolbar.
       
   305       setUpdatesEnabled(false);
       
   306 
       
   307       if(isFullScreen())
       
   308           showNormal();
       
   309       else {
       
   310           // Show full screen unless it's showing a super page: bookmarks, histroy etc. should always
       
   311           // be in normal mode.
       
   312           if(!m_windows->contentView()->currentPageIsSuperPage()) {
       
   313               showFullScreen();
       
   314           }
       
   315       }
       
   316       // Un-block updates.
       
   317       setUpdatesEnabled(true);
       
   318   }
       
   319   
       
   320   #ifdef Q_WS_MAEMO_5
       
   321   // Tell the system we want to handle volume key events (or not).
       
   322   void BrowserWindow::grabZoomKeys(bool grab)
       
   323   {
       
   324       if (!winId()) {
       
   325           qWarning("Can't grab keys unless we have a window id");
       
   326           return;
       
   327       }
       
   328 
       
   329       unsigned long val = (grab) ? 1 : 0;
       
   330       Atom atom = XInternAtom(QX11Info::display(), "_HILDON_ZOOM_KEY_ATOM", False);
       
   331       if (!atom) {
       
   332           qWarning("Unable to obtain _HILDON_ZOOM_KEY_ATOM. This example will only work "
       
   333                    "on a Maemo 5 device!");
       
   334           return;
       
   335       }
       
   336 
       
   337       XChangeProperty (QX11Info::display(),
       
   338               winId(),
       
   339               atom,
       
   340               XA_INTEGER,
       
   341               32,
       
   342               PropModeReplace,
       
   343               reinterpret_cast<unsigned char *>(&val),
       
   344               1);
       
   345   }
       
   346 
       
   347   void BrowserWindow::keyPressEvent(QKeyEvent* event)
       
   348   {
       
   349       switch (event->key()) {
       
   350       case Qt::Key_F7:
       
   351           {
       
   352               // Handle "volume down" key by triggering zoom-in.
       
   353               ControllableViewBase *view = m_chrome->getView("WebView");
       
   354               if(view) {
       
   355                   view->triggerAction("ZoomIn");
       
   356               }
       
   357               event->accept();
       
   358           }
       
   359           break;
       
   360 
       
   361       case Qt::Key_F8:
       
   362           {
       
   363               // Handle "volume up" key by triggering zoom-out.
       
   364               ControllableViewBase *view = m_chrome->getView("WebView");
       
   365               if(view) {
       
   366                   view->triggerAction("ZoomOut");
       
   367               }
       
   368               event->accept();
       
   369           }
       
   370           break;
       
   371       }
       
   372       QWidget::keyPressEvent(event);
       
   373   }
       
   374 #endif
       
   375 };