Advertisement
Guest User

Untitled

a guest
Jul 28th, 2017
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 27.35 KB | None | 0 0
  1. diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
  2. index 22382cd..9f342f6 100644
  3. --- a/src/corelib/global/qnamespace.qdoc
  4. +++ b/src/corelib/global/qnamespace.qdoc
  5. @@ -161,7 +161,7 @@
  6. like editing on previous versions of Symbian behave. When this attribute
  7. is true, a virtual keyboard window is shown on top of application and it
  8. is ensured that the focused text widget is visible. This is only supported in
  9. - Symbian^3. (internal)
  10. + Symbian^3. Not supported for QWebView. Not supported for QML applications. (internal)
  11.  
  12. \omitvalue AA_AttributeCount
  13. */
  14. diff --git a/src/gui/dialogs/qdialog.cpp b/src/gui/dialogs/qdialog.cpp
  15. index e44c38c..1ab441e 100644
  16. --- a/src/gui/dialogs/qdialog.cpp
  17. +++ b/src/gui/dialogs/qdialog.cpp
  18. @@ -414,7 +414,7 @@ bool QDialog::event(QEvent *e)
  19. result = true;
  20. }
  21. #elif defined(Q_WS_S60)
  22. - if ((e->type() == QEvent::StyleChange) || (e->type() == QEvent::Resize )) {
  23. + if ((e->type() == QEvent::StyleChange) || (e->type() == QEvent::Resize ) || (e->type() == QEvent::PolishRequest)) {
  24. if (!testAttribute(Qt::WA_Moved)) {
  25. Qt::WindowStates state = windowState();
  26. adjustPosition(parentWidget());
  27. diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h
  28. index 8c8ffd4..db2339b 100644
  29. --- a/src/gui/inputmethod/qcoefepinputcontext_p.h
  30. +++ b/src/gui/inputmethod/qcoefepinputcontext_p.h
  31. @@ -93,6 +93,9 @@ public:
  32.  
  33. TCoeInputCapabilities inputCapabilities();
  34.  
  35. + void resetSplitViewWidget(bool keepInputWidget = false);
  36. + void ensureFocusWidgetVisible(QWidget *widget, bool forceOperation = false);
  37. +
  38. protected:
  39. void timerEvent(QTimerEvent *timerEvent);
  40.  
  41. @@ -104,6 +107,7 @@ private:
  42. void queueInputCapabilitiesChanged();
  43. bool needsInputPanel();
  44. void commitTemporaryPreeditString();
  45. + bool isWidgetVisible(QWidget *widget, int offset = 0);
  46.  
  47. private Q_SLOTS:
  48. void ensureInputCapabilitiesChanged();
  49. @@ -155,6 +159,12 @@ private:
  50. QBasicTimer m_tempPreeditStringTimeout;
  51. bool m_hasTempPreeditString;
  52.  
  53. + int m_splitViewMoveBy;
  54. + int m_splitViewResizeBy;
  55. + int m_splitViewScrollBy;
  56. + int m_splitViewTotalScroll;
  57. + Qt::WindowStates m_splitViewPreviousWindowStates;
  58. +
  59. friend class tst_QInputContext;
  60. };
  61.  
  62. diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
  63. index 1bef64d..f99eefd 100644
  64. --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
  65. +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
  66. @@ -48,6 +48,7 @@
  67. #include <qgraphicsscene.h>
  68. #include <qgraphicswidget.h>
  69. #include <qsymbianevent.h>
  70. +#include <qlayout.h>
  71. #include <private/qcore_symbian_p.h>
  72.  
  73. #include <fepitfr.h>
  74. @@ -67,6 +68,9 @@
  75. // that support text selection.
  76. #define QT_EAknEditorFlagSelectionVisible 0x100000
  77.  
  78. +// EAknEditorFlagEnablePartialScreen is only valid from Sym^3 onwards.
  79. +#define QT_EAknEditorFlagEnablePartialScreen 0x200000
  80. +
  81. QT_BEGIN_NAMESPACE
  82.  
  83. QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
  84. @@ -80,13 +84,22 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
  85. m_inlinePosition(0),
  86. m_formatRetriever(0),
  87. m_pointerHandler(0),
  88. - m_hasTempPreeditString(false)
  89. + m_hasTempPreeditString(false),
  90. + m_splitViewMoveBy(0),
  91. + m_splitViewResizeBy(0),
  92. + m_splitViewScrollBy(0),
  93. + m_splitViewTotalScroll(0),
  94. + m_splitViewPreviousWindowStates(Qt::WindowNoState)
  95. {
  96. m_fepState->SetObjectProvider(this);
  97. - if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0)
  98. - m_fepState->SetFlags(EAknEditorFlagDefault | QT_EAknEditorFlagSelectionVisible);
  99. - else
  100. - m_fepState->SetFlags(EAknEditorFlagDefault);
  101. + int defaultFlags = EAknEditorFlagDefault;
  102. + if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) {
  103. + if (!QApplication::testAttribute(Qt::AA_S60DisablePartialScreenInputMode)) {
  104. + defaultFlags |= QT_EAknEditorFlagEnablePartialScreen;
  105. + }
  106. + defaultFlags |= QT_EAknEditorFlagSelectionVisible;
  107. + }
  108. + m_fepState->SetFlags(defaultFlags);
  109. m_fepState->SetDefaultInputMode( EAknEditorTextInputMode );
  110. m_fepState->SetPermittedInputModes( EAknEditorAllInputModes );
  111. m_fepState->SetDefaultCase( EAknEditorTextCase );
  112. @@ -210,6 +223,21 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event)
  113. return false;
  114.  
  115. switch (event->type()) {
  116. + case QEvent::MouseButtonPress:
  117. + // Alphanumeric keypad doesn't like it when we click and text is still getting displayed
  118. + // It ignores the mouse event, so we need to commit and send a selection event (which will get triggered
  119. + // after the commit)
  120. + if (!m_preeditString.isEmpty()) {
  121. + commitCurrentString(false);
  122. +
  123. + int pos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt();
  124. +
  125. + QList<QInputMethodEvent::Attribute> selectAttributes;
  126. + selectAttributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, pos, 0, QVariant());
  127. + QInputMethodEvent selectEvent(QLatin1String(""), selectAttributes);
  128. + sendEvent(selectEvent);
  129. + }
  130. + break;
  131. case QEvent::KeyPress:
  132. commitTemporaryPreeditString();
  133. // fall through intended
  134. @@ -299,13 +327,38 @@ bool QCoeFepInputContext::symbianFilterEvent(QWidget *keyWidget, const QSymbianE
  135. // This should also happen for commands.
  136. reset();
  137.  
  138. +
  139. + // We need to scroll the window content when window becomes available. Scrolling window while it is
  140. + // not yet ready with OpenVg graphicssystem results in scroll()/resize() silently failing.
  141. +
  142. + if (event->windowServerEvent() && event->windowServerEvent()->Type() == EEventWindowVisibilityChanged) {
  143. + if (S60->splitViewLastWidget) {
  144. + QGraphicsView *gv = qobject_cast<QGraphicsView*>(S60->splitViewLastWidget);
  145. + const bool alwaysResize = (gv && gv->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff);
  146. + TUint visibleFlags = event->windowServerEvent()->VisibilityChanged()->iFlags;
  147. +
  148. + if (!alwaysResize && (visibleFlags & TWsVisibilityChangedEvent::EPartiallyVisible)) {
  149. +
  150. + // If visibility is changed and new position for the input widget is not yet
  151. + // calculated, force calculation and scrolling/resizing to happen immediately.
  152. + const bool forceMove = (!m_splitViewTotalScroll && !m_splitViewScrollBy && !m_splitViewResizeBy);
  153. + if (!isWidgetVisible(S60->splitViewLastWidget)) {
  154. + ensureFocusWidgetVisible(S60->splitViewLastWidget, forceMove);
  155. + }
  156. + } else if (visibleFlags & TWsVisibilityChangedEvent::ENotVisible) {
  157. + resetSplitViewWidget(true);
  158. + }
  159. + }
  160. + }
  161. +
  162. return false;
  163. }
  164.  
  165. void QCoeFepInputContext::timerEvent(QTimerEvent *timerEvent)
  166. {
  167. - if (timerEvent->timerId() == m_tempPreeditStringTimeout.timerId())
  168. + if (timerEvent->timerId() == m_tempPreeditStringTimeout.timerId()) {
  169. commitTemporaryPreeditString();
  170. + }
  171. }
  172.  
  173. void QCoeFepInputContext::commitTemporaryPreeditString()
  174. @@ -343,6 +396,308 @@ TCoeInputCapabilities QCoeFepInputContext::inputCapabilities()
  175. return TCoeInputCapabilities(m_textCapabilities, this, 0);
  176. }
  177.  
  178. +void QCoeFepInputContext::resetSplitViewWidget(bool keepInputWidget)
  179. +{
  180. + if (!S60->splitViewLastWidget) {
  181. + return;
  182. + }
  183. +
  184. + QSymbianControl *symControl = static_cast<QSymbianControl*>(S60->splitViewLastWidget->effectiveWinId());
  185. + symControl->CancelLongTapTimer();
  186. +
  187. + QGraphicsView *gv = qobject_cast<QGraphicsView*>(S60->splitViewLastWidget);
  188. + QWidget *windowToMove = gv ? gv : symControl->widget();
  189. + if (!S60->splitViewLastWidget->isWindow()) {
  190. + windowToMove = S60->splitViewLastWidget->window();
  191. + }
  192. +
  193. + bool userResize = S60->splitViewLastWidget->testAttribute(Qt::WA_Resized);
  194. + bool userMove = windowToMove->testAttribute(Qt::WA_Moved);
  195. +
  196. + // Resizing might have led to widget losing its original windowstate.
  197. + // Restore previous window state.
  198. +
  199. + if (gv) {
  200. + windowToMove->setUpdatesEnabled(false);
  201. + }
  202. +
  203. + if (m_splitViewPreviousWindowStates != windowToMove->windowState()) {
  204. + windowToMove->setWindowState(m_splitViewPreviousWindowStates);
  205. + }
  206. +
  207. + if (m_splitViewResizeBy) {
  208. + S60->splitViewLastWidget->updateGeometry();
  209. + }
  210. +
  211. + if (m_splitViewTotalScroll) {
  212. + if (S60->splitViewLastWidget->isTopLevel()) {
  213. + S60->splitViewLastWidget->scroll(0, -m_splitViewTotalScroll);
  214. + } else {
  215. + if (windowToMove->layout()) {
  216. + windowToMove->layout()->invalidate();
  217. + } else {
  218. + windowToMove->update();
  219. + }
  220. + }
  221. + }
  222. +
  223. + if (m_splitViewMoveBy) {
  224. + if (!userMove && (windowToMove->windowType() & Qt::Dialog) && !(windowToMove->isFullScreen() || windowToMove->isMaximized())) {
  225. + QEvent layoutReq(QEvent::PolishRequest);
  226. + QApplication::sendEvent(windowToMove, &layoutReq);
  227. + } else {
  228. + windowToMove->move(windowToMove->pos().x(), windowToMove->pos().y() - m_splitViewMoveBy);
  229. + }
  230. + }
  231. +
  232. + if (gv) {
  233. + windowToMove->setUpdatesEnabled(true);
  234. + }
  235. +
  236. + S60->splitViewLastWidget->setAttribute(Qt::WA_Resized, userResize); //not a user resize
  237. + windowToMove->setAttribute(Qt::WA_Moved, userMove); //not a user move
  238. +
  239. + m_splitViewMoveBy = 0;
  240. + m_splitViewResizeBy = 0;
  241. + m_splitViewScrollBy = 0;
  242. + m_splitViewTotalScroll = 0;
  243. + if (!keepInputWidget) {
  244. + m_splitViewPreviousWindowStates = Qt::WindowNoState;
  245. + S60->splitViewLastWidget = 0;
  246. + }
  247. +
  248. +}
  249. +
  250. +// Checks if a given widget is visible in the splitview rect. The offset
  251. +// parameter can be used to validate if moving widget upwards or downwards
  252. +// by the offset would make a difference for the visibility.
  253. +
  254. +bool QCoeFepInputContext::isWidgetVisible(QWidget *widget, int offset)
  255. +{
  256. + bool visible = false;
  257. + if (widget) {
  258. + QRect splitViewRect = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect());
  259. + QWidget *window = QApplication::activeWindow();
  260. +
  261. + // If statuspane is visible, it needs to be excluded from allowed visible area for
  262. + // the widgets, to avoid moving input widgets underneath the statuspane.
  263. +
  264. + CEikStatusPane *const s = S60->statusPane();
  265. + if (s && s->IsVisible()) {
  266. + TRect statusPaneRect;
  267. + AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EStatusPane, statusPaneRect);
  268. + if (!((window->windowType() & Qt::Dialog) && !(window->isMaximized() || window->isFullScreen()))) {
  269. + splitViewRect.adjust(0, statusPaneRect.Height(), 0, 0);
  270. + }
  271. + }
  272. +
  273. + QGraphicsView *gv = qobject_cast<QGraphicsView*>(widget);
  274. + if (gv) {
  275. + if (QGraphicsScene *scene = gv->scene()) {
  276. + if (QGraphicsItem *focusItem = scene->focusItem()) {
  277. + QPoint cursorPos = window->mapToGlobal(focusItem->cursor().pos());
  278. + cursorPos.setY(cursorPos.y() + offset);
  279. + if (splitViewRect.contains(cursorPos)) {
  280. + visible = true;
  281. + }
  282. + }
  283. + }
  284. +
  285. + } else {
  286. + if (splitViewRect.contains(widget->mapToGlobal(QPoint(0, widget->rect().bottom() + offset))) &&
  287. + splitViewRect.contains(widget->mapToGlobal(QPoint(0, widget->rect().top() + offset)))) {
  288. + visible = true;
  289. + }
  290. + }
  291. + }
  292. + return visible;
  293. +}
  294. +
  295. +// Ensure that the input widget is visible in the splitview rect.
  296. +// When forceOperation is true, input widget operations (resize, scroll) are carried out
  297. +// immediately. Otherwise only re-positioning values are calculated when splitview opens.
  298. +// If splitview is already open when ensureFocusWidgetVisible is called, forceOperation
  299. +// parameter is ignored, as the widget re-positioning can be done immediately.
  300. +
  301. +// todo: Note that this currently does not work with QML applications.
  302. +// todo: Not that with QWebView the input widget re-positioning is not done.
  303. +
  304. +void QCoeFepInputContext::ensureFocusWidgetVisible(QWidget *widget, bool forceOperation)
  305. +{
  306. + // Native side opening and closing its virtual keyboard when it changes the keyboard layout,
  307. + // has an adverse impact on long tap timer. Cancel the timer when splitview opens to avoid this.
  308. + QSymbianControl *symControl = static_cast<QSymbianControl*>(widget->effectiveWinId());
  309. + symControl->CancelLongTapTimer();
  310. +
  311. + // Graphicsviews that have vertical scrollbars and webviews should always be resized to
  312. + // the splitview area. With widgets, or graphicsviews without scrollbars, splitview move/resize
  313. + // operations should be avoided if the widget is already visible on-screen.
  314. +
  315. + QGraphicsView *gv = qobject_cast<QGraphicsView*>(widget);
  316. + const bool alwaysResize = (gv && gv->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff);
  317. + const bool moveWithinVisibleArea =
  318. + (m_splitViewMoveBy != 0 || m_splitViewResizeBy != 0 ||
  319. + m_splitViewScrollBy != 0 || m_splitViewTotalScroll != 0);
  320. +
  321. + QWidget *windowToMove = gv ? gv : symControl->widget();
  322. + if (!windowToMove->isWindow()) {
  323. + windowToMove = windowToMove->window();
  324. + }
  325. + if (!windowToMove) {
  326. + return;
  327. + }
  328. +
  329. + // When opening the keyboard (not moving within the splitview area), save the original
  330. + // window state. In some cases, ensuring input widget visibility might lead to window
  331. + // states getting changed.
  332. +
  333. + if (!moveWithinVisibleArea) {
  334. + S60->splitViewLastWidget = widget;
  335. + m_splitViewPreviousWindowStates = windowToMove->windowState();
  336. + }
  337. +
  338. + int windowTop = widget->window()->pos().y();
  339. +
  340. + const bool userResize = widget->testAttribute(Qt::WA_Resized);
  341. + const bool userMove = windowToMove->testAttribute(Qt::WA_Moved);
  342. +
  343. + QRect splitViewRect = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect());
  344. +
  345. + // Graphicsviews and webviews with scrollbars are just resized to the splitview - content is unaffected.
  346. + // Microfocus location is set as visible, if possible.
  347. +
  348. + if (alwaysResize) {
  349. + QWidget *w = gv ? gv : widget;
  350. + if (!moveWithinVisibleArea)
  351. + m_splitViewResizeBy = w->height();
  352. +
  353. + windowToMove->setUpdatesEnabled(false);
  354. +
  355. + // When resizing a window widget, it will lose its maximized window state.
  356. + // Native applications hide statuspane in splitview state, so lets move to
  357. + // fullscreen mode. This makes available area slightly bigger, which helps usability
  358. + // and greatly reduces event passing in orientation switch cases,
  359. + // as the statuspane size is not changing.
  360. +
  361. + if (!(windowToMove->windowState() & Qt::WindowFullScreen)) {
  362. + w->setWindowState(
  363. + (windowToMove->windowState() & ~(Qt::WindowMinimized | Qt::WindowFullScreen)) | Qt::WindowFullScreen);
  364. + }
  365. +
  366. + windowTop = w->geometry().top();
  367. + w->resize(w->width(), splitViewRect.height() - windowTop);
  368. +
  369. + if (gv && gv->scene()) {
  370. + const QRectF microFocusRect = gv->scene()->inputMethodQuery(Qt::ImMicroFocus).toRectF();
  371. + gv->ensureVisible(microFocusRect);
  372. + }
  373. + windowToMove->setUpdatesEnabled(true);
  374. +
  375. + } else {
  376. +
  377. + int resizeBy = 0;
  378. + int moveBy = 0;
  379. + int scrollBy = 0;
  380. + int currentHeight = 0;
  381. + int currentTop = 0;
  382. +
  383. + if (gv) {
  384. + const QRectF sceneRect = gv->scene()->inputMethodQuery(Qt::ImMicroFocus).toRectF();
  385. + const QPoint p = windowToMove->mapToGlobal(gv->mapFromScene(sceneRect.topLeft()));
  386. + currentHeight = sceneRect.height();
  387. + currentTop = p.y() + windowTop;
  388. + } else {
  389. + currentHeight = widget->rect().height();
  390. + currentTop = widget->mapToGlobal(QPoint(0, widget->rect().top())).y();
  391. + }
  392. +
  393. + int availableSpace = splitViewRect.height();
  394. + const bool canResideOverStatusPane =
  395. + (windowToMove->windowType() & Qt::Dialog)
  396. + && !(windowToMove->isMaximized() || windowToMove->isFullScreen());
  397. +
  398. + // Native side indicates that statuspane area is included in the splitview rect; even if statuspane is visible.
  399. + // Reduce the available area, if statuspane is shown.
  400. +
  401. + CEikStatusPane *const s = S60->statusPane();
  402. + TRect statusPaneRect;
  403. + if (s && s->IsVisible() && !canResideOverStatusPane) {
  404. + AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EStatusPane, statusPaneRect);
  405. + availableSpace -= statusPaneRect.Height();
  406. + }
  407. +
  408. + //Widget needs to be resized, if it won't fit into the available area.
  409. + resizeBy = currentHeight > availableSpace ? availableSpace - currentHeight : 0;
  410. +
  411. + bool nowVisible = false;
  412. +
  413. + if (!gv && windowToMove->mapToGlobal(QPoint(0,0)).y() >= 0 && canResideOverStatusPane) {
  414. +
  415. + // Dialogs with normal geometry are positioned just above the virtual keyboard, if possible.
  416. + // If the dialog window is taller than splitview area, dialog is placed to screen top.
  417. +
  418. + moveBy = (windowToMove->height() < splitViewRect.height()) ?
  419. + windowToMove->mapToGlobal(windowToMove->rect().bottomLeft()).y() - splitViewRect.bottom() :
  420. + windowToMove->mapToGlobal(QPoint(0,0)).y();
  421. + currentTop -= moveBy;
  422. + nowVisible = isWidgetVisible(widget, -moveBy);
  423. + }
  424. +
  425. + // Widget's new position should preferable be at the center (y-axis) of the splitview rect.
  426. + int newTopCentered = (availableSpace / 2 - (currentHeight + resizeBy) / 2);
  427. + if (s && s->IsVisible()) {
  428. + newTopCentered += statusPaneRect.Height();
  429. + }
  430. +
  431. + // By default, widget should be centered in the available area.
  432. + // However, window content scrolling should be limited by the top and bottom of the window.
  433. +
  434. + const int centerOffset = currentTop - newTopCentered;
  435. + const int bottomLimit = windowToMove->geometry().bottom() - splitViewRect.bottom() + m_splitViewTotalScroll - moveBy;
  436. + const int topLimit = moveBy ? (windowToMove->geometry().top() - moveBy + m_splitViewTotalScroll)
  437. + : (windowToMove->geometry().top() - statusPaneRect.iBr.iY + m_splitViewTotalScroll);
  438. +
  439. + if (!nowVisible) {
  440. + if ((centerOffset < bottomLimit) && (centerOffset > topLimit)) {
  441. + scrollBy = centerOffset;
  442. + } else {
  443. + if (centerOffset < 0) {
  444. + scrollBy = qMax(centerOffset, topLimit);
  445. + } else {
  446. + scrollBy = qMin(centerOffset, bottomLimit);
  447. + }
  448. + }
  449. + }
  450. +
  451. + if (moveWithinVisibleArea) {
  452. + S60->splitViewLastWidget = widget;
  453. + }
  454. +
  455. + if (resizeBy) {
  456. + m_splitViewResizeBy = resizeBy;
  457. + if (moveWithinVisibleArea || forceOperation) {
  458. + widget->resize(widget->width(), widget->height() + resizeBy);
  459. + }
  460. + }
  461. + if (scrollBy) {
  462. + m_splitViewScrollBy = -scrollBy;
  463. + if (moveWithinVisibleArea || forceOperation) {
  464. + windowToMove->scroll(0, m_splitViewScrollBy);
  465. + m_splitViewTotalScroll += m_splitViewScrollBy;
  466. + m_splitViewScrollBy = 0;
  467. + }
  468. + }
  469. +
  470. + if (moveBy) {
  471. + m_splitViewMoveBy -= moveBy;
  472. + windowToMove->move(windowToMove->pos().x(), windowTop - moveBy);
  473. + }
  474. + }
  475. +
  476. + widget->setAttribute(Qt::WA_Resized, userResize); //not a user resize
  477. + windowToMove->setAttribute(Qt::WA_Moved, userMove); //not a user move
  478. +}
  479. +
  480. static QTextCharFormat qt_TCharFormat2QTextCharFormat(const TCharFormat &cFormat, bool validStyleColor)
  481. {
  482. QTextCharFormat qFormat;
  483. @@ -474,10 +829,12 @@ void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints)
  484. m_fepState->SetPermittedCases(flags);
  485. ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateCaseModeUpdate);
  486.  
  487. - if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0)
  488. - flags = QT_EAknEditorFlagSelectionVisible;
  489. - else
  490. - flags = 0;
  491. + flags = 0;
  492. + if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) {
  493. + if (!QApplication::testAttribute(Qt::AA_S60DisablePartialScreenInputMode))
  494. + flags |= QT_EAknEditorFlagEnablePartialScreen;
  495. + flags |= QT_EAknEditorFlagSelectionVisible;
  496. + }
  497. if (hints & ImhUppercaseOnly && !(hints & ImhLowercaseOnly)
  498. || hints & ImhLowercaseOnly && !(hints & ImhUppercaseOnly)) {
  499. flags |= EAknEditorFlagFixedCase;
  500. diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
  501. index 59aec91..8033e5f 100644
  502. --- a/src/gui/kernel/qapplication.cpp
  503. +++ b/src/gui/kernel/qapplication.cpp
  504. @@ -1004,6 +1004,10 @@ void QApplicationPrivate::initialize()
  505. #endif //QT_AUTO_MAXIMIZE_THRESHOLD
  506. #endif //Q_WS_WINCE
  507.  
  508. +#ifdef Q_WS_S60
  509. + q->setAttribute(Qt::AA_S60DisablePartialScreenInputMode, true);
  510. +#endif
  511. +
  512. // Set up which span functions should be used in raster engine...
  513. qInitDrawhelperAsm();
  514. // and QImage conversion functions
  515. diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
  516. index fb0c6b8..d573722 100644
  517. --- a/src/gui/kernel/qapplication_s60.cpp
  518. +++ b/src/gui/kernel/qapplication_s60.cpp
  519. @@ -96,6 +96,10 @@ QT_BEGIN_NAMESPACE
  520. // Goom Events through Window Server
  521. static const int KGoomMemoryLowEvent = 0x10282DBF;
  522. static const int KGoomMemoryGoodEvent = 0x20026790;
  523. +// Split view open/close events from AVKON
  524. +static const int KSplitViewOpenEvent = 0x2001E2C0;
  525. +static const int KSplitViewCloseEvent = 0x2001E2C1;
  526. +
  527.  
  528. #if defined(QT_DEBUG)
  529. static bool appNoGrab = false; // Grabbing enabled
  530. @@ -1224,6 +1228,11 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */)
  531. if (m_ignoreFocusChanged || (qwidget->windowType() & Qt::WindowType_Mask) == Qt::Desktop)
  532. return;
  533.  
  534. +#ifdef Q_WS_S60
  535. + if (S60->splitViewLastWidget)
  536. + return;
  537. +#endif
  538. +
  539. // Popups never get focused, but still receive the FocusChanged when they are hidden.
  540. if (QApplicationPrivate::popupWidgets != 0
  541. || (qwidget->windowType() & Qt::Popup) == Qt::Popup)
  542. @@ -1288,6 +1297,19 @@ void QSymbianControl::handleClientAreaChange()
  543. SetExtentToWholeScreen();
  544. } else if (qwidget->isMaximized() || (qwidget->isFullScreen() && cbaVisibilityHint)) {
  545. TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
  546. + if (S60->splitViewLastWidget) {
  547. + //For some curious reason, native side indicates that splitviewRect starts underneath statuspane.
  548. + //So, if statuspane is visible, move the mainpane rect in splitview down a little bit.
  549. + CEikStatusPane *const s = S60->statusPane();
  550. + if (s && s->IsVisible()) {
  551. + TRect statusPaneRect;
  552. + AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EStatusPane, statusPaneRect);
  553. + r.Move(0, statusPaneRect.Height());
  554. + }
  555. + TRect mainRect;
  556. + AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane, mainRect);
  557. + r.SetHeight(mainRect.Height());
  558. + }
  559. SetExtent(r.iTl, r.Size());
  560. } else if (!qwidget->isMinimized()) { // Normal geometry
  561. if (!qwidget->testAttribute(Qt::WA_Resized)) {
  562. @@ -1302,9 +1324,59 @@ void QSymbianControl::handleClientAreaChange()
  563. }
  564. }
  565.  
  566. +bool QSymbianControl::isSplitViewWidget(QWidget *widget) {
  567. + bool returnValue = true;
  568. + //Ignore events sent to non-active windows, not visible widgets and not parents of input widget.
  569. + if (!qwidget->isActiveWindow()
  570. + || !qwidget->isVisible()
  571. + || !qwidget->isAncestorOf(widget)) {
  572. +
  573. + returnValue = false;
  574. + }
  575. + return returnValue;
  576. +}
  577. +
  578. void QSymbianControl::HandleResourceChange(int resourceType)
  579. {
  580. switch (resourceType) {
  581. + case KSplitViewCloseEvent: //intentional fall-through
  582. + case KSplitViewOpenEvent: {
  583. +#if !defined(QT_NO_IM) && defined(Q_WS_S60)
  584. +
  585. + //Fetch widget getting the text input
  586. + QWidget *widget = QWidget::keyboardGrabber();
  587. + if (!widget) {
  588. + if (QApplicationPrivate::popupWidgets) {
  589. + widget = QApplication::activePopupWidget()->focusWidget();
  590. + if (!widget) {
  591. + widget = QApplication::activePopupWidget();
  592. + }
  593. + } else {
  594. + widget = QApplicationPrivate::focus_widget;
  595. + if (!widget) {
  596. + widget = qwidget;
  597. + }
  598. + }
  599. + }
  600. + if (widget) {
  601. + QCoeFepInputContext *ic = qobject_cast<QCoeFepInputContext *>(widget->inputContext());
  602. + if (!ic) {
  603. + ic = qobject_cast<QCoeFepInputContext *>(qApp->inputContext());
  604. + }
  605. +
  606. + if (ic && isSplitViewWidget(widget)) {
  607. + if (resourceType == KSplitViewCloseEvent) {
  608. + ic->resetSplitViewWidget();
  609. + handleClientAreaChange();
  610. + } else {
  611. + ic->ensureFocusWidgetVisible(widget);
  612. + }
  613. + }
  614. +
  615. + }
  616. +#endif // !defined(QT_NO_IM) && defined(Q_WS_S60)
  617. + }
  618. + break;
  619. case KInternalStatusPaneChange:
  620. handleClientAreaChange();
  621. if (IsFocused() && IsVisible()) {
  622. diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
  623. index 40697bf..18259a8 100644
  624. --- a/src/gui/kernel/qt_s60_p.h
  625. +++ b/src/gui/kernel/qt_s60_p.h
  626. @@ -143,6 +143,8 @@ public:
  627. int menuBeingConstructed : 1;
  628. int orientationSet : 1;
  629. QApplication::QS60MainApplicationFactory s60ApplicationFactory; // typedef'ed pointer type
  630. + QPointer<QWidget> splitViewLastWidget;
  631. +
  632. static CEikButtonGroupContainer *cba;
  633.  
  634. enum ScanCodeState {
  635. @@ -252,6 +254,7 @@ private:
  636. #ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
  637. void translateAdvancedPointerEvent(const TAdvancedPointerEvent *event);
  638. #endif
  639. + bool isSplitViewWidget(QWidget *widget);
  640.  
  641. public:
  642. void handleClientAreaChange();
  643. diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp
  644. index 605872e..6afa1f3 100644
  645. --- a/src/gui/styles/qs60style_s60.cpp
  646. +++ b/src/gui/styles/qs60style_s60.cpp
  647. @@ -65,7 +65,6 @@
  648. #include <aknnavi.h>
  649. #include <gulicon.h>
  650. #include <AknBitmapAnimation.h>
  651. -
  652. #include <centralrepository.h>
  653.  
  654. #if !defined(QT_NO_STYLE_S60) || defined(QT_PLUGIN)
  655. @@ -1413,7 +1412,6 @@ void QS60StylePrivate::handleDynamicLayoutVariantSwitch()
  656. {
  657. clearCaches(QS60StylePrivate::CC_LayoutChange);
  658. setActiveLayout();
  659. - refreshUI();
  660. foreach (QWidget *widget, QApplication::allWidgets())
  661. widget->ensurePolished();
  662. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement