--- /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
+};