|
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 <QInputMethodEvent> |
|
26 #include <QGraphicsWidget> |
|
27 #include <QGraphicsScene> |
|
28 #include <QGraphicsProxyWidget> |
|
29 #include <QLineEdit> |
|
30 #include <QTextEdit> |
|
31 #include <QPointer> |
|
32 |
|
33 #include "hbinputmethod.h" |
|
34 #include "hbinputfocusobject.h" |
|
35 #include "hbinputeditorinterface.h" |
|
36 #include "hbinputvkbhost.h" |
|
37 #include "hbinputstandardfilters.h" |
|
38 |
|
39 const qreal HbInputVkbZPlaneEpsilon = 0.5; |
|
40 |
|
41 /*! |
|
42 @alpha |
|
43 @hbcore |
|
44 \class HbInputFocusObject |
|
45 \brief A helper class for accessing editor widget in abstract way. |
|
46 |
|
47 This class is input method side API for accessing editor widgets. It was added because |
|
48 in some cases Qt's QInputMethodEvent/inputMethodQuery system is not enough for our purposes |
|
49 and direct access via type casting between QWidget and QGraphiscWidget based editors is needed. |
|
50 |
|
51 This class is purely a convenience or helper type of class in nature. Everything |
|
52 it does, can be done directly in input method code as well. It just wraps |
|
53 most commonly used operations behind one API to avoid duplicate code in input method implementations. |
|
54 |
|
55 Application developers should never need to use this class, it is for input method developers only. |
|
56 |
|
57 \sa HbEditorInterface |
|
58 */ |
|
59 |
|
60 |
|
61 |
|
62 /// @cond |
|
63 |
|
64 /* |
|
65 This function ensures cursor visibility for known editor types. |
|
66 */ |
|
67 void ensureCursorVisible(QObject *widget) |
|
68 { |
|
69 if (widget) { |
|
70 QTextEdit *textEdit = qobject_cast<QTextEdit*>(widget); |
|
71 if (textEdit) { |
|
72 textEdit->ensureCursorVisible(); |
|
73 } |
|
74 } |
|
75 } |
|
76 |
|
77 |
|
78 class HbInputFocusObjectPrivate |
|
79 { |
|
80 public: |
|
81 HbInputFocusObjectPrivate(QObject *focusedObject) |
|
82 : mFocusedObject(focusedObject), |
|
83 mEditorInterface(focusedObject) |
|
84 {} |
|
85 |
|
86 public: |
|
87 QPointer<QObject> mFocusedObject; |
|
88 HbEditorInterface mEditorInterface; |
|
89 QString mPreEditString; |
|
90 }; |
|
91 |
|
92 |
|
93 /// @endcond |
|
94 |
|
95 HbInputFocusObject::HbInputFocusObject(QObject *focusedObject) |
|
96 : d_ptr(new HbInputFocusObjectPrivate(focusedObject)) |
|
97 { |
|
98 } |
|
99 |
|
100 |
|
101 HbInputFocusObject::~HbInputFocusObject() |
|
102 { |
|
103 delete d_ptr; |
|
104 } |
|
105 |
|
106 /*! |
|
107 Creates an input method event where given string is a pre-edit string and sends |
|
108 it to focused editor. See QInputMethodEvent for more information on pre-edit strings. |
|
109 */ |
|
110 void HbInputFocusObject::sendPreEditString(const QString& string) |
|
111 { |
|
112 QList<QInputMethodEvent::Attribute> list; |
|
113 QInputMethodEvent event(string, list); |
|
114 sendEvent(event); |
|
115 } |
|
116 |
|
117 /*! |
|
118 Creates an input method event where given string is a commit string and sends |
|
119 it to focused editor. See QInputMethodEvent for more information on commit strings. |
|
120 */ |
|
121 void HbInputFocusObject::sendCommitString(const QString& string) |
|
122 { |
|
123 QList<QInputMethodEvent::Attribute> list; |
|
124 QInputMethodEvent event(QString(), list); |
|
125 event.setCommitString(string); |
|
126 sendEvent(event); |
|
127 } |
|
128 |
|
129 /*! |
|
130 Sends given event to focused editor. |
|
131 */ |
|
132 void HbInputFocusObject::sendEvent(QEvent& event) |
|
133 { |
|
134 Q_D(HbInputFocusObject); |
|
135 |
|
136 if (event.type() == QEvent::InputMethod) { |
|
137 QInputMethodEvent* imEvent = static_cast<QInputMethodEvent*>(&event); |
|
138 if (imEvent->commitString().size() > 0) { |
|
139 d->mPreEditString = QString(); |
|
140 } else { |
|
141 d->mPreEditString = imEvent->preeditString(); |
|
142 } |
|
143 } |
|
144 |
|
145 if (d->mFocusedObject) { |
|
146 QApplication::sendEvent(d->mFocusedObject, &event); |
|
147 if (event.type() == QEvent::InputMethod) { |
|
148 // Currently in Qt, QTextEdit doesn't ensure cursor visibility |
|
149 // in case we are sending text in the form of QInputMethodEvent. So we need |
|
150 // to call QTextEdit:ensureCursorVisible() here till we get a fix from Qt. |
|
151 ensureCursorVisible(d->mFocusedObject); |
|
152 } |
|
153 } |
|
154 } |
|
155 |
|
156 /*! |
|
157 Posts given event to focused editor in an asynchronous manner. |
|
158 */ |
|
159 void HbInputFocusObject::postEvent(QEvent& event) |
|
160 { |
|
161 Q_D(HbInputFocusObject); |
|
162 |
|
163 if (event.type() == QEvent::InputMethod) { |
|
164 QInputMethodEvent* imEvent = static_cast<QInputMethodEvent*>(&event); |
|
165 if (imEvent->commitString().size() > 0) { |
|
166 d->mPreEditString = QString(); |
|
167 } else { |
|
168 d->mPreEditString = imEvent->preeditString(); |
|
169 } |
|
170 } |
|
171 |
|
172 if (d->mFocusedObject) { |
|
173 QApplication::postEvent(d->mFocusedObject, &event); |
|
174 } |
|
175 } |
|
176 |
|
177 /*! |
|
178 Passes input method query to focused editor. |
|
179 */ |
|
180 QVariant HbInputFocusObject::inputMethodQuery(Qt::InputMethodQuery query) const |
|
181 { |
|
182 Q_D(const HbInputFocusObject); |
|
183 |
|
184 QGraphicsWidget *graphicsWidget = qobject_cast<QGraphicsWidget*>(d->mFocusedObject); |
|
185 if (graphicsWidget && graphicsWidget->scene()) { |
|
186 return graphicsWidget->scene()->inputMethodQuery(query); |
|
187 } |
|
188 |
|
189 QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject); |
|
190 if (widget) { |
|
191 return widget->inputMethodQuery(query); |
|
192 } |
|
193 |
|
194 return QVariant(); |
|
195 } |
|
196 |
|
197 /*! |
|
198 Returns editor cursor position by sending Qt::ImCursorPosition event to it. |
|
199 */ |
|
200 int HbInputFocusObject::editorCursorPosition() |
|
201 { |
|
202 return inputMethodQuery(Qt::ImCursorPosition).toInt(); |
|
203 } |
|
204 |
|
205 /*! |
|
206 Returns editor's font by sending Qt::ImFont input method query to it. |
|
207 */ |
|
208 QFont HbInputFocusObject::editorFont() |
|
209 { |
|
210 return inputMethodQuery(Qt::ImFont).value<QFont>(); |
|
211 } |
|
212 |
|
213 /*! |
|
214 Returns text selection by sending Qt::ImCurrentTextSelection to editor. |
|
215 */ |
|
216 QString HbInputFocusObject::editorTextSelection() |
|
217 { |
|
218 return inputMethodQuery(Qt::ImCurrentSelection).toString(); |
|
219 } |
|
220 |
|
221 /*! |
|
222 Returns text surrounding the editor cursor position by sending Qt::ImSurroundingText event to editor. |
|
223 */ |
|
224 QString HbInputFocusObject::editorSurroundingText() |
|
225 { |
|
226 return inputMethodQuery(Qt::ImSurroundingText).toString(); |
|
227 } |
|
228 |
|
229 /*! |
|
230 Returns editor interface object pointing to focused editor. |
|
231 */ |
|
232 HbEditorInterface& HbInputFocusObject::editorInterface() const |
|
233 { |
|
234 return d_ptr->mEditorInterface; |
|
235 } |
|
236 |
|
237 /*! |
|
238 Sends left arrow key press to focused editor. |
|
239 */ |
|
240 void HbInputFocusObject::cursorLeft(int modifiers) |
|
241 { |
|
242 QKeyEvent keyEvent(QEvent::KeyPress, Qt::Key_Left, (Qt::KeyboardModifiers)modifiers); |
|
243 sendEvent(keyEvent); |
|
244 } |
|
245 |
|
246 /*! |
|
247 Sends right arrow key press to focused editor. |
|
248 */ |
|
249 void HbInputFocusObject::cursorRight(int modifiers) |
|
250 { |
|
251 QKeyEvent keyEvent(QEvent::KeyPress, Qt::Key_Right, (Qt::KeyboardModifiers)modifiers); |
|
252 sendEvent(keyEvent); |
|
253 } |
|
254 |
|
255 /*! |
|
256 Removes focus from the editor. |
|
257 */ |
|
258 void HbInputFocusObject::releaseFocus() |
|
259 { |
|
260 Q_D(HbInputFocusObject); |
|
261 |
|
262 QGraphicsWidget *graphicsWidget = qobject_cast<QGraphicsWidget*>(d->mFocusedObject); |
|
263 if (!graphicsWidget) { |
|
264 QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject); |
|
265 if (widget) { |
|
266 if (widget->graphicsProxyWidget()) { |
|
267 graphicsWidget = widget->graphicsProxyWidget(); |
|
268 } else { |
|
269 widget->clearFocus(); |
|
270 } |
|
271 } |
|
272 } |
|
273 |
|
274 if (graphicsWidget && graphicsWidget->scene()) { |
|
275 graphicsWidget->scene()->setFocusItem(0); |
|
276 } |
|
277 } |
|
278 |
|
279 /*! |
|
280 Runs the given character through active input filter and commits it if it was accepted. |
|
281 Returns true if the character was accepted. |
|
282 */ |
|
283 bool HbInputFocusObject::filterAndCommitCharacter(QChar aChar) |
|
284 { |
|
285 // Two pass filtering because this may be a case constrained editor |
|
286 // with a filter. |
|
287 Qt::InputMethodHints hints = inputMethodHints(); |
|
288 if (hints & Qt::ImhLowercaseOnly) { |
|
289 if (!HbInputLowerCaseFilter::instance()->filter(aChar)) { |
|
290 return false; |
|
291 } |
|
292 } else if (hints & Qt::ImhUppercaseOnly) { |
|
293 if (!HbInputUpperCaseFilter::instance()->filter(aChar)) { |
|
294 return false; |
|
295 } |
|
296 } |
|
297 |
|
298 HbInputFilter *filter = editorInterface().filter(); |
|
299 if (filter) { |
|
300 if (!filter->filter(aChar)) { |
|
301 return false; |
|
302 } |
|
303 } |
|
304 |
|
305 QString cString; |
|
306 cString.append(aChar); |
|
307 sendCommitString(cString); |
|
308 |
|
309 return true; |
|
310 } |
|
311 |
|
312 /*! |
|
313 Returns editor widget geometry. In case of QGraphicsWidget, the returned value is in scene coordinates. |
|
314 */ |
|
315 QRectF HbInputFocusObject::editorGeometry() const |
|
316 { |
|
317 Q_D(const HbInputFocusObject); |
|
318 |
|
319 QGraphicsWidget *graphicsWidget = qobject_cast<QGraphicsWidget*>(d->mFocusedObject); |
|
320 if (!graphicsWidget) { |
|
321 QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject); |
|
322 if (widget) { |
|
323 if (widget->graphicsProxyWidget()) { |
|
324 graphicsWidget = widget->graphicsProxyWidget(); |
|
325 } else { |
|
326 return widget->geometry(); |
|
327 } |
|
328 } |
|
329 } |
|
330 |
|
331 if (graphicsWidget) { |
|
332 return QRectF(graphicsWidget->scenePos(), graphicsWidget->size()); |
|
333 } |
|
334 |
|
335 return QRectF(); |
|
336 } |
|
337 |
|
338 /*! |
|
339 Returns cursor micro focus by sending Qt::ImMicroFocus to focused editor. |
|
340 In case of QGraphicsWidget, the returned rectangle is in scene coordinates. |
|
341 */ |
|
342 QRectF HbInputFocusObject::microFocus() const |
|
343 { |
|
344 return inputMethodQuery(Qt::ImMicroFocus).toRectF(); |
|
345 } |
|
346 |
|
347 /*! |
|
348 Returns active pre-edit string. Note that this method works only if the pre-edit |
|
349 string was set by using this class. |
|
350 */ |
|
351 QString HbInputFocusObject::preEditString() const |
|
352 { |
|
353 Q_D(const HbInputFocusObject); |
|
354 return d->mPreEditString; |
|
355 } |
|
356 |
|
357 /*! |
|
358 Returns the Z-value that should be used with virtual keyboard widget. Usually only HbVkbHost |
|
359 needs this value. |
|
360 */ |
|
361 qreal HbInputFocusObject::findVkbZValue() const |
|
362 { |
|
363 Q_D(const HbInputFocusObject); |
|
364 |
|
365 QGraphicsWidget *editorWidget = qobject_cast<QGraphicsWidget*>(d->mFocusedObject); |
|
366 if (!editorWidget) { |
|
367 QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject); |
|
368 if (widget) { |
|
369 editorWidget = widget->graphicsProxyWidget(); |
|
370 } |
|
371 } |
|
372 |
|
373 if (editorWidget) { |
|
374 qreal result = editorWidget->zValue(); |
|
375 for (QGraphicsWidget *parent = editorWidget->parentWidget(); parent; parent = parent->parentWidget()) { |
|
376 result += parent->zValue(); |
|
377 } |
|
378 |
|
379 return result + HbInputVkbZPlaneEpsilon; |
|
380 } |
|
381 |
|
382 return 0.0; |
|
383 } |
|
384 |
|
385 /*! |
|
386 Returns input method hints. See QWidget and QGraphicsWidget documentation for more information. |
|
387 */ |
|
388 Qt::InputMethodHints HbInputFocusObject::inputMethodHints() const |
|
389 { |
|
390 Q_D(const HbInputFocusObject); |
|
391 |
|
392 QGraphicsWidget *graphicsWidget = qobject_cast<QGraphicsWidget*>(d->mFocusedObject); |
|
393 if (graphicsWidget) { |
|
394 return graphicsWidget->inputMethodHints(); |
|
395 } |
|
396 |
|
397 QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject); |
|
398 if (widget) { |
|
399 return widget->inputMethodHints(); |
|
400 } |
|
401 |
|
402 return Qt::ImhNone; |
|
403 } |
|
404 |
|
405 /*! |
|
406 Sets input method hints. See QWidget and QGraphicsWidget documentation for more information. |
|
407 */ |
|
408 void HbInputFocusObject::setInputMethodHints(Qt::InputMethodHints hints) |
|
409 { |
|
410 Q_D(HbInputFocusObject); |
|
411 |
|
412 QGraphicsWidget *graphicsWidget = qobject_cast<QGraphicsWidget*>(d->mFocusedObject); |
|
413 if (graphicsWidget) { |
|
414 graphicsWidget->setInputMethodHints(hints); |
|
415 return; |
|
416 } |
|
417 |
|
418 QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject); |
|
419 if (widget) { |
|
420 widget->setInputMethodHints(hints); |
|
421 } |
|
422 } |
|
423 |
|
424 /*! |
|
425 A convenience method for filtering strings. Uses filter attached to connected editor |
|
426 and filters given string with it. |
|
427 */ |
|
428 void HbInputFocusObject::filterStringWithEditorFilter(const QString& source, QString& result) |
|
429 { |
|
430 QString intermediate = source; |
|
431 |
|
432 // Chained two-pass filtering because this can be case-constrained editor with a filter. |
|
433 Qt::InputMethodHints hints = inputMethodHints(); |
|
434 if (hints & Qt::ImhLowercaseOnly) { |
|
435 intermediate.clear(); |
|
436 HbInputLowerCaseFilter::instance()->filterString(source, intermediate); |
|
437 } else if (hints & Qt::ImhUppercaseOnly) { |
|
438 intermediate.clear(); |
|
439 HbInputUpperCaseFilter::instance()->filterString(source, intermediate); |
|
440 } |
|
441 |
|
442 HbInputFilter *filter = editorInterface().filter(); |
|
443 if (filter) { |
|
444 filter->filterString(intermediate, result); |
|
445 return; |
|
446 } |
|
447 |
|
448 result = intermediate; |
|
449 } |
|
450 |
|
451 /*! |
|
452 Returns true if given character is allowed in active editor. |
|
453 */ |
|
454 bool HbInputFocusObject::characterAllowedInEditor(QChar character) const |
|
455 { |
|
456 // Two pass filtering, this can be case constrained editor with a filter. |
|
457 Qt::InputMethodHints hints = inputMethodHints(); |
|
458 if (hints & Qt::ImhLowercaseOnly) { |
|
459 if (HbInputLowerCaseFilter::instance()->filter(character) == false) { |
|
460 return false; |
|
461 } |
|
462 } else if (hints & Qt::ImhUppercaseOnly) { |
|
463 if (HbInputUpperCaseFilter::instance()->filter(character) == false) { |
|
464 return false; |
|
465 } |
|
466 } |
|
467 |
|
468 HbInputFilter *filter = editorInterface().filter(); |
|
469 if (filter) { |
|
470 return filter->filter(character); |
|
471 } |
|
472 |
|
473 return true; |
|
474 } |
|
475 |
|
476 /*! |
|
477 Returns the scenePos of the associated editor widget, if the concept makes sense |
|
478 in its context (i.e. the editor is part of a scene, either being a QGraphicsWidget or |
|
479 a QWidget embedded in a QGraphicsProxyWidget). Otherwise returns QPointF(0.0, 0.0). |
|
480 */ |
|
481 QPointF HbInputFocusObject::scenePos() const |
|
482 { |
|
483 Q_D(const HbInputFocusObject); |
|
484 |
|
485 QGraphicsWidget *graphicsWidget = qobject_cast<QGraphicsWidget*>(d->mFocusedObject); |
|
486 if (graphicsWidget) { |
|
487 return graphicsWidget->scenePos(); |
|
488 } |
|
489 |
|
490 QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject); |
|
491 if (widget && widget->graphicsProxyWidget()) { |
|
492 return widget->graphicsProxyWidget()->scenePos(); |
|
493 } |
|
494 |
|
495 return QPointF(0.0, 0.0); |
|
496 } |
|
497 |
|
498 /*! |
|
499 Returns true if all the characters in given string are allowed in active editor. |
|
500 */ |
|
501 bool HbInputFocusObject::stringAllowedInEditor(const QString& string) const |
|
502 { |
|
503 // Two pass filtering. This can be a case constrained editor with a filter. |
|
504 Qt::InputMethodHints hints; |
|
505 if (hints & Qt::ImhLowercaseOnly) { |
|
506 QString outStr; |
|
507 HbInputLowerCaseFilter::instance()->filterString(string, outStr); |
|
508 if (string != outStr) { |
|
509 return false; |
|
510 } |
|
511 } else if (hints & Qt::ImhUppercaseOnly) { |
|
512 QString outStr; |
|
513 HbInputUpperCaseFilter::instance()->filterString(string, outStr); |
|
514 if (string != outStr) { |
|
515 return false; |
|
516 } |
|
517 } |
|
518 |
|
519 HbInputFilter *filter = editorInterface().filter(); |
|
520 if (filter) { |
|
521 QString outStr; |
|
522 filter->filterString(string, outStr); |
|
523 return string == outStr; |
|
524 } |
|
525 |
|
526 return true; |
|
527 } |
|
528 |
|
529 /*! |
|
530 Commits given smiley. |
|
531 */ |
|
532 void HbInputFocusObject::commitSmiley(QString smiley) |
|
533 { |
|
534 Q_D(HbInputFocusObject); |
|
535 |
|
536 if (d->mFocusedObject) { |
|
537 d->mFocusedObject->setProperty("SmileyIcon", smiley); |
|
538 } |
|
539 } |
|
540 |
|
541 /*! |
|
542 Returns the editor widget as QObject. |
|
543 */ |
|
544 QObject *HbInputFocusObject::object() const |
|
545 { |
|
546 Q_D(const HbInputFocusObject); |
|
547 return d->mFocusedObject; |
|
548 } |
|
549 |
|
550 /*! |
|
551 Returns true if widget is read-only widget. This works |
|
552 only for known editor types. |
|
553 */ |
|
554 bool HbInputFocusObject::isReadOnlyWidget(QObject *editorObject) |
|
555 { |
|
556 if (editorObject) { |
|
557 QWidget *widget = qobject_cast<QWidget*>(editorObject); |
|
558 if (widget) { |
|
559 if (!widget->testAttribute(Qt::WA_InputMethodEnabled)) { |
|
560 return true; |
|
561 } |
|
562 |
|
563 QLineEdit *lineEdit = qobject_cast<QLineEdit*>(widget); |
|
564 if (lineEdit) { |
|
565 return lineEdit->isReadOnly(); |
|
566 } |
|
567 |
|
568 QTextEdit *textEdit = qobject_cast<QTextEdit*>(widget); |
|
569 if (textEdit) { |
|
570 return textEdit->isReadOnly(); |
|
571 } |
|
572 |
|
573 return false; |
|
574 } else { |
|
575 QGraphicsWidget *graphicsWidget = qobject_cast<QGraphicsWidget*>(editorObject); |
|
576 if (graphicsWidget) { |
|
577 if (!(graphicsWidget->flags() & QGraphicsItem::ItemAcceptsInputMethod)) { |
|
578 return true; |
|
579 } |
|
580 } |
|
581 |
|
582 return false; |
|
583 } |
|
584 } |
|
585 |
|
586 return true; |
|
587 } |
|
588 |
|
589 /*! |
|
590 Returns true if the input framework recognizes given object as editor. |
|
591 */ |
|
592 bool HbInputFocusObject::isEditor(QObject *object) |
|
593 { |
|
594 if (object && object->inherits("HbAbstractEdit")) { |
|
595 return true; |
|
596 } |
|
597 |
|
598 if (qobject_cast<QLineEdit*>(object)) { |
|
599 return true; |
|
600 } |
|
601 |
|
602 if (qobject_cast<QTextEdit*>(object)) { |
|
603 return true; |
|
604 } |
|
605 |
|
606 return false; |
|
607 } |
|
608 |
|
609 /*! |
|
610 Sets focus to the editor point by this focus objetc. This method is needed because sometimes |
|
611 input method does something that temporarily removes focus from the original editor, |
|
612 for example displays a dialog which itself contains an editor in it. This method can |
|
613 be used to return the focus to the original editor. |
|
614 */ |
|
615 void HbInputFocusObject::setFocus() |
|
616 { |
|
617 Q_D(HbInputFocusObject); |
|
618 |
|
619 QGraphicsWidget *graphicsWidget = qobject_cast<QGraphicsWidget*>(d->mFocusedObject); |
|
620 if (graphicsWidget && graphicsWidget->scene()) { |
|
621 graphicsWidget->scene()->setFocusItem(graphicsWidget); |
|
622 } else { |
|
623 QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject); |
|
624 if (widget) { |
|
625 widget->setFocus(); |
|
626 } |
|
627 } |
|
628 } |
|
629 |
|
630 // End of file |
|
631 |