src/hbcore/gui/hbmainwindow.cpp
changeset 34 ed14f46c0e55
parent 7 923ff622b8b9
equal deleted inserted replaced
31:7516d6d86cf5 34:ed14f46c0e55
    28 
    28 
    29 #include <QGraphicsView>
    29 #include <QGraphicsView>
    30 #include <QGraphicsWidget>
    30 #include <QGraphicsWidget>
    31 #include <QGraphicsItem>
    31 #include <QGraphicsItem>
    32 #include <QGraphicsScene>
    32 #include <QGraphicsScene>
    33 
    33 #include <QApplication>
    34 #include "hbaction.h"
    34 #include "hbaction.h"
    35 #include "hbbackgrounditem_p.h"
    35 #include "hbbackgrounditem_p.h"
       
    36 #include "hbscreenshotitem_p.h"
    36 #include "hbdeviceprofile_p.h"
    37 #include "hbdeviceprofile_p.h"
    37 #include "hbindicatorgroup_p.h"
    38 #include "hbindicatorgroup_p.h"
    38 #include "hbinstance.h"
    39 #include "hbinstance.h"
    39 #include "hbinstance_p.h"
    40 #include "hbinstance_p.h"
    40 #include "hbgraphicsscene.h"
    41 #include "hbgraphicsscene.h"
    61 #include "hbmainwindoworientation_p.h"
    62 #include "hbmainwindoworientation_p.h"
    62 #include "hbfeaturemanager_r.h"
    63 #include "hbfeaturemanager_r.h"
    63 #include "hboogmwatcher_p.h"
    64 #include "hboogmwatcher_p.h"
    64 #include "hbwindowobscured_p.h"
    65 #include "hbwindowobscured_p.h"
    65 #include "hbsleepmodelistener_p.h"
    66 #include "hbsleepmodelistener_p.h"
       
    67 #include "hbforegroundwatcher_p.h"
    66 
    68 
    67 #ifdef Q_OS_SYMBIAN
    69 #ifdef Q_OS_SYMBIAN
    68 #include <coecntrl.h>
    70 #include <coecntrl.h>
    69 #include <w32std.h>
    71 #include <w32std.h>
       
    72 #include <e32property.h>
    70 #include "hbnativewindow_sym_p.h"
    73 #include "hbnativewindow_sym_p.h"
    71 #endif
    74 #endif
    72 
    75 
    73 /*!
    76 /*!
    74     @stable
    77     @stable
   261   (so we won't waste time with that).
   264   (so we won't waste time with that).
   262 
   265 
   263   \internal
   266   \internal
   264  */
   267  */
   265 
   268 
       
   269 #ifdef Q_OS_SYMBIAN
       
   270 // When defined, the surface for the HbMainWindow is made transparent upon
       
   271 // showing, until the 3rd phase construction is done, to prevent
       
   272 // flickering. However it will also check wsini.ini for a line containing
       
   273 // [tfxrenderstage] and disable the workaround when such a line is present (the
       
   274 // workaround should not be needed when system tfx is enabled).
       
   275 //
       
   276 // When system tfx is known to be enabled permanently, the following define can
       
   277 // be commented out or removed.
       
   278 #define HB_SPLASH_FLICKER_WORKAROUND
       
   279 #endif
       
   280 
   266 class HbRootItem : public HbWidget
   281 class HbRootItem : public HbWidget
   267 {
   282 {
   268 public:
   283 public:
   269     explicit  HbRootItem(QGraphicsItem *parent = 0);
   284     explicit  HbRootItem(QGraphicsItem *parent = 0);
   270     ~HbRootItem() {}
   285     ~HbRootItem() {}
   285     Q_D(HbMainWindow);
   300     Q_D(HbMainWindow);
   286     d->q_ptr = this;
   301     d->q_ptr = this;
   287 
   302 
   288     // No need for any default (e.g. blank white) background for this window.
   303     // No need for any default (e.g. blank white) background for this window.
   289     setAttribute(Qt::WA_NoSystemBackground);
   304     setAttribute(Qt::WA_NoSystemBackground);
       
   305     viewport()->setAttribute(Qt::WA_NoSystemBackground);
   290     setOptimizationFlag(QGraphicsView::DontSavePainterState);
   306     setOptimizationFlag(QGraphicsView::DontSavePainterState);
   291 
   307 
   292     // Continue with basic initialization. Note: Prefer doing everything that is
   308     // Continue with basic initialization. Note: Prefer doing everything that is
   293     // not absolutely compulsory in _q_delayedConstruction instead.
   309     // not absolutely compulsory in _q_delayedConstruction instead.
   294 
   310 
   324     } else {
   340     } else {
   325         d->mOrientation = d->mDefaultOrientation;
   341         d->mOrientation = d->mDefaultOrientation;
   326         d->mAutomaticOrientationSwitch = false;
   342         d->mAutomaticOrientationSwitch = false;
   327     }
   343     }
   328 
   344 
   329 #if defined(Q_WS_S60) || defined(HB_Q_WS_MAEMO)
   345 #if defined(Q_OS_SYMBIAN) || defined(HB_Q_WS_MAEMO)
   330     setWindowState(Qt::WindowFullScreen);
   346     setWindowState(Qt::WindowFullScreen);
   331 #endif//Q_WS_S60
   347 #endif
   332 
   348 
   333     setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
   349     setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
   334     setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
   350     setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
   335     setFrameStyle(QFrame::NoFrame);
   351     setFrameStyle(QFrame::NoFrame);
   336 
   352 
   353         d->addBackgroundItem();
   369         d->addBackgroundItem();
   354     }
   370     }
   355 
   371 
   356     // add clipping item
   372     // add clipping item
   357     d->mClippingItem = new HbScreen;
   373     d->mClippingItem = new HbScreen;
       
   374     // Makes sure clipingItem layout is activated before any of its child items.
       
   375     QApplication::postEvent(d->mClippingItem, new QEvent(QEvent::LayoutRequest));
   358     d->mClippingItem->setParentItem(d->mRootItem);
   376     d->mClippingItem->setParentItem(d->mRootItem);
   359     d->mClippingItem->setZValue(HbPrivate::ContentZValue);
   377     d->mClippingItem->setZValue(HbPrivate::ContentZValue);
   360 
   378 
   361     // create content (stacked) widget
   379     // Create content (stacked) widget as a child of the HbScreen. Its size,
       
   380     // position, etc. will be managed by the clipping item (HbScreen).
   362     d->mViewStackWidget = new HbContentWidget(this, d->mClippingItem);
   381     d->mViewStackWidget = new HbContentWidget(this, d->mClippingItem);
   363     d->mEffectItem = d->mViewStackWidget;
   382     d->mEffectItem = d->mViewStackWidget;
   364     d->mClippingItem->setStackWidget(d->mViewStackWidget);
   383     d->mClippingItem->setStackWidget(d->mViewStackWidget);
   365     connect(d->mViewStackWidget, SIGNAL(currentChanged(int)),
   384     connect(d->mViewStackWidget, SIGNAL(currentChanged(int)),
   366             this, SLOT(_q_viewChanged()));
   385             this, SLOT(_q_viewChanged()));
   396     HbOogmWatcher::instance();
   415     HbOogmWatcher::instance();
   397 
   416 
   398     // Make sure the sleep mode listener instance is created.
   417     // Make sure the sleep mode listener instance is created.
   399     HbSleepModeListener::instance();
   418     HbSleepModeListener::instance();
   400 
   419 
       
   420     // Have also the foregroundwatcher up and running.
       
   421     HbForegroundWatcher::instance();
       
   422 
   401     HbWindowObscured::installWindowEventFilter();
   423     HbWindowObscured::installWindowEventFilter();
   402 
   424 
   403 #ifdef HB_GESTURE_FW
   425 #ifdef HB_GESTURE_FW
   404     // @todo remove after view auto-subscribes to gestures
   426     // @todo remove after view auto-subscribes to gestures
   405     viewport()->grabGesture(Qt::TapGesture);
   427     viewport()->grabGesture(Qt::TapGesture);
   434     // QWidget dtor already initiates some shutdown activities.
   456     // QWidget dtor already initiates some shutdown activities.
   435     HbEffectInternal::safeCancelAll();
   457     HbEffectInternal::safeCancelAll();
   436 
   458 
   437     HbInstancePrivate::d_ptr()->removeWindow(this);
   459     HbInstancePrivate::d_ptr()->removeWindow(this);
   438     delete d_ptr;
   460     delete d_ptr;
   439 
       
   440     // to workaround problem when creating/destroying multiple hbmainwindow's in unit tests (win env)
       
   441 #ifdef Q_OS_WIN
       
   442     destroy();
       
   443 #endif
       
   444 }
   461 }
   445 
   462 
   446 /*!
   463 /*!
   447     Adds a \a widget to the HbMainWindow object. Passing 0 in
   464     Adds a \a widget to the HbMainWindow object. Passing 0 in
   448     \a widget creates an empty HbView.
   465     \a widget creates an empty HbView.
   629     Q_D(HbMainWindow);
   646     Q_D(HbMainWindow);
   630     HbView *oldView = currentView();
   647     HbView *oldView = currentView();
   631     // Switching to null view or to the one that is current will do nothing.
   648     // Switching to null view or to the one that is current will do nothing.
   632     if (view && oldView != view) {
   649     if (view && oldView != view) {
   633         emit aboutToChangeView(oldView, view);
   650         emit aboutToChangeView(oldView, view);
       
   651         if (isObscured()) {
       
   652             animate = false;
       
   653         }
   634         if (oldView && animate) {
   654         if (oldView && animate) {
   635             if (flags & Hb::ViewSwitchFullScreen) {
   655             if (flags & Hb::ViewSwitchFullScreen) {
   636                 flags |= Hb::ViewSwitchSequential;
   656                 flags |= Hb::ViewSwitchSequential;
   637             }
   657             }
   638             if (flags & Hb::ViewSwitchUseBackAnim) {
   658             if (flags & Hb::ViewSwitchUseBackAnim) {
   936         if (currentView()) {
   956         if (currentView()) {
   937             action = currentView()->navigationAction();
   957             action = currentView()->navigationAction();
   938         }
   958         }
   939         event->accept();
   959         event->accept();
   940         break;
   960         break;
       
   961 
       
   962 #ifdef __WINSCW__
       
   963     // Support for testing orientation change on the winscw emulator: When enabled,
       
   964     // pressing '9' will toggle (and force) the orientation.
       
   965     case Qt::Key_9:
       
   966         if (QFile::exists("c:/resource/hb_ori_simu")) {
       
   967             if (orientation() == Qt::Horizontal) {
       
   968                 setOrientation(Qt::Vertical);
       
   969             } else {
       
   970                 setOrientation(Qt::Horizontal);
       
   971             }
       
   972         }
       
   973         QGraphicsView::keyPressEvent(event);
       
   974         break;
       
   975 #endif
   941 
   976 
   942     default:
   977     default:
   943         QGraphicsView::keyPressEvent(event);
   978         QGraphicsView::keyPressEvent(event);
   944         break;
   979         break;
   945     }
   980     }
   980         setSceneRect(0, 0, newSize.width(), newSize.height());
  1015         setSceneRect(0, 0, newSize.width(), newSize.height());
   981         d->mClippingItem->resize(newSize);
  1016         d->mClippingItem->resize(newSize);
   982         if (d->mBgItem) {
  1017         if (d->mBgItem) {
   983             d->mBgItem->resize(newSize);
  1018             d->mBgItem->resize(newSize);
   984         }
  1019         }
   985     }
  1020         if (d->mScreenshotItem) {
   986 }
  1021             d->mScreenshotItem->resize(newSize);
       
  1022         }
       
  1023     }
       
  1024 }
       
  1025 
       
  1026 #ifdef HB_SPLASH_FLICKER_WORKAROUND
       
  1027 static bool tfxRenderStagePresent()
       
  1028 {
       
  1029     // Cannot afford to read wsini.ini in every app, let themeserver
       
  1030     // do it once and use the property published by it.
       
  1031     static int wsini_has_tfxrenderstage = -1;
       
  1032     if (wsini_has_tfxrenderstage == -1) {
       
  1033         wsini_has_tfxrenderstage = 0;
       
  1034         TInt v = -1;
       
  1035         if (RProperty::Get(TUid::Uid(0x20022E82), 0x746678, v) == KErrNone) {
       
  1036             wsini_has_tfxrenderstage = v;
       
  1037         }
       
  1038     }
       
  1039     return wsini_has_tfxrenderstage == 1;
       
  1040 }
       
  1041 #endif
   987 
  1042 
   988 /*!
  1043 /*!
   989     Reimplemented from QObject::customEvent().
  1044     Reimplemented from QObject::customEvent().
   990 */
  1045 */
   991 void HbMainWindow::customEvent(QEvent *event)
  1046 void HbMainWindow::customEvent(QEvent *event)
   998                 // create the test utility
  1053                 // create the test utility
   999                 if (!d->mTheTestUtility) {
  1054                 if (!d->mTheTestUtility) {
  1000                     d->mTheTestUtility = new HbTheTestUtility(this);
  1055                     d->mTheTestUtility = new HbTheTestUtility(this);
  1001                 }
  1056                 }
  1002             }
  1057             }
  1003 #ifdef Q_OS_SYMBIAN
  1058 #ifdef HB_SPLASH_FLICKER_WORKAROUND
  1004             // Disable surface transparency unless we were really asked to be transparent.
  1059             // Disable surface transparency unless we were really asked to be transparent.
  1005             // Must be done before destroying the splash screen widget.
  1060             // Must be done before destroying the splash screen widget.
  1006             if (!testAttribute(Qt::WA_TranslucentBackground)) {
  1061             if (!tfxRenderStagePresent() && !testAttribute(Qt::WA_TranslucentBackground)) {
  1007                 RWindow *const window = static_cast<RWindow *>(effectiveWinId()->DrawableWindow());
  1062                 RWindow *const window = static_cast<RWindow *>(effectiveWinId()->DrawableWindow());
  1008                 window->SetSurfaceTransparency(false);
  1063                 window->SetSurfaceTransparency(false);
  1009             }
  1064             }
  1010 #endif
  1065 #endif
  1011             // Get rid of the splash screen widget. (it is not visible to the user anyway at this point)
  1066             // Get rid of the splash screen widget. (it is not visible to the user anyway at this point)
  1074     QGraphicsView::paintEvent(event);
  1129     QGraphicsView::paintEvent(event);
  1075 }
  1130 }
  1076 
  1131 
  1077 void HbMainWindow::showEvent(QShowEvent *event)
  1132 void HbMainWindow::showEvent(QShowEvent *event)
  1078 {
  1133 {
  1079 #ifdef Q_OS_SYMBIAN
  1134 #ifdef HB_SPLASH_FLICKER_WORKAROUND
  1080     // Enable surface transparency if QWidget did not do it already. This is a
  1135     // Enable surface transparency if QWidget did not do it already. This is a
  1081     // workaround for having non-transparent surfaces filled automatically with
  1136     // workaround for having non-transparent surfaces filled automatically with
  1082     // black color. The showEvent is a suitable place because the native control
  1137     // black color. The showEvent is a suitable place because the native control
  1083     // is already created at this point, but it is not too late either.
  1138     // is already created at this point, but it is not too late either. Note
  1084     if (!testAttribute(Qt::WA_TranslucentBackground)) {
  1139     // that while this is meant to be a workaround, the system transition
       
  1140     // effects may actually rely on (and require) this behavior.
       
  1141     if (!tfxRenderStagePresent() && !testAttribute(Qt::WA_TranslucentBackground)) {
       
  1142         // The Qt::WA_TranslucentBackground attribute cannot be used here
       
  1143         // because that can only be enabled, disabling does not seem to be
       
  1144         // supported.
  1085         RWindow *const window = static_cast<RWindow *>(effectiveWinId()->DrawableWindow());
  1145         RWindow *const window = static_cast<RWindow *>(effectiveWinId()->DrawableWindow());
  1086         window->SetSurfaceTransparency(true);
  1146         window->SetSurfaceTransparency(true);
  1087     }
  1147     }
  1088 #endif
  1148 #endif
  1089 
  1149 
  1094 
  1154 
  1095     QGraphicsView::showEvent(event);
  1155     QGraphicsView::showEvent(event);
  1096 }
  1156 }
  1097 
  1157 
  1098 /*!
  1158 /*!
  1099     Reimplemented from QAbstractScrollArea::scrollContentsBy().
  1159     \reimp
  1100 */
  1160 */
  1101 void HbMainWindow::scrollContentsBy(int dx, int dy)
  1161 void HbMainWindow::scrollContentsBy(int dx, int dy)
  1102 {
  1162 {
  1103     // ignore scrolling attempt
  1163     // ignore scrolling attempt
  1104     Q_UNUSED(dx);
  1164     Q_UNUSED(dx);
  1129 
  1189 
  1130     return d->mObscuredState;
  1190     return d->mObscuredState;
  1131 }
  1191 }
  1132 
  1192 
  1133 /*
  1193 /*
  1134     // reimplemented from QWidget
  1194     \reimp
  1135 */
  1195 */
  1136 bool HbMainWindow::event(QEvent *event)
  1196 bool HbMainWindow::event(QEvent *event)
  1137 {
  1197 {
  1138     Q_D(HbMainWindow);
  1198     Q_D(HbMainWindow);
  1139     if (event->type() == HbEvent::WindowObscuredChanged) {
  1199     if (event->type() == HbEvent::WindowObscuredChanged) {
  1140         HbWindowObscuredChangedEvent *wosEvent = static_cast<HbWindowObscuredChangedEvent *>(event);
  1200         HbWindowObscuredChangedEvent *wosEvent = static_cast<HbWindowObscuredChangedEvent *>(event);
  1141         d->setObscuredState(wosEvent->obscuredState());
  1201         d->setObscuredState(wosEvent->obscuredState());
  1142     }
  1202     }
  1143     return QGraphicsView::event(event);
  1203     return QGraphicsView::event(event);
       
  1204 }
       
  1205 
       
  1206 /*
       
  1207     \reimp
       
  1208 */
       
  1209 void HbMainWindow::drawBackground(QPainter *painter, const QRectF &rect)
       
  1210 {
       
  1211     QGraphicsView::drawBackground(painter, rect);
       
  1212     // The background item's paint() does not get called automatically so call
       
  1213     // it directly and optimize it by setting a proper clipping rectangle.
       
  1214     Q_D(HbMainWindow);
       
  1215     if (d->mBgItem) {
       
  1216         bool restoreState = false;
       
  1217         if (d->mBgItem->imageMode() != Hb::DoNotDrawBackground &&
       
  1218             (!qFuzzyCompare(rect.height(), d->mBgItem->boundingRect().height()) ||
       
  1219              !qFuzzyCompare(rect.width(), d->mBgItem->boundingRect().width()))) {
       
  1220             //Need to save the state since some widget in scene could apply a smaller
       
  1221             //clip than this
       
  1222             restoreState = true;
       
  1223             painter->save();
       
  1224             painter->setClipRect(rect);
       
  1225         }
       
  1226         d->mBgItem->paint(painter, 0, 0);
       
  1227         if (restoreState) {
       
  1228             painter->restore();
       
  1229         }
       
  1230     }
  1144 }
  1231 }
  1145 
  1232 
  1146 HbRootItem::HbRootItem(QGraphicsItem *parent)
  1233 HbRootItem::HbRootItem(QGraphicsItem *parent)
  1147     : HbWidget(parent)
  1234     : HbWidget(parent)
  1148 {
  1235 {