2011-05-22 Hui Huang <hui.2.huang@nokia.com>, Yi Shen <yi.4.shen@nokia.com>
[webkit:qtwebkit.git] / Source / WebKit / qt / symbian / platformplugin / WebPlugin.cpp
1 /*
2  * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  *
19  */
20
21 #include "WebPlugin.h"
22
23 #if defined(WTF_USE_QT_MULTIMEDIA) && WTF_USE_QT_MULTIMEDIA
24 #include "HTML5VideoPlugin.h"
25 #endif
26
27 #include <QtGui>
28 #include <QtPlugin>
29 #include <akndiscreetpopup.h>
30
31 class ItemListDelegate : public QStyledItemDelegate {
32 public:
33     ItemListDelegate(QObject* parent = 0)
34         : QStyledItemDelegate(parent)
35     {
36     }
37
38     void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
39     {
40         Q_ASSERT(index.isValid());
41
42         QStyleOptionViewItemV4 opt = option;
43         opt.state = opt.state & (~QStyle::State_HasFocus);
44         opt.text = index.data().toString();
45         initStyleOption(&opt, index);
46
47         const QWidget* widget = 0;
48         Popup* selectPopup = qobject_cast<Popup*>(parent());
49         if (selectPopup)
50             widget = selectPopup->listWidget();
51
52         QStyle* style = widget ? widget->style() : QApplication::style();
53         style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget);
54     }
55 };
56
57 Popup::Popup(const QWebSelectData& data)
58     : m_data(data)
59 {
60     setModal(true);
61     m_list = new QListWidget(this);
62     int width = QApplication::desktop()->size().width();
63     QVBoxLayout* vLayout = new QVBoxLayout(this);
64     vLayout->setContentsMargins(width / 20, 5, 5, 5);
65     if (data.multiple())
66         m_list->setSelectionMode(QAbstractItemView::MultiSelection);
67     populateList();
68     vLayout->addWidget(m_list);
69    
70     ItemListDelegate* itemDelegate = new ItemListDelegate(this);
71     m_list->setItemDelegate(itemDelegate);
72 }
73
74 void Popup::resizeEvent(QResizeEvent* e)
75 {
76     QDialog::resizeEvent(e);
77     m_list->setGeometry(m_list->geometry().x(), m_list->geometry().y(), m_list->width(), m_list->height());
78 }
79
80 void Popup::populateList()
81 {
82     QListWidgetItem* listItem;
83     m_preSelectedIndices.clear();
84     for (int i = 0; i < m_data.itemCount(); ++i) {
85         if (m_data.itemType(i) == QWebSelectData::Option) {
86             listItem = new QListWidgetItem(m_data.itemText(i));
87             m_list->addItem(listItem);
88             listItem->setSelected(m_data.itemIsSelected(i));
89             if (m_data.itemIsSelected(i)) {
90                 m_preSelectedIndices.append(i);
91                 m_list->setCurrentItem(listItem);
92             }
93         } else if (m_data.itemType(i) == QWebSelectData::Group) {
94             listItem = new QListWidgetItem(m_data.itemText(i));
95             m_list->addItem(listItem);
96             listItem->setSelected(false);
97             listItem->setFlags(Qt::NoItemFlags);
98         }
99     }
100     connect(m_list, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(onItemSelected(QListWidgetItem*)));
101 }
102
103 void Popup::onItemSelected(QListWidgetItem* item)
104 {
105     if (item->flags() != Qt::NoItemFlags) {
106         if (!m_data.multiple())
107             updateAndClose();
108     }
109 }
110
111 void Popup::updateSelectionsBeforeDialogClosing()
112 {
113     QList<QListWidgetItem*> selected = m_list->selectedItems();
114     if (m_data.multiple()) {
115         QList<int> selectedIndices;
116         Q_FOREACH(QListWidgetItem* item, selected)
117             selectedIndices.append(m_list->row(item));
118
119         for (int i = 0; i < m_data.itemCount(); ++i) {
120             if ((m_preSelectedIndices.contains(i) && !selectedIndices.contains(i)) || (!m_preSelectedIndices.contains(i) && selectedIndices.contains(i)))
121                 emit itemClicked(i);
122         }
123     } else {
124         Q_FOREACH(QListWidgetItem* item, selected)
125             emit itemClicked(m_list->row(item));
126     }
127 }
128
129 void Popup::updateAndClose()
130 {
131     updateSelectionsBeforeDialogClosing();
132     accept();
133 }
134
135 WebPopup::WebPopup()
136     : m_popup(0)
137 {
138 }
139
140 WebPopup::~WebPopup()
141 {
142     if (m_popup)
143         m_popup->deleteLater();
144 }
145
146 Popup* WebPopup::createSingleSelectionPopup(const QWebSelectData& data)
147 {
148     return new SingleSelectionPopup(data);
149 }
150
151 Popup* WebPopup::createMultipleSelectionPopup(const QWebSelectData& data)
152 {
153     return new MultipleSelectionPopup(data);
154 }
155
156 Popup* WebPopup::createPopup(const QWebSelectData& data)
157 {
158     Popup* result = data.multiple() ? createMultipleSelectionPopup(data) : createSingleSelectionPopup(data);
159     connect(result, SIGNAL(finished(int)), this, SLOT(popupClosed()));
160     connect(result, SIGNAL(itemClicked(int)), this, SLOT(itemClicked(int)));
161     return result;
162 }
163
164 void WebPopup::show(const QWebSelectData& data)
165 {
166     if (m_popup)
167         return;
168
169     m_popup = createPopup(data);
170     m_popup->showMaximized();
171 }
172
173 void WebPopup::hide()
174 {
175     if (!m_popup)
176         return;
177
178     m_popup->accept();
179 }
180
181 void WebPopup::popupClosed()
182 {
183     if (!m_popup)
184         return;
185
186     m_popup->deleteLater();
187     m_popup = 0;
188     emit didHide();
189 }
190
191 void WebPopup::itemClicked(int idx)
192 {
193     emit selectItem(idx, true, false);
194 }
195
196 SingleSelectionPopup::SingleSelectionPopup(const QWebSelectData& data)
197     : Popup(data)
198 {
199     setWindowTitle("Select item");
200
201     QAction* cancelAction = new QAction("Cancel", this);
202     cancelAction->setSoftKeyRole(QAction::NegativeSoftKey);
203     addAction(cancelAction);
204     connect(cancelAction, SIGNAL(triggered(bool)), this, SLOT(reject()));
205 }
206
207 MultipleSelectionPopup::MultipleSelectionPopup(const QWebSelectData& data)
208     : Popup(data)
209 {
210     setWindowTitle("Select items");
211
212     QAction* cancelAction = new QAction("Cancel", this);
213     cancelAction->setSoftKeyRole(QAction::NegativeSoftKey);
214     addAction(cancelAction);
215     connect(cancelAction, SIGNAL(triggered(bool)), this, SLOT(reject()));
216
217     QAction* okAction = new QAction("Ok", this);
218     okAction->setSoftKeyRole(QAction::PositiveSoftKey);
219     addAction(okAction);
220     connect(okAction, SIGNAL(triggered(bool)), this, SLOT(updateAndClose()));
221 }
222
223 void WebNotificationPresenter::showNotification(const QWebNotificationData* data)
224 {
225     HBufC* title = HBufC::New(data->title().size());
226     *title = TPtrC(data->title().utf16(), data->title().size());
227     HBufC* message = HBufC::New(data->message().size());
228     *message = TPtrC(data->message().utf16(), data->message().size());
229     TRAP_IGNORE(CAknDiscreetPopup::ShowGlobalPopupL(*title, *message, KAknsIIDNone, KNullDesC));
230     emit notificationClosed();
231     deleteLater();
232     delete title;
233     delete message;
234 }
235
236 bool WebPlugin::supportsExtension(Extension extension) const
237 {
238     if (extension == MultipleSelections)
239         return true;
240     if (extension == Notifications)
241         return true;
242     if (extension == FullScreenVideoPlayer)
243         return true;        
244     return false;
245 }
246
247 QObject* WebPlugin::createExtension(Extension extension) const
248 {
249     switch (extension) {
250     case MultipleSelections:
251         return new WebPopup();
252     case Notifications:
253         return new WebNotificationPresenter();
254 #if defined(WTF_USE_QT_MULTIMEDIA) && WTF_USE_QT_MULTIMEDIA
255     case FullScreenVideoPlayer:
256         return new HTML5FullScreenVideoHandler();
257 #endif
258     default:
259         return 0;
260     }
261 }
262
263 Q_EXPORT_PLUGIN2(qwebselectim, WebPlugin)