src/hbcore/inputfw/hbinputmainwindow.cpp
changeset 21 4633027730f5
parent 7 923ff622b8b9
child 28 b7da29130b0e
equal deleted inserted replaced
7:923ff622b8b9 21:4633027730f5
    26 
    26 
    27 #include <QGraphicsWidget>
    27 #include <QGraphicsWidget>
    28 #include <QGraphicsSceneMouseEvent>
    28 #include <QGraphicsSceneMouseEvent>
    29 #include <QStyleOptionGraphicsItem>
    29 #include <QStyleOptionGraphicsItem>
    30 #include <QInputContext>
    30 #include <QInputContext>
       
    31 #include <QPointer>
    31 
    32 
    32 #include "hbinputregioncollector_p.h"
    33 #include "hbinputregioncollector_p.h"
    33 #include "hbinstance.h"
    34 #include "hbinstance.h"
    34 #include "hbwidget.h"
    35 #include "hbwidget.h"
    35 #include "hbview.h"
    36 #include "hbview.h"
    36 #include "hbnamespace_p.h"
       
    37 #include "hbstackedlayout.h"
    37 #include "hbstackedlayout.h"
    38 
    38 
    39 #if defined (Q_OS_SYMBIAN)
    39 #if defined (Q_OS_SYMBIAN)
    40 #include <coemain.h>
    40 #include <coemain.h>
    41 #include <coecntrl.h>
    41 #include <coecntrl.h>
    50 }
    50 }
    51 
    51 
    52 Q_DECLARE_TYPEINFO(TRect, Q_MOVABLE_TYPE);
    52 Q_DECLARE_TYPEINFO(TRect, Q_MOVABLE_TYPE);
    53 #endif
    53 #endif
    54 
    54 
       
    55 
       
    56 class HbProxyWindow: public QWidget
       
    57 {
       
    58 public:
       
    59     HbProxyWindow()
       
    60     {
       
    61         setGeometry(0,0,0,0);
       
    62     }
       
    63     void setWindow(QWidget* window)
       
    64     {
       
    65         this->window = window;
       
    66         if (window) {
       
    67             window->setParent(this);
       
    68         }
       
    69     }
       
    70     ~HbProxyWindow()
       
    71     {
       
    72         if (window) {
       
    73             window->setParent(0);
       
    74         }
       
    75     }
       
    76 private:
       
    77     QPointer<QWidget> window;
       
    78 };
       
    79 
       
    80 
    55 class HbInputTransparentWindow : public HbWidget
    81 class HbInputTransparentWindow : public HbWidget
    56 {
    82 {
    57 public:
    83 public:
    58 
    84 
    59     HbInputTransparentWindow(QGraphicsItem *parent = 0);
    85     HbInputTransparentWindow(QGraphicsItem *parent = 0);
    68 };
    94 };
    69 
    95 
    70 HbInputTransparentWindow::HbInputTransparentWindow(QGraphicsItem *parent) :
    96 HbInputTransparentWindow::HbInputTransparentWindow(QGraphicsItem *parent) :
    71     HbWidget(parent)
    97     HbWidget(parent)
    72 {
    98 {
    73 	setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, true);
    99     setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, true);
    74 }
   100 }
    75 
   101 
    76 
   102 
    77 /*!
   103 /*!
    78     Destructs the transparent window.
   104     Destructs the transparent window.
    88     painter->setCompositionMode(QPainter::CompositionMode_Source);
   114     painter->setCompositionMode(QPainter::CompositionMode_Source);
    89     painter->fillRect(option->exposedRect, QColor(0, 0, 0, 0));
   115     painter->fillRect(option->exposedRect, QColor(0, 0, 0, 0));
    90     painter->setCompositionMode(compositionMode);
   116     painter->setCompositionMode(compositionMode);
    91 }
   117 }
    92 
   118 
       
   119 class HbInputMainWindowPrivate
       
   120 {
       
   121 public:
       
   122  HbInputMainWindowPrivate(HbInputMainWindow *owner)
       
   123     :q_ptr(owner), mLastFocusedWidget(0), mSpellQueryLaunched(false), mProxyWindow(0), mIsInputWindowFocusLocked(false)
       
   124     {
       
   125     }
       
   126     ~HbInputMainWindowPrivate();
       
   127     
       
   128     HbInputMainWindow *q_ptr;
       
   129     QPointer<QWidget> mLastFocusedWidget;
       
   130     QRegion mMask;
       
   131     bool mSpellQueryLaunched;
       
   132     QPointer<HbProxyWindow > mProxyWindow;
       
   133     bool mIsInputWindowFocusLocked;
       
   134 };
       
   135 
       
   136 HbInputMainWindowPrivate::~HbInputMainWindowPrivate()
       
   137 {
       
   138     delete mProxyWindow;
       
   139 }
       
   140 
    93 /*
   141 /*
    94 creates an instance of HbInputMainWindow.
   142 creates an instance of HbInputMainWindow.
    95 */
   143 */
    96 HbInputMainWindow *HbInputMainWindow::instance()
   144 HbInputMainWindow *HbInputMainWindow::instance()
    97 {
   145 {
    99     return mainWindow;
   147     return mainWindow;
   100 }
   148 }
   101 
   149 
   102 HbInputMainWindow::~HbInputMainWindow()
   150 HbInputMainWindow::~HbInputMainWindow()
   103 {
   151 {
   104     delete mProxyWindow;
   152     delete d_ptr;
   105 }
   153 }
   106 
   154 
   107 // constructor.
   155 // constructor.
   108 HbInputMainWindow::HbInputMainWindow()
   156 HbInputMainWindow::HbInputMainWindow()
   109 // HbMainWindow creates a background QGraphicsItem, which has the background image. we need to hide it that.
   157 // HbMainWindow creates a background QGraphicsItem, which has the background image. we need to hide it that.
   110     : HbMainWindow(0, Hb::WindowFlagTransparent), mLastFocusedWidget(0), mSpellQueryLaunched(false), mProxyWindow(0)
   158     : HbMainWindow(0, Hb::WindowFlagTransparent), d_ptr(new HbInputMainWindowPrivate(this))
   111 {
   159 {
   112     // We need a window which is of type Qt::Window flag at the same time does not show
   160     // We need a window which is of type Qt::Window flag at the same time does not show
   113     // any decorators Qt::Tool seems to be the option, and we want this window to be always on top so Qt::WindowStaysOnTopHint.
   161     // any decorators Qt::Tool seems to be the option, and we want this window to be always on top so Qt::WindowStaysOnTopHint.
   114     // And since transparency requires to have a frameless window we are setting that too.
   162     // And since transparency requires to have a frameless window we are setting that too.
   115     setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Tool | Qt::FramelessWindowHint);
   163     setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Tool | Qt::FramelessWindowHint);
   155 }
   203 }
   156 
   204 
   157 
   205 
   158 void HbInputMainWindow::updateRegion(QRegion region)
   206 void HbInputMainWindow::updateRegion(QRegion region)
   159 {
   207 {
   160     mMask = region;
   208     d_ptr->mMask = region;
   161 #if defined (Q_OS_SYMBIAN)
   209 #if defined (Q_OS_SYMBIAN)
   162     RWindowBase *rwindow = effectiveWinId()->DrawableWindow();
   210     RWindowBase *rwindow = effectiveWinId()->DrawableWindow();
   163     if (region.isEmpty()) {
   211     if (region.isEmpty()) {
   164         TRegionFix<1> tregion(TRect(TPoint(0, 0), TSize(0, 0)));
   212         TRegionFix<1> tregion(TRect(TPoint(0, 0), TSize(0, 0)));
   165         rwindow->SetShape(tregion);
   213         rwindow->SetShape(tregion);
   166     } else {
   214     } else {
   167         // Using QVector assumes the memory layout is the same as RRegion
   215         // Using QVector assumes the memory layout is the same as RRegion 
   168         QVector<QRect> rects = region.rects();
   216         QVector<QRect> rects = region.rects(); 
   169         QVector<TRect> trects(rects.count());
   217         QVector<TRect> trects(rects.count()); 
       
   218         RRegion rregion;
   170         for (int i = 0; i < trects.count(); ++i) {
   219         for (int i = 0; i < trects.count(); ++i) {
   171             trects[i] = qt_QRect2TRect(rects.at(i));
   220             rregion.AddRect(qt_QRect2TRect(rects.at(i)));
   172         }
   221         }
   173         RRegion rregion(trects.count(), trects.data());
   222         if (!rregion.CheckError())
   174         if (!rregion.CheckError()) {
   223             rwindow->SetShape(rregion); 
   175             rwindow->SetShape(rregion);
   224    }
   176         }
       
   177     }
       
   178 #else
   225 #else
   179     setMask(region);
   226     setMask(region);
   180 #endif
   227 #endif
   181 }
   228 }
   182 
   229 
   186 */
   233 */
   187 bool HbInputMainWindow::event(QEvent *e)
   234 bool HbInputMainWindow::event(QEvent *e)
   188 {
   235 {
   189     switch (e->type()) {
   236     switch (e->type()) {
   190     case QEvent::WindowActivate:
   237     case QEvent::WindowActivate:
   191         if (mLastFocusedWidget && !mSpellQueryLaunched) {
   238         if (d_ptr->mLastFocusedWidget && !d_ptr->mIsInputWindowFocusLocked) {
   192             qApp->setActiveWindow(mLastFocusedWidget);
   239             qApp->setActiveWindow(d_ptr->mLastFocusedWidget);
   193         }
   240         }
   194         break;
   241         break;
   195     default:
   242     default:
   196         break;
   243         break;
   197     }
   244     }
   203 and blocks the events to the application window by launching a widget which sits exactly in between the applicaion
   250 and blocks the events to the application window by launching a widget which sits exactly in between the applicaion
   204 and HbInputMainWindow.
   251 and HbInputMainWindow.
   205 */
   252 */
   206 bool HbInputMainWindow::eventFilter(QObject *obj, QEvent *event)
   253 bool HbInputMainWindow::eventFilter(QObject *obj, QEvent *event)
   207 {
   254 {
   208     if (event->type() == QEvent::DynamicPropertyChange) {
       
   209         const QString p = static_cast<QDynamicPropertyChangeEvent *>(event)->propertyName();
       
   210         if (p == "SpellQueryLaunched") {
       
   211             QVariant variant = obj->property("SpellQueryLaunched");
       
   212             if (variant.isValid()) {
       
   213                 mSpellQueryLaunched = variant.toBool();
       
   214                 if (mSpellQueryLaunched) {
       
   215                     qApp->setActiveWindow(this);
       
   216                     setFocus(Qt::OtherFocusReason);
       
   217                 } else {
       
   218                     if (mLastFocusedWidget) {
       
   219                         qApp->setActiveWindow(mLastFocusedWidget);
       
   220                     }
       
   221                 }
       
   222             }
       
   223             // return true as we are interested party!
       
   224             return true;
       
   225         }
       
   226     }
       
   227 
       
   228     // we need to only check for spontaneous events.
   255     // we need to only check for spontaneous events.
   229     if (event->spontaneous() && (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease)) {
   256     if (event->spontaneous() && (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease)) {
   230         QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
   257         QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
   231         if (mouseEvent) {
   258         if (mouseEvent) {
   232             // get the top level widget at the point, and see if that widget is a HbMainWindow,
   259             // get the top level widget at the point, and see if that widget is a HbMainWindow,
   233             // If it is a HbMainWindow then do not do any thing, as events will propagate
   260             // If it is a HbMainWindow then do not do any thing, as events will propagate
   234             // correctly. But when it is clicked inside application window then send the event to
   261             // correctly. But when it is clicked inside application window then send the event to
   235             // viewport as we might want to close a popup.
   262             // viewport as we might want to close a popup.
   236             if (!mMask.contains(mouseEvent->globalPos())) {
   263             if (!d_ptr->mMask.contains(mouseEvent->globalPos())) {
   237                 qApp->sendEvent(viewport(), event);
   264                 qApp->sendEvent(viewport(), event);
   238             }
   265             }
       
   266         }
       
   267     } else if(event->spontaneous() && event->type() == QEvent::WindowActivate) {
       
   268         if(d_ptr->mIsInputWindowFocusLocked && (qApp->activeWindow()!= this)) {
       
   269             qApp->setActiveWindow(this);
   239         }
   270         }
   240     }
   271     }
   241 
   272 
   242     return HbMainWindow::eventFilter(obj, event);
   273     return HbMainWindow::eventFilter(obj, event);
   243 }
   274 }
   248 lost.
   279 lost.
   249 */
   280 */
   250 void HbInputMainWindow::saveFocusWidget(QWidget * /*Old*/, QWidget *newFocus)
   281 void HbInputMainWindow::saveFocusWidget(QWidget * /*Old*/, QWidget *newFocus)
   251 {
   282 {
   252     if (newFocus && !this->isAncestorOf(newFocus)) {
   283     if (newFocus && !this->isAncestorOf(newFocus)) {
   253         mLastFocusedWidget = newFocus;
   284         d_ptr->mLastFocusedWidget = newFocus;
   254     }
   285     }
   255 }
   286 }
   256 
   287 
   257 void HbInputMainWindow::showInputWindow()
   288 void HbInputMainWindow::showInputWindow()
   258 {
   289 {
   273     }
   304     }
   274 #endif
   305 #endif
   275 
   306 
   276     HbInputRegionCollector::instance()->setEnabled(true);
   307     HbInputRegionCollector::instance()->setEnabled(true);
   277     if (win && win->windowModality() != Qt::NonModal) {
   308     if (win && win->windowModality() != Qt::NonModal) {
   278         if (!mProxyWindow) {
   309         if (!d_ptr->mProxyWindow) {
   279             mProxyWindow = new HbProxyWindow();
   310             d_ptr->mProxyWindow = new HbProxyWindow();
   280         }
   311         }
   281         mProxyWindow->setWindow(this);
   312         d_ptr->mProxyWindow->setWindow(this);
   282         // since the focused widget is inside a modal dialog which blocks events to other_window.
   313         // since the focused widget is inside a modal dialog which blocks events to other_window.
   283         // and since hbinputmainwindow also comes under the other_window. It does will not get the 
   314         // and since hbinputmainwindow also comes under the other_window. It does will not get the 
   284         // mouse click events.
   315         // mouse click events.
   285         mProxyWindow->setParent(win);
   316         d_ptr->mProxyWindow->setParent(win);
   286         // setParent resets the window flags, so we have to set the flags once again before show() is called.
   317         // setParent resets the window flags, so we have to set the flags once again before show() is called.
   287         setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Tool | Qt::FramelessWindowHint);
   318         setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Tool | Qt::FramelessWindowHint);
   288         show();
   319         show();
   289     } else {
   320     } else {
   290         if (mProxyWindow && mProxyWindow->isAncestorOf(this)) {
   321         if (d_ptr->mProxyWindow && d_ptr->mProxyWindow->isAncestorOf(this)) {
   291             mProxyWindow->setWindow(0);
   322             d_ptr->mProxyWindow->setParent(0);
       
   323             d_ptr->mProxyWindow->setWindow(0);
   292             setParent(0);
   324             setParent(0);
   293             // setParent resets the window flags, so we have to set the flags once again before show is called.
   325             // setParent resets the window flags, so we have to set the flags once again before show is called.
   294             setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Tool | Qt::FramelessWindowHint);
   326             setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Tool | Qt::FramelessWindowHint);
   295         }
   327         }
   296         show();
   328         show();
   304 #endif
   336 #endif
   305 }
   337 }
   306 
   338 
   307 void HbInputMainWindow::hideInputWindow()
   339 void HbInputMainWindow::hideInputWindow()
   308 {
   340 {
   309     if (mSpellQueryLaunched) {
   341     if (d_ptr->mIsInputWindowFocusLocked) {
   310         return;
   342         return;
   311     }
   343     }
   312 
   344 
   313     if (isVisible()) {
   345     if (isVisible()) {
   314         hide();
   346         hide();
   324     // installing event filter to the application.. this is needed to get
   356     // installing event filter to the application.. this is needed to get
   325     // the events happening in other vanilla windows.
   357     // the events happening in other vanilla windows.
   326     qApp->removeEventFilter(this);
   358     qApp->removeEventFilter(this);
   327 }
   359 }
   328 
   360 
       
   361 void HbInputMainWindow::lockFocus()
       
   362 {
       
   363     // lock only when HbinputMainWindow is active.
       
   364     if (!isVisible())
       
   365         return;
       
   366 
       
   367     d_ptr->mIsInputWindowFocusLocked = true;
       
   368     setFocus(Qt::OtherFocusReason);
       
   369     qApp->setActiveWindow(this);
       
   370 #if defined(Q_OS_SYMBIAN)
       
   371     // this is done to come on top of all the controls in symbian OS, done to overlap soft keys as well.
       
   372     RWindow *rWindow = static_cast<RWindow *>(effectiveWinId()->DrawableWindow());
       
   373     const int positionForeground(0);
       
   374     // Now window ordinal position works with latest symbian release. So giving back this window
       
   375     // a FEP priority. This will enable this window to come on top of any softkeys.
       
   376     rWindow->SetOrdinalPosition(positionForeground, ECoeWinPriorityFep);
       
   377 #endif
       
   378 }
       
   379 
       
   380 void HbInputMainWindow::unlockFocus()
       
   381 {
       
   382     if (!isVisible())
       
   383         return;
       
   384 
       
   385     d_ptr->mIsInputWindowFocusLocked = false;
       
   386     if (d_ptr->mLastFocusedWidget) {
       
   387         qApp->setActiveWindow(d_ptr->mLastFocusedWidget);
       
   388     }
       
   389 }
       
   390 
   329 //EOF
   391 //EOF