--- a/src/hbcore/inputfw/hbinputmainwindow.cpp Mon Oct 04 17:49:30 2010 +0300
+++ b/src/hbcore/inputfw/hbinputmainwindow.cpp Mon Oct 18 18:23:13 2010 +0300
@@ -28,13 +28,14 @@
#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"
+#include "hbpopup.h"
#if defined (Q_OS_SYMBIAN)
#include <coemain.h>
@@ -52,6 +53,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 +97,7 @@
HbInputTransparentWindow::HbInputTransparentWindow(QGraphicsItem *parent) :
HbWidget(parent)
{
- setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, true);
+ setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, true);
}
@@ -90,6 +117,48 @@
painter->setCompositionMode(compositionMode);
}
+class HbInputMainWindowPrivate
+{
+public:
+ HbInputMainWindowPrivate(HbInputMainWindow *owner)
+ :q_ptr(owner), mLastFocusedWidget(0), mSpellQueryLaunched(false), mProxyWindow(0), mIsInputWindowFocusLocked(false)
+ {
+ }
+ ~HbInputMainWindowPrivate();
+ void dismissNonModalDialogs();
+ HbInputMainWindow *q_ptr;
+ QPointer<QWidget> mLastFocusedWidget;
+ QRegion mMask;
+ bool mSpellQueryLaunched;
+ QPointer<HbProxyWindow > mProxyWindow;
+ bool mIsInputWindowFocusLocked;
+};
+
+/*
+Dismisses all non-modal dialogs with tap-outside dismiss policy which are attached to the region collector.
+*/
+void HbInputMainWindowPrivate::dismissNonModalDialogs()
+{
+ HbInputRegionCollectorPrivate *const regionColPrivate = HbInputRegionCollector::instance()->d_ptr;
+ if (regionColPrivate->mEnabled && !regionColPrivate->mModalDialogs) {
+ QList<HbWidgetFilterList> list = regionColPrivate->mInputWidgets;
+ for (int i = 0; i < list.size(); ++i) {
+ if (list.at(i).mIsVisible) {
+ HbPopup *popup = qobject_cast<HbPopup *>(list.at(i).mWidget);
+ // dismiss non-modal dialogs, which have tap-outside dismiss policy.
+ if (popup && (popup->dismissPolicy() & HbPopup::TapOutside) && !popup->isModal()) {
+ popup->close();
+ }
+ }
+ }
+ }
+}
+
+HbInputMainWindowPrivate::~HbInputMainWindowPrivate()
+{
+ delete mProxyWindow;
+}
+
/*
creates an instance of HbInputMainWindow.
*/
@@ -101,13 +170,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 +226,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 +256,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,38 +273,23 @@
*/
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)) {
+ if (event->spontaneous() && (event->type() == QEvent::MouseButtonPress)) {
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
- // viewport as we might want to close a popup.
- if (!mMask.contains(mouseEvent->globalPos())) {
- qApp->sendEvent(viewport(), event);
+ // when we have only non-modal dialogs launched inside HbInputMainWindow, for instance exactword popup.
+ // in that case HbInputMainWindow's window region is such that it only has exactword popup and the
+ // vkb. And clicking anywhere other than vkb and exactword popup will not be know to HbInputMainWindow.
+ // With the help of this eventfilter we will come to know if there are any click events outside
+ // of HbInputMainWindow's region and we should close all the non-modal with tapoutside dismiss policy.
+ if (!d_ptr->mMask.contains(mouseEvent->globalPos())) {
+ d_ptr->dismissNonModalDialogs();
}
}
+ } 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 +303,7 @@
void HbInputMainWindow::saveFocusWidget(QWidget * /*Old*/, QWidget *newFocus)
{
if (newFocus && !this->isAncestorOf(newFocus)) {
- mLastFocusedWidget = newFocus;
+ d_ptr->mLastFocusedWidget = newFocus;
}
}
@@ -275,20 +328,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 +360,7 @@
void HbInputMainWindow::hideInputWindow()
{
- if (mSpellQueryLaunched) {
+ if (d_ptr->mIsInputWindowFocusLocked) {
return;
}
@@ -326,4 +380,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);
+#endif
+}
+
+void HbInputMainWindow::unlockFocus()
+{
+ if (!isVisible())
+ return;
+
+ d_ptr->mIsInputWindowFocusLocked = false;
+ if (d_ptr->mLastFocusedWidget) {
+ qApp->setActiveWindow(d_ptr->mLastFocusedWidget);
+ }
+}
+
//EOF