src/hbcore/inputfw/hbinputmainwindow.cpp
changeset 5 627c4a0fd0e7
child 6 c3690ec91ef8
equal deleted inserted replaced
3:11d3954df52a 5:627c4a0fd0e7
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (developer.feedback@nokia.com)
       
     6 **
       
     7 ** This file is part of the HbCore module of the UI Extensions for Mobile.
       
     8 **
       
     9 ** GNU Lesser General Public License Usage
       
    10 ** This file may be used under the terms of the GNU Lesser General Public
       
    11 ** License version 2.1 as published by the Free Software Foundation and
       
    12 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
       
    13 ** Please review the following information to ensure the GNU Lesser General
       
    14 ** Public License version 2.1 requirements will be met:
       
    15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    16 **
       
    17 ** In addition, as a special exception, Nokia gives you certain additional
       
    18 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    20 **
       
    21 ** If you have questions regarding the use of this file, please contact
       
    22 ** Nokia at developer.feedback@nokia.com.
       
    23 **
       
    24 ****************************************************************************/
       
    25 #include <QGraphicsWidget>
       
    26 #include <QGraphicsSceneMouseEvent>
       
    27 #include <QStyleOptionGraphicsItem>
       
    28 #include <QInputContext>
       
    29 
       
    30 #include "hbinputmainwindow_p.h"
       
    31 #include "hbinputregioncollector_p.h"
       
    32 #include "hbinstance.h"
       
    33 #include "hbwidget.h"
       
    34 #include "hbview.h"
       
    35 #include "hbnamespace_p.h"
       
    36 #include "hbview.h"
       
    37 #include "hbstackedlayout.h"
       
    38 
       
    39 #if defined (Q_OS_SYMBIAN)
       
    40 #include <coemain.h>
       
    41 #include <coecntrl.h>
       
    42 #include <e32cmn.h>
       
    43 
       
    44 TRect qt_QRect2TRect(const QRectF &rect)
       
    45 {
       
    46     TRect trect;
       
    47     trect.SetRect(rect.topLeft().x(), rect.topLeft().y(),
       
    48         rect.bottomRight().x() + 1, rect.bottomRight().y() + 1);
       
    49     return trect;
       
    50 }
       
    51 
       
    52 Q_DECLARE_TYPEINFO(TRect, Q_MOVABLE_TYPE);
       
    53 #endif
       
    54 
       
    55 class HbInputTransparentWindow : public HbWidget
       
    56 {
       
    57 public:
       
    58 
       
    59     HbInputTransparentWindow(QGraphicsItem *parent = 0);
       
    60     ~HbInputTransparentWindow();
       
    61     
       
    62     enum { Type = Hb::ItemType_TransparentWindow };
       
    63     int type() const { return Type; }
       
    64 
       
    65     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
       
    66 };
       
    67 
       
    68 HbInputTransparentWindow::HbInputTransparentWindow(QGraphicsItem *parent) :
       
    69     HbWidget(parent)
       
    70 {
       
    71 }
       
    72 
       
    73 
       
    74 /*!
       
    75     Destructs the transparent window.
       
    76  */
       
    77 HbInputTransparentWindow::~HbInputTransparentWindow()
       
    78 {
       
    79 }
       
    80 
       
    81 void HbInputTransparentWindow::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
       
    82 {
       
    83     Q_UNUSED(widget)
       
    84     QPainter::CompositionMode compositionMode = painter->compositionMode();
       
    85     painter->setCompositionMode(QPainter::CompositionMode_Source);
       
    86     painter->fillRect(option->exposedRect, QColor(0,0,0,0));
       
    87     painter->setCompositionMode(compositionMode);
       
    88 }
       
    89 
       
    90 /*
       
    91 creates an instance of HbInputMainWindow.
       
    92 */
       
    93 HbInputMainWindow *HbInputMainWindow::instance()
       
    94 {
       
    95     static HbInputMainWindow *mainWindow = new HbInputMainWindow();
       
    96     return mainWindow;
       
    97 }
       
    98 
       
    99 HbInputMainWindow::~HbInputMainWindow()
       
   100 {
       
   101 }
       
   102 
       
   103 // constructor.
       
   104 HbInputMainWindow::HbInputMainWindow()
       
   105 // HbMainWindow creates a background QGraphicsItem, which has the background image. we need to hide it that.
       
   106 :HbMainWindow(0, Hb::WindowFlagTransparent), mLastFocusedWidget(0), mSpellQueryLaunched(false)
       
   107 {
       
   108     // We need a window which is of type Qt::Window flag at the same time does not show
       
   109     // any decorators Qt::Tool seems to be the option, and we want this window to be always on top so Qt::WindowStaysOnTopHint.
       
   110     // And since transparency requires to have a frameless window we are setting that too.
       
   111     setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Tool | Qt::FramelessWindowHint);
       
   112 
       
   113     // By default QGraphicsView has a background which is white in color (Other controls eg. QPushButton 
       
   114     // have a grey background), we need to make that transparent too.
       
   115     setStyleSheet("background: transparent");
       
   116 
       
   117     // No fous is necessary as we dont want the hbmainwindw to steal focus.
       
   118     setFocusPolicy(Qt::NoFocus);
       
   119   
       
   120     // add transparency begin.
       
   121     HbView* view = new HbView;
       
   122     view->hideItems(Hb::AllItems);
       
   123     view->setContentFullScreen();
       
   124 
       
   125 #if defined (Q_OS_SYMBIAN)
       
   126     CCoeControl *c = effectiveWinId();
       
   127     c->SetFocusing(false);
       
   128     RWindow *rw = static_cast<RWindow*>(c->DrawableWindow());
       
   129     rw->SetRequiredDisplayMode( EColor16MA );
       
   130     TInt err = rw->SetTransparencyAlphaChannel();
       
   131     if ( err == KErrNone ) {
       
   132         rw->SetBackgroundColor(~0);
       
   133     }
       
   134 #endif // Q_OS_SYMBIAN
       
   135 
       
   136     HbInputTransparentWindow *transparentWindow = new HbInputTransparentWindow;
       
   137     HbStackedLayout *stackedLayout = new HbStackedLayout;
       
   138     stackedLayout->addItem(transparentWindow);
       
   139     view->setLayout(stackedLayout);
       
   140     addView(view);
       
   141     // add transparency ends.
       
   142 
       
   143     connect(HbInputRegionCollector::instance(), SIGNAL(updateRegion(QRegion)), this, SLOT(updateRegion(QRegion)));
       
   144 
       
   145     // QApplication signal for getting notification of any focus change. If therer
       
   146     // is a switch between application window and HbInputMainWindow then we need to 
       
   147     // set the focus back to the application window, if we don't do that it will
       
   148     // result in focusLost call inside framework.
       
   149     connect(qApp, SIGNAL(focusChanged(QWidget *, QWidget *)),
       
   150         this, SLOT(saveFocusWidget(QWidget *, QWidget *)));
       
   151 }
       
   152 
       
   153 
       
   154 void HbInputMainWindow::updateRegion(QRegion region)
       
   155 {
       
   156     mMask = region;
       
   157 #if defined (Q_OS_SYMBIAN)
       
   158     RWindowBase *rwindow = effectiveWinId()->DrawableWindow();
       
   159     if (region.isEmpty()) { 
       
   160         TRegionFix<1> tregion(TRect(TPoint(0, 0), TSize(0,0))); 
       
   161         rwindow->SetShape(tregion); 
       
   162     } else {
       
   163         // Using QVector assumes the memory layout is the same as RRegion 
       
   164         QVector<QRect> rects = region.rects(); 
       
   165         QVector<TRect> trects(rects.count()); 
       
   166         for (int i = 0; i < trects.count(); ++i) 
       
   167             trects[i] = qt_QRect2TRect(rects.at(i)); 
       
   168         RRegion rregion(trects.count(), trects.data()); 
       
   169         if (!rregion.CheckError())
       
   170             rwindow->SetShape(rregion); 
       
   171    }
       
   172 #else
       
   173     setMask(region);
       
   174 #endif
       
   175 }
       
   176 
       
   177 
       
   178 /*
       
   179 we should always set the focus back to the application window.
       
   180 */
       
   181 bool HbInputMainWindow::event(QEvent *e)
       
   182 {
       
   183     switch (e->type()) {
       
   184     case QEvent::WindowActivate:
       
   185         if (mLastFocusedWidget && !mSpellQueryLaunched) {
       
   186             qApp->setActiveWindow(mLastFocusedWidget);
       
   187         }
       
   188         break;
       
   189     default:
       
   190         break;
       
   191     }
       
   192     return HbMainWindow::event(e);
       
   193 }
       
   194 
       
   195 /*
       
   196 This function checks for any modal dialog present in the HbGraphicsScene by checking DynamicPropertyChange
       
   197 and blocks the events to the application window by launching a widget which sits exactly in between the applicaion
       
   198 and HbInputMainWindow.
       
   199 */
       
   200 bool HbInputMainWindow::eventFilter(QObject *obj, QEvent *event)
       
   201 {
       
   202     if (event->type() == QEvent::DynamicPropertyChange) {
       
   203         const QString p = static_cast<QDynamicPropertyChangeEvent *>(event)->propertyName();
       
   204         if (p == "SpellQueryLaunched") {
       
   205             QVariant variant = obj->property("SpellQueryLaunched");
       
   206             if (variant.isValid()) {
       
   207                 mSpellQueryLaunched = variant.toBool();
       
   208                 if (mSpellQueryLaunched) {
       
   209                     qApp->setActiveWindow(this);
       
   210                     setFocus(Qt::OtherFocusReason);
       
   211                 } else {
       
   212                     if (mLastFocusedWidget) {
       
   213                         qApp->setActiveWindow(mLastFocusedWidget);
       
   214                     }
       
   215                 }
       
   216             }
       
   217             // return true as we are interested party!
       
   218             return true;
       
   219         }
       
   220     }
       
   221 
       
   222     // we need to only check for spontaneous events. 
       
   223     if (event->spontaneous() && (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease)) {
       
   224         QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
       
   225         if (mouseEvent) {
       
   226             // get the top level widget at the point, and see if that widget is a HbMainWindow,
       
   227             // If it is a HbMainWindow then do not do any thing, as events will propagate 
       
   228             // correctly. But when it is clicked inside application window then send the event to 
       
   229             // viewport as we might want to close a popup.
       
   230             if (!mMask.contains(mouseEvent->globalPos())) {
       
   231                 qApp->sendEvent(viewport(), event);
       
   232             }
       
   233         }
       
   234     }
       
   235 
       
   236     return HbMainWindow::eventFilter(obj, event);
       
   237 }
       
   238 
       
   239 /*
       
   240 Since hbmainwindow is overlapped on top of the application window, we need to 
       
   241 set the focus back to the application window. Not doing so will result in a focus
       
   242 lost.
       
   243 */
       
   244 void HbInputMainWindow::saveFocusWidget(QWidget * /*Old*/, QWidget *newFocus)
       
   245 {
       
   246     if (newFocus && !this->isAncestorOf(newFocus)) {
       
   247         mLastFocusedWidget = newFocus;
       
   248     }
       
   249 }
       
   250 
       
   251 void HbInputMainWindow::showInputWindow()
       
   252 {
       
   253     // installing event filter to the application.. this is needed to get 
       
   254     // the events happening in other vanilla windows.
       
   255     qApp->installEventFilter(this);
       
   256 
       
   257 #ifdef Q_WS_WIN
       
   258     // As in windows OS HbMainWindow can come anywhere on the screen.
       
   259     // so we need to launch main window exactly at the top windows position.
       
   260     QInputContext *ic = qApp->inputContext();
       
   261     QWidget *fw = ic ? ic->focusWidget() : 0 ;
       
   262     if (fw) {
       
   263         QWidget *win = fw->window();
       
   264         if (win) {
       
   265             move(win->frameGeometry().x(), win->pos().y());
       
   266         }
       
   267     }
       
   268 #endif
       
   269 
       
   270     HbInputRegionCollector::instance()->setEnabled(true);
       
   271     show();
       
   272 
       
   273 #if defined(Q_OS_SYMBIAN)
       
   274     // this is done to come on top of all the controls in symbian OS, done to overlap soft keys as well.
       
   275     RWindow * rWindow = static_cast<RWindow *>(effectiveWinId()->DrawableWindow());
       
   276     const int positionForeground(0);
       
   277     rWindow->SetOrdinalPosition(positionForeground,
       
   278         ECoeWinPriorityAlwaysAtFront);
       
   279 #endif
       
   280 }
       
   281 
       
   282 void HbInputMainWindow::hideInputWindow()
       
   283 {
       
   284     if (mSpellQueryLaunched) {
       
   285         return;
       
   286     }
       
   287 
       
   288     if (isVisible()) {
       
   289         hide();
       
   290 #if defined(Q_OS_SYMBIAN)
       
   291         RWindow *rWindow = static_cast<RWindow *>(effectiveWinId()->DrawableWindow());
       
   292         const int positionBackground(-1);
       
   293         rWindow->SetOrdinalPosition(positionBackground, ECoeWinPriorityNormal);
       
   294 #endif
       
   295     }
       
   296     
       
   297     HbInputRegionCollector::instance()->setEnabled(false);
       
   298 
       
   299     // installing event filter to the application.. this is needed to get 
       
   300     // the events happening in other vanilla windows.
       
   301     qApp->removeEventFilter(this);
       
   302 }
       
   303 
       
   304 //EOF