src/hbcore/inputfw/hbinputmainwindow.cpp
changeset 21 4633027730f5
parent 7 923ff622b8b9
child 28 b7da29130b0e
--- a/src/hbcore/inputfw/hbinputmainwindow.cpp	Tue Jul 06 14:36:53 2010 +0300
+++ b/src/hbcore/inputfw/hbinputmainwindow.cpp	Wed Aug 18 10:05:37 2010 +0300
@@ -28,12 +28,12 @@
 #include <QGraphicsSceneMouseEvent>
 #include <QStyleOptionGraphicsItem>
 #include <QInputContext>
+#include <QPointer>
 
 #include "hbinputregioncollector_p.h"
 #include "hbinstance.h"
 #include "hbwidget.h"
 #include "hbview.h"
-#include "hbnamespace_p.h"
 #include "hbstackedlayout.h"
 
 #if defined (Q_OS_SYMBIAN)
@@ -52,6 +52,32 @@
 Q_DECLARE_TYPEINFO(TRect, Q_MOVABLE_TYPE);
 #endif
 
+
+class HbProxyWindow: public QWidget
+{
+public:
+    HbProxyWindow()
+    {
+        setGeometry(0,0,0,0);
+    }
+    void setWindow(QWidget* window)
+    {
+        this->window = window;
+        if (window) {
+            window->setParent(this);
+        }
+    }
+    ~HbProxyWindow()
+    {
+        if (window) {
+            window->setParent(0);
+        }
+    }
+private:
+    QPointer<QWidget> window;
+};
+
+
 class HbInputTransparentWindow : public HbWidget
 {
 public:
@@ -70,7 +96,7 @@
 HbInputTransparentWindow::HbInputTransparentWindow(QGraphicsItem *parent) :
     HbWidget(parent)
 {
-	setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, true);
+    setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, true);
 }
 
 
@@ -90,6 +116,28 @@
     painter->setCompositionMode(compositionMode);
 }
 
+class HbInputMainWindowPrivate
+{
+public:
+ HbInputMainWindowPrivate(HbInputMainWindow *owner)
+    :q_ptr(owner), mLastFocusedWidget(0), mSpellQueryLaunched(false), mProxyWindow(0), mIsInputWindowFocusLocked(false)
+    {
+    }
+    ~HbInputMainWindowPrivate();
+    
+    HbInputMainWindow *q_ptr;
+    QPointer<QWidget> mLastFocusedWidget;
+    QRegion mMask;
+    bool mSpellQueryLaunched;
+    QPointer<HbProxyWindow > mProxyWindow;
+    bool mIsInputWindowFocusLocked;
+};
+
+HbInputMainWindowPrivate::~HbInputMainWindowPrivate()
+{
+    delete mProxyWindow;
+}
+
 /*
 creates an instance of HbInputMainWindow.
 */
@@ -101,13 +149,13 @@
 
 HbInputMainWindow::~HbInputMainWindow()
 {
-    delete mProxyWindow;
+    delete d_ptr;
 }
 
 // constructor.
 HbInputMainWindow::HbInputMainWindow()
 // HbMainWindow creates a background QGraphicsItem, which has the background image. we need to hide it that.
-    : HbMainWindow(0, Hb::WindowFlagTransparent), mLastFocusedWidget(0), mSpellQueryLaunched(false), mProxyWindow(0)
+    : HbMainWindow(0, Hb::WindowFlagTransparent), d_ptr(new HbInputMainWindowPrivate(this))
 {
     // We need a window which is of type Qt::Window flag at the same time does not show
     // any decorators Qt::Tool seems to be the option, and we want this window to be always on top so Qt::WindowStaysOnTopHint.
@@ -157,24 +205,23 @@
 
 void HbInputMainWindow::updateRegion(QRegion region)
 {
-    mMask = region;
+    d_ptr->mMask = region;
 #if defined (Q_OS_SYMBIAN)
     RWindowBase *rwindow = effectiveWinId()->DrawableWindow();
     if (region.isEmpty()) {
         TRegionFix<1> tregion(TRect(TPoint(0, 0), TSize(0, 0)));
         rwindow->SetShape(tregion);
     } else {
-        // Using QVector assumes the memory layout is the same as RRegion
-        QVector<QRect> rects = region.rects();
-        QVector<TRect> trects(rects.count());
+        // Using QVector assumes the memory layout is the same as RRegion 
+        QVector<QRect> rects = region.rects(); 
+        QVector<TRect> trects(rects.count()); 
+        RRegion rregion;
         for (int i = 0; i < trects.count(); ++i) {
-            trects[i] = qt_QRect2TRect(rects.at(i));
+            rregion.AddRect(qt_QRect2TRect(rects.at(i)));
         }
-        RRegion rregion(trects.count(), trects.data());
-        if (!rregion.CheckError()) {
-            rwindow->SetShape(rregion);
-        }
-    }
+        if (!rregion.CheckError())
+            rwindow->SetShape(rregion); 
+   }
 #else
     setMask(region);
 #endif
@@ -188,8 +235,8 @@
 {
     switch (e->type()) {
     case QEvent::WindowActivate:
-        if (mLastFocusedWidget && !mSpellQueryLaunched) {
-            qApp->setActiveWindow(mLastFocusedWidget);
+        if (d_ptr->mLastFocusedWidget && !d_ptr->mIsInputWindowFocusLocked) {
+            qApp->setActiveWindow(d_ptr->mLastFocusedWidget);
         }
         break;
     default:
@@ -205,26 +252,6 @@
 */
 bool HbInputMainWindow::eventFilter(QObject *obj, QEvent *event)
 {
-    if (event->type() == QEvent::DynamicPropertyChange) {
-        const QString p = static_cast<QDynamicPropertyChangeEvent *>(event)->propertyName();
-        if (p == "SpellQueryLaunched") {
-            QVariant variant = obj->property("SpellQueryLaunched");
-            if (variant.isValid()) {
-                mSpellQueryLaunched = variant.toBool();
-                if (mSpellQueryLaunched) {
-                    qApp->setActiveWindow(this);
-                    setFocus(Qt::OtherFocusReason);
-                } else {
-                    if (mLastFocusedWidget) {
-                        qApp->setActiveWindow(mLastFocusedWidget);
-                    }
-                }
-            }
-            // return true as we are interested party!
-            return true;
-        }
-    }
-
     // we need to only check for spontaneous events.
     if (event->spontaneous() && (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease)) {
         QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
@@ -233,10 +260,14 @@
             // If it is a HbMainWindow then do not do any thing, as events will propagate
             // correctly. But when it is clicked inside application window then send the event to
             // viewport as we might want to close a popup.
-            if (!mMask.contains(mouseEvent->globalPos())) {
+            if (!d_ptr->mMask.contains(mouseEvent->globalPos())) {
                 qApp->sendEvent(viewport(), event);
             }
         }
+    } else if(event->spontaneous() && event->type() == QEvent::WindowActivate) {
+        if(d_ptr->mIsInputWindowFocusLocked && (qApp->activeWindow()!= this)) {
+            qApp->setActiveWindow(this);
+        }
     }
 
     return HbMainWindow::eventFilter(obj, event);
@@ -250,7 +281,7 @@
 void HbInputMainWindow::saveFocusWidget(QWidget * /*Old*/, QWidget *newFocus)
 {
     if (newFocus && !this->isAncestorOf(newFocus)) {
-        mLastFocusedWidget = newFocus;
+        d_ptr->mLastFocusedWidget = newFocus;
     }
 }
 
@@ -275,20 +306,21 @@
 
     HbInputRegionCollector::instance()->setEnabled(true);
     if (win && win->windowModality() != Qt::NonModal) {
-        if (!mProxyWindow) {
-            mProxyWindow = new HbProxyWindow();
+        if (!d_ptr->mProxyWindow) {
+            d_ptr->mProxyWindow = new HbProxyWindow();
         }
-        mProxyWindow->setWindow(this);
+        d_ptr->mProxyWindow->setWindow(this);
         // since the focused widget is inside a modal dialog which blocks events to other_window.
         // and since hbinputmainwindow also comes under the other_window. It does will not get the 
         // mouse click events.
-        mProxyWindow->setParent(win);
+        d_ptr->mProxyWindow->setParent(win);
         // setParent resets the window flags, so we have to set the flags once again before show() is called.
         setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Tool | Qt::FramelessWindowHint);
         show();
     } else {
-        if (mProxyWindow && mProxyWindow->isAncestorOf(this)) {
-            mProxyWindow->setWindow(0);
+        if (d_ptr->mProxyWindow && d_ptr->mProxyWindow->isAncestorOf(this)) {
+            d_ptr->mProxyWindow->setParent(0);
+            d_ptr->mProxyWindow->setWindow(0);
             setParent(0);
             // setParent resets the window flags, so we have to set the flags once again before show is called.
             setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Tool | Qt::FramelessWindowHint);
@@ -306,7 +338,7 @@
 
 void HbInputMainWindow::hideInputWindow()
 {
-    if (mSpellQueryLaunched) {
+    if (d_ptr->mIsInputWindowFocusLocked) {
         return;
     }
 
@@ -326,4 +358,34 @@
     qApp->removeEventFilter(this);
 }
 
+void HbInputMainWindow::lockFocus()
+{
+    // lock only when HbinputMainWindow is active.
+    if (!isVisible())
+        return;
+
+    d_ptr->mIsInputWindowFocusLocked = true;
+    setFocus(Qt::OtherFocusReason);
+    qApp->setActiveWindow(this);
+#if defined(Q_OS_SYMBIAN)
+    // this is done to come on top of all the controls in symbian OS, done to overlap soft keys as well.
+    RWindow *rWindow = static_cast<RWindow *>(effectiveWinId()->DrawableWindow());
+    const int positionForeground(0);
+    // Now window ordinal position works with latest symbian release. So giving back this window
+    // a FEP priority. This will enable this window to come on top of any softkeys.
+    rWindow->SetOrdinalPosition(positionForeground, ECoeWinPriorityFep);
+#endif
+}
+
+void HbInputMainWindow::unlockFocus()
+{
+    if (!isVisible())
+        return;
+
+    d_ptr->mIsInputWindowFocusLocked = false;
+    if (d_ptr->mLastFocusedWidget) {
+        qApp->setActiveWindow(d_ptr->mLastFocusedWidget);
+    }
+}
+
 //EOF