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); |
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 |
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 } |
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(); |
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 |