Home · All Classes · Main Classes · Deprecated

mwindow.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002 **
00003 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
00004 ** All rights reserved.
00005 ** Contact: Nokia Corporation (directui@nokia.com)
00006 **
00007 ** This file is part of libmeegotouch.
00008 **
00009 ** If you have questions regarding the use of this file, please contact
00010 ** Nokia at directui@nokia.com.
00011 **
00012 ** This library is free software; you can redistribute it and/or
00013 ** modify it under the terms of the GNU Lesser General Public
00014 ** License version 2.1 as published by the Free Software Foundation
00015 ** and appearing in the file LICENSE.LGPL included in the packaging
00016 ** of this file.
00017 **
00018 ****************************************************************************/
00019 
00020 #ifdef QT_OPENGL_LIB
00021 #include "mgles2renderer.h"
00022 #endif
00023 
00024 #include "mwindow.h"
00025 #include "mwindow_p.h"
00026 
00027 #include "mscene.h"
00028 #include "mscene_p.h"
00029 #include "mapplication.h"
00030 #include "mapplication_p.h"
00031 #include "mcomponentcache.h"
00032 #include "morientationtracker.h"
00033 #include "mdeviceprofile.h"
00034 #include "mdeviceprofile.h"
00035 #include "mwidget.h"
00036 #include "mcomponentdata.h"
00037 #include "morientationchangeevent.h"
00038 #include "mondisplaychangeevent.h"
00039 #include "mdebug.h"
00040 #include "mgconfitem.h"
00041 #include "mlocale.h"
00042 #include "mgraphicssystemhelper.h"
00043 
00044 #include <QPropertyAnimation>
00045 #include <QSettings>
00046 #include <QDir>
00047 #include <QTimer>
00048 #include <QDynamicPropertyChangeEvent>
00049 
00050 #include "morientationtracker_p.h"
00051 #include "mscenemanager_p.h"
00052 
00053 #ifdef Q_WS_X11
00054 # include <QX11Info>
00055 # include <X11/Xatom.h>
00056 # include <X11/Xlib.h>
00057 // Avoid conflict with QEvent::KeyPress usage in MWindow::Event
00058 # undef KeyPress
00059 #endif
00060 
00061 namespace {
00062     const QString ImagesPath(QDir::homePath() + "/MyDocs/.images");
00063     const int DisplayExitedDelay = 1000; //ms.
00064 #ifdef Q_WS_X11
00065     const char* FollowsCurrentApplicationWindowOrientationPropertyName =
00066             "followsCurrentApplicationWindowOrientation";
00067 #endif
00068 }
00069 
00071 
00072 MWindowPrivate::MWindowPrivate() :
00073     glContext(0),
00074     sceneManager(0),
00075     oldOrientation(M::Landscape), // the initial value is not used at all
00076     orientationAngleLocked(false),
00077     orientationLocked(false),
00078     isLogicallyClosed(true),
00079     isInSwitcher(false),
00080     closeOnLazyShutdown(false),
00081     delayedMOnDisplayChangeEvent(0),
00082     onDisplay(false),
00083     onDisplaySet(false),
00084     displayExitedTimer(),
00085     visibleInSwitcher(false),
00086     fullyObscured(false),
00087 #ifdef HAVE_GCONF
00088     minimizedSoftwareSwitchItem("/meegotouch/debug/minimized_software_switch"),
00089 #endif
00090     minimizedSoftwareSwitch(false),
00091     updateIsPending(false),
00092     discardedPaintEvent(false),
00093     q_ptr(NULL)
00094 {
00095 #ifdef Q_WS_X11
00096     removeWindowFromSwitcherInProgress = false;
00097     skipTaskbar = false;
00098 #endif
00099 
00100     MWindow *window = MApplication::activeWindow();
00101 
00102     if (window)
00103         angle = window->orientationAngle();
00104     else
00105         angle = MOrientationTracker::instance()->orientationAngle();
00106 
00107     timeSinceLastPaintInSwitcher.invalidate();
00108 }
00109 
00110 MWindowPrivate::~MWindowPrivate()
00111 {
00112     delete delayedMOnDisplayChangeEvent;
00113 }
00114 
00115 void MWindowPrivate::init()
00116 {
00117     Q_Q(MWindow);
00118 
00119     displayExitedTimer.connect(&displayExitedTimer, SIGNAL(timeout()),
00120                                q, SLOT(_q_exitDisplayStabilized()));
00121     displayExitedTimer.setInterval(DisplayExitedDelay);
00122     displayExitedTimer.setSingleShot(true);
00123 
00124 #ifdef HAVE_GCONF
00125     minimizedSoftwareSwitch = minimizedSoftwareSwitchItem.value(true).toBool();
00126     QObject::connect(&minimizedSoftwareSwitchItem, SIGNAL(valueChanged()), q_ptr, SLOT(_q_updateMinimizedSoftwareSwitch()));
00127 #endif
00128 
00129 #ifdef Q_WS_X11
00130     // We do window decorations ourselves. Set env variable accordingly for
00131     // development purposes
00132 
00133 #ifdef M_OS_MAEMO5
00134     if ( !MApplication::fullScreen() ) {
00135 #endif //M_OS_MAEMO5
00136 
00137     QString env = qgetenv("M_DECORATED");
00138     if (env.contains("0")) {
00139         q->setWindowFlags(Qt::FramelessWindowHint);
00140     }
00141     /* Workaround until we get M_DECORATED defined in the target env */
00142 #ifdef __arm__
00143     else if (env.isEmpty()) {
00144         q->setWindowFlags(Qt::FramelessWindowHint);
00145     }
00146 #endif // __arm__
00147 
00148 #ifdef M_OS_MAEMO5
00149     }
00150 #endif //M_OS_MAEMO5
00151 
00152 #endif // Q_WS_X11
00153 
00154     // resize always to the size in landscape mode,
00155     // since it's not the window but the scene content that is rotated
00156     q->resize(q->visibleSceneSize(M::Landscape));
00157     q->setFrameStyle(0);
00158     q->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00159     q->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00160 
00161     if (MApplication::softwareRendering() == false) {
00162 #ifdef QT_OPENGL_LIB
00163         mDebug("MWindowPrivate") << "Renderer: OpenGL";
00164 #else
00165         mDebug("MWindowPrivate") << "Renderer: Software";
00166 #endif
00167     } else {
00168         mDebug("MWindowPrivate") << "Renderer: Software (forced)";
00169     }
00170 
00171 #ifdef Q_WS_X11
00172     appendVisibilityChangeMask();
00173     // If the window is created for the application in prestarted mode
00174     // we have to set X11 property _MEEGOTOUCH_PRESTARTED
00175     if(MApplication::isPrestarted()) {
00176         setX11PrestartProperty(true);
00177     }
00178     setX11OrientationAngleProperty(angle);
00179 #endif
00180 
00181     q->setTranslucentBackground(false);
00182 
00183     if (MApplication::fullScreen())
00184         q->showFullScreen();
00185 }
00186 
00187 void MWindowPrivate::initSoftwareViewport()
00188 {
00189     Q_Q(MWindow);
00190 
00191     mDebug("MWindow") << "Switching to software rendering";
00192 
00193 #ifdef M_USE_OPENGL
00194     MGLES2Renderer::activate((QGLContext*)NULL);
00195     MGLES2Renderer::destroy(glContext);
00196     glContext = NULL;
00197 #endif
00198 
00199     MGraphicsSystemHelper::switchToSoftwareRendering(q);
00200 
00201     q->setViewportUpdateMode(MWindow::MinimalViewportUpdate);
00202 
00203     configureViewport();
00204 }
00205 
00206 void MWindowPrivate::initGLViewport()
00207 {
00208     Q_Q(MWindow);
00209 
00210 #ifdef QT_OPENGL_LIB
00211     mDebug("MWindow") << "Window restored, switching to GL rendering";
00212 
00213     bool translucent = q->testAttribute(Qt::WA_TranslucentBackground);
00214 
00215     MGraphicsSystemHelper::switchToHardwareRendering(q, &glContext);
00216 
00217     if (translucent) {
00218         QPalette palette;
00219         palette.setColor(QPalette::Base, Qt::transparent);
00220         palette.setColor(QPalette::Window, Qt::transparent);
00221         q->setAutoFillBackground(true);
00222         q->setPalette(palette);
00223         q->viewport()->setAutoFillBackground(true);
00224         q->viewport()->setPalette(palette);
00225     }
00226 
00227 #ifdef M_USE_OPENGL
00228     MGLES2Renderer::instance(glContext);
00229     MGLES2Renderer::activate(glContext);
00230 #endif
00231 #endif // QT_OPENGL_LIB
00232 
00233     q->setViewportUpdateMode(MWindow::FullViewportUpdate);
00234 
00235     configureViewport();
00236 }
00237 
00238 void MWindowPrivate::configureViewport()
00239 {
00240     Q_Q(MWindow);
00241 
00242     q->viewport()->grabGesture(Qt::TapAndHoldGesture);
00243     q->viewport()->grabGesture(Qt::PinchGesture);
00244     q->viewport()->grabGesture(Qt::PanGesture);
00245     q->viewport()->grabGesture(Qt::SwipeGesture);
00246     q->viewport()->grabGesture(Qt::TapGesture);
00247 
00248     q->setAttribute(Qt::WA_AcceptTouchEvents);
00249 
00250     // If we don't set this flag, the technique of discarding paintEvent() calls
00251     // for limiting the framerate (e.g. because window is a thumbnail in the
00252     // application switcher) will cause the window to flicker between its regular
00253     // appearance and a blank window.
00254     // That's because even though we avoided the actual rendering of the contents,
00255     // by the time paintEvent() is called Qt might have already painted the system
00256     // background over of the window's previous state. This seems to be happening only
00257     // with softare rendering.
00258     q->setAttribute(Qt::WA_OpaquePaintEvent);
00259     q->setAttribute(Qt::WA_NoSystemBackground);
00260     q->viewport()->setAttribute(Qt::WA_OpaquePaintEvent);
00261     q->viewport()->setAttribute(Qt::WA_NoSystemBackground);
00262 }
00263 
00264 
00266 class ScreenshotEffect : public QGraphicsWidget
00267 {
00268     virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
00269                        QWidget *widget = 0)
00270     {
00271         Q_UNUSED(option);
00272         Q_UNUSED(widget);
00273 
00274         painter->fillRect(boundingRect(), Qt::white);
00275     }
00276 };
00278 
00279 void MWindowPrivate::playScreenshotEffect()
00280 {
00281     Q_Q(MWindow);
00282 
00283     ScreenshotEffect *flash = new ScreenshotEffect();
00284     flash->setGeometry(0, 0, q->width(), q->height());
00285 
00286     QPropertyAnimation *animation = new QPropertyAnimation(flash, "opacity", q);
00287     animation->setDuration(400);
00288     animation->setEndValue(0.0f);
00289     animation->start(QAbstractAnimation::DeleteWhenStopped);
00290 
00291     q->scene()->addItem(flash);
00292 
00293     QObject::connect(animation, SIGNAL(finished()), flash, SLOT(deleteLater()));
00294 }
00295 
00296 WId MWindowPrivate::robustEffectiveWinId() const
00297 {
00298     Q_Q(const MWindow);
00299     if (q->isVisible()) {
00300         return q->effectiveWinId();
00301     } else {
00302         if (QWidget *parent = q->parentWidget()) {
00303             while (parent->parentWidget()) {
00304                 parent = parent->parentWidget();
00305             }
00306             return parent->winId();
00307         } else {
00308             return  q->winId();
00309         }
00310     }
00311 }
00312 
00313 #ifdef Q_WS_X11
00314 void MWindowPrivate::appendVisibilityChangeMask()
00315 {
00316     XWindowAttributes existingAttributes;
00317     XSetWindowAttributes newAttributes;
00318     Status status;
00319 
00320    status = XGetWindowAttributes(QX11Info::display(), robustEffectiveWinId(), &existingAttributes);
00321     if (status == 0) {
00322         qFatal("MWindow: XGetWindowAttributes() failed!");
00323     }
00324 
00325     newAttributes.event_mask = existingAttributes.your_event_mask | VisibilityChangeMask;
00326 
00327     XChangeWindowAttributes(QX11Info::display(), robustEffectiveWinId(), CWEventMask, &newAttributes);
00328 }
00329 #endif
00330 
00331 void MWindowPrivate::_q_onPixmapRequestsFinished()
00332 {
00333     Q_Q(MWindow);
00334 
00335     q->disconnect(MTheme::instance(), SIGNAL(pixmapRequestsFinished()),
00336                   q, SLOT(_q_onPixmapRequestsFinished()));
00337     q->setVisible(true);
00338 }
00339 
00340 void MWindowPrivate::handleApplicationLayoutDirectionChangeEvent(QGraphicsItem *item)
00341 {
00342     if (item->isWidget()) {
00343         QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
00344         Qt::LayoutDirection direction = qApp->layoutDirection();
00345         // if the direction has not changed or has been specified
00346         // directly, do not update.
00347         if (((direction == Qt::RightToLeft) == widget->testAttribute(Qt::WA_RightToLeft))
00348                 || widget->testAttribute(Qt::WA_SetLayoutDirection))
00349             return;
00350         widget->setAttribute(Qt::WA_RightToLeft, (direction == Qt::RightToLeft));
00351         // Send the notification event to this widget item.
00352         QEvent e(QEvent::LayoutDirectionChange);
00353         QApplication::sendEvent(widget, &e);
00354     }
00355     // Propagate this change to all children.
00356     const int size = item->childItems().size();
00357     for (int i = 0; i < size; ++i) {
00358         QGraphicsItem *childItem = item->childItems().at(i);
00359         handleApplicationLayoutDirectionChangeEvent(childItem);
00360     }
00361 }
00362 
00363 void MWindowPrivate::handleLanguageChangeEvent(QGraphicsItem *item)
00364 {
00365     if (item->isWidget()) {
00366         QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
00367         if (qobject_cast<MWidget*> (widget)) {
00368             // If it is a MWidget, sent it the language change event
00369             // to trigger the retranslateUi() method of the MWidget:
00370             QEvent e(QEvent::LanguageChange);
00371             qApp->sendEvent(widget, &e);
00372         }
00373     }
00374     // Propagate this change to all children.
00375     const int size = item->childItems().size();
00376     for (int i = 0; i < size; ++i) {
00377         QGraphicsItem *childItem = item->childItems().at(i);
00378         handleLanguageChangeEvent(childItem);
00379     }
00380 }
00381 
00382 bool MWindow::isInSwitcher() const
00383 {
00384     Q_D(const MWindow);
00385 
00386     return d->isInSwitcher;
00387 }
00388 
00389 M::Orientation MWindowPrivate::orientation(M::OrientationAngle angle) const
00390 {
00391     return (angle == M::Angle0 || angle == M::Angle180) ? M::Landscape : M::Portrait;
00392 }
00393 
00394 // return true if modifiers match what is required for debug keyboard shortcuts
00395 bool MWindowPrivate::debugShortcutModifiersPresent(Qt::KeyboardModifiers modifiers) const
00396 {
00397     return (modifiers & (Qt::ControlModifier | Qt::AltModifier)
00398             && (modifiers & Qt::ShiftModifier));
00399 }
00400 
00401 void MWindowPrivate::notifyWidgetsAboutOrientationChange()
00402 {
00403     Q_Q(MWindow);
00404 
00405     M::Orientation newOrientation = q->orientation();
00406 
00407     if (sceneManager == 0 && oldOrientation != newOrientation) {
00408         QGraphicsScene *graphicsScene = q->QGraphicsView::scene();
00409         if (graphicsScene) {
00410             MOrientationChangeEvent event(newOrientation);
00411             foreach(QGraphicsItem * item, graphicsScene->items())
00412                 graphicsScene->sendEvent(item, &event);
00413         }
00414 
00415         emit q->orientationChanged(newOrientation);
00416         emit q->orientationChangeFinished(newOrientation);
00417     }
00418 }
00419 
00420 void MWindowPrivate::doEnterDisplayEvent()
00421 {
00422     Q_Q(MWindow);
00423 
00424     onDisplay = true;
00425     onDisplaySet = true;
00426 
00427     q->enterDisplayEvent();
00428     emit q->displayEntered();
00429 
00430     if (discardedPaintEvent) {
00431         // we discarded a paint event while beeing invisible
00432         // make sure the screen is up to date
00433         discardedPaintEvent = false;
00434         QTimer::singleShot(0, q->viewport(), SLOT(update()));
00435     }
00436 }
00437 
00438 void MWindowPrivate::doExitDisplayEvent()
00439 {
00440     Q_Q(MWindow);
00441 
00442     onDisplay = false;
00443     onDisplaySet = true;
00444 
00445     q->exitDisplayEvent();
00446     emit q->displayExited();
00447 
00448     if (q->scene() && delayedMOnDisplayChangeEvent != 0) {
00449         propagateMOnDisplayChangeEventToScene(delayedMOnDisplayChangeEvent);
00450         delete delayedMOnDisplayChangeEvent;
00451         delayedMOnDisplayChangeEvent = 0;
00452     }
00453 }
00454 
00455 void MWindowPrivate::_q_exitDisplayStabilized()
00456 {
00457     doExitDisplayEvent();
00458 }
00459 
00460 void MWindowPrivate::sendExitDisplayEvent(bool delayedSending)
00461 {
00462     Q_Q(MWindow);
00463 
00464     delete delayedMOnDisplayChangeEvent;
00465     delayedMOnDisplayChangeEvent = new MOnDisplayChangeEvent(MOnDisplayChangeEvent::FullyOffDisplay, q->sceneRect());
00466     if (delayedSending) {
00467         displayExitedTimer.start();
00468     } else {
00469         _q_exitDisplayStabilized();
00470     }
00471 }
00472 
00473 void MWindowPrivate::propagateMOnDisplayChangeEventToScene(MOnDisplayChangeEvent *event)
00474 {
00475     Q_Q(MWindow);
00476 
00477     MOnDisplayChangeEvent::State eventState;
00478 
00479     if (event->state() == MOnDisplayChangeEvent::PartiallyOnDisplay ||
00480             event->state() == MOnDisplayChangeEvent::FullyOnDisplay ||
00481             event->state() == MOnDisplayChangeEvent::MustBeResolved) {
00482         eventState = MOnDisplayChangeEvent::MustBeResolved;
00483     } else {
00484         eventState = MOnDisplayChangeEvent::FullyOffDisplay;
00485     }
00486 
00487 
00488     MOnDisplayChangeEvent ev(eventState, q->sceneRect());
00489 
00490     // FIXME:
00491     // Actually sending the event would require overriding customEvent() which
00492     // would mess ABI compatibility. Calling the event handler directly for now
00493     q->scene()->d_func()->onDisplayChangeEvent(&ev);
00494 
00495 }
00496 
00497 void MWindowPrivate::_q_enablePaintUpdates()
00498 {
00499     Q_Q(MWindow);
00500 
00501     q->setUpdatesEnabled(true);
00502 }
00503 
00504 void MWindowPrivate::windowStateChangeEvent(QWindowStateChangeEvent *event)
00505 {
00506     Q_Q(MWindow);
00507 
00508     // Check if window has entered / left the switcher
00509     if (!event->oldState().testFlag(Qt::WindowMinimized) && q->windowState().testFlag(Qt::WindowMinimized)) {
00510         isInSwitcher = true;
00511         emit q->switcherEntered();
00512     }
00513     else if (event->oldState().testFlag(Qt::WindowMinimized) &&
00514              !q->windowState().testFlag(Qt::WindowMinimized)) {
00515         isInSwitcher = false;
00516         timeSinceLastPaintInSwitcher.invalidate();
00517         emit q->switcherExited();
00518     }
00519 
00520 #ifdef QT_OPENGL_LIB
00521     if (!minimizedSoftwareSwitch || MApplication::softwareRendering())
00522         return;
00523 
00524     if (!event->oldState().testFlag(Qt::WindowMinimized) && q->windowState().testFlag(Qt::WindowMinimized)) {
00525         initSoftwareViewport();
00526         MComponentCache::cleanupCache();
00527         MTheme::cleanupGarbage();
00528     } else if (event->oldState().testFlag(Qt::WindowMinimized)
00529                && !q->windowState().testFlag(Qt::WindowMinimized)) {
00530         if (MGraphicsSystemHelper::isRunningNativeGraphicssystem()) {
00531             q->setUpdatesEnabled(false);
00532         }
00533         initGLViewport();
00534         if (MGraphicsSystemHelper::isRunningNativeGraphicssystem()) {
00535             QTimer::singleShot(700, q, SLOT(_q_enablePaintUpdates()));
00536         }
00537     }
00538 #endif
00539 }
00540 
00541 void MWindowPrivate::closeEvent(QCloseEvent *event)
00542 {
00543     Q_Q(MWindow);
00544 
00545     // Call close event manually here, because we want to check if the
00546     // event got ignored before executing lazy shutdown routines.
00547     q->closeEvent(static_cast<QCloseEvent *>(event));
00548 
00549     if (!event->isAccepted()) {
00550         return;
00551     }
00552 
00553     isLogicallyClosed = true;
00554 
00555     sendExitDisplayEvent(false);
00556 
00557     if (MApplication::prestartMode() == M::LazyShutdownMultiWindow ||
00558         MApplication::prestartMode() == M::LazyShutdown) {
00559 
00560 #ifdef Q_WS_X11
00561         MApplicationPrivate::removeWindowFromSwitcher(q->effectiveWinId(), true);
00562 #endif
00563 
00564         // Check if all windows are closed. If so,
00565         // return to the prestarted state.
00566         bool allWindowsLogicallyClosed = true;
00567         Q_FOREACH(MWindow * win, MApplication::windows()) {
00568             if (!win->d_ptr->isLogicallyClosed) {
00569                 allWindowsLogicallyClosed = false;
00570             }
00571         }
00572 
00573         if (allWindowsLogicallyClosed) {
00574             MApplication::setPrestarted(true);
00575         }
00576 
00577         if (!q->closeOnLazyShutdown()) {
00578             q->hide();
00579             q->lower();
00580             event->ignore();
00581             return;
00582         }
00583     }
00584 
00585 #ifdef M_USE_OPENGL
00586     if (!MApplication::softwareRendering()) {
00587         MGLES2Renderer::destroy(glContext);
00588     }
00589 #endif
00590 
00591 }
00592 
00593 #ifdef HAVE_GCONF
00594 void MWindowPrivate::_q_updateMinimizedSoftwareSwitch() {
00595     minimizedSoftwareSwitch = minimizedSoftwareSwitchItem.value().toBool();
00596 }
00597 #endif
00598 
00599 MWindow::MWindow(MWindowPrivate &dd, QWidget *parent)
00600     : QGraphicsView(parent),
00601       d_ptr(&dd)
00602 {
00603     Q_D(MWindow);
00604 
00605     d->q_ptr = this;
00606     d->init();
00607     MComponentData::registerWindow(this);
00608 }
00609 
00610 MWindow::MWindow(MWindowPrivate &dd, MScene *scene, QWidget *parent)
00611     : QGraphicsView(parent), d_ptr(&dd)
00612 {
00613     Q_D(MWindow);
00614     d->q_ptr = this;
00615     d->init();
00616     MComponentData::registerWindow(this);
00617     setSceneManager(new MSceneManager(scene, this));
00618 }
00619 
00620 MWindow::MWindow(MWindowPrivate &dd, MSceneManager *sceneManager, QWidget *parent)
00621     : QGraphicsView(parent), d_ptr(&dd)
00622 {
00623     Q_D(MWindow);
00624     d->q_ptr = this;
00625     d->init();
00626     MComponentData::registerWindow(this);
00627     setSceneManager(sceneManager);
00628 }
00629 
00630 MWindow::MWindow(MSceneManager *sceneManager, QWidget *parent)
00631     : QGraphicsView(parent), d_ptr(new MWindowPrivate)
00632 {
00633     Q_D(MWindow);
00634     d->q_ptr = this;
00635     d->init();
00636     MComponentData::registerWindow(this);
00637     setSceneManager(sceneManager);
00638 }
00639 
00640 MWindow::MWindow(QWidget *parent)
00641     : QGraphicsView(parent),
00642       d_ptr(new MWindowPrivate)
00643 {
00644     Q_D(MWindow);
00645     d->q_ptr = this;
00646     d->init();
00647     MComponentData::registerWindow(this);
00648 }
00649 
00650 MWindow::~MWindow()
00651 {
00652 #ifdef Q_WS_X11
00653     MOrientationTracker::instance()->d_func()->stopFollowingCurrentAppWindow(this);
00654 #endif
00655     MComponentData::unregisterWindow(this);
00656     delete d_ptr;
00657 }
00658 
00659 void MWindow::setTranslucentBackground(bool enable)
00660 {
00661     Q_D(MWindow);
00662 
00663     if (enable) {
00664         setAttribute(Qt::WA_TranslucentBackground);
00665 #ifdef Q_WS_X11
00666         // This is workaround for NB#170883
00667         // Setting Qt::WA_TranslucentBackground property for window
00668         // changes mask for yet unknown reason, only on hardware,
00669         // not in scratchbox and supposingly its a candidate for
00670         // filing bug against Qt when confirmed
00671         d->appendVisibilityChangeMask();
00672 #endif
00673     }
00674 
00675     // when the gl widget is not initialized yet we will also not initialize it
00676     if (MApplication::softwareRendering() || MApplication::isPrestarted() ||
00677         (MGraphicsSystemHelper::isRunningNativeGraphicssystem() && !dynamic_cast<QGLWidget*>(viewport()))) {
00678         d->initSoftwareViewport();
00679     } else {
00680         d->initGLViewport();
00681     }
00682 
00683     if (MApplication::softwareRendering())
00684         viewport()->setAutoFillBackground(!enable);
00685 }
00686 
00687 #ifdef Q_WS_X11
00688 void MWindowPrivate::setX11Property(const char *propertyName, qreal value)
00689 {
00690     Q_Q(MWindow);
00691 
00692     Atom atom = XInternAtom(QX11Info::display(), propertyName, False);
00693 
00694     if (value < 0.0 || value >= 1.0) {
00695         XDeleteProperty(QX11Info::display(), q->effectiveWinId(), atom);
00696     } else {
00697         // We use same conventions as _NET_WM_WINDOW_OPACITY so we could re-use
00698         // same code in the compositor
00699         unsigned int opacity = (unsigned int) (0xffffffff * value);
00700 
00701         XChangeProperty(QX11Info::display(), q->effectiveWinId(), atom, XA_CARDINAL, 32 ,
00702                         PropModeReplace, (unsigned char *) &opacity, 1);
00703     }
00704 }
00705 
00706 qreal MWindowPrivate::getX11Property(const char *propertyName) const
00707 {
00708     Q_Q(const MWindow);
00709 
00710     qreal level = 1.0;
00711     Atom actualType = 0;
00712     int actualFormat = 0;
00713     unsigned long nitems = 0;
00714     unsigned long bytes = 0;
00715 
00716     union {
00717         unsigned char* asUChar;
00718         unsigned long* asULong;
00719     } data = {0};
00720 
00721     Atom propertyAtom = XInternAtom(QX11Info::display(), propertyName, False);
00722 
00723     int status = XGetWindowProperty(QX11Info::display(), q->effectiveWinId(), propertyAtom,
00724                                     0, 1, False, AnyPropertyType,
00725                                     &actualType, &actualFormat, &nitems,
00726                                     &bytes, &data.asUChar);
00727 
00728     if (status == Success && actualType == XA_CARDINAL && actualFormat == 32 && nitems == 1)
00729         level = (qreal)data.asULong[0] / 0xffffffff;
00730     if (status == Success)
00731         XFree(data.asUChar);
00732     return level;
00733 }
00734 
00735 void MWindowPrivate::setX11PrestartProperty(bool set)
00736 {
00737     Q_Q(MWindow);
00738     Display *dpy  = QX11Info::display();
00739     if (dpy) {
00740         Atom prestartAtom = XInternAtom(dpy, "_MEEGOTOUCH_PRESTARTED", False);
00741         unsigned char data=1;
00742         if (set) {
00743             XChangeProperty(dpy, q->effectiveWinId(), prestartAtom,
00744                             XA_CARDINAL, 8, PropModeAppend, &data, 1);
00745         } else {
00746             XDeleteProperty(dpy, q->effectiveWinId(), prestartAtom);
00747         }
00748     }
00749 }
00750 
00751 void MWindowPrivate::setX11OrientationAngleProperty(M::OrientationAngle angle)
00752 {
00753     Q_Q(MWindow);
00754     Display *display = QX11Info::display();
00755 
00756     if (!display)
00757         return;
00758 
00759     //sometimes this class is used without valid x11 window
00760     if (q->effectiveWinId() == 0)
00761         return;
00762 
00763     Atom orientationAngleAtom = XInternAtom(display, "_MEEGOTOUCH_ORIENTATION_ANGLE", False);
00764 
00765     XChangeProperty(display, q->effectiveWinId(), orientationAngleAtom, XA_CARDINAL, 32,
00766                     PropModeReplace, (unsigned char*)&angle, 1);
00767 }
00768 #endif
00769 
00770 void MWindow::setGlobalAlpha(qreal level)
00771 {
00772 #ifdef Q_WS_X11
00773     Q_D(MWindow);
00774     d->setX11Property("_MEEGOTOUCH_GLOBAL_ALPHA", level);
00775 #else
00776     Q_UNUSED(level);
00777 #endif
00778 }
00779 
00780 qreal MWindow::globalAlpha()
00781 {
00782 #ifdef Q_WS_X11
00783     Q_D(MWindow);
00784     return d->getX11Property("_MEEGOTOUCH_GLOBAL_ALPHA");
00785 #else
00786     return 1.0;
00787 #endif
00788 }
00789 
00790 void MWindow::setVideoGlobalAlpha(qreal level)
00791 {
00792 #ifdef Q_WS_X11
00793     Q_D(MWindow);
00794     d->setX11Property("_MEEGOTOUCH_VIDEO_ALPHA", level);
00795 #else
00796     Q_UNUSED(level);
00797 #endif
00798 }
00799 
00800 qreal MWindow::videoGlobalAlpha()
00801 {
00802 #ifdef Q_WS_X11
00803     Q_D(MWindow);
00804     return d->getX11Property("_MEEGOTOUCH_VIDEO_ALPHA");
00805 #else
00806     return 1.0;
00807 #endif
00808 }
00809 
00810 MScene *MWindow::scene()
00811 {
00812     return qobject_cast<MScene *>(QGraphicsView::scene());
00813 }
00814 
00815 bool MWindow::isOrientationAngleLocked() const
00816 {
00817     Q_D(const MWindow);
00818 
00819     return d->orientationAngleLocked;
00820 }
00821 
00822 void MWindow::setOrientationAngleLocked(bool locked)
00823 {
00824     Q_D(MWindow);
00825 
00826     if (d->orientationAngleLocked != locked) {
00827         d->orientationAngleLocked = locked;
00828 
00829         // update from the orientation tracker if we're unlocking orientation changes
00830         if (!locked)
00831             setOrientationAngle(MOrientationTracker::instance()->orientationAngle());
00832     }
00833 }
00834 
00835 bool MWindow::isOrientationLocked() const
00836 {
00837     Q_D(const MWindow);
00838 
00839     return d->orientationLocked;
00840 }
00841 
00842 void MWindow::setOrientationLocked(bool locked)
00843 {
00844     Q_D(MWindow);
00845 
00846     if (d->orientationLocked != locked) {
00847         d->orientationLocked = locked;
00848 
00849         // update from the orientation tracker if we're unlocking orientation changes
00850         if (!locked)
00851             setOrientationAngle(MOrientationTracker::instance()->orientationAngle());
00852     }
00853 }
00854 
00855 void MWindow::lockOrientationAngle()
00856 {
00857     setOrientationAngleLocked(true);
00858 }
00859 
00860 void MWindow::unlockOrientationAngle()
00861 {
00862     setOrientationAngleLocked(false);
00863 }
00864 
00865 void MWindow::lockOrientation()
00866 {
00867     setOrientationLocked(true);
00868 }
00869 
00870 void MWindow::unlockOrientation()
00871 {
00872     setOrientationLocked(false);
00873 }
00874 
00875 void MWindow::setSceneManager(MSceneManager *sceneManager)
00876 {
00877     Q_D(MWindow);
00878 
00879     if (d->sceneManager == sceneManager) {
00880         return;
00881     }
00882 
00883     if (d->sceneManager) {
00884         delete d->sceneManager;
00885     }
00886 
00887     d->sceneManager = sceneManager;
00888 
00889     if (sceneManager) {
00890         connect(sceneManager, SIGNAL(orientationAngleChanged(M::OrientationAngle)),
00891                 SIGNAL(orientationAngleChanged(M::OrientationAngle)));
00892         connect(sceneManager, SIGNAL(orientationChanged(M::Orientation)),
00893                 SIGNAL(orientationChanged(M::Orientation)));
00894         connect(sceneManager, SIGNAL(orientationChangeFinished(M::Orientation)),
00895                 SIGNAL(orientationChangeFinished(M::Orientation)));
00896         sceneManager->setParent(this);
00897         setScene(sceneManager->scene());
00898         setSceneRect(QRectF(QPointF(), visibleSceneSize(M::Landscape)));
00899         centerOn(sceneRect().center());
00900     }
00901 }
00902 
00903 MSceneManager *MWindow::sceneManager()
00904 {
00905     Q_D(MWindow);
00906 
00907     // A scene manager is needed. Let's create one on the fly
00908     // if we don't have one already.
00909     if (!d->sceneManager) {
00910         setSceneManager(new MSceneManager);
00911     }
00912 
00913     return d->sceneManager;
00914 }
00915 
00916 MSceneManager *MWindow::sceneManager() const
00917 {
00918     Q_D(const MWindow);
00919 
00920     return d->sceneManager;
00921 }
00922 
00923 M::Orientation MWindow::orientation() const
00924 {
00925     Q_D(const MWindow);
00926 
00927     if (d->sceneManager) {
00928         return d->sceneManager->orientation();
00929     } else {
00930         return d->orientation(d->angle);
00931     }
00932 }
00933 
00934 M::OrientationAngle MWindow::orientationAngle() const
00935 {
00936     Q_D(const MWindow);
00937 
00938     if (d->sceneManager) {
00939         return d->sceneManager->orientationAngle();
00940     } else {
00941         return d->angle;
00942     }
00943 }
00944 
00945 void MWindow::setOrientationAngle(M::OrientationAngle angle)
00946 {
00947     Q_D(MWindow);
00948 
00949     //orientation was forced by command line option
00950     if (MComponentData::isOrientationForced())
00951         return;
00952 
00953     M::OrientationAngle targetAngle;
00954     if (d->sceneManager && d->sceneManager->d_ptr->pendingRotation)
00955         targetAngle = d->sceneManager->d_ptr->pendingRotation->angle;
00956     else
00957         targetAngle = orientationAngle();
00958 
00959     if (targetAngle != angle) {
00960         d->oldOrientation = orientation();
00961         d->angle = angle;
00962 
00963         if (d->sceneManager) {
00964             MSceneManager::TransitionMode mode = isVisible() ?
00965                 MSceneManager::AnimatedTransition :
00966                 MSceneManager::ImmediateTransition;
00967 
00968             d->sceneManager->setOrientationAngle(angle, mode);
00969         } else {
00970             // first notify widgets, then emit the signal (in case someone
00971             // would like to connect to the signal and get correct size hints for widgets)
00972             d->notifyWidgetsAboutOrientationChange();
00973             emit orientationAngleChanged(angle);
00974         }
00975 #ifdef Q_WS_X11
00976         d->setX11OrientationAngleProperty(angle);
00977 #endif
00978     }
00979 }
00980 
00981 void MWindow::setLandscapeOrientation()
00982 {
00983     if (orientation() != M::Landscape)
00984         setOrientationAngle(M::Angle0);
00985 }
00986 
00987 void MWindow::setPortraitOrientation()
00988 {
00989     if (orientation() != M::Portrait)
00990         setOrientationAngle(M::Angle270);
00991 }
00992 
00993 QSize MWindow::visibleSceneSize(M::Orientation orientation) const
00994 {
00995     QSize s;
00996 
00997     if (orientation == M::Landscape) {
00998         s = MDeviceProfile::instance()->resolution();
00999     } else {
01000         s = QSize(MDeviceProfile::instance()->resolution().height(),
01001                   MDeviceProfile::instance()->resolution().width());
01002     }
01003 
01004     return s;
01005 }
01006 
01007 QSize MWindow::visibleSceneSize() const
01008 {
01009     return visibleSceneSize(orientation());
01010 }
01011 
01012 bool MWindow::isOnDisplay() const
01013 {
01014     Q_D(const MWindow);
01015 
01016     return d->onDisplay;
01017 }
01018 
01019 void MWindow::enterDisplayEvent()
01020 {}
01021 
01022 void MWindow::exitDisplayEvent()
01023 {}
01024 
01025 void MWindow::onDisplayChangeEvent(MOnDisplayChangeEvent *event)
01026 {
01027     Q_D(MWindow);
01028 
01029     switch (event->state()) {
01030 
01031     case MOnDisplayChangeEvent::FullyOnDisplay:
01032         d->displayExitedTimer.stop();
01033         if (!d->onDisplay || !d->onDisplaySet) {
01034             d->doEnterDisplayEvent();
01035             if (scene()) {
01036                 d->propagateMOnDisplayChangeEventToScene(event);
01037             }
01038         }
01039         break;
01040 
01041     case MOnDisplayChangeEvent::FullyOffDisplay:
01042         if (d->onDisplay || !d->onDisplaySet) {
01043             // displayEntered signal is emitted immediately above, but
01044             // emitting displayExited is delayed by default. Emitting
01045             // will be canceled if FullyOnDisplay event is received
01046             // during the delay. displayExitedTimer timeout will call
01047             // d->doExitDisplayEvent() which will take care of
01048             // propagating delayedMOnDisplayChangeEvent to the scene.
01049             d->sendExitDisplayEvent(true);
01050         }
01051         break;
01052 
01053     default:
01054         event->ignore();
01055         break;
01056     }
01057 }
01058 
01059 void MWindow::paintEvent(QPaintEvent *event)
01060 {
01061     Q_D(MWindow);
01062 #ifdef M_USE_OPENGL
01063     if (!MApplication::softwareRendering()) {
01064         MGLES2Renderer::activate(d->glContext);
01065     }
01066 #endif // M_USE_OPENGL
01067 
01068     if (isInSwitcher()) {
01069         if (!isOnDisplay()) {
01070             // TODO: also do this check for the foreground app not visible in the switcher once onDisplay is immediately
01071             // true when starting an application. right now during startup the first frames would be discarded
01072             mWarning("MWindow::paintEvent") << "Application is not visible. Paint event discarded. Make sure the application does not paint in the first place.";
01073             event->accept();
01074             d->discardedPaintEvent = true;
01075             return;
01076         } else if (!d->timeSinceLastPaintInSwitcher.isValid()) {
01077             d->timeSinceLastPaintInSwitcher.start();
01078             d->updateIsPending = false;
01079         } else {
01080             const int maxFpsInSwitcher = 5;
01081             const int minDelay = 1000. / maxFpsInSwitcher;
01082             qint64 msSinceLastPaint = d->timeSinceLastPaintInSwitcher.elapsed();
01083             if (msSinceLastPaint < minDelay) {
01084                 event->accept();
01085                 if (!d->updateIsPending) {
01086                     // trigger a new paint event as otherwise the screen may not be up to date
01087                     QTimer::singleShot(minDelay, viewport(), SLOT(update()));
01088                     d->updateIsPending = true;
01089                 }
01090                 return;
01091             } else {
01092                 d->timeSinceLastPaintInSwitcher.restart();
01093                 d->updateIsPending = false;
01094             }
01095         }
01096     }
01097 
01098     QGraphicsView::paintEvent(event);
01099 }
01100 
01101 bool MWindow::event(QEvent *event)
01102 {
01103     Q_D(MWindow);
01104 
01105     if (event->type() == QEvent::Show || event->type() == QEvent::WindowActivate) {
01106         MComponentData::setActiveWindow(this);
01107     } else if (event->type() == QEvent::WindowStateChange) {
01108         d->windowStateChangeEvent(static_cast<QWindowStateChangeEvent *>(event));
01109     } else if (event->type() == QEvent::Close) {
01110         d->closeEvent(static_cast<QCloseEvent *>(event));
01111         // closeEvent() already called.
01112         return true;
01113     } else if (QEvent::KeyPress == event->type()) {
01114         bool updateNeeded = false;
01115 
01116         //SIMULATION OF ROTATION FOR DEVELOPMENT PURPOSES
01117         QKeyEvent *k = static_cast<QKeyEvent *>(event);
01118         if (Qt::Key_R == k->key() && d->debugShortcutModifiersPresent(k->modifiers())) {
01119             foreach (MWindow *window, MApplication::windows()) {
01120                 int newAngle = (window->orientationAngle()
01121                                 + ((k->modifiers() & Qt::AltModifier) ? 270 : 90)) % 360;
01122                 if (!window->isOrientationAngleLocked()) {
01123                     if ((!window->isOrientationLocked())
01124                         || window->orientation() == static_cast<M::Orientation>(newAngle)) {
01125                         window->setOrientationAngle(static_cast<M::OrientationAngle>(newAngle));
01126                     }
01127                 }
01128             }
01129         } else if (Qt::Key_T == k->key() && d->debugShortcutModifiersPresent(k->modifiers())) {
01130             MApplication::setShowPosition(!MApplication::showPosition());
01131             updateNeeded = true;
01132         } else if (Qt::Key_S == k->key() && d->debugShortcutModifiersPresent(k->modifiers())) {
01133             MApplication::setShowSize(!MApplication::showSize());
01134             updateNeeded = true;
01135         } else if (Qt::Key_B == k->key() && d->debugShortcutModifiersPresent(k->modifiers())) {
01136             MApplication::setShowBoundingRect(!MApplication::showBoundingRect());
01137             updateNeeded = true;
01138         } else if (Qt::Key_M == k->key() && d->debugShortcutModifiersPresent(k->modifiers())) {
01139             MApplication::setShowMargins(!MApplication::showMargins());
01140             updateNeeded = true;
01141         } else if (Qt::Key_N == k->key() && d->debugShortcutModifiersPresent(k->modifiers())) {
01142             MApplication::setShowObjectNames(!MApplication::showObjectNames());
01143             MApplication::setShowStyleNames(!MApplication::showStyleNames());
01144             updateNeeded = true;
01145         } else if (Qt::Key_F == k->key() && d->debugShortcutModifiersPresent(k->modifiers())) {
01146             MApplication::setShowFps(!MApplication::showFps());
01147             updateNeeded = true;
01148         } else if (Qt::Key_D == k->key() && d->debugShortcutModifiersPresent(k->modifiers())) {
01149             Qt::LayoutDirection dir = MApplication::layoutDirection();
01150 
01151             if (dir == Qt::LeftToRight)
01152                 dir = Qt::RightToLeft;
01153             else
01154                 dir = Qt::LeftToRight;
01155 
01156             MApplication::setLayoutDirection(dir);
01157 
01158             updateNeeded = true;
01159         } else if (Qt::Key_L == k->key() && d->debugShortcutModifiersPresent(k->modifiers())) {
01160             // switch language
01161             QString language;
01162 
01163             MLocale oldLocale; // get current system default
01164             language = oldLocale.name();
01165 
01166             if (language == "en_US_POSIX" || language.isEmpty())
01167                 language = "fi";
01168             else if (language == "fi")
01169                 language = "en";
01170             else if (language == "en")
01171                 language = "de";
01172             else if (language == "de")
01173                 language = "ar";
01174             else if (language == "ar")
01175                 language = "hu";
01176             else if (language == "hu")
01177                 language = "ur";
01178             else if (language == "ur")
01179                 language = "zh_CN";
01180             else
01181                 // engineering English:
01182                 language = "";
01183 
01184             MLocale newLocale(language);
01185             MLocale::setDefault(newLocale);
01186 
01187             updateNeeded = true;
01188         } else if (Qt::Key_P == k->key() && d->debugShortcutModifiersPresent(k->modifiers())) {
01189             QPixmap screenshot;
01190             screenshot = QPixmap::grabWindow(effectiveWinId());
01191 
01192             QString path;
01193             if (QDir(ImagesPath).exists())
01194                 path = ImagesPath;
01195             else
01196                 path = QDir::homePath();
01197 
01198             if (!screenshot.save(QString("%1/%2-%3.png").arg(path)
01199                 .arg(QDate::currentDate().toString("yyyyMMdd"))
01200                 .arg(QTime::currentTime().toString("hhmmss"))))
01201                 mWarning("MWindow") << "Could not save screenshot to" << path;
01202 
01203             d->playScreenshotEffect();
01204         } else if (Qt::Key_Q == k->key() && (k->modifiers() & Qt::ControlModifier)) {
01205             foreach(MWindow* window, MApplication::windows())
01206                 window->close();
01207         }
01208 
01209         if (updateNeeded) {
01210             this->viewport()->update();
01211         }
01212     } else if (event->type() == QEvent::ApplicationLayoutDirectionChange) {
01213         // tell the scene and its items about the layout change
01214         if (scene()) {
01215             QList<QGraphicsItem *> items = scene()->items();
01216 
01217             // call setLayoutDirection_helper() for all top-level items
01218             for (int i = 0; i < items.size(); i++) {
01219                 QGraphicsItem *item = items.at(i);
01220                 if (scene()->items().contains(item) && !item->parentItem()) {
01221                     d->handleApplicationLayoutDirectionChangeEvent(item);
01222                 }
01223             }
01224         }
01225         return true;
01226     } else if (event->type() == QEvent::LanguageChange) {
01227         // Tell the scene and its top-level items about the language change
01228         if (scene()) {
01229             QList<QGraphicsItem *> items = scene()->items();
01230             // Call handler for language change event only for top
01231             // level widgets. The handler then recurses over the
01232             // children.
01233             QList<QGraphicsItem *> itemsWithoutParents;
01234             foreach(QGraphicsItem *item, items)
01235                 if(!item->parentItem()) itemsWithoutParents << item;
01236             foreach(QGraphicsItem * item, itemsWithoutParents) {
01237                 d->handleLanguageChangeEvent(item);
01238             }
01239         }
01240         return true;
01241     } else if (event->type() == MOnDisplayChangeEvent::eventNumber()) {
01242         onDisplayChangeEvent(static_cast<MOnDisplayChangeEvent *>(event));
01243         return true;
01244     }
01245 #ifdef Q_WS_X11
01246     else if (event->type() == QEvent::DynamicPropertyChange) {
01247         QDynamicPropertyChangeEvent* dynamicEvent = static_cast<QDynamicPropertyChangeEvent*>(event);
01248         if (dynamicEvent->propertyName() == FollowsCurrentApplicationWindowOrientationPropertyName) {
01249             //property was set, does not matter what value
01250             if (property(FollowsCurrentApplicationWindowOrientationPropertyName).isValid()) {
01251                 mDebug("MWindow") << "window follows current app window orientation";
01252                 MOrientationTracker::instance()->d_func()->startFollowingCurrentAppWindow(this);
01253             }
01254             //propery was unset
01255             else
01256                 MOrientationTracker::instance()->d_func()->stopFollowingCurrentAppWindow(this);
01257         }
01258     }
01259 #endif
01260     return QGraphicsView::event(event);
01261 }
01262 
01263 void MWindow::setVisible(bool visible)
01264 {
01265     Q_D(MWindow);
01266 
01267     if (visible) {
01268 
01269         // This effectively overrides call to show() when in
01270         // prestarted state.
01271         if (MApplication::isPrestarted()) {
01272             return;
01273         }
01274 
01275         // Set onDisplay if it's not already set, because
01276         // it is used to discard paint events and we don't have
01277         // time to wait for visibility notifies from compositor.
01278         if (!d->onDisplaySet) {
01279             d->onDisplay = true;
01280         }
01281 
01282         if (MTheme::hasPendingRequests()) {
01283             // The showing of the window gets delayed until the theme
01284             // has finished to load all pixmap requests. This prevents
01285             // a flickering of the application on startup and improves
01286             // the performance.
01287             connect(MTheme::instance(), SIGNAL(pixmapRequestsFinished()),
01288                     this, SLOT(_q_onPixmapRequestsFinished()));
01289             return;
01290         } else {
01291             if (!windowState().testFlag(Qt::WindowMinimized) && !MApplication::softwareRendering()) {
01292                 if (MGraphicsSystemHelper::isRunningNativeGraphicssystem()) {
01293                     if (!dynamic_cast<QGLWidget*>(viewport())) {
01294                         d->initGLViewport();
01295                     }
01296                 } else {
01297                     d->initGLViewport();
01298                 }
01299             }
01300             d->isLogicallyClosed = false;
01301         }
01302 
01303 #ifdef Q_WS_X11
01304         MApplicationPrivate::removeWindowFromSwitcher(effectiveWinId(), false);
01305 #endif
01306 
01307     } else {
01308         MOnDisplayChangeEvent ev(false, sceneRect());
01309         onDisplayChangeEvent(&ev);
01310     }
01311 
01312     QGraphicsView::setVisible(visible);
01313 }
01314 
01315 void MWindow::setCloseOnLazyShutdown(bool enable)
01316 {
01317     Q_D(MWindow);
01318 
01319     d->closeOnLazyShutdown = enable;
01320 }
01321 
01322 bool MWindow::closeOnLazyShutdown() const
01323 {
01324     Q_D(const MWindow);
01325 
01326     return d->closeOnLazyShutdown;
01327 }
01328 
01329 #include "moc_mwindow.cpp"

Copyright © 2010 Nokia Corporation Generated on Thu Nov 4 2010 18:14:22 (PDT)
Doxygen 1.7.1
MeeGo Touch