[Qt] Transform QtFallbackWebPopupCombo into QtWebComboBox
authorcaio.oliveira@openbossa.org <caio.oliveira@openbossa.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 1 Sep 2011 18:39:12 +0000 (18:39 +0000)
committercaio.oliveira@openbossa.org <caio.oliveira@openbossa.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 1 Sep 2011 18:39:12 +0000 (18:39 +0000)
https://bugs.webkit.org/show_bug.cgi?id=67344

Reviewed by Andreas Kling.

Renamed QtFallbackWebPopup to QtWebComboBox and decoupled it from
QtFallbackWebPopup. The new class is a QComboBox with the features that
we need for QtWebKit: tracking when the popup is hidden (via the didHide()
signal) and a convenience method to show its popup in the cursor position.

An important change was made to the combobox: instead of hooking our actions in
showPopup() and hidePopup(), as well as watching for popup visibility events, we
now just watch for the visibility events. This allowed us to get rid of
m_popupVisible and tracking the Show event.

This commit also removed a workaround for input focus added in r40970 after
reviewers request. See bug report for details.

* QtWebKit.pro:
* WebCoreSupport/QtFallbackWebPopup.cpp:
(WebCore::QtFallbackWebPopup::QtFallbackWebPopup):
(WebCore::QtFallbackWebPopup::~QtFallbackWebPopup):
(WebCore::QtFallbackWebPopup::show):
(WebCore::QtFallbackWebPopup::deleteComboBox):
* WebCoreSupport/QtFallbackWebPopup.h:
* WebCoreSupport/QtWebComboBox.cpp: Added.
(WebCore::QtWebComboBox::QtWebComboBox):
(WebCore::QtWebComboBox::showPopupAtCursorPosition):
(WebCore::QtWebComboBox::eventFilter):
* WebCoreSupport/QtWebComboBox.h: Added.

* tests/qwebframe/tst_qwebframe.cpp:
(tst_QWebFrame::popupFocus):
Change the test to use QObject::findChild(). The old method couldn't find our
new class because we defined a new metaclass for it.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@94321 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit/qt/ChangeLog
Source/WebKit/qt/QtWebKit.pro
Source/WebKit/qt/WebCoreSupport/QtFallbackWebPopup.cpp
Source/WebKit/qt/WebCoreSupport/QtFallbackWebPopup.h
Source/WebKit/qt/WebCoreSupport/QtWebComboBox.cpp [new file with mode: 0644]
Source/WebKit/qt/WebCoreSupport/QtWebComboBox.h [new file with mode: 0644]
Source/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp

index 6173cd6..304ac6a 100644 (file)
@@ -1,3 +1,41 @@
+2011-09-01  Caio Marcelo de Oliveira Filho  <caio.oliveira@openbossa.org>
+
+        [Qt] Transform QtFallbackWebPopupCombo into QtWebComboBox
+        https://bugs.webkit.org/show_bug.cgi?id=67344
+
+        Reviewed by Andreas Kling.
+
+        Renamed QtFallbackWebPopup to QtWebComboBox and decoupled it from
+        QtFallbackWebPopup. The new class is a QComboBox with the features that
+        we need for QtWebKit: tracking when the popup is hidden (via the didHide()
+        signal) and a convenience method to show its popup in the cursor position.
+
+        An important change was made to the combobox: instead of hooking our actions in
+        showPopup() and hidePopup(), as well as watching for popup visibility events, we
+        now just watch for the visibility events. This allowed us to get rid of
+        m_popupVisible and tracking the Show event.
+
+        This commit also removed a workaround for input focus added in r40970 after
+        reviewers request. See bug report for details.
+
+        * QtWebKit.pro:
+        * WebCoreSupport/QtFallbackWebPopup.cpp:
+        (WebCore::QtFallbackWebPopup::QtFallbackWebPopup):
+        (WebCore::QtFallbackWebPopup::~QtFallbackWebPopup):
+        (WebCore::QtFallbackWebPopup::show):
+        (WebCore::QtFallbackWebPopup::deleteComboBox):
+        * WebCoreSupport/QtFallbackWebPopup.h:
+        * WebCoreSupport/QtWebComboBox.cpp: Added.
+        (WebCore::QtWebComboBox::QtWebComboBox):
+        (WebCore::QtWebComboBox::showPopupAtCursorPosition):
+        (WebCore::QtWebComboBox::eventFilter):
+        * WebCoreSupport/QtWebComboBox.h: Added.
+
+        * tests/qwebframe/tst_qwebframe.cpp:
+        (tst_QWebFrame::popupFocus):
+        Change the test to use QObject::findChild(). The old method couldn't find our
+        new class because we defined a new metaclass for it.
+
 2011-08-31  Ryosuke Niwa  <rniwa@webkit.org>
 
         Move text() and textWithHardLineBreaks() from RenderTextControl to HTMLTextFormControlElement
 2011-08-31  Ryosuke Niwa  <rniwa@webkit.org>
 
         Move text() and textWithHardLineBreaks() from RenderTextControl to HTMLTextFormControlElement
index 991fe9e..060ad9f 100644 (file)
@@ -177,6 +177,7 @@ SOURCES += \
     $$PWD/Api/qwebkitversion.cpp \
     \
     $$PWD/WebCoreSupport/QtFallbackWebPopup.cpp \
     $$PWD/Api/qwebkitversion.cpp \
     \
     $$PWD/WebCoreSupport/QtFallbackWebPopup.cpp \
+    $$PWD/WebCoreSupport/QtWebComboBox.cpp \
     $$PWD/WebCoreSupport/ChromeClientQt.cpp \
     $$PWD/WebCoreSupport/ContextMenuClientQt.cpp \
     $$PWD/WebCoreSupport/DragClientQt.cpp \
     $$PWD/WebCoreSupport/ChromeClientQt.cpp \
     $$PWD/WebCoreSupport/ContextMenuClientQt.cpp \
     $$PWD/WebCoreSupport/DragClientQt.cpp \
@@ -202,6 +203,7 @@ HEADERS += \
     \
     $$PWD/WebCoreSupport/InspectorServerQt.h \
     $$PWD/WebCoreSupport/QtFallbackWebPopup.h \
     \
     $$PWD/WebCoreSupport/InspectorServerQt.h \
     $$PWD/WebCoreSupport/QtFallbackWebPopup.h \
+    $$PWD/WebCoreSupport/QtWebComboBox.h \
     $$PWD/WebCoreSupport/FrameLoaderClientQt.h \
     $$PWD/WebCoreSupport/FrameNetworkingContextQt.h \
     $$PWD/WebCoreSupport/GeolocationPermissionClientQt.h \
     $$PWD/WebCoreSupport/FrameLoaderClientQt.h \
     $$PWD/WebCoreSupport/FrameNetworkingContextQt.h \
     $$PWD/WebCoreSupport/GeolocationPermissionClientQt.h \
index a516106..710ba3e 100644 (file)
 #ifndef QT_NO_COMBOBOX
 
 #include "ChromeClientQt.h"
 #ifndef QT_NO_COMBOBOX
 
 #include "ChromeClientQt.h"
+#include "QtWebComboBox.h"
 #include "QWebPageClient.h"
 #include "qgraphicswebview.h"
 #include "QWebPageClient.h"
 #include "qgraphicswebview.h"
-#include <QAbstractItemView>
-#include <QApplication>
 #include <QGraphicsProxyWidget>
 #include <QGraphicsProxyWidget>
-#include <QGraphicsScene>
-#include <QGraphicsView>
-#include <QInputContext>
-#include <QMouseEvent>
 #include <QStandardItemModel>
 
 namespace WebCore {
 
 #include <QStandardItemModel>
 
 namespace WebCore {
 
-QtFallbackWebPopupCombo::QtFallbackWebPopupCombo(QtFallbackWebPopup& ownerPopup)
-    : m_ownerPopup(ownerPopup)
-{
-    // Install an event filter on the view inside the combo box popup to make sure we know
-    // when the popup got closed. E.g. QComboBox::hidePopup() won't be called when the popup
-    // is closed by a mouse wheel event outside its window.
-    view()->installEventFilter(this);
-}
-
-void QtFallbackWebPopupCombo::showPopup()
-{
-    QComboBox::showPopup();
-    m_ownerPopup.m_popupVisible = true;
-}
-
-void QtFallbackWebPopupCombo::hidePopup()
-{
-#ifndef QT_NO_IM
-    QWidget* activeFocus = QApplication::focusWidget();
-    if (activeFocus && activeFocus == QComboBox::view()
-        && activeFocus->testAttribute(Qt::WA_InputMethodEnabled)) {
-        QInputContext* qic = activeFocus->inputContext();
-        if (qic) {
-            qic->reset();
-            qic->setFocusWidget(0);
-        }
-    }
-#endif // QT_NO_IM
-
-    QComboBox::hidePopup();
-
-    if (!m_ownerPopup.m_popupVisible)
-        return;
-
-    m_ownerPopup.m_popupVisible = false;
-    emit m_ownerPopup.didHide();
-    m_ownerPopup.destroyPopup();
-}
-
-bool QtFallbackWebPopupCombo::eventFilter(QObject* watched, QEvent* event)
-{
-    Q_ASSERT(watched == view());
-
-    if (event->type() == QEvent::Show && !m_ownerPopup.m_popupVisible)
-        showPopup();
-    else if (event->type() == QEvent::Hide && m_ownerPopup.m_popupVisible)
-        hidePopup();
-
-    return false;
-}
-
-// QtFallbackWebPopup
-
 QtFallbackWebPopup::QtFallbackWebPopup(const ChromeClientQt* chromeClient)
 QtFallbackWebPopup::QtFallbackWebPopup(const ChromeClientQt* chromeClient)
-    : m_popupVisible(false)
-    , m_combo(0)
+    : m_combo(0)
     , m_chromeClient(chromeClient)
 {
 }
 
 QtFallbackWebPopup::~QtFallbackWebPopup()
 {
     , m_chromeClient(chromeClient)
 {
 }
 
 QtFallbackWebPopup::~QtFallbackWebPopup()
 {
-    destroyPopup();
+    deleteComboBox();
 }
 
 void QtFallbackWebPopup::show(const QWebSelectData& data)
 }
 
 void QtFallbackWebPopup::show(const QWebSelectData& data)
@@ -107,10 +48,12 @@ void QtFallbackWebPopup::show(const QWebSelectData& data)
     if (!pageClient())
         return;
 
     if (!pageClient())
         return;
 
-    destroyPopup();
-    m_combo = new QtFallbackWebPopupCombo(*this);
-    connect(m_combo, SIGNAL(activated(int)),
-            SLOT(activeChanged(int)), Qt::QueuedConnection);
+    deleteComboBox();
+
+    m_combo = new QtWebComboBox();
+    connect(m_combo, SIGNAL(activated(int)), SLOT(activeChanged(int)), Qt::QueuedConnection);
+    connect(m_combo, SIGNAL(didHide()), SLOT(deleteComboBox()));
+    connect(m_combo, SIGNAL(didHide()), SIGNAL(didHide()));
 
     populate(data);
 
 
     populate(data);
 
@@ -123,12 +66,9 @@ void QtFallbackWebPopup::show(const QWebSelectData& data)
         m_combo->setParent(pageClient()->ownerWidget());
         m_combo->setGeometry(QRect(rect.left(), rect.top(),
                                rect.width(), m_combo->sizeHint().height()));
         m_combo->setParent(pageClient()->ownerWidget());
         m_combo->setGeometry(QRect(rect.left(), rect.top(),
                                rect.width(), m_combo->sizeHint().height()));
-
     }
 
     }
 
-    QMouseEvent event(QEvent::MouseButtonPress, QCursor::pos(), Qt::LeftButton,
-                      Qt::LeftButton, Qt::NoModifier);
-    QCoreApplication::sendEvent(m_combo, &event);
+    m_combo->showPopupAtCursorPosition();
 }
 
 void QtFallbackWebPopup::hide()
 }
 
 void QtFallbackWebPopup::hide()
@@ -138,14 +78,6 @@ void QtFallbackWebPopup::hide()
     // Qt::Popup window will hide itself on mouse events outside its window.
 }
 
     // Qt::Popup window will hide itself on mouse events outside its window.
 }
 
-void QtFallbackWebPopup::destroyPopup()
-{
-    if (m_combo) {
-        m_combo->deleteLater();
-        m_combo = 0;
-    }
-}
-
 void QtFallbackWebPopup::populate(const QWebSelectData& data)
 {
     QStandardItemModel* model = qobject_cast<QStandardItemModel*>(m_combo->model());
 void QtFallbackWebPopup::populate(const QWebSelectData& data)
 {
     QStandardItemModel* model = qobject_cast<QStandardItemModel*>(m_combo->model());
@@ -191,6 +123,14 @@ void QtFallbackWebPopup::activeChanged(int index)
     emit selectItem(index, false, false);
 }
 
     emit selectItem(index, false, false);
 }
 
+void QtFallbackWebPopup::deleteComboBox()
+{
+    if (!m_combo)
+        return;
+    m_combo->deleteLater();
+    m_combo = 0;
+}
+
 QWebPageClient* QtFallbackWebPopup::pageClient() const
 {
     return m_chromeClient->platformPageClient();
 QWebPageClient* QtFallbackWebPopup::pageClient() const
 {
     return m_chromeClient->platformPageClient();
index a3bd905..ea111fa 100644 (file)
@@ -36,7 +36,7 @@ class QWebPageClient;
 namespace WebCore {
 
 class ChromeClientQt;
 namespace WebCore {
 
 class ChromeClientQt;
-class QtFallbackWebPopupCombo;
+class QtWebComboBox;
 
 class QtFallbackWebPopup : public QWebSelectMethod {
     Q_OBJECT
 
 class QtFallbackWebPopup : public QWebSelectMethod {
     Q_OBJECT
@@ -47,8 +47,6 @@ public:
     virtual void show(const QWebSelectData&);
     virtual void hide();
 
     virtual void show(const QWebSelectData&);
     virtual void hide();
 
-    void destroyPopup();
-
     void setGeometry(const QRect& rect) { m_geometry = rect; }
     QRect geometry() const { return m_geometry; }
 
     void setGeometry(const QRect& rect) { m_geometry = rect; }
     QRect geometry() const { return m_geometry; }
 
@@ -57,11 +55,10 @@ public:
 
 private slots:
     void activeChanged(int);
 
 private slots:
     void activeChanged(int);
+    void deleteComboBox();
 
 private:
 
 private:
-    friend class QtFallbackWebPopupCombo;
-    bool m_popupVisible;
-    QtFallbackWebPopupCombo* m_combo;
+    QtWebComboBox* m_combo;
     const ChromeClientQt* m_chromeClient;
     QRect m_geometry;
     QFont m_font;
     const ChromeClientQt* m_chromeClient;
     QRect m_geometry;
     QFont m_font;
@@ -71,17 +68,6 @@ private:
     void populate(const QWebSelectData&);
 };
 
     void populate(const QWebSelectData&);
 };
 
-class QtFallbackWebPopupCombo : public QComboBox {
-public:
-    QtFallbackWebPopupCombo(QtFallbackWebPopup& ownerPopup);
-    virtual void showPopup();
-    virtual void hidePopup();
-    virtual bool eventFilter(QObject* watched, QEvent* event);
-
-private:
-    QtFallbackWebPopup& m_ownerPopup;
-};
-
 }
 
 #endif // QT_NO_COMBOBOX
 }
 
 #endif // QT_NO_COMBOBOX
diff --git a/Source/WebKit/qt/WebCoreSupport/QtWebComboBox.cpp b/Source/WebKit/qt/WebCoreSupport/QtWebComboBox.cpp
new file mode 100644 (file)
index 0000000..b6347fc
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2010 Girish Ramakrishnan <girish@forwardbias.in>
+ * Copyright (C) 2009, 2011 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "QtWebComboBox.h"
+
+#ifndef QT_NO_COMBOBOX
+
+#include <QtGui/QAbstractItemView>
+#include <QtGui/QApplication>
+#include <QtGui/QMouseEvent>
+
+namespace WebCore {
+
+QtWebComboBox::QtWebComboBox()
+    : QComboBox()
+{
+    // Install an event filter on the view inside the combo box popup to make sure we know
+    // when the popup got closed. E.g. QComboBox::hidePopup() won't be called when the popup
+    // is closed by a mouse wheel event outside its window.
+    view()->installEventFilter(this);
+}
+
+void QtWebComboBox::showPopupAtCursorPosition()
+{
+    QMouseEvent event(QEvent::MouseButtonPress, QCursor::pos(), Qt::LeftButton,
+                      Qt::LeftButton, Qt::NoModifier);
+    QApplication::sendEvent(this, &event);
+}
+
+bool QtWebComboBox::eventFilter(QObject* watched, QEvent* event)
+{
+    Q_ASSERT(watched == view());
+    if (event->type() == QEvent::Hide)
+        emit didHide();
+    return false;
+}
+
+}
+
+#endif // QT_NO_COMBOBOX
diff --git a/Source/WebKit/qt/WebCoreSupport/QtWebComboBox.h b/Source/WebKit/qt/WebCoreSupport/QtWebComboBox.h
new file mode 100644 (file)
index 0000000..6cc5f21
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef QtWebComboBox_h
+#define QtWebComboBox_h
+
+#include "Platform.h"
+
+#include <QtGui/QComboBox>
+
+#ifndef QT_NO_COMBOBOX
+
+namespace WebCore {
+
+class QtWebComboBox : public QComboBox {
+    Q_OBJECT
+public:
+    QtWebComboBox();
+
+    void showPopupAtCursorPosition();
+    virtual bool eventFilter(QObject* watched, QEvent*);
+
+Q_SIGNALS:
+    void didHide();
+};
+
+}
+
+#endif // QT_NO_COMBOBOX
+
+#endif // QtWebComboBox_h
index b423317..c0c4a35 100644 (file)
@@ -709,15 +709,6 @@ private:
         evalJS("delete retvalue; delete typevalue");
         return ret;
     }
         evalJS("delete retvalue; delete typevalue");
         return ret;
     }
-    QObject* firstChildByClassName(QObject* parent, const char* className) {
-        const QObjectList & children = parent->children();
-        foreach (QObject* child, children) {
-            if (!strcmp(child->metaObject()->className(), className)) {
-                return child;
-            }
-        }
-        return 0;
-    }
 
     const QString sTrue;
     const QString sFalse;
 
     const QString sTrue;
     const QString sFalse;
@@ -2711,8 +2702,8 @@ void tst_QWebFrame::popupFocus()
     // open the popup by clicking. check if focus is on the popup
     const QWebElement webCombo = view.page()->mainFrame()->documentElement().findFirst(QLatin1String("select[name=select]"));
     QTest::mouseClick(&view, Qt::LeftButton, 0, webCombo.geometry().center());
     // open the popup by clicking. check if focus is on the popup
     const QWebElement webCombo = view.page()->mainFrame()->documentElement().findFirst(QLatin1String("select[name=select]"));
     QTest::mouseClick(&view, Qt::LeftButton, 0, webCombo.geometry().center());
-    QObject* webpopup = firstChildByClassName(&view, "QComboBox");
-    QComboBox* combo = qobject_cast<QComboBox*>(webpopup);
+
+    QComboBox* combo = view.findChild<QComboBox*>();
     QVERIFY(combo != 0);
     QTRY_VERIFY(!view.hasFocus() && combo->view()->hasFocus()); // Focus should be on the popup
 
     QVERIFY(combo != 0);
     QTRY_VERIFY(!view.hasFocus() && combo->view()->hasFocus()); // Focus should be on the popup