src/hbcore/inputfw/hbinputmainwindow.cpp
changeset 6 c3690ec91ef8
parent 5 627c4a0fd0e7
child 7 923ff622b8b9
--- a/src/hbcore/inputfw/hbinputmainwindow.cpp	Fri Jun 11 13:58:22 2010 +0300
+++ b/src/hbcore/inputfw/hbinputmainwindow.cpp	Wed Jun 23 18:33:25 2010 +0300
@@ -22,18 +22,18 @@
 ** Nokia at developer.feedback@nokia.com.
 **
 ****************************************************************************/
+#include "hbinputmainwindow_p.h"
+
 #include <QGraphicsWidget>
 #include <QGraphicsSceneMouseEvent>
 #include <QStyleOptionGraphicsItem>
 #include <QInputContext>
 
-#include "hbinputmainwindow_p.h"
 #include "hbinputregioncollector_p.h"
 #include "hbinstance.h"
 #include "hbwidget.h"
 #include "hbview.h"
 #include "hbnamespace_p.h"
-#include "hbview.h"
 #include "hbstackedlayout.h"
 
 #if defined (Q_OS_SYMBIAN)
@@ -45,7 +45,7 @@
 {
     TRect trect;
     trect.SetRect(rect.topLeft().x(), rect.topLeft().y(),
-        rect.bottomRight().x() + 1, rect.bottomRight().y() + 1);
+                  rect.bottomRight().x() + 1, rect.bottomRight().y() + 1);
     return trect;
 }
 
@@ -58,9 +58,11 @@
 
     HbInputTransparentWindow(QGraphicsItem *parent = 0);
     ~HbInputTransparentWindow();
-    
+
     enum { Type = Hb::ItemType_TransparentWindow };
-    int type() const { return Type; }
+    int type() const {
+        return Type;
+    }
 
     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
 };
@@ -68,6 +70,7 @@
 HbInputTransparentWindow::HbInputTransparentWindow(QGraphicsItem *parent) :
     HbWidget(parent)
 {
+    setFlag(QGraphicsItem::ItemHasNoContents, false);
 }
 
 
@@ -83,7 +86,7 @@
     Q_UNUSED(widget)
     QPainter::CompositionMode compositionMode = painter->compositionMode();
     painter->setCompositionMode(QPainter::CompositionMode_Source);
-    painter->fillRect(option->exposedRect, QColor(0,0,0,0));
+    painter->fillRect(option->exposedRect, QColor(0, 0, 0, 0));
     painter->setCompositionMode(compositionMode);
 }
 
@@ -98,37 +101,38 @@
 
 HbInputMainWindow::~HbInputMainWindow()
 {
+    delete mProxyWindow;
 }
 
 // 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)
+    : HbMainWindow(0, Hb::WindowFlagTransparent), mLastFocusedWidget(0), mSpellQueryLaunched(false), mProxyWindow(0)
 {
     // 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.
     // And since transparency requires to have a frameless window we are setting that too.
     setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Tool | Qt::FramelessWindowHint);
 
-    // By default QGraphicsView has a background which is white in color (Other controls eg. QPushButton 
+    // By default QGraphicsView has a background which is white in color (Other controls eg. QPushButton
     // have a grey background), we need to make that transparent too.
     setStyleSheet("background: transparent");
 
-    // No fous is necessary as we dont want the hbmainwindw to steal focus.
+    // No focus is necessary as we don't want the hbmainwindw to steal focus.
     setFocusPolicy(Qt::NoFocus);
-  
+
     // add transparency begin.
-    HbView* view = new HbView;
+    HbView *view = new HbView;
     view->hideItems(Hb::AllItems);
     view->setContentFullScreen();
 
 #if defined (Q_OS_SYMBIAN)
     CCoeControl *c = effectiveWinId();
     c->SetFocusing(false);
-    RWindow *rw = static_cast<RWindow*>(c->DrawableWindow());
-    rw->SetRequiredDisplayMode( EColor16MA );
+    RWindow *rw = static_cast<RWindow *>(c->DrawableWindow());
+    rw->SetRequiredDisplayMode(EColor16MA);
     TInt err = rw->SetTransparencyAlphaChannel();
-    if ( err == KErrNone ) {
+    if (err == KErrNone) {
         rw->SetBackgroundColor(~0);
     }
 #endif // Q_OS_SYMBIAN
@@ -143,11 +147,11 @@
     connect(HbInputRegionCollector::instance(), SIGNAL(updateRegion(QRegion)), this, SLOT(updateRegion(QRegion)));
 
     // QApplication signal for getting notification of any focus change. If therer
-    // is a switch between application window and HbInputMainWindow then we need to 
+    // is a switch between application window and HbInputMainWindow then we need to
     // set the focus back to the application window, if we don't do that it will
     // result in focusLost call inside framework.
     connect(qApp, SIGNAL(focusChanged(QWidget *, QWidget *)),
-        this, SLOT(saveFocusWidget(QWidget *, QWidget *)));
+            this, SLOT(saveFocusWidget(QWidget *, QWidget *)));
 }
 
 
@@ -156,19 +160,21 @@
     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); 
+    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()); 
-        for (int i = 0; i < trects.count(); ++i) 
-            trects[i] = qt_QRect2TRect(rects.at(i)); 
-        RRegion rregion(trects.count(), trects.data()); 
-        if (!rregion.CheckError())
-            rwindow->SetShape(rregion); 
-   }
+        // Using QVector assumes the memory layout is the same as RRegion
+        QVector<QRect> rects = region.rects();
+        QVector<TRect> trects(rects.count());
+        for (int i = 0; i < trects.count(); ++i) {
+            trects[i] = qt_QRect2TRect(rects.at(i));
+        }
+        RRegion rregion(trects.count(), trects.data());
+        if (!rregion.CheckError()) {
+            rwindow->SetShape(rregion);
+        }
+    }
 #else
     setMask(region);
 #endif
@@ -219,13 +225,13 @@
         }
     }
 
-    // we need to only check for spontaneous events. 
+    // 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);
         if (mouseEvent) {
             // get the top level widget at the point, and see if that widget is a HbMainWindow,
-            // 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 
+            // 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())) {
                 qApp->sendEvent(viewport(), event);
@@ -237,7 +243,7 @@
 }
 
 /*
-Since hbmainwindow is overlapped on top of the application window, we need to 
+Since hbmainwindow is overlapped on top of the application window, we need to
 set the focus back to the application window. Not doing so will result in a focus
 lost.
 */
@@ -250,32 +256,52 @@
 
 void HbInputMainWindow::showInputWindow()
 {
-    // installing event filter to the application.. this is needed to get 
+    // installing event filter to the application.. this is needed to get
     // the events happening in other vanilla windows.
     qApp->installEventFilter(this);
-
+    QInputContext *ic = qApp->inputContext();
+    QWidget *fw = ic ? ic->focusWidget() : 0 ;
+    QWidget *win = 0;
+    if (fw) {
+       win = fw->window();
+    }
 #ifdef Q_WS_WIN
     // As in windows OS HbMainWindow can come anywhere on the screen.
     // so we need to launch main window exactly at the top windows position.
-    QInputContext *ic = qApp->inputContext();
-    QWidget *fw = ic ? ic->focusWidget() : 0 ;
-    if (fw) {
-        QWidget *win = fw->window();
-        if (win) {
-            move(win->frameGeometry().x(), win->pos().y());
-        }
+    if (win) {
+        move(win->frameGeometry().x(), win->pos().y());
     }
 #endif
 
     HbInputRegionCollector::instance()->setEnabled(true);
-    show();
+    if (win && win->windowModality() != Qt::NonModal) {
+        if (!mProxyWindow) {
+            mProxyWindow = new HbProxyWindow();
+        }
+        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);
+        // 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);
+            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);
+        }
+        show();
+    }
 
 #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());
+    RWindow *rWindow = static_cast<RWindow *>(effectiveWinId()->DrawableWindow());
     const int positionForeground(0);
     rWindow->SetOrdinalPosition(positionForeground,
-        ECoeWinPriorityAlwaysAtFront);
+                                ECoeWinPriorityAlwaysAtFront);
 #endif
 }
 
@@ -293,10 +319,10 @@
         rWindow->SetOrdinalPosition(positionBackground, ECoeWinPriorityNormal);
 #endif
     }
-    
+
     HbInputRegionCollector::instance()->setEnabled(false);
 
-    // installing event filter to the application.. this is needed to get 
+    // installing event filter to the application.. this is needed to get
     // the events happening in other vanilla windows.
     qApp->removeEventFilter(this);
 }