Home | History | Annotate | Download | only in WebCoreSupport
      1 /*
      2  * Copyright (C) 2010 Girish Ramakrishnan <girish (at) forwardbias.in>
      3  * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
      4  *
      5  * This library is free software; you can redistribute it and/or
      6  * modify it under the terms of the GNU Library General Public
      7  * License as published by the Free Software Foundation; either
      8  * version 2 of the License, or (at your option) any later version.
      9  *
     10  * This library is distributed in the hope that it will be useful,
     11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13  * Library General Public License for more details.
     14  *
     15  * You should have received a copy of the GNU Library General Public License
     16  * along with this library; see the file COPYING.LIB.  If not, write to
     17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     18  * Boston, MA 02110-1301, USA.
     19  *
     20  */
     21 #include "config.h"
     22 #include "QtFallbackWebPopup.h"
     23 
     24 #include "HostWindow.h"
     25 #include "PopupMenuClient.h"
     26 #include "qgraphicswebview.h"
     27 #include "QWebPageClient.h"
     28 #include <QAbstractItemView>
     29 #include <QApplication>
     30 #include <QGraphicsProxyWidget>
     31 #include <QGraphicsScene>
     32 #include <QGraphicsView>
     33 #include <QInputContext>
     34 #include <QMouseEvent>
     35 #include <QStandardItemModel>
     36 
     37 namespace WebCore {
     38 
     39 QtFallbackWebPopupCombo::QtFallbackWebPopupCombo(QtFallbackWebPopup& ownerPopup)
     40     : m_ownerPopup(ownerPopup)
     41 {
     42 }
     43 
     44 void QtFallbackWebPopupCombo::showPopup()
     45 {
     46     QComboBox::showPopup();
     47     m_ownerPopup.m_popupVisible = true;
     48 }
     49 
     50 void QtFallbackWebPopupCombo::hidePopup()
     51 {
     52     QWidget* activeFocus = QApplication::focusWidget();
     53     if (activeFocus && activeFocus == QComboBox::view()
     54         && activeFocus->testAttribute(Qt::WA_InputMethodEnabled)) {
     55         QInputContext* qic = activeFocus->inputContext();
     56         if (qic) {
     57             qic->reset();
     58             qic->setFocusWidget(0);
     59         }
     60     }
     61 
     62     QComboBox::hidePopup();
     63 
     64     if (QGraphicsProxyWidget* proxy = graphicsProxyWidget())
     65         proxy->setVisible(false);
     66 
     67     if (!m_ownerPopup.m_popupVisible)
     68         return;
     69 
     70     m_ownerPopup.m_popupVisible = false;
     71     m_ownerPopup.popupDidHide();
     72 }
     73 
     74 // QtFallbackWebPopup
     75 
     76 QtFallbackWebPopup::QtFallbackWebPopup()
     77     : QtAbstractWebPopup()
     78     , m_popupVisible(false)
     79     , m_combo(new QtFallbackWebPopupCombo(*this))
     80     , m_proxy(0)
     81 {
     82     connect(m_combo, SIGNAL(activated(int)),
     83             SLOT(activeChanged(int)), Qt::QueuedConnection);
     84 }
     85 
     86 QtFallbackWebPopup::~QtFallbackWebPopup()
     87 {
     88     // If we create a proxy, then the deletion of the proxy and the
     89     // combo will be done by the proxy's parent (QGraphicsWebView)
     90     if (!m_proxy)
     91         delete m_combo;
     92 }
     93 
     94 void QtFallbackWebPopup::show()
     95 {
     96     populate();
     97     m_combo->setCurrentIndex(currentIndex());
     98 
     99 #if defined(Q_WS_MAEMO_5)
    100     // Comboboxes with Qt on Maemo 5 come up in their full width on the screen, so neither
    101     // the proxy widget, nor the coordinates are needed.
    102     m_combo->setParent(pageClient()->ownerWidget());
    103     m_combo->showPopup();
    104     return;
    105 #endif
    106 
    107     QRect rect = geometry();
    108     if (QGraphicsWebView *webView = qobject_cast<QGraphicsWebView*>(pageClient()->pluginParent())) {
    109         if (!m_proxy) {
    110             m_proxy = new QGraphicsProxyWidget(webView);
    111             m_proxy->setWidget(m_combo);
    112         } else
    113             m_proxy->setVisible(true);
    114         m_proxy->setGeometry(rect);
    115     } else {
    116         m_combo->setParent(pageClient()->ownerWidget());
    117         m_combo->setGeometry(QRect(rect.left(), rect.top(),
    118                                rect.width(), m_combo->sizeHint().height()));
    119 
    120     }
    121 
    122     // QCursor::pos() is not a great idea for a touch screen, but as Maemo 5 is handled
    123     // separately above, this should be okay.
    124     QMouseEvent event(QEvent::MouseButtonPress, QCursor::pos(), Qt::LeftButton,
    125                       Qt::LeftButton, Qt::NoModifier);
    126     QCoreApplication::sendEvent(m_combo, &event);
    127 }
    128 
    129 void QtFallbackWebPopup::hide()
    130 {
    131     m_combo->hidePopup();
    132 }
    133 
    134 void QtFallbackWebPopup::populate()
    135 {
    136     m_combo->clear();
    137 
    138     QStandardItemModel* model = qobject_cast<QStandardItemModel*>(m_combo->model());
    139     Q_ASSERT(model);
    140 
    141 #if !defined(Q_WS_S60) && !defined(Q_WS_MAEMO_5)
    142     m_combo->setFont(font());
    143 #endif
    144     for (int i = 0; i < itemCount(); ++i) {
    145         switch (itemType(i)) {
    146         case Separator:
    147             m_combo->insertSeparator(i);
    148             break;
    149         case Group:
    150             m_combo->insertItem(i, itemText(i));
    151             model->item(i)->setEnabled(false);
    152             break;
    153         case Option:
    154             m_combo->insertItem(i, itemText(i));
    155             model->item(i)->setEnabled(itemIsEnabled(i));
    156             break;
    157         }
    158     }
    159 }
    160 
    161 void QtFallbackWebPopup::activeChanged(int index)
    162 {
    163     if (index < 0)
    164         return;
    165 
    166     valueChanged(index);
    167 }
    168 
    169 }
    170